diff options
Diffstat (limited to 'docker-tools')
-rw-r--r-- | docker-tools/pom.xml | 77 | ||||
-rw-r--r-- | docker-tools/src/main/java/com/yahoo/vespa/hosted/dockerapi/tool/PullImageCommand.java | 122 |
2 files changed, 199 insertions, 0 deletions
diff --git a/docker-tools/pom.xml b/docker-tools/pom.xml new file mode 100644 index 00000000000..ab6dd9303b2 --- /dev/null +++ b/docker-tools/pom.xml @@ -0,0 +1,77 @@ +<?xml version="1.0"?> +<!-- Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. --> +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <!-- Cannot have parent, as we will get wrong jersey dependencies --> + + <groupId>com.yahoo.vespa</groupId> + <artifactId>docker-tools</artifactId> + <version>6-SNAPSHOT</version> + <name>${project.artifactId}</name> + + <dependencies> + <dependency> + <groupId>com.github.docker-java</groupId> + <artifactId>docker-java</artifactId> + <version>3.0.6</version> + </dependency> + <dependency> + <groupId>com.yahoo.vespa</groupId> + <artifactId>vespalog</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>io.airlift</groupId> + <artifactId>airline</artifactId> + <version>0.7</version> + </dependency> + + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>com.yahoo.vespa</groupId> + <artifactId>bundle-plugin</artifactId> + <extensions>true</extensions> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.1</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + <compilerArgs> + <arg>-Xlint:all</arg> + <arg>-Werror</arg> + </compilerArgs> + </configuration> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-assembly-plugin</artifactId> + <version>2.4</version> + <configuration> + <finalName>docker-tools</finalName> + <descriptorRefs> + <descriptor>jar-with-dependencies</descriptor> + </descriptorRefs> + </configuration> + <executions> + <execution> + <id>make-assembly</id> + <phase>package</phase> + <goals> + <goal>single</goal> + </goals> + </execution> + </executions> + </plugin> + </plugins> + </build> +</project> diff --git a/docker-tools/src/main/java/com/yahoo/vespa/hosted/dockerapi/tool/PullImageCommand.java b/docker-tools/src/main/java/com/yahoo/vespa/hosted/dockerapi/tool/PullImageCommand.java new file mode 100644 index 00000000000..b6018134867 --- /dev/null +++ b/docker-tools/src/main/java/com/yahoo/vespa/hosted/dockerapi/tool/PullImageCommand.java @@ -0,0 +1,122 @@ +// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.dockerapi.tool; + +import com.github.dockerjava.api.command.DockerCmdExecFactory; +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.core.DefaultDockerClientConfig; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.DockerClientImpl; +import com.github.dockerjava.core.RemoteApiVersion; +import com.github.dockerjava.core.command.PullImageResultCallback; + +import com.github.dockerjava.jaxrs.JerseyDockerCmdExecFactory; + +import io.airlift.airline.Arguments; +import io.airlift.airline.Cli; +import io.airlift.airline.Command; +import io.airlift.airline.Help; +import io.airlift.airline.ParseArgumentsUnexpectedException; +import io.airlift.airline.ParseOptionMissingException; + +import java.lang.InterruptedException; +import java.lang.String; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +/** + * Command to pull a Docker image + */ +public class PullImageCommand { + static final String dockerDaemonUri = "unix:///host/var/run/docker.sock"; + + @SuppressWarnings("unchecked") + public static void main(String[] args) { + Cli.CliBuilder<Runnable> builder = Cli.<Runnable>builder("pull-image") + .withDescription("tool to pull a Docker image from a Docker repo") + .withDefaultCommand(Help.class) + .withCommands(PullImage.class); + Cli<Runnable> gitParser = builder.build(); + try { + gitParser.parse(args).run(); + } catch (ParseArgumentsUnexpectedException | ParseOptionMissingException e) { + System.err.println(e.getMessage()); + gitParser.parse("help").run(); + } + } + + @Command(name = "pull-image", description = "Pulls a Docker image") + public static class PullImage implements Runnable { + + @Arguments(description = "Docker image to pull") + public String image; + + public void run() { + System.out.println("\nPulling Docker image " + image); + final CompletableFuture<String> pullResult = pullImage(image); + try { + pullResult.get(30, TimeUnit.MINUTES); + } catch (InterruptedException | ExecutionException | TimeoutException e) { + System.out.println("Failed to pull Docker image " + image + ": " + e); + System.out.println(e.getMessage()); + System.exit(1); + } + } + + private CompletableFuture<String> pullImage(String image) { + DockerClient dockerClient = createDockerClient(); + final CompletableFuture<String> completionListener = new CompletableFuture<>(); + dockerClient.pullImageCmd(image).exec(new ImagePullCallback(image, completionListener)); + return completionListener; + } + + private class ImagePullCallback extends PullImageResultCallback { + private final String dockerImage; + private final CompletableFuture<String> completableFuture; + + private ImagePullCallback(String dockerImage, CompletableFuture<String> completableFuture) { + this.dockerImage = dockerImage; + this.completableFuture = completableFuture; + } + + @Override + public void onError(Throwable throwable) { + } + + @Override + public void onComplete() { + System.out.println("Finished pulling Docker image " + dockerImage); + completableFuture.complete(dockerImage); + } + } + + private DockerClient createDockerClient() { + DockerCmdExecFactory dockerFactory = new JerseyDockerCmdExecFactory(); + RemoteApiVersion remoteApiVersion; + DefaultDockerClientConfig.Builder dockerConfigBuilder = new DefaultDockerClientConfig.Builder() + .withDockerHost(dockerDaemonUri); + DockerClientConfig dockerClientConfig; + try { + dockerClientConfig = dockerConfigBuilder.build(); + remoteApiVersion = RemoteApiVersion.parseConfig(DockerClientImpl.getInstance(dockerClientConfig) + .withDockerCmdExecFactory(dockerFactory) + .versionCmd() + .exec() + .getApiVersion()); + // From version 1.24 a field was removed which causes trouble with the current docker java code. + // When this is fixed, we can remove this and do not specify version. + if (remoteApiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_24)) { + remoteApiVersion = RemoteApiVersion.VERSION_1_23; + } + } catch (Exception e) { + remoteApiVersion = RemoteApiVersion.VERSION_1_23; + } + + return DockerClientImpl.getInstance( + dockerConfigBuilder.withApiVersion(remoteApiVersion).build()) + .withDockerCmdExecFactory(dockerFactory); + } + } + +} |