diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..9a39f917 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Unix shell files use Unix line endings +*.sh text eol=lf + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore index 8f1fdc77..8e77a15b 100644 --- a/.gitignore +++ b/.gitignore @@ -20,5 +20,8 @@ target # Ignore all log files *.log +# Ignore all dot files +.* + #Ignore Test Output -test-output \ No newline at end of file +test-output diff --git a/LICENSE b/LICENSE index d6456956..38275f2f 100644 --- a/LICENSE +++ b/LICENSE @@ -187,7 +187,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [yyyy] [name of copyright owner] + Copyright [2013] [docker-java@googlegroups.com] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index 24cfc9ad..8eff82a2 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ -# docker-java +# docker-java Java API client for [Docker](http://docs.docker.io/ "Docker") -Supports a subset of the Docker Client API v1.11, Docker Server version 0.11 +Supports a subset of the Docker Client API v1.15, Docker Server version 1.3.0 + +The current implementation is based on Jersey 2.x and therefore classpath incompatible with older Jersey 1.x dependent libraries! Developer forum for [docker-java](https://groups.google.com/forum/?hl=de#!forum/docker-java-dev "docker-java") @@ -10,136 +12,118 @@ Developer forum for [docker-java](https://groups.google.com/forum/?hl=de#!forum/ ###### Prerequisites: -* Java 1.6+ +* Java 1.6 * Maven 3.0.5 * Docker daemon running -Maven may run tests during build process but tests are disabled by default. The tests are using a localhost instance of Docker, make sure that you have Docker running for tests to work. To run the tests you have to provide your https://www.docker.io/account/login/ information: +The Maven build includes integration tests which are using a localhost instance of Docker and require manual setup. Make sure you have a local Docker daemon running and then provide your https://registry.hub.docker.com/account/login/ information via system properties: + + $ mvn clean install -Ddocker.io.username=... -Ddocker.io.password=... -Ddocker.io.email=... + +_If your Docker server is remote, add its URL like this: `-Ddocker.io.url=https://...:2376`._ - $ mvn clean install -DskipTests=false -Ddocker.io.username=... -Ddocker.io.password=... -Ddocker.io.email=... +If you do not have access to a Docker server or just want to execute the build quickly, you can run the build without the integration tests: + + $ mvn clean install -DskipITs By default Docker server is using UNIX sockets for communication with the Docker client, however docker-java client uses TCP/IP to connect to the Docker server, so you will need to make sure that your Docker server is listening on TCP port. To allow Docker server to use TCP add the following line to /etc/default/docker - DOCKER_OPTS="-H tcp://127.0.0.1:4243 -H unix:///var/run/docker.sock" + DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock" -More details setting up docket server can be found in official documentation: http://docs.docker.io/en/latest/use/basics/ +More details setting up Docker server can be found in official documentation: http://docs.docker.io/en/latest/use/basics/ Now make sure that docker is up: - $ docker -H tcp://127.0.0.1:4243 version + $ docker -H tcp://127.0.0.1:2375 version + + Client version: 0.8.0 + Go version (client): go1.2 + Git commit (client): cc3a8c8 + Server version: 1.2.0 + Git commit (server): fa7b24f + Go version (server): go1.3.1 - Client version: 0.8.1 - Go version (client): go1.2 - Git commit (client): a1598d1 - Server version: 0.8.1 - Git commit (server): a1598d1 - Go version (server): go1.2 - Last stable version: 0.8.1 +Run build without integration tests: -Run build with tests: + $ mvn clean install -DskipITs - $ mvn clean install +## Docker-Java maven dependencies -## Docker-Java maven dependency: +### Latest release version - com.kpelykh + com.github.docker-java docker-java - 0.8.1 + 0.10.2 +### Latest SNAPSHOT version -## Example code snippets: - - DockerClient dockerClient = new DockerClient("http://localhost:4243"); - -###### Get Docker info: - - Info info = dockerClient.info(); - System.out.print(info); - -###### Search Docker repository: - - List dockerSearch = dockerClient.search("busybox"); - System.out.println("Search returned" + dockerSearch.toString()); - -###### Create new Docker container, wait for its start and stop it: - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] {"touch", "/test"}); - ContainerCreateResponse container = dockerClient.createContainer(containerConfig); - - dockerClient.startContainer(container.id); - - dockerClient.waitContainer(container.id); - - dockerClient.stopContainer(container.id); - - -##### Support for UNIX sockets: - - Support for UNIX socket should appear in docker-java pretty soon. I'm working on its integration. - -##### Docker Builder: - -To use Docker Builder, as described on page http://docs.docker.io/en/latest/use/builder/, -user dockerClient.build(baseDir), where baseDir is a path to folder containing Dockerfile. - - - File baseDir = new File("~/kpelykh/docker/netcat"); - - ClientResponse response = dockerClient.build(baseDir); - - StringWriter logwriter = new StringWriter(); - - try { - LineIterator itr = IOUtils.lineIterator(response.getEntityInputStream(), "UTF-8"); - while (itr.hasNext()) { - String line = itr.next(); - logwriter.write(line); - LOG.info(line); - } - } finally { - IOUtils.closeQuietly(response.getEntityInputStream()); - } + + com.github.docker-java + docker-java + 0.10.3-SNAPSHOT + +Latest SNAPSHOT is published to maven repo: https://oss.sonatype.org/content/groups/public via ![Build on CloudBees](http://cloudbees.prod.acquia-sites.com/sites/default/files/styles/large/public/Button-Powered-by-CB.png?itok=uMDWINfY) +## Documentation -For additional examples, please look at [DockerClientTest.java](https://github.com/kpelykh/docker-java/blob/master/src/test/java/com/kpelykh/docker/client/test/DockerClientTest.java "DockerClientTest.java") +For code examples, please look at the [Wiki](https://github.com/docker-java/docker-java/wiki) or [Test cases](https://github.com/docker-java/docker-java/tree/master/src/test/java/com/github/dockerjava/core/command "Test cases") ## Configuration There are a couple of configuration items, all of which have sensible defaults: -* `url` The Docker URL, e.g. `http://localhost:4243`. -* `version` The API version, e.g. `1.11`. +* `url` The Docker URL, e.g. `https://localhost:2376`. +* `version` The API version, e.g. `1.15`. * `username` Your repository username (required to push containers). * `password` Your repository password. * `email` Your repository email. +* `dockerCertPath` Path to the docker certs. There are three ways to configure, in descending order of precedence: -##### Programatic: +#### Programmatic: In your application, e.g. - DockerClient docker = new DockerClient("http://localhost:4243"); - docker.setCredentials("dockeruser", "ilovedocker", "dockeruser@github.com");` + DockerClientConfig config = DockerClientConfig.createDefaultConfigBuilder() + .withVersion("1.15") + .withUri("https://my-docker-host.tld:2376") + .withUsername("dockeruser") + .withPassword("ilovedocker") + .withEmail("dockeruser@github.com") + .withDockerCertPath("/home/user/.docker") + .build(); + DockerClient docker = DockerClientBuilder.getInstance(config).build(); + +#### Properties + + docker.io.url=https://localhost:2376 + docker.io.version=1.15 + docker.io.username=dockeruser + docker.io.password=ilovedocker + docker.io.email=dockeruser@github.com + docker.io.dockerCertPath=/home/user/.docker + ##### System Properties: -E.g. - java -Ddocker.io.username=kpelykh pkg.Main + java -Ddocker.io.username=dockeruser pkg.Main + +##### System Environment + + export DOCKER_URL=http://localhost:2376 + +Note: we also auto-detect defaults. If you use `DOCKER_HOST` we use that value, and if `DOCKER_CERT_PATH` is set, we switch to SSL. ##### File System -In `$HOME/.docker.io.properties`, e.g.: - docker.io.username=dockeruser +In `$HOME/.docker.io.properties` ##### Class Path -In the class path at `/docker.io.properties`, e.g.: - docker.io.url=http://localhost:4243 - docker.io.version=1.11 +In the class path at `/docker.io.properties` + diff --git a/pom.xml b/pom.xml index 3de239d1..9f4101bc 100644 --- a/pom.xml +++ b/pom.xml @@ -1,305 +1,417 @@ - - 4.0.0 - - - org.sonatype.oss - oss-parent - 7 - - - com.kpelykh - docker-java - jar - 0.8.2-SNAPSHOT - - docker-java - https://github.com/kpelykh/docker-java - Java API Client for Docker - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - - scm:git:git@github.com:kpelykh/docker-java.git - git@github.com:kpelykh/docker-java.git - scm:git:git@github.com:kpelykh/docker-java.git - - - - - kpelykh - Konstantin Pelykh - kpelykh@gmail.com - - - - - true - - UTF-8 - true - false - 1.6 - 1.6 - - 1.6.1 - - 1.18 - 1.9 - - 2.3.3 - - 4.2.5 - 1.5 - 2.3 - 2.6 - 1.7.5 - 1.3.9 - 0.3 - - - 1.0.1 - 5.12.1 - 1.3 - 1.6 - 2.3.3 - - - 2.2 - 2.3.1 - 2.3.1 - 2.8.1 - 2.5.1 - 1.7 - - - + + 4.0.0 + + + org.sonatype.oss + oss-parent + 9 + + + com.github.docker-java + docker-java + jar + 1.3 + + docker-java + https://github.com/docker-java/docker-java + Java API Client for Docker + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + + + + + scm:git:git@github.com:docker-java/docker-java.git + git@github.com:docker-java/docker-java.git + scm:git:git@github.com:docker-java/docker-java.git + HEAD + + + + + kpelykh + Konstantin Pelykh + kpelykh@gmail.com + + + + + UTF-8 + UTF-8 + true + false + 1.6 + 1.6 + + 1.6.1 + + 2.6 + 1.9 + + 2.3.3 + + 4.2.5 + 1.5 + 1.8 + 2.3 + 2.6 + 1.7.5 + 1.3.9 + 0.3 + 18.0 + 1.51 + + + 1.0.1 + 5.12.1 + 1.3 + 1.6 + 2.3.3 + + + 2.2 + 2.3.1 + 2.3.1 + 2.17 + 2.17 + 2.5.1 + 1.7 + + + + + junit + junit + 4.11 + test + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-json-provider + ${jackson-jaxrs.version} + + + + + + + + org.glassfish.jersey.core + jersey-client + ${jersey.version} + + + + org.apache.commons + commons-compress + ${commons-compress.version} + - com.fasterxml.jackson.jaxrs - jackson-jaxrs-json-provider - ${jackson-jaxrs.version} + commons-codec + commons-codec + ${commons-codec.version} - - com.sun.jersey - jersey-core - ${jersey.version} - - - com.sun.jersey - jersey-client - ${jersey.version} - - - - com.sun.jersey.contribs - jersey-multipart - ${jersey.version} - - - com.sun.jersey.contribs - jersey-apache-client4 - ${jersey-apache-client4.version} - - - - org.apache.httpcomponents - httpclient - ${httpclient.version} + + commons-lang + commons-lang + ${commons-lang.version} + + + commons-io + commons-io + ${commons-io.version} + + + + com.github.jnr + jnr-unixsocket + ${jnr.unixsocket.version} + + + + org.slf4j + slf4j-api + ${slf4j-api.version} + + + + org.slf4j + jul-to-slf4j + ${slf4j-api.version} + + + + com.google.guava + guava + ${guava.version} - - - org.apache.commons - commons-compress - ${commons-compress.version} - - - commons-lang - commons-lang - ${commons-lang.version} - - - commons-io - commons-io - ${commons-io.version} - - - - com.github.jnr - jnr-unixsocket - ${jnr.unixsocket.version} - - - - org.slf4j - slf4j-api - ${slf4j-api.version} - - - - org.slf4j - jul-to-slf4j - ${slf4j-api.version} - - - - - ch.qos.logback - logback-core - ${version.logback} - test - - - - ch.qos.logback - logback-classic - ${version.logback} - test - - - - org.testng - testng - ${version.testng} - test - - - - org.hamcrest - hamcrest-library - ${hamcrest.library.version} - test - - - - com.googlecode.lambdaj - lambdaj - ${lambdaj.version} - test - - - org.hamcrest - hamcrest-all - - - - + - org.testinfected.hamcrest-matchers - jpa-matchers - ${hamcrest.jpa-matchers} - test + org.bouncycastle + bcpkix-jdk15on + ${bouncycastle.version} - - - - - com.github.jnr - jffi - 1.2.7 - - - com.github.jnr - jffi - native - 1.2.7 - - - - - - - - - - - org.apache.maven.plugins - maven-release-plugin - ${maven-release-plugin.version} - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven-compiler-plugin.version} - - ${jdk.source} - ${jdk.target} - ISO-8859-1 - ${jdk.debug} - ${jdk.optimize} - - - - - org.apache.maven.plugins - maven-jar-plugin - ${maven-jar-plugin.version} - - - - test-jar - - - - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven-surefire-plugin.version} - - ${skipTests} - - - - - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura-maven-plugin.version} - - - - org.apache.maven.plugins - maven-antrun-plugin - ${maven-antrun-plugin.version} - - - validate - - run - - - - ******************************************************************* - ******************************************************************* - [project.name] : ${project.name} - [project.basedir] : ${project.basedir} - [project.version] : ${project.version} - [project.artifactId] ${project.artifactId} - [project.build.directory] ${project.build.directory} - [jdk.source] : ${jdk.source} - [jdk.target] : ${jdk.target} - [jdk.debug] : ${jdk.debug} - [jdk.optimize] : ${jdk.optimize} - [source encoding]: ${project.build.sourceEncoding} - [LocalRepository] : ${settings.localRepository} - ******************************************************************* - ******************************************************************* - - - - - - - - - + + + ch.qos.logback + logback-core + ${version.logback} + test + + + + ch.qos.logback + logback-classic + ${version.logback} + test + + + + org.testng + testng + ${version.testng} + test + + + + org.hamcrest + hamcrest-library + ${hamcrest.library.version} + test + + + + com.googlecode.lambdaj + lambdaj + ${lambdaj.version} + test + + + org.hamcrest + hamcrest-all + + + + + + org.testinfected.hamcrest-matchers + jpa-matchers + ${hamcrest.jpa-matchers} + test + + + + + + com.github.jnr + jffi + 1.2.7 + + + com.github.jnr + jffi + native + 1.2.7 + + + + + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + + + + + + + + + org.apache.maven.plugins + maven-release-plugin + ${maven-release-plugin.version} + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${jdk.source} + ${jdk.target} + ${jdk.debug} + ${jdk.optimize} + + + + + org.apache.maven.plugins + maven-jar-plugin + ${maven-jar-plugin.version} + + + + test-jar + + + + + + + org.codehaus.mojo + cobertura-maven-plugin + ${cobertura-maven-plugin.version} + + + + org.apache.maven.plugins + maven-antrun-plugin + ${maven-antrun-plugin.version} + + + validate + + run + + + + ******************************************************************* + ******************************************************************* + [project.name] : ${project.name} + [project.basedir] : ${project.basedir} + [project.version] : ${project.version} + [project.artifactId] ${project.artifactId} + [project.build.directory] ${project.build.directory} + [jdk.source] : ${jdk.source} + [jdk.target] : ${jdk.target} + [jdk.debug] : ${jdk.debug} + [jdk.optimize] : ${jdk.optimize} + [source encoding]: ${project.build.sourceEncoding} + [LocalRepository] : ${settings.localRepository} + ******************************************************************* + ******************************************************************* + + + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.2 + true + + ossrh + https://oss.sonatype.org/ + true + + + + + org.apache.maven.plugins + maven-release-plugin + 2.5 + + true + false + release + deploy nexus-staging:release + + + + + + + + + release + + + + org.apache.maven.plugins + maven-gpg-plugin + + + sign-artifacts + verify + + sign + + + + + + + org.apache.maven.plugins + maven-source-plugin + 2.2.1 + + + attach-sources + + jar-no-fork + + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + + + + + diff --git a/src/main/java/com/github/dockerjava/api/BadRequestException.java b/src/main/java/com/github/dockerjava/api/BadRequestException.java new file mode 100644 index 00000000..1e04bcb3 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/BadRequestException.java @@ -0,0 +1,23 @@ +package com.github.dockerjava.api; + + +/** + * + */ +public class BadRequestException extends DockerException { + + private static final long serialVersionUID = -2450396075981100160L; + + public BadRequestException(String message, Throwable cause) { + super(message, 400, cause); + } + + public BadRequestException(String message) { + this(message, null); + } + + public BadRequestException(Throwable cause) { + this(cause.getMessage(), cause); + } + +} diff --git a/src/main/java/com/github/dockerjava/api/ConflictException.java b/src/main/java/com/github/dockerjava/api/ConflictException.java new file mode 100644 index 00000000..bed2a375 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/ConflictException.java @@ -0,0 +1,23 @@ +package com.github.dockerjava.api; + + +/** + * + */ +public class ConflictException extends DockerException { + + private static final long serialVersionUID = -290093024775500239L; + + public ConflictException(String message, Throwable cause) { + super(message, 409, cause); + } + + public ConflictException(String message) { + this(message, null); + } + + public ConflictException(Throwable cause) { + this(cause.getMessage(), cause); + } + +} diff --git a/src/main/java/com/github/dockerjava/api/DeviceIsBusyException.java b/src/main/java/com/github/dockerjava/api/DeviceIsBusyException.java new file mode 100644 index 00000000..38c2e2f6 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/DeviceIsBusyException.java @@ -0,0 +1,21 @@ +package com.github.dockerjava.api; + +public class DeviceIsBusyException extends DockerException { + + /** + * + */ + private static final long serialVersionUID = 8301793561056058849L; + + public DeviceIsBusyException(String message, Throwable cause) { + super(message, 599, cause); + } + + public DeviceIsBusyException(String message) { + this(message, null); + } + + public DeviceIsBusyException(Throwable cause) { + this(cause.getMessage(), cause); + } +} diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java new file mode 100644 index 00000000..52323942 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/DockerClient.java @@ -0,0 +1,123 @@ +package com.github.dockerjava.api; + +import java.io.*; + +import com.github.dockerjava.api.command.AttachContainerCmd; +import com.github.dockerjava.api.command.AuthCmd; +import com.github.dockerjava.api.command.BuildImageCmd; +import com.github.dockerjava.api.command.CommitCmd; +import com.github.dockerjava.api.command.ContainerDiffCmd; +import com.github.dockerjava.api.command.CopyFileFromContainerCmd; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateImageCmd; +import com.github.dockerjava.api.command.EventCallback; +import com.github.dockerjava.api.command.EventsCmd; +import com.github.dockerjava.api.command.InfoCmd; +import com.github.dockerjava.api.command.InspectContainerCmd; +import com.github.dockerjava.api.command.InspectImageCmd; +import com.github.dockerjava.api.command.KillContainerCmd; +import com.github.dockerjava.api.command.ListContainersCmd; +import com.github.dockerjava.api.command.ListImagesCmd; +import com.github.dockerjava.api.command.LogContainerCmd; +import com.github.dockerjava.api.command.PauseContainerCmd; +import com.github.dockerjava.api.command.PingCmd; +import com.github.dockerjava.api.command.PullImageCmd; +import com.github.dockerjava.api.command.PushImageCmd; +import com.github.dockerjava.api.command.RemoveContainerCmd; +import com.github.dockerjava.api.command.RemoveImageCmd; +import com.github.dockerjava.api.command.RestartContainerCmd; +import com.github.dockerjava.api.command.SearchImagesCmd; +import com.github.dockerjava.api.command.StartContainerCmd; +import com.github.dockerjava.api.command.StopContainerCmd; +import com.github.dockerjava.api.command.TagImageCmd; +import com.github.dockerjava.api.command.TopContainerCmd; +import com.github.dockerjava.api.command.UnpauseContainerCmd; +import com.github.dockerjava.api.command.VersionCmd; +import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.model.AuthConfig; + +// https://godoc.org/github.com/fsouza/go-dockerclient +public interface DockerClient extends Closeable { + + public AuthConfig authConfig() throws DockerException; + + /** + * Authenticate with the server, useful for checking authentication. + */ + public AuthCmd authCmd(); + + public InfoCmd infoCmd(); + + public PingCmd pingCmd(); + + public VersionCmd versionCmd(); + + /** + * * IMAGE API * + */ + + public PullImageCmd pullImageCmd(String repository); + + public PushImageCmd pushImageCmd(String name); + + public CreateImageCmd createImageCmd(String repository, + InputStream imageStream); + + public SearchImagesCmd searchImagesCmd(String term); + + public RemoveImageCmd removeImageCmd(String imageId); + + public ListImagesCmd listImagesCmd(); + + public InspectImageCmd inspectImageCmd(String imageId); + + /** + * * CONTAINER API * + */ + + public ListContainersCmd listContainersCmd(); + + public CreateContainerCmd createContainerCmd(String image); + + public StartContainerCmd startContainerCmd(String containerId); + + public InspectContainerCmd inspectContainerCmd(String containerId); + + public RemoveContainerCmd removeContainerCmd(String containerId); + + public WaitContainerCmd waitContainerCmd(String containerId); + + public AttachContainerCmd attachContainerCmd(String containerId); + + public LogContainerCmd logContainerCmd(String containerId); + + public CopyFileFromContainerCmd copyFileFromContainerCmd( + String containerId, String resource); + + public ContainerDiffCmd containerDiffCmd(String containerId); + + public StopContainerCmd stopContainerCmd(String containerId); + + public KillContainerCmd killContainerCmd(String containerId); + + public RestartContainerCmd restartContainerCmd(String containerId); + + public CommitCmd commitCmd(String containerId); + + public BuildImageCmd buildImageCmd(File dockerFolder); + + public BuildImageCmd buildImageCmd(InputStream tarInputStream); + + public TopContainerCmd topContainerCmd(String containerId); + + public TagImageCmd tagImageCmd(String imageId, String repository, String tag); + + public PauseContainerCmd pauseContainerCmd(String containerId); + + public UnpauseContainerCmd unpauseContainerCmd(String containerId); + + public EventsCmd eventsCmd(EventCallback eventCallback); + + public void close() throws IOException; + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/DockerClientException.java b/src/main/java/com/github/dockerjava/api/DockerClientException.java new file mode 100644 index 00000000..85efc349 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/DockerClientException.java @@ -0,0 +1,18 @@ +package com.github.dockerjava.api; + +/** + * + * + */ +public class DockerClientException extends RuntimeException { + +private static final long serialVersionUID = 7667768099261650608L; + + public DockerClientException(String message) { + super(message); + } + + public DockerClientException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/src/main/java/com/github/dockerjava/api/DockerException.java b/src/main/java/com/github/dockerjava/api/DockerException.java new file mode 100644 index 00000000..673bf2cc --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/DockerException.java @@ -0,0 +1,30 @@ +package com.github.dockerjava.api; + + + + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ + +public class DockerException extends RuntimeException { + +private static final long serialVersionUID = 7667768099261650608L; + + private int httpStatus = 0; + + public DockerException(String message, int httpStatus) { + super(message); + this.httpStatus = httpStatus; + } + + public DockerException(String message, int httpStatus, Throwable cause) { + super(message, cause); + } + + public int getHttpStatus() { + return httpStatus; + } +} diff --git a/src/main/java/com/github/dockerjava/api/EnhancedDockerClient.java b/src/main/java/com/github/dockerjava/api/EnhancedDockerClient.java new file mode 100644 index 00000000..bcd19f26 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/EnhancedDockerClient.java @@ -0,0 +1,36 @@ +package com.github.dockerjava.api; + +import com.github.dockerjava.api.command.CgroupContainerCmd; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateExecCmd; +import com.github.dockerjava.api.command.ExecContainerCmd; +import com.github.dockerjava.api.command.LimitContainerCmd; +import com.github.dockerjava.api.command.MetricContainerCmd; +import com.github.dockerjava.api.command.StartContainerCmd; +import com.github.dockerjava.api.command.StartExecCmd; +import com.github.dockerjava.api.command.SweepContainerCmd; +import com.github.dockerjava.api.model.CreateContainerConfig; +import com.github.dockerjava.api.model.LimitationConfig; +import com.github.dockerjava.api.model.StartContainerConfig; + + +public interface EnhancedDockerClient extends DockerClient { + + public CgroupContainerCmd cgroupContainerCmd(String containerId); + + public SweepContainerCmd sweepContainerCmd(String containerId); + + public MetricContainerCmd metricContainerCmd(String containerId); + + public CreateExecCmd createExecCmd(String containerId); + + public StartExecCmd startExecCmd(String execId); + + public ExecContainerCmd execContainerCmd(String containerId); + + public CreateContainerCmd createContainerCmd(CreateContainerConfig createContainerConfig); + + public StartContainerCmd startContainerCmd(String containerId, StartContainerConfig startContainerConfig); + + public LimitContainerCmd limitContainerCmd(LimitationConfig limitationConfig, String containerId); +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/InternalServerErrorException.java b/src/main/java/com/github/dockerjava/api/InternalServerErrorException.java new file mode 100644 index 00000000..366484e5 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/InternalServerErrorException.java @@ -0,0 +1,22 @@ +package com.github.dockerjava.api; + +/** + * + */ +public class InternalServerErrorException extends DockerException { + + private static final long serialVersionUID = -2450396075981100160L; + + public InternalServerErrorException(String message, Throwable cause) { + super(message, 500, cause); + } + + public InternalServerErrorException(String message) { + this(message, null); + } + + public InternalServerErrorException(Throwable cause) { + this(cause.getMessage(), cause); + } + +} diff --git a/src/main/java/com/github/dockerjava/api/NotAcceptableException.java b/src/main/java/com/github/dockerjava/api/NotAcceptableException.java new file mode 100644 index 00000000..affa4ce9 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/NotAcceptableException.java @@ -0,0 +1,22 @@ +package com.github.dockerjava.api; + +/** + * + */ +public class NotAcceptableException extends DockerException { + + private static final long serialVersionUID = -1771212181727204375L; + + public NotAcceptableException(String message, Throwable cause) { + super(message, 406, cause); + } + + public NotAcceptableException(String message) { + this(message, null); + } + + public NotAcceptableException(Throwable cause) { + this(cause.getMessage(), cause); + } + +} diff --git a/src/main/java/com/github/dockerjava/api/NotFoundException.java b/src/main/java/com/github/dockerjava/api/NotFoundException.java new file mode 100644 index 00000000..10f328cd --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/NotFoundException.java @@ -0,0 +1,23 @@ +package com.github.dockerjava.api; + +/** + * Indicates that the given entity does not exist. + * + * @author Ryan Campbell ryan.campbell@gmail.com + */ +public class NotFoundException extends DockerException { + + private static final long serialVersionUID = -2450396075981100160L; + + public NotFoundException(String message, Throwable cause) { + super(message, 404, cause); + } + + public NotFoundException(String message) { + this(message, null); + } + + public NotFoundException(Throwable cause) { + this(cause.getMessage(), cause); + } +} diff --git a/src/main/java/com/github/dockerjava/api/NotModifiedException.java b/src/main/java/com/github/dockerjava/api/NotModifiedException.java new file mode 100644 index 00000000..d521bae2 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/NotModifiedException.java @@ -0,0 +1,22 @@ +package com.github.dockerjava.api; + +/** + * + */ +public class NotModifiedException extends DockerException { + + private static final long serialVersionUID = -290093024775500239L; + + public NotModifiedException(String message, Throwable cause) { + super(message, 304, cause); + } + + public NotModifiedException(String message) { + this(message, null); + } + + public NotModifiedException(Throwable cause) { + this(cause.getMessage(), cause); + } + +} diff --git a/src/main/java/com/github/dockerjava/api/UnauthorizedException.java b/src/main/java/com/github/dockerjava/api/UnauthorizedException.java new file mode 100644 index 00000000..5d48d216 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/UnauthorizedException.java @@ -0,0 +1,22 @@ +package com.github.dockerjava.api; + +/** + * + */ +public class UnauthorizedException extends DockerException { + + private static final long serialVersionUID = 8257731964780578278L; + + public UnauthorizedException(String message, Throwable cause) { + super(message, 401, cause); + } + + public UnauthorizedException(String message) { + this(message, null); + } + + public UnauthorizedException(Throwable cause) { + this(cause.getMessage(), cause); + } + +} diff --git a/src/main/java/com/github/dockerjava/api/command/AttachContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/AttachContainerCmd.java new file mode 100644 index 00000000..8abbef72 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/AttachContainerCmd.java @@ -0,0 +1,64 @@ +package com.github.dockerjava.api.command; + +import java.io.InputStream; + +import com.github.dockerjava.api.NotFoundException; + +/** + * Attach to container + * + * @param logs + * - true or false, includes logs. Defaults to false. + * + * @param followStream + * - true or false, return stream. Defaults to false. + * @param stdout + * - true or false, includes stdout log. Defaults to false. + * @param stderr + * - true or false, includes stderr log. Defaults to false. + * @param timestamps + * - true or false, if true, print timestamps for every log line. + * Defaults to false. + */ +public interface AttachContainerCmd extends DockerCmd{ + + public String getContainerId(); + + public boolean hasLogsEnabled(); + + public boolean hasFollowStreamEnabled(); + + public boolean hasTimestampsEnabled(); + + public boolean hasStdoutEnabled(); + + public boolean hasStderrEnabled(); + + public AttachContainerCmd withContainerId(String containerId); + + public AttachContainerCmd withFollowStream(); + + public AttachContainerCmd withFollowStream(boolean followStream); + + public AttachContainerCmd withTimestamps(boolean timestamps); + + public AttachContainerCmd withStdOut(); + + public AttachContainerCmd withStdOut(boolean stdout); + + public AttachContainerCmd withStdErr(); + + public AttachContainerCmd withStdErr(boolean stderr); + + public AttachContainerCmd withLogs(boolean logs); + + /** + * @throws NotFoundException No such container + */ + @Override + public InputStream exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/AuthCmd.java b/src/main/java/com/github/dockerjava/api/command/AuthCmd.java new file mode 100644 index 00000000..f71a132b --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/AuthCmd.java @@ -0,0 +1,23 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.UnauthorizedException; +import com.github.dockerjava.api.model.AuthConfig; + +/** + * + * Authenticate with the server, useful for checking authentication. + * + */ +public interface AuthCmd extends DockerCmd { + + public AuthConfig getAuthConfig(); + + public AuthCmd withAuthConfig(AuthConfig authConfig); + + @Override + public Void exec() throws UnauthorizedException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/BaseExecCmd.java b/src/main/java/com/github/dockerjava/api/command/BaseExecCmd.java new file mode 100644 index 00000000..d57011eb --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/BaseExecCmd.java @@ -0,0 +1,38 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.model.ExecConfig; + +public interface BaseExecCmd, RES_T> extends DockerCmd { + + public String getContainerId(); + + public boolean isTty(); + + public boolean isAttachStdin(); + + public boolean isAttachStdout(); + + public boolean isAttachStderr(); + + public boolean isDetach(); + + public boolean isPrivileged(); + + public String[] getCmd(); + + public ExecConfig getExecConfig(); + + public CMD_T withContainerId(String containerId); + + public CMD_T withTty(boolean tty); + + public CMD_T withAttachStdin(boolean attachStdin); + + public CMD_T withDetach(boolean detach); + + public CMD_T withCmd(String... cmd); + + public CMD_T withExecConfig(ExecConfig execConfig); + + public CMD_T withPrivileged(boolean privileged); +} diff --git a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java new file mode 100644 index 00000000..7c2deb63 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java @@ -0,0 +1,43 @@ +package com.github.dockerjava.api.command; + +import java.io.InputStream; + +/** + * + * Build an image from Dockerfile. + * + * TODO: http://docs.docker.com/reference/builder/#dockerignore + * + */ +public interface BuildImageCmd extends DockerCmd{ + + public BuildImageCmd withTag(String tag); + + public InputStream getTarInputStream(); + + public String getTag(); + + public boolean hasNoCacheEnabled(); + + public boolean hasRemoveEnabled(); + + public boolean isQuiet(); + + public BuildImageCmd withTarInputStream(InputStream tarInputStream); + + public BuildImageCmd withNoCache(); + + public BuildImageCmd withNoCache(boolean noCache); + + public BuildImageCmd withRemove(); + + public BuildImageCmd withRemove(boolean rm); + + public BuildImageCmd withQuiet(); + + public BuildImageCmd withQuiet(boolean quiet); + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/CgroupContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CgroupContainerCmd.java new file mode 100644 index 00000000..cd022003 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/CgroupContainerCmd.java @@ -0,0 +1,25 @@ +package com.github.dockerjava.api.command; + +import java.util.List; + +import com.github.dockerjava.api.model.Subsystem; +import com.github.dockerjava.api.model.WriteSubsystem; + +public interface CgroupContainerCmd extends DockerCmd>{ + + public String getContainerId(); + + public List getReadSubsystem(); + + public List getWriteSubsystem(); + + public CgroupContainerCmd withContainerId(String containerId); + + public CgroupContainerCmd withReadSubsystem(List toRead); + + public CgroupContainerCmd withWriteSubsystem(List toWrite); + + public static interface Exec extends DockerCmdExec> { + } + +} diff --git a/src/main/java/com/github/dockerjava/api/command/CommitCmd.java b/src/main/java/com/github/dockerjava/api/command/CommitCmd.java new file mode 100644 index 00000000..5eb5a3e8 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/CommitCmd.java @@ -0,0 +1,114 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.model.ExposedPorts; +import com.github.dockerjava.api.model.Volumes; + +/** +* +* Create a new image from a container's changes. Returns the new image ID. +* +*/ +public interface CommitCmd extends DockerCmd{ + + public String getContainerId(); + + public CommitCmd withContainerId(String containerId); + + public String getRepository(); + + public String getTag(); + + public String getMessage(); + + public String getAuthor(); + + public boolean hasPauseEnabled(); + + public CommitCmd withAttachStderr(boolean attachStderr); + + public CommitCmd withAttachStderr(); + + public CommitCmd withAttachStdin(boolean attachStdin); + + public CommitCmd withAttachStdin(); + + public CommitCmd withAttachStdout(boolean attachStdout); + + public CommitCmd withAttachStdout(); + + public CommitCmd withCmd(String... cmd); + + public CommitCmd withDisableNetwork(boolean disableNetwork); + + public CommitCmd withAuthor(String author); + + public CommitCmd withMessage(String message); + + public CommitCmd withTag(String tag); + + public CommitCmd withRepository(String repository); + + public CommitCmd withPause(boolean pause); + + public String[] getEnv(); + + public CommitCmd withEnv(String... env); + + public ExposedPorts getExposedPorts(); + + public CommitCmd withExposedPorts(ExposedPorts exposedPorts); + + public String getHostname(); + + public CommitCmd withHostname(String hostname); + + public Integer getMemory(); + + public CommitCmd withMemory(Integer memory); + + public Integer getMemorySwap(); + + public CommitCmd withMemorySwap(Integer memorySwap); + + public boolean isOpenStdin(); + + public CommitCmd withOpenStdin(boolean openStdin); + + public String[] getPortSpecs(); + + public CommitCmd withPortSpecs(String... portSpecs); + + public boolean isStdinOnce(); + + public CommitCmd withStdinOnce(boolean stdinOnce); + + public CommitCmd withStdinOnce(); + + public boolean isTty(); + + public CommitCmd withTty(boolean tty); + + public CommitCmd withTty(); + + public String getUser(); + + public CommitCmd withUser(String user); + + public Volumes getVolumes(); + + public CommitCmd withVolumes(Volumes volumes); + + public String getWorkingDir(); + + public CommitCmd withWorkingDir(String workingDir); + + /** + * @throws NotFoundException No such container + */ + public String exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/ContainerDiffCmd.java b/src/main/java/com/github/dockerjava/api/command/ContainerDiffCmd.java new file mode 100644 index 00000000..516ea365 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/ContainerDiffCmd.java @@ -0,0 +1,28 @@ +package com.github.dockerjava.api.command; + +import java.util.List; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.InternalServerErrorException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.model.ChangeLog; + +public interface ContainerDiffCmd extends DockerCmd> { + + public String getContainerId(); + + public ContainerDiffCmd withContainerId(String containerId); + + public String toString(); + + /** + * @throws NotFoundException No such container + * @throws InternalServerErrorException server error + * @throws DockerException unexpected http status code + */ + public List exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec> { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/CopyFileFromContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CopyFileFromContainerCmd.java new file mode 100644 index 00000000..0ebd3cc1 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/CopyFileFromContainerCmd.java @@ -0,0 +1,29 @@ +package com.github.dockerjava.api.command; + +import java.io.InputStream; + +import com.github.dockerjava.api.NotFoundException; + +public interface CopyFileFromContainerCmd extends DockerCmd { + + public String getContainerId(); + + public String getResource(); + + public CopyFileFromContainerCmd withContainerId(String containerId); + + public CopyFileFromContainerCmd withResource(String resource); + + public String getHostPath(); + + public CopyFileFromContainerCmd withHostPath(String hostPath); + + /** + * @throws NotFoundException No such container + */ + public InputStream exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java new file mode 100644 index 00000000..ef4ad306 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java @@ -0,0 +1,118 @@ + package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.ConflictException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.model.ExposedPort; +import com.github.dockerjava.api.model.Volume; + +public interface CreateContainerCmd extends DockerCmd{ + + public CreateContainerCmd withName(String name); + + public String getName(); + + public CreateContainerCmd withExposedPorts(ExposedPort... exposedPorts); + + public ExposedPort[] getExposedPorts(); + + public boolean isDisableNetwork(); + + public String getWorkingDir(); + + public CreateContainerCmd withWorkingDir(String workingDir); + + public String getHostName(); + + public CreateContainerCmd withDisableNetwork(boolean disableNetwork); + + public CreateContainerCmd withHostName(String hostName); + + public String[] getPortSpecs(); + + public CreateContainerCmd withPortSpecs(String... portSpecs); + + public String getUser(); + + public CreateContainerCmd withUser(String user); + + public boolean isTty(); + + public CreateContainerCmd withTty(boolean tty); + + public boolean isStdinOpen(); + + public CreateContainerCmd withStdinOpen(boolean stdinOpen); + + public boolean isStdInOnce(); + + public CreateContainerCmd withStdInOnce(boolean stdInOnce); + + public long getMemoryLimit(); + + public CreateContainerCmd withMemoryLimit(long memoryLimit); + + public long getMemorySwap(); + + public CreateContainerCmd withMemorySwap(long memorySwap); + + public int getCpuShares(); + + public CreateContainerCmd withCpuShares(int cpuShares); + + public String getCpuset(); + + public CreateContainerCmd withCpuset(String cpuset); + + public boolean isAttachStdin(); + + public CreateContainerCmd withAttachStdin(boolean attachStdin); + + public boolean isAttachStdout(); + + public CreateContainerCmd withAttachStdout(boolean attachStdout); + + public boolean isAttachStderr(); + + public CreateContainerCmd withAttachStderr(boolean attachStderr); + + public String[] getEnv(); + + public CreateContainerCmd withEnv(String... env); + + public String[] getCmd(); + + public CreateContainerCmd withCmd(String... cmd); + + public String[] getDns(); + + public CreateContainerCmd withDns(String... dns); + + public String getImage(); + + public CreateContainerCmd withImage(String image); + + public Volume[] getVolumes(); + + public CreateContainerCmd withVolumes(Volume... volumes); + + public String[] getVolumesFrom(); + + public CreateContainerCmd withVolumesFrom(String... volumesFrom); + + public String getIp(); + + public CreateContainerCmd withIp(String ip); + + + /** + * @throws NotFoundException No such container + * @throws ConflictException Named container already exists + */ + @Override + public CreateContainerResponse exec() throws NotFoundException, + ConflictException; + + public static interface Exec extends DockerCmdExec { + } + +} diff --git a/src/main/java/com/kpelykh/docker/client/model/ContainerCreateResponse.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerResponse.java similarity index 67% rename from src/main/java/com/kpelykh/docker/client/model/ContainerCreateResponse.java rename to src/main/java/com/github/dockerjava/api/command/CreateContainerResponse.java index 8f60ce15..5b0b5a53 100644 --- a/src/main/java/com/kpelykh/docker/client/model/ContainerCreateResponse.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerResponse.java @@ -1,45 +1,41 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Arrays; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class ContainerCreateResponse { - - @JsonProperty("Id") - private String id; - - @JsonProperty("Warnings") - private String[] warnings; - - public String getId() { - return id; - } - - public String[] getWarnings() { - return warnings; - } - - public void setId(String id) { - this.id = id; - } - - public void setWarnings(String[] warnings) { - this.warnings = warnings; - } - - @Override - public String toString() { - return "ContainerCreateResponse{" + - "id='" + id + '\'' + - ", warnings=" + Arrays.toString(warnings) + - '}'; - } -} +package com.github.dockerjava.api.command; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class CreateContainerResponse { + + @JsonProperty("Id") + private String id; + + @JsonProperty("Warnings") + private String[] warnings; + + public String getId() { + return id; + } + + public String[] getWarnings() { + return warnings; + } + + public void setId(String id) { + this.id = id; + } + + public void setWarnings(String[] warnings) { + this.warnings = warnings; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/CreateExecCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateExecCmd.java new file mode 100644 index 00000000..c576e1f0 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/CreateExecCmd.java @@ -0,0 +1,12 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +public interface CreateExecCmd extends BaseExecCmd { + + @Override + public CreateExecResponse exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/CreateExecResponse.java b/src/main/java/com/github/dockerjava/api/command/CreateExecResponse.java new file mode 100644 index 00000000..73fad01c --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/CreateExecResponse.java @@ -0,0 +1,26 @@ +package com.github.dockerjava.api.command; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class CreateExecResponse { + + @JsonProperty("Id") + private String id; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/CreateImageCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateImageCmd.java new file mode 100644 index 00000000..d2682471 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/CreateImageCmd.java @@ -0,0 +1,34 @@ +package com.github.dockerjava.api.command; + +import java.io.InputStream; + +public interface CreateImageCmd extends DockerCmd { + + public String getRepository(); + + // TODO remove method + public String getTag(); + + public InputStream getImageStream(); + + /** + * @param repository the repository to import to + */ + public CreateImageCmd withRepository(String repository); + + /** + * @param imageStream the InputStream of the tar file + */ + public CreateImageCmd withImageStream(InputStream imageStream); + + /** + * @param tag any tag for this image + * @deprecated use repo:tag format for repository + */ + public CreateImageCmd withTag(String tag); + + public static interface Exec extends DockerCmdExec { + } + + +} \ No newline at end of file diff --git a/src/main/java/com/kpelykh/docker/client/model/ImageCreateResponse.java b/src/main/java/com/github/dockerjava/api/command/CreateImageResponse.java similarity index 66% rename from src/main/java/com/kpelykh/docker/client/model/ImageCreateResponse.java rename to src/main/java/com/github/dockerjava/api/command/CreateImageResponse.java index 21545a2d..43731703 100644 --- a/src/main/java/com/kpelykh/docker/client/model/ImageCreateResponse.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateImageResponse.java @@ -1,30 +1,27 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * Parse reponses from /images/create - * - * @author Ryan Campbell (ryan.campbell@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class ImageCreateResponse { - - @JsonProperty("status") - private String id; - - - public String getId() { - return id; - } - - - @Override - public String toString() { - return "ContainerCreateResponse{" + - "id='" + id + '\'' + - '}'; - } -} +package com.github.dockerjava.api.command; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * Parse reponses from /images/create + * + * @author Ryan Campbell (ryan.campbell@gmail.com) + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class CreateImageResponse { + + @JsonProperty("status") + private String id; + + public String getId() { + return id; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmd.java b/src/main/java/com/github/dockerjava/api/command/DockerCmd.java new file mode 100644 index 00000000..4c30382b --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmd.java @@ -0,0 +1,7 @@ +package com.github.dockerjava.api.command; + +public interface DockerCmd { + + public RES_T exec(); + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExec.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExec.java new file mode 100644 index 00000000..8cf13e7b --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExec.java @@ -0,0 +1,7 @@ +package com.github.dockerjava.api.command; + +public interface DockerCmdExec, RES_T> { + + public RES_T exec(CMD_T command); + +} diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java new file mode 100644 index 00000000..f4866643 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java @@ -0,0 +1,90 @@ +package com.github.dockerjava.api.command; + +import java.io.Closeable; +import java.io.IOException; + +import com.github.dockerjava.core.DockerClientConfig; + +public interface DockerCmdExecFactory extends Closeable { + + public void init(DockerClientConfig dockerClientConfig); + + public AuthCmd.Exec createAuthCmdExec(); + + public InfoCmd.Exec createInfoCmdExec(); + + public PingCmd.Exec createPingCmdExec(); + + public VersionCmd.Exec createVersionCmdExec(); + + public PullImageCmd.Exec createPullImageCmdExec(); + + public PushImageCmd.Exec createPushImageCmdExec(); + + public CreateImageCmd.Exec createCreateImageCmdExec(); + + public SearchImagesCmd.Exec createSearchImagesCmdExec(); + + public RemoveImageCmd.Exec createRemoveImageCmdExec(); + + public ListImagesCmd.Exec createListImagesCmdExec(); + + public InspectImageCmd.Exec createInspectImageCmdExec(); + + public ListContainersCmd.Exec createListContainersCmdExec(); + + public CreateContainerCmd.Exec createCreateContainerCmdExec(); + + public StartContainerCmd.Exec createStartContainerCmdExec(); + + public InspectContainerCmd.Exec createInspectContainerCmdExec(); + + public RemoveContainerCmd.Exec createRemoveContainerCmdExec(); + + public WaitContainerCmd.Exec createWaitContainerCmdExec(); + + public AttachContainerCmd.Exec createAttachContainerCmdExec(); + + public LogContainerCmd.Exec createLogContainerCmdExec(); + + public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec(); + + public StopContainerCmd.Exec createStopContainerCmdExec(); + + public ContainerDiffCmd.Exec createContainerDiffCmdExec(); + + public KillContainerCmd.Exec createKillContainerCmdExec(); + + public RestartContainerCmd.Exec createRestartContainerCmdExec(); + + public CommitCmd.Exec createCommitCmdExec(); + + public BuildImageCmd.Exec createBuildImageCmdExec(); + + public TopContainerCmd.Exec createTopContainerCmdExec(); + + public TagImageCmd.Exec createTagImageCmdExec(); + + public PauseContainerCmd.Exec createPauseContainerCmdExec(); + + public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec(); + + public EventsCmd.Exec createEventsCmdExec(); + + public CgroupContainerCmd.Exec createCgroupContainerCmdExec(); + + public SweepContainerCmd.Exec createSweepContainerCmdExec(); + + public MetricContainerCmd.Exec createMetricContainerCmdExec(); + + public CreateExecCmd.Exec createCreateExecCmdExec(); + + public StartExecCmd.Exec createStartExecCmdExec(); + + public ExecContainerCmd.Exec createExecContainerCmdExec(CreateExecCmd createExecCmd, StartExecCmd startExecCmd); + + public LimitContainerCmd.Exec createLimitContainerCmdExec(); + + public void close() throws IOException; + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/EventCallback.java b/src/main/java/com/github/dockerjava/api/command/EventCallback.java new file mode 100644 index 00000000..45ac34dc --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/EventCallback.java @@ -0,0 +1,12 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.model.Event; + +/** + * Event callback + */ +public interface EventCallback { + public void onEvent(Event event); + public void onException(Throwable throwable); + public void onCompletion(int numEvents); +} diff --git a/src/main/java/com/github/dockerjava/api/command/EventsCmd.java b/src/main/java/com/github/dockerjava/api/command/EventsCmd.java new file mode 100644 index 00000000..cfdb23a6 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/EventsCmd.java @@ -0,0 +1,27 @@ +package com.github.dockerjava.api.command; + +import java.util.concurrent.ExecutorService; + + +/** + * Get events + * + * @param since - Show all events created since timestamp + * @param until - Stream events until this timestamp + */ +public interface EventsCmd extends DockerCmd { + public EventsCmd withSince(String since); + + public EventsCmd withUntil(String until); + + public String getSince(); + + public String getUntil(); + + public EventCallback getEventCallback(); + + public EventsCmd withEventCallback(EventCallback eventCallback); + + public static interface Exec extends DockerCmdExec { + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/ExecContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/ExecContainerCmd.java new file mode 100644 index 00000000..eb63faa7 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/ExecContainerCmd.java @@ -0,0 +1,13 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +public interface ExecContainerCmd extends BaseExecCmd { + + @Override + public String exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} diff --git a/src/main/java/com/github/dockerjava/api/command/InfoCmd.java b/src/main/java/com/github/dockerjava/api/command/InfoCmd.java new file mode 100644 index 00000000..d340fe26 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/InfoCmd.java @@ -0,0 +1,10 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.model.Info; + +public interface InfoCmd extends DockerCmd { + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java new file mode 100644 index 00000000..ca6a9a69 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java @@ -0,0 +1,19 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +public interface InspectContainerCmd extends DockerCmd { + + public String getContainerId(); + + public InspectContainerCmd withContainerId(String containerId); + + /** + * @throws NotFoundException No such container + */ + public InspectContainerResponse exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java b/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java new file mode 100644 index 00000000..32156745 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java @@ -0,0 +1,354 @@ +package com.github.dockerjava.api.command; + + +import java.util.Map; + +import com.github.dockerjava.api.model.*; +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class InspectContainerResponse { + + @JsonProperty("Args") + private String[] args; + + @JsonProperty("Config") + private ContainerConfig config; + + @JsonProperty("Created") + private String created; + + @JsonProperty("Driver") + private String driver; + + @JsonProperty("ExecDriver") + private String execDriver; + + @JsonProperty("HostConfig") + private HostConfig hostConfig; + + @JsonProperty("HostnamePath") + private String hostnamePath; + + @JsonProperty("HostsPath") + private String hostsPath; + + @JsonProperty("Id") + private String id; + + @JsonProperty("Image") + private String imageId; + + @JsonProperty("MountLabel") + private String mountLabel; + + @JsonProperty("Name") + private String name; + + @JsonProperty("NetworkSettings") + private NetworkSettings networkSettings; + + @JsonProperty("Path") + private String path; + + @JsonProperty("ProcessLabel") + private String processLabel; + + @JsonProperty("ResolvConfPath") + private String resolvConfPath; + + @JsonProperty("State") + private ContainerState state; + + @JsonProperty("Volumes") + private VolumeBinds volumes; + + @JsonProperty("VolumesRW") + private Volumes volumesRW; + + public String getId() { + return id; + } + + public String getCreated() { + return created; + } + + public String getPath() { + return path; + } + + public String getProcessLabel() { + return processLabel; + } + + public String[] getArgs() { + return args; + } + + public ContainerConfig getConfig() { + return config; + } + + public ContainerState getState() { + return state; + } + + public String getImageId() { + return imageId; + } + + public NetworkSettings getNetworkSettings() { + return networkSettings; + } + + public String getResolvConfPath() { + return resolvConfPath; + } + + @JsonIgnore + public VolumeBind[] getVolumes() { + return volumes.getBinds(); + } + + @JsonIgnore + public Volume[] getVolumesRW() { + return volumesRW.getVolumes(); + } + + public String getHostnamePath() { + return hostnamePath; + } + + public String getHostsPath() { + return hostsPath; + } + + public String getName() { + return name; + } + + public String getDriver() { + return driver; + } + + public HostConfig getHostConfig() { + return hostConfig; + } + + public String getExecDriver() { + return execDriver; + } + + public String getMountLabel() { + return mountLabel; + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public class NetworkSettings { + + @JsonProperty("IPAddress") private String ipAddress; + @JsonProperty("IPPrefixLen") private int ipPrefixLen; + @JsonProperty("Gateway") private String gateway; + @JsonProperty("Bridge") private String bridge; + @JsonProperty("PortMapping") private Map> portMapping; + @JsonProperty("Ports") private Ports ports; + + public String getIpAddress() { + return ipAddress; + } + + public int getIpPrefixLen() { + return ipPrefixLen; + } + + public String getGateway() { + return gateway; + } + + public String getBridge() { + return bridge; + } + + public Map> getPortMapping() { + return portMapping; + } + + public Ports getPorts() { + return ports; + } + + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public class ContainerState { + + @JsonProperty("Running") private boolean running; + @JsonProperty("Paused") private boolean paused; + @JsonProperty("Pid") private int pid; + @JsonProperty("ExitCode") private int exitCode; + @JsonProperty("StartedAt") private String startedAt; + @JsonProperty("FinishedAt") private String finishedAt; + + public boolean isRunning() { + return running; + } + + public boolean isPaused() { + return paused; + } + + public int getPid() { + return pid; + } + + public int getExitCode() { + return exitCode; + } + + public String getStartedAt() { + return startedAt; + } + + public String getFinishedAt() { + return finishedAt; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public class HostConfig { + + @JsonProperty("Binds") + private String[] binds; + + @JsonProperty("LxcConf") + private LxcConf[] lxcConf; + + @JsonProperty("PortBindings") + private Ports portBindings; + + @JsonProperty("PublishAllPorts") + private boolean publishAllPorts; + + @JsonProperty("Privileged") + private boolean privileged; + + @JsonProperty("Dns") + private String[] dns; + + @JsonProperty("DnsSearch") + private String[] dnsSearch; + + @JsonProperty("VolumesFrom") + private String[] volumesFrom; + + @JsonProperty("ContainerIDFile") + private String containerIDFile; + + // TODO: use Links class here? + @JsonProperty("Links") + private String[] links; + + @JsonProperty("NetworkMode") + private String networkMode; + + @JsonProperty("Devices") + private Device[] devices; + + @JsonProperty("RestartPolicy") + private RestartPolicy restartPolicy; + + @JsonProperty("CapAdd") + private String[] capAdd; + + @JsonProperty("CapDrop") + private String[] capDrop; + + public String[] getBinds() { + return binds; + } + + public LxcConf[] getLxcConf() { + return lxcConf; + } + + public Ports getPortBindings() { + return portBindings; + } + + public boolean isPublishAllPorts() { + return publishAllPorts; + } + + public boolean isPrivileged() { + return privileged; + } + + public String[] getDns() { + return dns; + } + + public String[] getVolumesFrom() { + return volumesFrom; + } + + public String getContainerIDFile() { + return containerIDFile; + } + + public String[] getDnsSearch() { + return dnsSearch; + } + + public String[] getLinks() { + return links; + } + + public String getNetworkMode() { + return networkMode; + } + + public Device[] getDevices() { + return devices; + } + + public RestartPolicy getRestartPolicy() { + return restartPolicy; + } + + public String[] getCapAdd() { + return capAdd; + } + + public String[] getCapDrop() { + return capDrop; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + } + +} + diff --git a/src/main/java/com/github/dockerjava/api/command/InspectImageCmd.java b/src/main/java/com/github/dockerjava/api/command/InspectImageCmd.java new file mode 100644 index 00000000..f2523487 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/InspectImageCmd.java @@ -0,0 +1,22 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +/** + * Inspect the details of an image. + */ +public interface InspectImageCmd extends DockerCmd{ + + public String getImageId(); + + public InspectImageCmd withImageId(String imageId); + + /** + * @throws NotFoundException No such image + */ + public InspectImageResponse exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/InspectImageResponse.java b/src/main/java/com/github/dockerjava/api/command/InspectImageResponse.java new file mode 100644 index 00000000..b5b6432d --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/InspectImageResponse.java @@ -0,0 +1,105 @@ +package com.github.dockerjava.api.command; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.dockerjava.api.model.ContainerConfig; + +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class InspectImageResponse { + + @JsonProperty("Architecture") + private String arch; + + @JsonProperty("Author") + private String author; + + @JsonProperty("Comment") + private String comment; + + @JsonProperty("Config") + private ContainerConfig config; + + @JsonProperty("Container") + private String container; + + @JsonProperty("ContainerConfig") + private ContainerConfig containerConfig; + + @JsonProperty("Created") + private String created; + + @JsonProperty("DockerVersion") + private String dockerVersion; + + @JsonProperty("Id") + private String id; + + @JsonProperty("Os") + private String os; + + @JsonProperty("Parent") + private String parent; + + @JsonProperty("Size") + private long size; + + public String getId() { + return id; + } + + public String getParent() { + return parent; + } + + public String getCreated() { + return created; + } + + public String getContainer() { + return container; + } + + public ContainerConfig getContainerConfig() { + return containerConfig; + } + + public long getSize() { + return size; + } + + public String getDockerVersion() { + return dockerVersion; + } + + public ContainerConfig getConfig() { + return config; + } + + public String getArch() { + return arch; + } + + public String getComment() { + return comment; + } + + public String getAuthor() { + return author; + } + + public String getOs() { + return os; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/KillContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/KillContainerCmd.java new file mode 100644 index 00000000..aff39f9e --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/KillContainerCmd.java @@ -0,0 +1,26 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +/** + * Kill a running container. + */ +public interface KillContainerCmd extends DockerCmd { + + public String getContainerId(); + + public String getSignal(); + + public KillContainerCmd withContainerId(String containerId); + + public KillContainerCmd withSignal(String signal); + + /** + * @throws NotFoundException No such container + */ + public Void exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/LimitContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/LimitContainerCmd.java new file mode 100644 index 00000000..bd6e5e2c --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/LimitContainerCmd.java @@ -0,0 +1,36 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.model.LimitationConfig; + +public interface LimitContainerCmd extends DockerCmd { + + public String getContainerId(); + + public long getMemoryLimit(); + + public int getCpuShares(); + + public String getCpuset(); + + public boolean isSaveChanges(); + + public LimitationConfig getLimitationConfig(); + + public LimitContainerCmd withCpuShares(int cpuShares); + + public LimitContainerCmd withCpuset(String cpuset); + + public LimitContainerCmd withMemoryLimit(long memoryLimit); + + public LimitContainerCmd withContainerId(String containerId); + + public LimitContainerCmd withSaveChanges(boolean saveChanges); + + public LimitContainerCmd withLimitationConfig(LimitationConfig limitationConfig); + + public Void exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java b/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java new file mode 100644 index 00000000..ed457dab --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java @@ -0,0 +1,42 @@ +package com.github.dockerjava.api.command; + +import java.util.List; + +import com.github.dockerjava.api.model.Container; + +/** + * List containers + * + * @param showAll - true or false, Show all containers. Only running containers are shown by default. + * @param showSize - true or false, Show the containers sizes. This is false by default. + * @param limit - Show `limit` last created containers, include non-running ones. There is no limit by default. + * @param sinceId - Show only containers created since Id, include non-running ones. + * @param beforeId - Show only containers created before Id, include non-running ones. + * + */ +public interface ListContainersCmd extends DockerCmd>{ + + public int getLimit(); + + public boolean hasShowSizeEnabled(); + + public boolean hasShowAllEnabled(); + + public String getSinceId(); + + public String getBeforeId(); + + public ListContainersCmd withShowAll(boolean showAll); + + public ListContainersCmd withShowSize(boolean showSize); + + public ListContainersCmd withLimit(int limit); + + public ListContainersCmd withSince(String since); + + public ListContainersCmd withBefore(String before); + + public static interface Exec extends DockerCmdExec> { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/ListImagesCmd.java b/src/main/java/com/github/dockerjava/api/command/ListImagesCmd.java new file mode 100644 index 00000000..502af84c --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/ListImagesCmd.java @@ -0,0 +1,26 @@ +package com.github.dockerjava.api.command; + +import java.util.List; + +import com.github.dockerjava.api.model.Image; + +/** + * List images + * + * @param showAll - Show all images (by default filter out the intermediate images used to build) + * @param filter - TODO: undocumented in docker remote api reference + */ +public interface ListImagesCmd extends DockerCmd> { + + public String getFilter(); + + public boolean hasShowAllEnabled(); + + public ListImagesCmd withShowAll(boolean showAll); + + public ListImagesCmd withFilter(String filter); + + public static interface Exec extends DockerCmdExec> { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/LogContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/LogContainerCmd.java new file mode 100644 index 00000000..e0f20f9a --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/LogContainerCmd.java @@ -0,0 +1,67 @@ +package com.github.dockerjava.api.command; + +import java.io.InputStream; + +import com.github.dockerjava.api.NotFoundException; + +/** + * Get container logs + * + * @param followStream + * - true or false, return stream. Defaults to false. + * @param stdout + * - true or false, includes stdout log. Defaults to false. + * @param stderr + * - true or false, includes stderr log. Defaults to false. + * @param timestamps + * - true or false, if true, print timestamps for every log line. + * Defaults to false. + * @param tail + * - `all` or ``, Output specified number of lines at the end of logs + */ +public interface LogContainerCmd extends DockerCmd{ + + public String getContainerId(); + + public int getTail(); + + public boolean hasFollowStreamEnabled(); + + public boolean hasTimestampsEnabled(); + + public boolean hasStdoutEnabled(); + + public boolean hasStderrEnabled(); + + public LogContainerCmd withContainerId(String containerId); + + public LogContainerCmd withFollowStream(); + + public LogContainerCmd withFollowStream(boolean followStream); + + public LogContainerCmd withTimestamps(); + + public LogContainerCmd withTimestamps(boolean timestamps); + + public LogContainerCmd withStdOut(); + + public LogContainerCmd withStdOut(boolean stdout); + + public LogContainerCmd withStdErr(); + + public LogContainerCmd withStdErr(boolean stderr); + + public LogContainerCmd withTailAll(); + + public LogContainerCmd withTail(int tail); + + /** + * @throws NotFoundException No such container + */ + public InputStream exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/MetricContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/MetricContainerCmd.java new file mode 100644 index 00000000..f6fc2ca1 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/MetricContainerCmd.java @@ -0,0 +1,16 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.model.metric.Metric; + +public interface MetricContainerCmd extends DockerCmd { + + public String getContainerId(); + + public MetricContainerCmd withContainerId(String containerId); + + public Metric exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/PauseContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/PauseContainerCmd.java new file mode 100644 index 00000000..a05733f9 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/PauseContainerCmd.java @@ -0,0 +1,25 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +/** + * Pause a container. + * + * @param containerId - Id of the container + * + */ +public interface PauseContainerCmd extends DockerCmd{ + + public String getContainerId(); + + public PauseContainerCmd withContainerId(String containerId); + + /** + * @throws NotFoundException No such container + */ + public Void exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/PingCmd.java b/src/main/java/com/github/dockerjava/api/command/PingCmd.java new file mode 100644 index 00000000..7d5af1e3 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/PingCmd.java @@ -0,0 +1,13 @@ +package com.github.dockerjava.api.command; + + +/** + * Ping the Docker server + * + */ +public interface PingCmd extends DockerCmd { + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/PullImageCmd.java b/src/main/java/com/github/dockerjava/api/command/PullImageCmd.java new file mode 100644 index 00000000..f938542d --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/PullImageCmd.java @@ -0,0 +1,27 @@ +package com.github.dockerjava.api.command; + +import java.io.InputStream; + +/** +* +* Pull image from repository. +* +*/ +public interface PullImageCmd extends DockerCmd{ + + public String getRepository(); + + public String getTag(); + + public String getRegistry(); + + public PullImageCmd withRepository(String repository); + + public PullImageCmd withTag(String tag); + + public PullImageCmd withRegistry(String registry); + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/PushImageCmd.java b/src/main/java/com/github/dockerjava/api/command/PushImageCmd.java new file mode 100644 index 00000000..cd3e6681 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/PushImageCmd.java @@ -0,0 +1,34 @@ +package com.github.dockerjava.api.command; + +import java.io.InputStream; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.model.AuthConfig; + +/** + * Push the latest image to the repository. + * + * @param name The name, e.g. "alexec/busybox" or just "busybox" if you want to default. Not null. + */ +public interface PushImageCmd extends DockerCmd{ + + public String getName(); + + /** + * @param name The name, e.g. "alexec/busybox" or just "busybox" if you want to default. Not null. + */ + public PushImageCmd withName(String name); + + public AuthConfig getAuthConfig(); + + public PushImageCmd withAuthConfig(AuthConfig authConfig); + + /** + * @throws NotFoundException No such image + */ + public InputStream exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/RemoveContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/RemoveContainerCmd.java new file mode 100644 index 00000000..e6c13b20 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/RemoveContainerCmd.java @@ -0,0 +1,41 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +/** + * Remove a container. + * + * @param removeVolumes - true or false, Remove the volumes associated to the container. Defaults to false + * @param force - true or false, Removes the container even if it was running. Defaults to false + */ +public interface RemoveContainerCmd extends DockerCmd { + + public String getContainerId(); + + public boolean hasRemoveVolumesEnabled(); + + public boolean hasForceEnabled(); + + public boolean hasCheckDevice(); + + public RemoveContainerCmd withContainerId(String containerId); + + public RemoveContainerCmd withRemoveVolumes(boolean removeVolumes); + + public RemoveContainerCmd withForce(); + + public RemoveContainerCmd withForce(boolean force); + + public RemoveContainerCmd withCheckDevice(); + + public RemoveContainerCmd withCheckDevice(boolean checkDevice); + + /** + * @throws NotFoundException No such container + */ + public Void exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/RemoveImageCmd.java b/src/main/java/com/github/dockerjava/api/command/RemoveImageCmd.java new file mode 100644 index 00000000..212c9290 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/RemoveImageCmd.java @@ -0,0 +1,49 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +/** +* +* Remove an image, deleting any tags it might have. +* +*/ +public interface RemoveImageCmd extends DockerCmd{ + + public String getImageId(); + + public boolean hasForceEnabled(); + + public boolean hasNoPruneEnabled(); + + public RemoveImageCmd withImageId(String imageId); + + /** + * force delete of an image, even if it's tagged in multiple repositories + */ + public RemoveImageCmd withForce(); + + /** + * force parameter to force delete of an image, even if it's tagged in multiple repositories + */ + public RemoveImageCmd withForce(boolean force); + + /** + * prevent the deletion of parent images + */ + public RemoveImageCmd withNoPrune(); + + /** + * noprune parameter to prevent the deletion of parent images + * + */ + public RemoveImageCmd withNoPrune(boolean noPrune); + + /** + * @throws NotFoundException No such image + */ + public Void exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/RestartContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/RestartContainerCmd.java new file mode 100644 index 00000000..793919c2 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/RestartContainerCmd.java @@ -0,0 +1,29 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +/** + * Restart a running container. + * + * @param timeout - Timeout in seconds before killing the container. Defaults to 10 seconds. + * + */ +public interface RestartContainerCmd extends DockerCmd { + + public String getContainerId(); + + public int getTimeout(); + + public RestartContainerCmd withContainerId(String containerId); + + public RestartContainerCmd withtTimeout(int timeout); + + /** + * @throws NotFoundException No such container + */ + public Void exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/SearchImagesCmd.java b/src/main/java/com/github/dockerjava/api/command/SearchImagesCmd.java new file mode 100644 index 00000000..c609e6e8 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/SearchImagesCmd.java @@ -0,0 +1,22 @@ +package com.github.dockerjava.api.command; + +import java.util.List; + +import com.github.dockerjava.api.model.SearchItem; + +/** + * Search images + * + * @param term - search term + * + */ +public interface SearchImagesCmd extends DockerCmd> { + + public String getTerm(); + + public SearchImagesCmd withTerm(String term); + + public static interface Exec extends DockerCmdExec> { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/StartContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/StartContainerCmd.java new file mode 100644 index 00000000..56dd3340 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/StartContainerCmd.java @@ -0,0 +1,128 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.NotModifiedException; +import com.github.dockerjava.api.model.Bind; +import com.github.dockerjava.api.model.Device; +import com.github.dockerjava.api.model.Link; +import com.github.dockerjava.api.model.LxcConf; +import com.github.dockerjava.api.model.Ports; +import com.github.dockerjava.api.model.RestartPolicy; + +/** + * Start a container + */ +public interface StartContainerCmd extends DockerCmd { + + public Bind[] getBinds(); + + public Link[] getLinks(); + + public LxcConf[] getLxcConf(); + + public Ports getPortBindings(); + + public boolean isPublishAllPorts(); + + public boolean isPrivileged(); + + public String[] getDns(); + + public String[] getDnsSearch(); + + public String[] getVolumesFrom(); + + public String getContainerId(); + + public String getNetworkMode(); + + public Device[] getDevices(); + + public RestartPolicy getRestartPolicy(); + + public String[] getCapAdd(); + + public String[] getCapDrop(); + + public StartContainerCmd withBinds(Bind... binds); + + /** + * Add link to another container. + */ + public StartContainerCmd withLinks(Link... links); + + public StartContainerCmd withLxcConf(LxcConf... lxcConf); + + public StartContainerCmd withPortBindings(Ports portBindings); + + public StartContainerCmd withPrivileged(boolean privileged); + + public StartContainerCmd withPublishAllPorts(boolean publishAllPorts); + + /** + * Set custom DNS servers + */ + public StartContainerCmd withDns(String... dns); + + /** + * Set custom DNS search domains + */ + public StartContainerCmd withDnsSearch(String... dnsSearch); + + public StartContainerCmd withVolumesFrom(String... volumesFrom); + + public StartContainerCmd withContainerId(String containerId); + + /** + * Set the Network mode for the container + *
    + *
  • 'bridge': creates a new network stack for the container on the docker + * bridge
  • + *
  • 'none': no networking for this container
  • + *
  • 'container:': reuses another container network stack
  • + *
  • 'host': use the host network stack inside the container. Note: the + * host mode gives the container full access to local system services such + * as D-bus and is therefore considered insecure.
  • + *
+ */ + public StartContainerCmd withNetworkMode(String networkMode); + + /** + * Add host devices to the container + */ + public StartContainerCmd withDevices(Device... devices); + + /** + * Set custom {@link RestartPolicy} for the container. Defaults to + * {@link RestartPolicy#noRestart()} + */ + public StartContainerCmd withRestartPolicy(RestartPolicy restartPolicy); + + /** + * Add linux kernel + * capability to the container. For example: adding capability "MKNOD" + * allows the container to create special files using the 'mknod' command. + */ + public StartContainerCmd withCapAdd(String... capAdd); + + /** + * Drop linux kernel + * capability from the container. For example: dropping capability + * "CHOWN" prevents the container from changing the owner of any files. + */ + public StartContainerCmd withCapDrop(String... capDrop); + + /** + * @throws NotFoundException + * No such container + * @throws NotModifiedException + * Container already started + */ + public Void exec() throws NotFoundException, NotModifiedException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/StartExecCmd.java b/src/main/java/com/github/dockerjava/api/command/StartExecCmd.java new file mode 100644 index 00000000..b8552feb --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/StartExecCmd.java @@ -0,0 +1,17 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +public interface StartExecCmd extends BaseExecCmd { + + public String getExecId(); + + public StartExecCmd withExecId(String execId); + + @Override + public String exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} diff --git a/src/main/java/com/github/dockerjava/api/command/StopContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/StopContainerCmd.java new file mode 100644 index 00000000..7e706c06 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/StopContainerCmd.java @@ -0,0 +1,32 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.NotModifiedException; + +/** + * Stop a running container. + * + * @param containerId - Id of the container + * @param timeout - Timeout in seconds before killing the container. Defaults to 10 seconds. + * + */ +public interface StopContainerCmd extends DockerCmd { + + public String getContainerId(); + + public int getTimeout(); + + public StopContainerCmd withContainerId(String containerId); + + public StopContainerCmd withTimeout(int timeout); + + /** + * @throws NotFoundException No such container + * @throws NotModifiedException Container already stopped + */ + public Void exec() throws NotFoundException, NotModifiedException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/SweepContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/SweepContainerCmd.java new file mode 100644 index 00000000..f53ddf2a --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/SweepContainerCmd.java @@ -0,0 +1,18 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +public interface SweepContainerCmd extends DockerCmd { + + public String getContainerId(); + + public SweepContainerCmd withContainerId(String containerId); + + /** + * @throws NotFoundException No such container + */ + public Void exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/TagImageCmd.java b/src/main/java/com/github/dockerjava/api/command/TagImageCmd.java new file mode 100644 index 00000000..ace84996 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/TagImageCmd.java @@ -0,0 +1,35 @@ +package com.github.dockerjava.api.command; + + +/** + * Tag an image into a repository + * + * @param image The local image to tag (either a name or an id) + * @param repository The repository to tag in + * @param force (not documented) + * + */ +public interface TagImageCmd extends DockerCmd { + + public String getImageId(); + + public String getRepository(); + + public String getTag(); + + public boolean hasForceEnabled(); + + public TagImageCmd withImageId(String imageId); + + public TagImageCmd withRepository(String repository); + + public TagImageCmd withTag(String tag); + + public TagImageCmd withForce(); + + public TagImageCmd withForce(boolean force); + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/TopContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/TopContainerCmd.java new file mode 100644 index 00000000..c7818a79 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/TopContainerCmd.java @@ -0,0 +1,26 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +/** + * List processes running inside a container + */ +public interface TopContainerCmd extends DockerCmd { + + public String getContainerId(); + + public String getPsArgs(); + + public TopContainerCmd withContainerId(String containerId); + + public TopContainerCmd withPsArgs(String psArgs); + + /** + * @throws NotFoundException No such container + */ + public TopContainerResponse exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/TopContainerResponse.java b/src/main/java/com/github/dockerjava/api/command/TopContainerResponse.java new file mode 100644 index 00000000..e479b269 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/TopContainerResponse.java @@ -0,0 +1,45 @@ +package com.github.dockerjava.api.command; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.Joiner; + +/** + * + * @author marcus + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class TopContainerResponse { + + @JsonProperty("Titles") + private String[] titles; + + @JsonProperty("Processes") + private String[][] processes; + + public String[] getTitles() { + return titles; + } + + public String[][] getProcesses() { + return processes; + } + + @Override + public String toString() { + Joiner joiner = Joiner.on("; ").skipNulls(); + + StringBuffer buffer = new StringBuffer(); + buffer.append("["); + for(String[] fields: processes) { + buffer.append("[" + joiner.join(fields) + "]"); + } + buffer.append("]"); + + return "TopContainerResponse{" + + "titles=" + joiner.join(titles) + + ", processes=" + buffer.toString() + + '}'; + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/UnpauseContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/UnpauseContainerCmd.java new file mode 100644 index 00000000..e74df14c --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/UnpauseContainerCmd.java @@ -0,0 +1,25 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +/** + * Unpause a container. + * + * @param containerId - Id of the container + * + */ +public interface UnpauseContainerCmd extends DockerCmd { + + public String getContainerId(); + + public UnpauseContainerCmd withContainerId(String containerId); + + /** + * @throws NotFoundException No such container + */ + public Void exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/VersionCmd.java b/src/main/java/com/github/dockerjava/api/command/VersionCmd.java new file mode 100644 index 00000000..740a335e --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/VersionCmd.java @@ -0,0 +1,13 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.model.Version; + +/** + * Returns the Docker version info. + */ +public interface VersionCmd extends DockerCmd { + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/command/WaitContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/WaitContainerCmd.java new file mode 100644 index 00000000..e7183155 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/WaitContainerCmd.java @@ -0,0 +1,25 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.NotFoundException; + +/** + * Wait a container + * + * Block until container stops, then returns its exit code + */ +public interface WaitContainerCmd extends DockerCmd { + + public String getContainerId(); + + public WaitContainerCmd withContainerId(String containerId); + + /** + * @throws NotFoundException container not found + */ + @Override + public Integer exec() throws NotFoundException; + + public static interface Exec extends DockerCmdExec { + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/model/AccessMode.java b/src/main/java/com/github/dockerjava/api/model/AccessMode.java new file mode 100644 index 00000000..e0106536 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/AccessMode.java @@ -0,0 +1,19 @@ +package com.github.dockerjava.api.model; + +/** + * The access mode of a file system or file: read-write + * or read-only. + */ +public enum AccessMode { + /** read-write */ + rw, + + /** read-only */ + ro; + + /** + * The default {@link AccessMode}: {@link #rw} + */ + public static final AccessMode DEFAULT = rw; + +} diff --git a/src/main/java/com/kpelykh/docker/client/model/AuthConfig.java b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java similarity index 87% rename from src/main/java/com/kpelykh/docker/client/model/AuthConfig.java rename to src/main/java/com/github/dockerjava/api/model/AuthConfig.java index 514e79be..7212d823 100644 --- a/src/main/java/com/kpelykh/docker/client/model/AuthConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java @@ -1,16 +1,18 @@ -package com.kpelykh.docker.client.model; +package com.github.dockerjava.api.model; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; -@JsonIgnoreProperties(ignoreUnknown = true) public class AuthConfig { + @JsonProperty private String username; + @JsonProperty private String password; + @JsonProperty private String email; + @JsonProperty("serveraddress") private String serverAddress = "https://index.docker.io/v1/"; diff --git a/src/main/java/com/github/dockerjava/api/model/Bind.java b/src/main/java/com/github/dockerjava/api/model/Bind.java new file mode 100644 index 00000000..2a838c27 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Bind.java @@ -0,0 +1,118 @@ +package com.github.dockerjava.api.model; + +import static com.github.dockerjava.api.model.AccessMode.ro; +import static com.github.dockerjava.api.model.AccessMode.rw; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * Represents a host path being bind mounted as a {@link Volume} + * in a Docker container. + * The Bind can be in read only or read write access mode. + */ +public class Bind { + + private String path; + + private Volume volume; + + private AccessMode accessMode; + + public Bind(String path, Volume volume) { + this(path, volume, AccessMode.DEFAULT); + } + + public Bind(String path, Volume volume, AccessMode accessMode) { + this.path = path; + this.volume = volume; + this.accessMode = accessMode; + } + + /** + * @deprecated use {@link #Bind(String, Volume, AccessMode)} + */ + @Deprecated + public Bind(String path, Volume volume, boolean readOnly) { + this(path, volume, readOnly ? ro : rw); + } + + public String getPath() { + return path; + } + + public Volume getVolume() { + return volume; + } + + public AccessMode getAccessMode() { + return accessMode; + } + + /** + * @deprecated use {@link #getAccessMode()} + */ + @Deprecated + public boolean isReadOnly() { + return ro.equals(accessMode); + } + + /** + * Parses a bind mount specification to a {@link Bind}. + * + * @param serialized the specification, e.g. /host:/container:ro + * @return a {@link Bind} matching the specification + * @throws IllegalArgumentException if the specification cannot be parsed + */ + public static Bind parse(String serialized) { + try { + String[] parts = serialized.split(":"); + switch (parts.length) { + case 2: { + return new Bind(parts[0], Volume.parse(parts[1])); + } + case 3: { + AccessMode accessMode = AccessMode.valueOf(parts[2].toLowerCase()); + return new Bind(parts[0], Volume.parse(parts[1]), accessMode); + } + default: { + throw new IllegalArgumentException(); + } + } + } catch (Exception e) { + throw new IllegalArgumentException("Error parsing Bind '" + serialized + + "'"); + } + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Bind) { + Bind other = (Bind) obj; + return new EqualsBuilder().append(path, other.getPath()) + .append(volume, other.getVolume()) + .append(accessMode, other.getAccessMode()).isEquals(); + } else + return super.equals(obj); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(path).append(volume) + .append(accessMode).toHashCode(); + } + + /** + * Returns a string representation of this {@link Bind} suitable + * for inclusion in a JSON message. + * The format is <host path>:<container path>:<access mode>, + * like the argument in {@link #parse(String)}. + * + * @return a string representation of this {@link Bind} + */ + @Override + public String toString() { + return path + ":" + volume.toString() + ":" + accessMode.toString(); + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/Binds.java b/src/main/java/com/github/dockerjava/api/model/Binds.java new file mode 100644 index 00000000..bfc8dbf2 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Binds.java @@ -0,0 +1,73 @@ +package com.github.dockerjava.api.model; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.node.NullNode; + + +@JsonSerialize(using = Binds.Serializer.class) +@JsonDeserialize(using = Binds.Deserializer.class) +public class Binds { + + private Bind[] binds; + + public Binds(Bind... binds) { + this.binds = binds; + } + + public Bind[] getBinds() { + return binds; + } + + public static class Serializer extends JsonSerializer { + + @Override + public void serialize(Binds binds, JsonGenerator jsonGen, + SerializerProvider serProvider) throws IOException, + JsonProcessingException { + + // + jsonGen.writeStartArray(); + for (Bind bind : binds.getBinds()) { + jsonGen.writeString(bind.toString()); + } + jsonGen.writeEndArray(); + // + } + + } + + public static class Deserializer extends JsonDeserializer { + @Override + public Binds deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + + List binds = new ArrayList(); + ObjectCodec oc = jsonParser.getCodec(); + JsonNode node = oc.readTree(jsonParser); + for (Iterator> it = node.fields(); it.hasNext();) { + + Map.Entry field = it.next(); + if (!field.getValue().equals(NullNode.getInstance())) { + binds.add(Bind.parse(field.getKey())); + } + } + return new Binds(binds.toArray(new Bind[0])); + } + } + +} diff --git a/src/main/java/com/kpelykh/docker/client/model/ChangeLog.java b/src/main/java/com/github/dockerjava/api/model/ChangeLog.java similarity index 71% rename from src/main/java/com/kpelykh/docker/client/model/ChangeLog.java rename to src/main/java/com/github/dockerjava/api/model/ChangeLog.java index 50fdab4a..9bc91069 100644 --- a/src/main/java/com/kpelykh/docker/client/model/ChangeLog.java +++ b/src/main/java/com/github/dockerjava/api/model/ChangeLog.java @@ -1,35 +1,33 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class ChangeLog { - - @JsonProperty("Path") - private String path; - - @JsonProperty("Kind") - private int kind; - - public String getPath() { - return path; - } - - public int getKind() { - return kind; - } - - @Override - public String toString() { - return "ChangeLog{" + - "path='" + path + '\'' + - ", kind=" + kind + - '}'; - } -} +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ChangeLog { + + @JsonProperty("Path") + private String path; + + @JsonProperty("Kind") + private int kind; + + public String getPath() { + return path; + } + + public int getKind() { + return kind; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/Container.java b/src/main/java/com/github/dockerjava/api/model/Container.java new file mode 100644 index 00000000..5b38ce48 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Container.java @@ -0,0 +1,107 @@ +package com.github.dockerjava.api.model; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ +@JsonIgnoreProperties(ignoreUnknown=true) +public class Container { + + @JsonProperty("Command") + private String command; + + @JsonProperty("Created") + private long created; + + @JsonProperty("Id") + private String id; + + @JsonProperty("Image") + private String image; + + @JsonProperty("Names") + private String[] names; + + @JsonProperty("Ports") + public Port[] ports; + + @JsonProperty("Status") + private String status; + + public String getId() { + return id; + } + + public String getCommand() { + return command; + } + + public String getImage() { + return image; + } + + public long getCreated() { + return created; + } + + public String getStatus() { + return status; + } + + public Port[] getPorts() { + return ports; + } + + public String[] getNames() { + return names; + } + + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Port { + + @JsonProperty("IP") + private String ip; + + @JsonProperty("PrivatePort") + private Integer privatePort; + + @JsonProperty("PublicPort") + private Integer publicPort; + + @JsonProperty("Type") + private String type; + + public String getIp() { + return ip; + } + + public Integer getPrivatePort() { + return privatePort; + } + + public Integer getPublicPort() { + return publicPort; + } + + public String getType() { + return type; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java new file mode 100644 index 00000000..c28d024a --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java @@ -0,0 +1,191 @@ +package com.github.dockerjava.api.model; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ContainerConfig { + + @JsonProperty("AttachStderr") + private boolean attachStderr = false; + + @JsonProperty("AttachStdin") + private boolean attachStdin = false; + + @JsonProperty("AttachStdout") + private boolean attachStdout = false; + + @JsonProperty("Cmd") + private String[] cmd; + + @JsonProperty("CpuShares") + private int cpuShares = 0; + + @JsonProperty("Cpuset") + private String cpuset = ""; + + @JsonProperty("Domainname") + private String domainName = ""; + + @JsonProperty("Entrypoint") + private String[] entrypoint = new String[] {}; + + @JsonProperty("Env") + private String[] env; + + @JsonProperty("ExposedPorts") + private ExposedPorts exposedPorts; + + @JsonProperty("Hostname") + private String hostName = ""; + + @JsonProperty("Image") + private String image; + + @JsonProperty("Memory") + private long memoryLimit = 0; + + @JsonProperty("MemorySwap") + private long memorySwap = 0; + + @JsonProperty("NetworkDisabled") + private boolean networkDisabled = false; + + @JsonProperty("OnBuild") + private int[] onBuild; + + @JsonProperty("OpenStdin") + private boolean stdinOpen = false; + + @JsonProperty("PortSpecs") + private String[] portSpecs; + + @JsonProperty("StdinOnce") + private boolean stdInOnce = false; + + @JsonProperty("Tty") + private boolean tty = false; + + @JsonProperty("User") + private String user = ""; + + @JsonProperty("Volumes") + private Map volumes; + + @JsonProperty("WorkingDir") + private String workingDir = ""; + + @JsonProperty("Ip") + private String ip = ""; + + @JsonIgnore + public ExposedPort[] getExposedPorts() { + return exposedPorts.getExposedPorts(); + } + + public boolean isNetworkDisabled() { + return networkDisabled; + } + + public String getDomainName() { + return domainName; + } + + public String getWorkingDir() { + return workingDir; + } + + public String getHostName() { + return hostName; + } + + public String[] getPortSpecs() { + return portSpecs; + } + + public String getUser() { + return user; + } + + public boolean isTty() { + return tty; + } + + public boolean isStdinOpen() { + return stdinOpen; + } + + public boolean isStdInOnce() { + return stdInOnce; + } + + public long getMemoryLimit() { + return memoryLimit; + } + + public long getMemorySwap() { + return memorySwap; + } + + public int getCpuShares() { + return cpuShares; + } + + public String getCpuset() { + return cpuset; + } + + public boolean isAttachStdin() { + return attachStdin; + } + + public boolean isAttachStdout() { + return attachStdout; + } + + public boolean isAttachStderr() { + return attachStderr; + } + + public String[] getEnv() { + return env; + } + + public String[] getCmd() { + return cmd; + } + + public String getImage() { + return image; + } + + public Map getVolumes() { + return volumes; + } + + public String[] getEntrypoint() { + return entrypoint; + } + + public int[] getOnBuild() { + return onBuild; + } + + public String getIp() { + return ip; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/CreateContainerConfig.java b/src/main/java/com/github/dockerjava/api/model/CreateContainerConfig.java new file mode 100644 index 00000000..601a6525 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/CreateContainerConfig.java @@ -0,0 +1,251 @@ +package com.github.dockerjava.api.model; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class CreateContainerConfig { + + @JsonProperty("Hostname") private String hostName = ""; + @JsonProperty("User") private String user = ""; + @JsonProperty("Memory") private long memoryLimit = 0; + @JsonProperty("MemorySwap") private long memorySwap = 0; + @JsonProperty("CpuShares") private int cpuShares = 0; + @JsonProperty("Cpuset") private String cpuset = ""; + @JsonProperty("AttachStdin") private boolean attachStdin = false; + @JsonProperty("AttachStdout") private boolean attachStdout = false; + @JsonProperty("AttachStderr") private boolean attachStderr = false; + @JsonProperty("PortSpecs") private String[] portSpecs = new String[] {}; + @JsonProperty("Tty") private boolean tty = false; + @JsonProperty("OpenStdin") private boolean stdinOpen = false; + @JsonProperty("StdinOnce") private boolean stdInOnce = false; + @JsonProperty("Env") private List env = new ArrayList(); + @JsonProperty("Cmd") private String[] cmd = new String[] {}; + @JsonProperty("Dns") private String[] dns = new String[] {}; + @JsonProperty("Image") private String image; + @JsonProperty("Volumes") private Volumes volumes = new Volumes(); + @JsonProperty("VolumesFrom") private String volumesFrom = ""; + @JsonProperty("WorkingDir") private String workingDir = ""; + @JsonProperty("DisableNetwork") private boolean disableNetwork = false; + @JsonProperty("ExposedPorts") private ExposedPorts exposedPorts = new ExposedPorts(); + @JsonProperty("Ip") private String ip = ""; + + public CreateContainerConfig withExposedPorts(ExposedPort[] exposedPorts) { + this.exposedPorts = new ExposedPorts(exposedPorts); + return this; + } + + @JsonIgnore + public ExposedPort[] getExposedPorts() { + return exposedPorts.getExposedPorts(); + } + + public boolean isDisableNetwork() { + return disableNetwork; + } + + public String getWorkingDir() { + return workingDir; + } + + public CreateContainerConfig withWorkingDir(String workingDir) { + this.workingDir = workingDir; + return this; + } + + public String getHostName() { + return hostName; + } + + public CreateContainerConfig withDisableNetwork(boolean disableNetwork) { + this.disableNetwork = disableNetwork; + return this; + } + + public CreateContainerConfig withHostName(String hostName) { + this.hostName = hostName; + return this; + } + + public String[] getPortSpecs() { + return portSpecs; + } + + public CreateContainerConfig withPortSpecs(String[] portSpecs) { + this.portSpecs = portSpecs; + return this; + } + + public String getUser() { + return user; + } + + public CreateContainerConfig withUser(String user) { + this.user = user; + return this; + } + + public boolean isTty() { + return tty; + } + + public CreateContainerConfig withTty(boolean tty) { + this.tty = tty; + return this; + } + + public boolean isStdinOpen() { + return stdinOpen; + } + + public CreateContainerConfig withStdinOpen(boolean stdinOpen) { + this.stdinOpen = stdinOpen; + return this; + } + + public boolean isStdInOnce() { + return stdInOnce; + } + + public CreateContainerConfig withStdInOnce(boolean stdInOnce) { + this.stdInOnce = stdInOnce; + return this; + } + + public long getMemoryLimit() { + return memoryLimit; + } + + public CreateContainerConfig withMemoryLimit(long memoryLimit) { + this.memoryLimit = memoryLimit; + return this; + } + + public long getMemorySwap() { + return memorySwap; + } + + public CreateContainerConfig withMemorySwap(long memorySwap) { + this.memorySwap = memorySwap; + return this; + } + + public boolean isAttachStdin() { + return attachStdin; + } + + public CreateContainerConfig withAttachStdin(boolean attachStdin) { + this.attachStdin = attachStdin; + return this; + } + + public boolean isAttachStdout() { + return attachStdout; + } + + public CreateContainerConfig withAttachStdout(boolean attachStdout) { + this.attachStdout = attachStdout; + return this; + } + + public boolean isAttachStderr() { + return attachStderr; + } + + public CreateContainerConfig withAttachStderr(boolean attachStderr) { + this.attachStderr = attachStderr; + return this; + } + + public List getEnv() { + return env; + } + + public CreateContainerConfig withEnv(String[] env) { + this.env = Arrays.asList(env); + return this; + } + + public String[] getCmd() { + return cmd; + } + + public CreateContainerConfig withCmd(String[] cmd) { + this.cmd = cmd; + return this; + } + + public String[] getDns() { + return dns; + } + + public CreateContainerConfig withDns(String[] dns) { + this.dns = dns; + return this; + } + + public String getImage() { + return image; + } + + public CreateContainerConfig withImage(String image) { + this.image = image; + return this; + } + + public int getCpuShares() { + return cpuShares; + } + + public String getCpuset() { + return cpuset; + } + + public String getIp() { + return ip; + } + + @JsonIgnore + public Volume[] getVolumes() { + return volumes.getVolumes(); + } + + public CreateContainerConfig withVolumes(Volume[] volumes) { + this.volumes = new Volumes(volumes); + return this; + } + + public String getVolumesFrom() { + return volumesFrom; + } + + public CreateContainerConfig withVolumesFrom(String volumesFrom) { + this.volumesFrom = volumesFrom; + return this; + } + + public CreateContainerConfig withCpuset(String cpuset) { + this.cpuset = cpuset; + return this; + } + + public CreateContainerConfig withCpuShare(int cpuShares) { + this.cpuShares = cpuShares; + return this; + } + + public CreateContainerConfig withIp(String ip) { + this.ip = ip; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/model/Device.java b/src/main/java/com/github/dockerjava/api/model/Device.java new file mode 100644 index 00000000..b0b32515 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Device.java @@ -0,0 +1,64 @@ +package com.github.dockerjava.api.model; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.Preconditions; + +public class Device { + + @JsonProperty("CgroupPermissions") + private String cGroupPermissions = ""; + + @JsonProperty("PathOnHost") + private String pathOnHost = null; + + @JsonProperty("PathInContainer") + private String pathInContainer = null; + + public Device() { + } + + public Device(String cGroupPermissions, String pathInContainer, + String pathOnHost) { + Preconditions.checkNotNull(cGroupPermissions, + "cGroupPermissions is null"); + Preconditions.checkNotNull(pathInContainer, "pathInContainer is null"); + Preconditions.checkNotNull(pathOnHost, "pathOnHost is null"); + this.cGroupPermissions = cGroupPermissions; + this.pathInContainer = pathInContainer; + this.pathOnHost = pathOnHost; + } + + public String getcGroupPermissions() { + return cGroupPermissions; + } + + public String getPathInContainer() { + return pathInContainer; + } + + public String getPathOnHost() { + return pathOnHost; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Device) { + Device other = (Device) obj; + return new EqualsBuilder() + .append(cGroupPermissions, other.getcGroupPermissions()) + .append(pathInContainer, other.getPathInContainer()) + .append(pathOnHost, other.getPathOnHost()).isEquals(); + } else + return super.equals(obj); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(cGroupPermissions) + .append(pathInContainer).append(pathOnHost).toHashCode(); + } + +} diff --git a/src/main/java/com/kpelykh/docker/client/model/DriverStatus.java b/src/main/java/com/github/dockerjava/api/model/DriverStatus.java similarity index 70% rename from src/main/java/com/kpelykh/docker/client/model/DriverStatus.java rename to src/main/java/com/github/dockerjava/api/model/DriverStatus.java index 5421bc44..c1bb8b7d 100644 --- a/src/main/java/com/kpelykh/docker/client/model/DriverStatus.java +++ b/src/main/java/com/github/dockerjava/api/model/DriverStatus.java @@ -1,33 +1,31 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * Created by ben on 12/12/13. - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class DriverStatus { - - @JsonProperty("Root Dir") - private String rootDir; - - @JsonProperty("Dirs") - private int dirs; - - public String getRootDir() { - return rootDir; - } - - public int getDirs() { - return dirs; - } - - @Override - public String toString() { - return "DriverStatus{" + - "rootDir='" + rootDir + '\'' + - ", dirs=" + dirs + - '}'; - } -} +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * Created by ben on 12/12/13. + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class DriverStatus { + + @JsonProperty("Root Dir") + private String rootDir; + + @JsonProperty("Dirs") + private int dirs; + + public String getRootDir() { + return rootDir; + } + + public int getDirs() { + return dirs; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/Event.java b/src/main/java/com/github/dockerjava/api/model/Event.java new file mode 100644 index 00000000..674cb66d --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Event.java @@ -0,0 +1,37 @@ +package com.github.dockerjava.api.model; + +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * Representation of a Docker event. + */ +public class Event { + private String status; + + private String id; + + private String from; + + private long time; + + public String getStatus() { + return status; + } + + public String getId() { + return id; + } + + public String getFrom() { + return from; + } + + public long getTime() { + return time; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/ExecConfig.java b/src/main/java/com/github/dockerjava/api/model/ExecConfig.java new file mode 100644 index 00000000..c101db5d --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/ExecConfig.java @@ -0,0 +1,95 @@ +package com.github.dockerjava.api.model; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class ExecConfig { + + @JsonProperty("User") private String user = ""; + @JsonProperty("Privileged") private boolean privileged = false; + @JsonProperty("Tty") private boolean tty = false; + @JsonProperty("Container") private String containerId = ""; + @JsonProperty("AttachStdin") private boolean attachStdin = false; + @JsonProperty("AttachStdout") private boolean attachStdout = true; + @JsonProperty("AttachStderr") private boolean attachStderr = true; + @JsonProperty("Detach") private boolean detach; + @JsonProperty("Cmd") private String[] cmd; + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public boolean isPrivileged() { + return privileged; + } + + public void setPrivileged(boolean privileged) { + this.privileged = privileged; + } + + public boolean isTty() { + return tty; + } + + public void setTty(boolean tty) { + this.tty = tty; + } + + public String getContainerId() { + return containerId; + } + + public void setContainerId(String containerId) { + this.containerId = containerId; + } + + public boolean isAttachStdin() { + return attachStdin; + } + + public void setAttachStdin(boolean attachStdin) { + this.attachStdin = attachStdin; + } + + public boolean isAttachStdout() { + return attachStdout; + } + + public void setAttachStdout(boolean attachStdout) { + this.attachStdout = attachStdout; + } + + public boolean isAttachStderr() { + return attachStderr; + } + + public void setAttachStderr(boolean attachStderr) { + this.attachStderr = attachStderr; + } + + public boolean isDetach() { + return detach; + } + + public void setDetach(boolean detach) { + this.detach = detach; + } + + public String[] getCmd() { + return cmd; + } + + public void setCmd(String[] cmd) { + this.cmd = cmd; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/ExposedPort.java b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java new file mode 100644 index 00000000..d19bfbf0 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java @@ -0,0 +1,173 @@ +package com.github.dockerjava.api.model; + +import static com.github.dockerjava.api.model.InternetProtocol.TCP; +import static com.github.dockerjava.api.model.InternetProtocol.UDP; + +import java.io.IOException; +import java.util.Map.Entry; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.node.NullNode; +import com.github.dockerjava.api.model.Ports.Binding; + +/** + * Represents a container port that Docker exposes to external clients. + * The port is defined by its {@link #getPort() port number} and an + * {@link InternetProtocol}. + * It can be published by Docker by {@link Ports#bind(ExposedPort, Binding) binding} + * it to a host port, represented by a {@link Binding}. + */ +@JsonDeserialize(using = ExposedPort.Deserializer.class) +@JsonSerialize(using = ExposedPort.Serializer.class) +public class ExposedPort { + + private final InternetProtocol protocol; + private final int port; + + /** + * Creates an {@link ExposedPort} for the given parameters. + * + * @param port the {@link #getPort() port number} + * @param protocol the {@link InternetProtocol} + */ + public ExposedPort(int port, InternetProtocol protocol) { + this.port = port; + this.protocol = protocol; + } + + /** + * Creates an {@link ExposedPort} for the given parameters. + * + * @param scheme the {@link #getScheme() scheme}, tcp or + * udp + * @param port the {@link #getPort() port number} + * @deprecated use {@link #ExposedPort(int, InternetProtocol)} + */ + @Deprecated + public ExposedPort(String scheme, int port) { + this(port, InternetProtocol.valueOf(scheme)); + } + + /** @return the {@link InternetProtocol} */ + public InternetProtocol getProtocol() { + return protocol; + } + + /** + * @return the scheme (internet protocol), tcp or udp + * @deprecated use {@link #getProtocol()} + */ + @Deprecated + public String getScheme() { + return protocol.toString(); + } + + /** @return the port number */ + public int getPort() { + return port; + } + + /** + * Creates an {@link ExposedPort} for {@link InternetProtocol#TCP}. + * This is a shortcut for new ExposedPort(port, {@link InternetProtocol#TCP}) + */ + public static ExposedPort tcp(int port) { + return new ExposedPort(port, TCP); + } + + /** + * Creates an {@link ExposedPort} for {@link InternetProtocol#UDP}. + * This is a shortcut for new ExposedPort(port, {@link InternetProtocol#UDP}) + */ + public static ExposedPort udp(int port) { + return new ExposedPort(port, UDP); + } + + /** + * Parses a textual port specification (as used by the Docker CLI) to an + * {@link ExposedPort}. + * + * @param serialized the specification, e.g. 80/tcp + * @return an {@link ExposedPort} matching the specification + * @throws IllegalArgumentException if the specification cannot be parsed + */ + public static ExposedPort parse(String serialized) throws IllegalArgumentException { + try { + String[] parts = serialized.split("/"); + return new ExposedPort(Integer.valueOf(parts[0]), InternetProtocol.parse(parts[1])); + } catch (Exception e) { + throw new IllegalArgumentException("Error parsing ExposedPort '" + serialized + "'"); + } + } + + /** + * Returns a string representation of this {@link ExposedPort} suitable + * for inclusion in a JSON message. + * The format is port/protocol, like the argument in {@link #parse(String)}. + * + * @return a string representation of this {@link ExposedPort} + */ + @Override + public String toString() { + return port + "/" + protocol.toString(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ExposedPort) { + ExposedPort other = (ExposedPort) obj; + return new EqualsBuilder().append(protocol, other.getProtocol()) + .append(port, other.getPort()).isEquals(); + } else + return super.equals(obj); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(protocol).append(port).toHashCode(); + } + + public static class Deserializer extends JsonDeserializer { + @Override + public ExposedPort deserialize(JsonParser jsonParser, + DeserializationContext deserializationContext) + throws IOException, JsonProcessingException { + ObjectCodec oc = jsonParser.getCodec(); + JsonNode node = oc.readTree(jsonParser); + if (!node.equals(NullNode.getInstance())) { + Entry field = node.fields().next(); + return ExposedPort.parse(field.getKey()); + } else { + return null; + } + } + } + + public static class Serializer extends JsonSerializer { + + @Override + public void serialize(ExposedPort exposedPort, JsonGenerator jsonGen, + SerializerProvider serProvider) throws IOException, + JsonProcessingException { + + jsonGen.writeStartObject(); + jsonGen.writeFieldName(exposedPort.toString()); + jsonGen.writeEndObject(); + } + + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java b/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java new file mode 100644 index 00000000..924d1300 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java @@ -0,0 +1,73 @@ +package com.github.dockerjava.api.model; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.node.NullNode; + + +@JsonSerialize(using = ExposedPorts.Serializer.class) +@JsonDeserialize(using = ExposedPorts.Deserializer.class) +public class ExposedPorts { + + private ExposedPort[] exposedPorts; + + public ExposedPorts(ExposedPort... exposedPorts) { + this.exposedPorts = exposedPorts; + } + + public ExposedPort[] getExposedPorts() { + return exposedPorts; + } + + public static class Serializer extends JsonSerializer { + + @Override + public void serialize(ExposedPorts exposedPorts, JsonGenerator jsonGen, + SerializerProvider serProvider) throws IOException, + JsonProcessingException { + + jsonGen.writeStartObject(); + for (ExposedPort exposedPort : exposedPorts.getExposedPorts()) { + jsonGen.writeFieldName(exposedPort.toString()); + jsonGen.writeStartObject(); + jsonGen.writeEndObject(); + } + jsonGen.writeEndObject(); + } + + } + + public static class Deserializer extends JsonDeserializer { + @Override + public ExposedPorts deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + + List exposedPorts = new ArrayList(); + ObjectCodec oc = jsonParser.getCodec(); + JsonNode node = oc.readTree(jsonParser); + for (Iterator> it = node.fields(); it.hasNext();) { + + Map.Entry field = it.next(); + if (!field.getValue().equals(NullNode.getInstance())) { + exposedPorts.add(ExposedPort.parse(field.getKey())); + } + } + return new ExposedPorts(exposedPorts.toArray(new ExposedPort[0])); + } + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/Image.java b/src/main/java/com/github/dockerjava/api/model/Image.java new file mode 100644 index 00000000..8c694dab --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Image.java @@ -0,0 +1,62 @@ +package com.github.dockerjava.api.model; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Image { + + @JsonProperty("Created") + private long created; + + @JsonProperty("Id") + private String id; + + @JsonProperty("ParentId") + private String parentId; + + @JsonProperty("RepoTags") + private String[] repoTags; + + @JsonProperty("Size") + private long size; + + @JsonProperty("VirtualSize") + private long virtualSize; + + public String getId() { + return id; + } + + public String[] getRepoTags() { + return repoTags; + } + + public String getParentId() { + return parentId; + } + + public long getCreated() { + return created; + } + + public long getSize() { + return size; + } + + public long getVirtualSize() { + return virtualSize; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/Info.java b/src/main/java/com/github/dockerjava/api/model/Info.java new file mode 100644 index 00000000..7fe6ae79 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Info.java @@ -0,0 +1,146 @@ +package com.github.dockerjava.api.model; + +import java.util.List; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ +@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) +@JsonInclude(Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +public class Info { + + @JsonProperty("Containers") + private int containers; + + @JsonProperty("Debug") + private boolean debug; + + @JsonProperty("Driver") + private String driver; + + @JsonProperty("DriverStatus") + private List driverStatuses; + + @JsonProperty("ExecutionDriver") + private String executionDriver; + + @JsonProperty("IPv4Forwarding") + private String IPv4Forwarding; + + @JsonProperty("Images") + private int images; + + @JsonProperty("IndexServerAddress") + private String IndexServerAddress; + + @JsonProperty("InitPath") + private String initPath; + + @JsonProperty("InitSha1") + private String initSha1; + + @JsonProperty("KernelVersion") + private String kernelVersion; + + @JsonProperty("MemoryLimit") + private boolean memoryLimit; + + @JsonProperty("NEventsListener") + private long nEventListener; + + @JsonProperty("NFd") + private int NFd; + + @JsonProperty("NGoroutines") + private int NGoroutines; + + @JsonProperty("Sockets") + private String[] sockets; + + @JsonProperty("SwapLimit") + private int swapLimit; + + public boolean isDebug() { + return debug; + } + + public int getContainers() { + return containers; + } + + public String getDriver() { + return driver; + } + + public List getDriverStatuses() { + return driverStatuses; + } + + public int getImages() { + return images; + } + + public String getIPv4Forwarding() { + return IPv4Forwarding; + } + + public String getIndexServerAddress() { + return IndexServerAddress; + } + + public String getInitPath() { + return initPath; + } + + public String getInitSha1() { + return initSha1; + } + + public String getKernelVersion() { + return kernelVersion; + } + + public String[] getSockets() { + return sockets; + } + + public boolean isMemoryLimit() { + return memoryLimit; + } + + public long getnEventListener() { + return nEventListener; + } + + public int getNFd() { + return NFd; + } + + public int getNGoroutines() { + return NGoroutines; + } + + public int getSwapLimit() { + return swapLimit; + } + + public String getExecutionDriver() { + return executionDriver; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/InternetProtocol.java b/src/main/java/com/github/dockerjava/api/model/InternetProtocol.java new file mode 100644 index 00000000..96c21524 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/InternetProtocol.java @@ -0,0 +1,49 @@ +package com.github.dockerjava.api.model; + + +/** + * The IP protocols supported by Docker. + * + * @see #TCP + * @see #UDP + */ +public enum InternetProtocol { + /** The Transmission Control Protocol */ + TCP, + + /** The User Datagram Protocol */ + UDP; + + /** + * The default {@link InternetProtocol}: {@link #TCP} + */ + public static final InternetProtocol DEFAULT = TCP; + + /** + * Returns a string representation of this {@link InternetProtocol} suitable + * for inclusion in a JSON message. + * The output is the lowercased name of the Protocol, e.g. tcp. + * + * @return a string representation of this {@link InternetProtocol} + */ + @Override + public String toString() { + return super.toString().toLowerCase(); + } + + /** + * Parses a string to an {@link InternetProtocol}. + * + * @param serialized the protocol, e.g. tcp or TCP + * @return an {@link InternetProtocol} described by the string + * @throws IllegalArgumentException if the argument cannot be parsed + */ + public static InternetProtocol parse(String serialized) throws IllegalArgumentException { + try { + return valueOf(serialized.toUpperCase()); + } catch (Exception e) { + throw new IllegalArgumentException("Error parsing Protocol '" + serialized + "'"); + } + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/LimitationConfig.java b/src/main/java/com/github/dockerjava/api/model/LimitationConfig.java new file mode 100644 index 00000000..85357911 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/LimitationConfig.java @@ -0,0 +1,56 @@ +package com.github.dockerjava.api.model; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class LimitationConfig { + + @JsonProperty("cpuShares") + private int cpuShares = 0; + + @JsonProperty("cpuset") + private String cpuset = ""; + + @JsonProperty("memory") + private long memoryLimit = 0; + + private boolean saveChanges = false; + + public int getCpuShares() { + return cpuShares; + } + + public void setCpuShares(int cpuShares) { + this.cpuShares = cpuShares; + } + + public String getCpuset() { + return cpuset; + } + + public void setCpuset(String cpuset) { + this.cpuset = cpuset; + } + + public long getMemoryLimit() { + return memoryLimit; + } + + public void setMemoryLimit(long memoryLimit) { + this.memoryLimit = memoryLimit; + } + + public boolean isSaveChanges() { + return saveChanges; + } + + public void setSaveChanges(boolean saveChanges) { + this.saveChanges = saveChanges; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/Link.java b/src/main/java/com/github/dockerjava/api/model/Link.java new file mode 100644 index 00000000..4416dca0 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Link.java @@ -0,0 +1,105 @@ +package com.github.dockerjava.api.model; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +/** + * Represents a network link between two Docker containers. + * The container with the name {@link #getName()} is made available in the + * target container with the aliased name {@link #getAlias()}. + * This involves creating an entry in /etc/hosts and some environment + * variables in the target container as well as creating a network bridge between + * both containers. + */ +public class Link +{ + + private final String name; + + private final String alias; + + /** + * Creates a {@link Link} for the container with the given name and an aliased + * name for use in the target container. + * + * @param name the name of the container that you want to link into the target + * container + * @param alias the aliased name under which the linked container will be available + * in the target container + */ + public Link(final String name, final String alias) + { + this.name = name; + this.alias = alias; + } + + /** + * @return the name of the container that is linked into the target container + */ + public String getName() + { + return name; + } + + /** + * @return the aliased name under which the linked container will be available + * in the target container + */ + public String getAlias() + { + return alias; + } + + /** + * Parses a textual link specification (as used by the Docker CLI) to a {@link Link}. + * + * @param serialized the specification, e.g. name:alias + * @return a {@link Link} matching the specification + * @throws IllegalArgumentException if the specification cannot be parsed + */ + public static Link parse(final String serialized) throws IllegalArgumentException + { + try { + final String[] parts = serialized.split(":"); + switch (parts.length) { + case 2: { + return new Link(parts[0], parts[1]); + } + default: { + throw new IllegalArgumentException(); + } + } + } catch (final Exception e) { + throw new IllegalArgumentException("Error parsing Link '" + serialized + "'"); + } + } + + @Override + public boolean equals(final Object obj) + { + if (obj instanceof Link) { + final Link other = (Link) obj; + return new EqualsBuilder().append(name, other.getName()).append(alias, other.getAlias()).isEquals(); + } else + return super.equals(obj); + } + + @Override + public int hashCode() + { + return new HashCodeBuilder().append(name).append(alias).toHashCode(); + } + + /** + * Returns a string representation of this {@link Link} suitable + * for inclusion in a JSON message. + * The format is name:alias, like the argument in {@link #parse(String)}. + * + * @return a string representation of this {@link Link} + */ + @Override + public String toString() { + return name + ":" + alias; + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/Links.java b/src/main/java/com/github/dockerjava/api/model/Links.java new file mode 100644 index 00000000..b0d0cc8d --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Links.java @@ -0,0 +1,75 @@ + +package com.github.dockerjava.api.model; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.node.NullNode; + +@JsonSerialize(using = Links.Serializer.class) +@JsonDeserialize(using = Links.Deserializer.class) +public class Links +{ + + private final Link[] links; + + public Links(final Link... links) + { + this.links = links; + } + + public Link[] getLinks() + { + return links; + } + + public static class Serializer extends JsonSerializer + { + + @Override + public void serialize(final Links links, final JsonGenerator jsonGen, final SerializerProvider serProvider) throws IOException, JsonProcessingException + { + jsonGen.writeStartArray(); + for (final Link link : links.getLinks()) { + jsonGen.writeString(link.toString()); + } + jsonGen.writeEndArray(); + } + + } + + public static class Deserializer extends JsonDeserializer + { + + @Override + public Links deserialize(final JsonParser jsonParser, final DeserializationContext deserializationContext) throws IOException, JsonProcessingException + { + final List binds = new ArrayList(); + final ObjectCodec oc = jsonParser.getCodec(); + final JsonNode node = oc.readTree(jsonParser); + for (final Iterator> it = node.fields(); it.hasNext();) { + + final Map.Entry field = it.next(); + if (!field.getValue().equals(NullNode.getInstance())) { + binds.add(Link.parse(field.getKey())); + } + } + return new Links(binds.toArray(new Link[0])); + } + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/LxcConf.java b/src/main/java/com/github/dockerjava/api/model/LxcConf.java new file mode 100644 index 00000000..67ce00ca --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/LxcConf.java @@ -0,0 +1,38 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class LxcConf { + @JsonProperty("Key") + public String key; + + @JsonProperty("Value") + public String value; + + public LxcConf(String key, String value) { + this.key = key; + this.value = value; + } + + public LxcConf() { + } + + public String getKey() { + return key; + } + + public LxcConf setKey(String key) { + this.key = key; + return this; + } + + public String getValue() { + return value; + } + + public LxcConf setValue(String value) { + this.value = value; + return this; + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/Ports.java b/src/main/java/com/github/dockerjava/api/model/Ports.java new file mode 100644 index 00000000..a14b3103 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Ports.java @@ -0,0 +1,178 @@ +package com.github.dockerjava.api.model; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.node.NullNode; +import com.github.dockerjava.api.command.InspectContainerResponse.HostConfig; +import com.github.dockerjava.api.command.InspectContainerResponse.NetworkSettings; + +/** + * A container for port bindings, made available as a {@link Map} via its + * {@link #getBindings()} method. + * + * @see HostConfig#getPortBindings() + * @see NetworkSettings#getPorts() + */ +@JsonDeserialize(using = Ports.Deserializer.class) +@JsonSerialize(using = Ports.Serializer.class) +public class Ports { + + private final Map ports = new HashMap(); + + public Ports() { } + + public Ports(ExposedPort exposedPort, Binding host) { + bind(exposedPort, host); + } + + public void bind(ExposedPort exposedPort, Binding host) { + if (ports.containsKey(exposedPort)) { + Binding[] bindings = ports.get(exposedPort); + ports.put(exposedPort, (Binding[]) ArrayUtils.add(bindings, host)); + } else { + ports.put(exposedPort, new Binding[]{host}); + } + } + + @Override + public String toString(){ + return ports.toString(); + } + + /** + * @return the port bindings as a {@link Map} that contains one or more + * {@link Binding}s per {@link ExposedPort}. + */ + public Map getBindings(){ + return ports; + } + + public static Binding Binding(String hostIp, int hostPort) { + return new Binding(hostIp, hostPort); + } + public static Binding Binding(int hostPort) { + return new Binding(hostPort); + } + + + /** + * The host part of a port binding. + * In a port binding a container port, expressed as an {@link ExposedPort}, + * is published as a port of the Docker host. + * + * @see ExposedPort + */ + public static class Binding { + + private final String hostIp; + + private final int hostPort; + + /** + * Creates the host part of a port binding. + * + * @see Ports#bind(ExposedPort, Binding) + * @see ExposedPort + */ + public Binding(String hostIp, int hostPort) { + this.hostIp = hostIp; + this.hostPort = hostPort; + } + + public Binding(int hostPort) { + this("", hostPort); + } + + public String getHostIp() { + return hostIp; + } + + public int getHostPort() { + return hostPort; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object obj) { + if(obj instanceof Binding) { + Binding other = (Binding) obj; + return new EqualsBuilder() + .append(hostIp, other.getHostIp()) + .append(hostPort, other.getHostPort()).isEquals(); + } else + return super.equals(obj); + } + } + + + public static class Deserializer extends JsonDeserializer { + @Override + public Ports deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + + Ports out = new Ports(); + ObjectCodec oc = jsonParser.getCodec(); + JsonNode node = oc.readTree(jsonParser); + for (Iterator> it = node.fields(); it.hasNext();) { + + Map.Entry portNode = it.next(); + JsonNode bindingsArray = portNode.getValue(); + for (int i = 0; i < bindingsArray.size(); i++) { + JsonNode bindingNode = bindingsArray.get(i); + if (!bindingNode.equals(NullNode.getInstance())) { + String hostIp = bindingNode.get("HostIp").textValue(); + int hostPort = bindingNode.get("HostPort").asInt(); + out.bind(ExposedPort.parse(portNode.getKey()), new Binding(hostIp, hostPort)); + } + } + } + return out; + } + } + + public static class Serializer extends JsonSerializer { + + @Override + public void serialize(Ports portBindings, JsonGenerator jsonGen, + SerializerProvider serProvider) throws IOException, JsonProcessingException { + + jsonGen.writeStartObject(); + for(Entry entry : portBindings.getBindings().entrySet()){ + jsonGen.writeFieldName(entry.getKey().toString()); + jsonGen.writeStartArray(); + for (Binding binding : entry.getValue()) { + jsonGen.writeStartObject(); + jsonGen.writeStringField("HostIp", binding.getHostIp()); + jsonGen.writeStringField("HostPort", "" + binding.getHostPort()); + jsonGen.writeEndObject(); + } + jsonGen.writeEndArray(); + } + jsonGen.writeEndObject(); + } + + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java b/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java new file mode 100644 index 00000000..936a5b81 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java @@ -0,0 +1,75 @@ +package com.github.dockerjava.api.model; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.base.Preconditions; + +/** + * Container restart policy + * + * no – Do not restart the container if it dies. (default) + * on-failure – Restart the container if it exits with a non-zero exit code. + * Can also accept an optional maximum restart count (e.g. on-failure:5). + * always – Always restart the container no matter what exit code is returned. + * + * @author marcus + * + */ +public class RestartPolicy { + + @JsonProperty("MaximumRetryCount") + private int maximumRetryCount = 0; + + @JsonProperty("Name") + private String name = "no"; + + public RestartPolicy() { + } + + private RestartPolicy(int maximumRetryCount, String name) { + Preconditions.checkNotNull(name, "name is null"); + this.maximumRetryCount = maximumRetryCount; + this.name = name; + } + + public static RestartPolicy noRestart() { + return new RestartPolicy(); + } + + public static RestartPolicy alwaysRestart() { + return new RestartPolicy(0, "always"); + } + + public static RestartPolicy onFailureRestart(int maximumRetryCount) { + return new RestartPolicy(maximumRetryCount, "on-failure"); + } + + public int getMaximumRetryCount() { + return maximumRetryCount; + } + + public String getName() { + return name; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof RestartPolicy) { + RestartPolicy other = (RestartPolicy) obj; + return new EqualsBuilder() + .append(maximumRetryCount, other.getMaximumRetryCount()) + .append(name, other.getName()) + .isEquals(); + } else + return super.equals(obj); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(maximumRetryCount) + .append(name).toHashCode(); + } + +} diff --git a/src/main/java/com/kpelykh/docker/client/model/SearchItem.java b/src/main/java/com/github/dockerjava/api/model/SearchItem.java similarity index 82% rename from src/main/java/com/kpelykh/docker/client/model/SearchItem.java rename to src/main/java/com/github/dockerjava/api/model/SearchItem.java index d7f6eb4f..cb4c5d7b 100644 --- a/src/main/java/com/kpelykh/docker/client/model/SearchItem.java +++ b/src/main/java/com/github/dockerjava/api/model/SearchItem.java @@ -1,54 +1,54 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class SearchItem { - - @JsonProperty("star_count") - private int starCount; - - @JsonProperty("is_official") - private boolean isOfficial; - - @JsonProperty("is_trusted") - private boolean isTrusted; - - @JsonProperty("name") - private String name; - - @JsonProperty("description") - private String description; - - public int getStarCount() { - return starCount; - } - - public boolean isOfficial() { - return isOfficial; - } - - public boolean isTrusted() { - return isTrusted; - } - - public String getName() { - return name; - } - - public String getDescription() { - return description; - } - - @Override - public String toString() { - return "name='" + name + '\'' + - ", description='" + description + '\'' + '}'; - } -} +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class SearchItem { + + @JsonProperty("star_count") + private int starCount; + + @JsonProperty("is_official") + private boolean isOfficial; + + @JsonProperty("is_trusted") + private boolean isTrusted; + + @JsonProperty("name") + private String name; + + @JsonProperty("description") + private String description; + + public int getStarCount() { + return starCount; + } + + public boolean isOfficial() { + return isOfficial; + } + + public boolean isTrusted() { + return isTrusted; + } + + public String getName() { + return name; + } + + public String getDescription() { + return description; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/StartContainerConfig.java b/src/main/java/com/github/dockerjava/api/model/StartContainerConfig.java new file mode 100644 index 00000000..50149a76 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/StartContainerConfig.java @@ -0,0 +1,180 @@ +package com.github.dockerjava.api.model; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; + +public class StartContainerConfig { + + @JsonProperty("Binds") + private Binds binds = new Binds(); + + @JsonProperty("Links") + private Links links = new Links(); + + @JsonProperty("LxcConf") + private LxcConf[] lxcConf = new LxcConf[] {}; + + @JsonProperty("PortBindings") + private Ports portBindings = new Ports(); + + @JsonProperty("PublishAllPorts") + private boolean publishAllPorts; + + @JsonProperty("Privileged") + private boolean privileged; + + @JsonProperty("Dns") + private String[] dns = new String[] {}; + + @JsonProperty("DnsSearch") + private String[] dnsSearch = new String[] {}; + + @JsonProperty("VolumesFrom") + private String[] volumesFrom = new String[] {}; + + @JsonProperty("NetworkMode") + private String networkMode = "bridge"; + + @JsonProperty("Devices") + private Device[] devices = new Device[] {}; + + @JsonProperty("RestartPolicy") + private RestartPolicy restartPolicy = new RestartPolicy(); + + @JsonProperty("CapAdd") + private String[] capAdd = new String[] {}; + + @JsonProperty("CapDrop") + private String[] capDrop = new String[] {}; + + @JsonIgnore + public Bind[] getBinds() { + return binds.getBinds(); + } + + @JsonIgnore + public void setBinds(Bind[] binds) { + this.binds = new Binds(binds); + } + + @JsonIgnore + public Link[] getLinks() { + return links.getLinks(); + } + + @JsonIgnore + public void setLinks(Link[] links) { + this.links = new Links(links); + } + + public LxcConf[] getLxcConf() { + return lxcConf; + } + + public void setLxcConf(LxcConf[] lxcConf) { + this.lxcConf = lxcConf; + } + + public Ports getPortBindings() { + return portBindings; + } + + public void setPortBindings(Ports portBindings) { + this.portBindings = portBindings; + } + + public boolean isPublishAllPorts() { + return publishAllPorts; + } + + public void setPublishAllPorts(boolean publishAllPorts) { + this.publishAllPorts = publishAllPorts; + } + + public boolean isPrivileged() { + return privileged; + } + + public void setPrivileged(boolean privileged) { + this.privileged = privileged; + } + + public String[] getDns() { + return dns; + } + + public void setDns(String[] dns) { + this.dns = dns; + } + + public String[] getVolumesFrom() { + return volumesFrom; + } + + public void setVolumesFrom(String[] volumesFrom) { + this.volumesFrom = volumesFrom; + } + + public String getNetworkMode() { + return networkMode; + } + + public void setNetworkMode(String networkMode) { + this.networkMode = networkMode; + } + + public Device[] getDevices() { + return devices; + } + + public void setDevices(Device[] devices) { + this.devices = devices; + } + + public RestartPolicy getRestartPolicy() { + return restartPolicy; + } + + public void setRestartPolicy(RestartPolicy restartPolicy) { + this.restartPolicy = restartPolicy; + } + + public String[] getCapAdd() { + return capAdd; + } + + public void setCapAdd(String[] capAdd) { + this.capAdd = capAdd; + } + + public String[] getCapDrop() { + return capDrop; + } + + public void setCapDrop(String[] capDrop) { + this.capDrop = capDrop; + } + + public void setBinds(Binds binds) { + this.binds = binds; + } + + public void setLinks(Links links) { + this.links = links; + } + + public String[] getDnsSearch() { + return dnsSearch; + } + + public void setDnsSearch(String[] dnsSearch) { + this.dnsSearch = dnsSearch; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/api/model/Subsystem.java b/src/main/java/com/github/dockerjava/api/model/Subsystem.java new file mode 100644 index 00000000..f39cd268 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Subsystem.java @@ -0,0 +1,51 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Subsystem { + + @JsonProperty("Subsystem") + private String name; + + @JsonProperty("Out") + private String out; + + @JsonProperty("Err") + private String err; + + @JsonProperty("Status") + private int status; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOut() { + return out; + } + + public void setOut(String out) { + this.out = out; + } + + public String getErr() { + return err; + } + + public void setErr(String err) { + this.err = err; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/Version.java b/src/main/java/com/github/dockerjava/api/model/Version.java new file mode 100644 index 00000000..4e02e2c0 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Version.java @@ -0,0 +1,68 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class Version { + + @JsonProperty("ApiVersion") + private String apiVersion; + + @JsonProperty("Arch") + private String arch; + + @JsonProperty("GitCommit") + private String gitCommit; + + @JsonProperty("GoVersion") + private String goVersion; + + @JsonProperty("KernelVersion") + private String kernelVersion; + + @JsonProperty("Os") + private String operatingSystem; + + @JsonProperty("Version") + private String version; + + public String getVersion() { + return version; + } + + public String getGitCommit() { + return gitCommit; + } + + public String getGoVersion() { + return goVersion; + } + + public String getKernelVersion() { + return kernelVersion; + } + + public String getArch() { + return arch; + } + + public String getOperatingSystem() { + return operatingSystem; + } + + public String getApiVersion() { + return apiVersion; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/Volume.java b/src/main/java/com/github/dockerjava/api/model/Volume.java new file mode 100644 index 00000000..1a189014 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Volume.java @@ -0,0 +1,111 @@ +package com.github.dockerjava.api.model; + +import java.io.IOException; +import java.util.Map.Entry; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.node.NullNode; + +/** + * Represents a bind mounted volume in a Docker container. + * + * @see Bind + */ +@JsonDeserialize(using = Volume.Deserializer.class) +@JsonSerialize(using = Volume.Serializer.class) +public class Volume { + + private String path; + + private boolean readWrite = true; + + public Volume(String path) { + this.path = path; + } + + public String getPath() { + return path; + } + + public boolean isReadWrite() { + return readWrite; + } + + public static Volume parse(String serialized) { + return new Volume(serialized); + } + + /** + * Returns a string representation of this {@link Volume} suitable + * for inclusion in a JSON message. + * The returned String is simply the container path, {@link #getPath()}. + * + * @return a string representation of this {@link Volume} + */ + @Override + public String toString() { + return getPath(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof Volume) { + Volume other = (Volume) obj; + return new EqualsBuilder().append(path, other.getPath()).append(readWrite, other.isReadWrite()) + .isEquals(); + } else + return super.equals(obj); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(path).append(readWrite).toHashCode(); + } + + public static class Serializer extends JsonSerializer { + + @Override + public void serialize(Volume volume, JsonGenerator jsonGen, + SerializerProvider serProvider) throws IOException, + JsonProcessingException { + + jsonGen.writeStartObject(); + jsonGen.writeFieldName(volume.getPath()); + jsonGen.writeString(Boolean.toString(volume.isReadWrite())); + jsonGen.writeEndObject(); + } + + } + + public static class Deserializer extends JsonDeserializer { + @Override + public Volume deserialize(JsonParser jsonParser, + DeserializationContext deserializationContext) + throws IOException, JsonProcessingException { + ObjectCodec oc = jsonParser.getCodec(); + JsonNode node = oc.readTree(jsonParser); + if (!node.equals(NullNode.getInstance())) { + Entry field = node.fields().next(); + return Volume.parse(field.getKey()); + } else { + return null; + } + } + } + + + +} diff --git a/src/main/java/com/github/dockerjava/api/model/VolumeBind.java b/src/main/java/com/github/dockerjava/api/model/VolumeBind.java new file mode 100644 index 00000000..d662f2b8 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/VolumeBind.java @@ -0,0 +1,19 @@ +package com.github.dockerjava.api.model; + +public class VolumeBind { + private final String hostPath; + private final String containerPath; + + public VolumeBind(String hostPath, String containerPath){ + this.hostPath = hostPath; + this.containerPath = containerPath; + } + + public String getContainerPath() { + return containerPath; + } + + public String getHostPath() { + return hostPath; + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/VolumeBinds.java b/src/main/java/com/github/dockerjava/api/model/VolumeBinds.java new file mode 100644 index 00000000..62ebc118 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/VolumeBinds.java @@ -0,0 +1,53 @@ +package com.github.dockerjava.api.model; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.node.NullNode; + +// This is not going to be serialized +@JsonDeserialize(using = VolumeBinds.Deserializer.class) +public class VolumeBinds { + private final VolumeBind[] binds; + + public VolumeBinds(VolumeBind... binds) { + this.binds = binds; + } + + public VolumeBind[] getBinds() { + return binds; + } + + public static final class Deserializer extends JsonDeserializer { + @Override + public VolumeBinds deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + + List binds = new ArrayList(); + ObjectCodec oc = jsonParser.getCodec(); + JsonNode node = oc.readTree(jsonParser); + for (Iterator> it = node.fields(); it.hasNext();) { + Map.Entry field = it.next(); + JsonNode value = field.getValue(); + if (!value.equals(NullNode.getInstance())) { + if (!value.isTextual()){ + throw deserializationContext.mappingException("Expected path for '"+field.getKey()+"'in host but got '"+ value+"'."); + } + VolumeBind bind = new VolumeBind(value.asText(),field.getKey()); + binds.add(bind); + } + } + return new VolumeBinds(binds.toArray(new VolumeBind[binds.size()])); + } + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/Volumes.java b/src/main/java/com/github/dockerjava/api/model/Volumes.java new file mode 100644 index 00000000..d06c0c0f --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/Volumes.java @@ -0,0 +1,73 @@ +package com.github.dockerjava.api.model; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.ObjectCodec; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.node.NullNode; + + +@JsonSerialize(using = Volumes.Serializer.class) +@JsonDeserialize(using = Volumes.Deserializer.class) +public class Volumes { + + private Volume[] volumes; + + public Volumes(Volume... volumes) { + this.volumes = volumes; + } + + public Volume[] getVolumes() { + return volumes; + } + + public static class Serializer extends JsonSerializer { + + @Override + public void serialize(Volumes volumes, JsonGenerator jsonGen, + SerializerProvider serProvider) throws IOException, + JsonProcessingException { + + jsonGen.writeStartObject(); + for (Volume volume : volumes.getVolumes()) { + jsonGen.writeFieldName(volume.getPath()); + jsonGen.writeString(Boolean.toString(volume.isReadWrite())); + } + jsonGen.writeEndObject(); + } + + } + + public static class Deserializer extends JsonDeserializer { + @Override + public Volumes deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + + List volumes = new ArrayList(); + ObjectCodec oc = jsonParser.getCodec(); + JsonNode node = oc.readTree(jsonParser); + for (Iterator> it = node.fields(); it.hasNext();) { + + Map.Entry field = it.next(); + if (!field.getValue().equals(NullNode.getInstance())) { + Volume volume = Volume.parse(field.getKey()); + volumes.add(volume); + } + } + return new Volumes(volumes.toArray(new Volume[0])); + } + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/WriteSubsystem.java b/src/main/java/com/github/dockerjava/api/model/WriteSubsystem.java new file mode 100644 index 00000000..c13f664e --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/WriteSubsystem.java @@ -0,0 +1,65 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class WriteSubsystem { + + @JsonProperty("Key") + private String key; + + @JsonProperty("Value") + private String value; + + public WriteSubsystem(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((key == null) ? 0 : key.hashCode()); + result = prime * result + ((value == null) ? 0 : value.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + WriteSubsystem other = (WriteSubsystem) obj; + if (key == null) { + if (other.key != null) + return false; + } else if (!key.equals(other.key)) + return false; + if (value == null) { + if (other.value != null) + return false; + } else if (!value.equals(other.value)) + return false; + return true; + } + +} diff --git a/src/main/java/com/github/dockerjava/api/model/metric/BlkioStatEntry.java b/src/main/java/com/github/dockerjava/api/model/metric/BlkioStatEntry.java new file mode 100644 index 00000000..8f1fc9c6 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/metric/BlkioStatEntry.java @@ -0,0 +1,42 @@ +package com.github.dockerjava.api.model.metric; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class BlkioStatEntry { + + @JsonProperty("major") + private long major; + + @JsonProperty("minor") + private long minor; + + @JsonProperty("op") + private String op; + + @JsonProperty("value") + private long value; + + public long getMajor() { + return major; + } + + public long getMinor() { + return minor; + } + + public String getOp() { + return op; + } + + public long getValue() { + return value; + } + + @Override + public String toString() { + return "BlkioStatEntry [major=" + major + ", minor=" + minor + ", op=" + + op + ", value=" + value + "]"; + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/metric/BlkioStats.java b/src/main/java/com/github/dockerjava/api/model/metric/BlkioStats.java new file mode 100644 index 00000000..3a349996 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/metric/BlkioStats.java @@ -0,0 +1,46 @@ +package com.github.dockerjava.api.model.metric; + +import java.util.Arrays; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class BlkioStats { + + @JsonProperty("io_service_bytes_recursive") + private BlkioStatEntry[] ioServiceBytesRecursive; + + @JsonProperty("io_serviced_recursive") + private BlkioStatEntry[] ioServicedRecursive; + + @JsonProperty("io_queue_recursive") + private BlkioStatEntry[] ioQueuedRecursive; + + @JsonProperty("sectors_recursive") + private BlkioStatEntry[] SectorsRecursive; + + public BlkioStatEntry[] getIoServiceBytesRecursive() { + return ioServiceBytesRecursive; + } + + public BlkioStatEntry[] getIoServicedRecursive() { + return ioServicedRecursive; + } + + public BlkioStatEntry[] getIoQueuedRecursive() { + return ioQueuedRecursive; + } + + public BlkioStatEntry[] getSectorsRecursive() { + return SectorsRecursive; + } + + @Override + public String toString() { + return "BlkioStats [ioServiceBytesRecursive=" + + Arrays.toString(ioServiceBytesRecursive) + + ", ioServicedRecursive=" + + Arrays.toString(ioServicedRecursive) + ", ioQueuedRecursive=" + + Arrays.toString(ioQueuedRecursive) + ", SectorsRecursive=" + + Arrays.toString(SectorsRecursive) + "]"; + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/metric/CpuStats.java b/src/main/java/com/github/dockerjava/api/model/metric/CpuStats.java new file mode 100644 index 00000000..1800e5da --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/metric/CpuStats.java @@ -0,0 +1,28 @@ +package com.github.dockerjava.api.model.metric; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class CpuStats { + + @JsonProperty("cpu_usage") + private CpuUsage cpuUsage; + + @JsonProperty("throlling_data") + private ThrottlingData throttlingData; + + public CpuUsage getCpuUsage() { + return cpuUsage; + } + + public ThrottlingData getThrottlingData() { + return throttlingData; + } + + @Override + public String toString() { + return "CpuStats [cpuUsage=" + cpuUsage + ", throttlingData=" + + throttlingData + "]"; + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/metric/CpuUsage.java b/src/main/java/com/github/dockerjava/api/model/metric/CpuUsage.java new file mode 100644 index 00000000..65230315 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/metric/CpuUsage.java @@ -0,0 +1,55 @@ +package com.github.dockerjava.api.model.metric; + +import java.util.Arrays; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + + +@JsonIgnoreProperties(ignoreUnknown = true) +public class CpuUsage { + + @JsonProperty("current_usage") + private double currentUsage; + + @JsonProperty("total_usage") + private long totalUsage; + + @JsonProperty("percpu_usage") + private long[] percpuUsage; + + @JsonProperty("usage_in_kernelmode") + private long usageInKernelMode; + + @JsonProperty("usage_in_usermode") + private long usageInUserMode; + + public double getCurrentUsage() { + return currentUsage; + } + + public long getTotalUsage() { + return totalUsage; + } + + public long[] getPercpuUsage() { + return percpuUsage; + } + + public long getUsageInKernelMode() { + return usageInKernelMode; + } + + public long getUsageInUserMode() { + return usageInUserMode; + } + + @Override + public String toString() { + return "CpuUsage [currentUsage=" + + currentUsage + ", totalUsage=" + totalUsage + + ", percpuUsage=" + Arrays.toString(percpuUsage) + + ", usageInKernelMode=" + usageInKernelMode + + ", usageInUserMode=" + usageInUserMode + "]"; + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/metric/FreezerStats.java b/src/main/java/com/github/dockerjava/api/model/metric/FreezerStats.java new file mode 100644 index 00000000..4cad9c4e --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/metric/FreezerStats.java @@ -0,0 +1,26 @@ +package com.github.dockerjava.api.model.metric; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class FreezerStats { + + @JsonProperty("parent_state") + private String parentState; + + @JsonProperty("self_state") + private String selfState; + + public String getParentState() { + return parentState; + } + + public String getSelfState() { + return selfState; + } + + @Override + public String toString() { + return "FreezerStats [parentState=" + parentState + ", selfState=" + + selfState + "]"; + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/metric/MemoryStats.java b/src/main/java/com/github/dockerjava/api/model/metric/MemoryStats.java new file mode 100644 index 00000000..1a5c4279 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/metric/MemoryStats.java @@ -0,0 +1,44 @@ +package com.github.dockerjava.api.model.metric; + +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class MemoryStats { + + @JsonProperty("usage") + private long usage; + + @JsonProperty("max_usage") + private long maxUsage; + + @JsonProperty("stats") + private Map stats; + + @JsonProperty("failcnt") + private long failcnt; + + public long getUsage() { + return usage; + } + + public long getMaxUsage() { + return maxUsage; + } + + public Map getStats() { + return stats; + } + + public long getFailcnt() { + return failcnt; + } + + @Override + public String toString() { + return "MemoryStats [usage=" + usage + ", maxUsage=" + maxUsage + + ", stats=" + stats + ", failcnt=" + failcnt + "]"; + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/metric/Metric.java b/src/main/java/com/github/dockerjava/api/model/metric/Metric.java new file mode 100644 index 00000000..a692f102 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/metric/Metric.java @@ -0,0 +1,43 @@ +package com.github.dockerjava.api.model.metric; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class Metric { + + @JsonProperty("cpu_stats") + private CpuStats cpuStats; + + @JsonProperty("memory_stats") + private MemoryStats memoryStats; + + @JsonProperty("blkio_stats") + private BlkioStats blkioStats; + + @JsonProperty("freezer_stats") + private FreezerStats freezerStats; + + public CpuStats getCpuStats() { + return cpuStats; + } + + public MemoryStats getMemoryStats() { + return memoryStats; + } + + public BlkioStats getBlkioStats() { + return blkioStats; + } + + public FreezerStats getFreezerStats() { + return freezerStats; + } + + @Override + public String toString() { + return "Metric [cpuStats=" + cpuStats + ", memoryStats=" + memoryStats + + ", blkioStats=" + blkioStats + ", freezerStats=" + + freezerStats + "]"; + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/metric/ThrottlingData.java b/src/main/java/com/github/dockerjava/api/model/metric/ThrottlingData.java new file mode 100644 index 00000000..36077cef --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/metric/ThrottlingData.java @@ -0,0 +1,35 @@ +package com.github.dockerjava.api.model.metric; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class ThrottlingData { + + @JsonProperty("periods") + private long periods; + + @JsonProperty("throttled_periods") + private long throttledPeriods; + + @JsonProperty("throttled_time") + private long throttledTime; + + public long getPeriods() { + return periods; + } + + public long getThrottledPeriods() { + return throttledPeriods; + } + + public long getThrottledTime() { + return throttledTime; + } + + @Override + public String toString() { + return "ThrottlingData [periods=" + periods + ", throttledPeriods=" + + throttledPeriods + ", throttledTime=" + throttledTime + "]"; + } +} diff --git a/src/main/java/com/github/dockerjava/core/CertificateUtils.java b/src/main/java/com/github/dockerjava/core/CertificateUtils.java new file mode 100644 index 00000000..6b19a201 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/CertificateUtils.java @@ -0,0 +1,141 @@ +package com.github.dockerjava.core; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; + +import org.apache.commons.io.IOUtils; +import org.bouncycastle.cert.X509CertificateHolder; +import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.openssl.PEMKeyPair; +import org.bouncycastle.openssl.PEMParser; + +public class CertificateUtils { + + public static boolean verifyCertificatesExist(String dockerCertPath) { + String[] files = {"ca.pem", "cert.pem", "key.pem"}; + for (String file : files) { + File path = new File(dockerCertPath, file); + boolean exists = path.exists(); + if(!exists) { + return false; + } + } + + return true; + } + + public static KeyStore createKeyStore(final String dockerCertPath) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, CertificateException, KeyStoreException { + KeyPair keyPair = loadPrivateKey(dockerCertPath); + Certificate privateCertificate = loadCertificate(dockerCertPath); + + KeyStore keyStore = KeyStore.getInstance("JKS"); + keyStore.load(null); + + keyStore.setKeyEntry("docker", keyPair.getPrivate(), "docker".toCharArray(), new Certificate[]{privateCertificate}); + return keyStore; + } + + public static KeyStore createTrustStore(final String dockerCertPath) throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException { + File caPath = new File(dockerCertPath, "ca.pem"); + BufferedReader reader = new BufferedReader(new FileReader(caPath)); + PEMParser pemParser = null; + + try { + pemParser = new PEMParser(reader); + X509CertificateHolder certificateHolder = (X509CertificateHolder) pemParser.readObject(); + Certificate caCertificate = new JcaX509CertificateConverter().setProvider("BC").getCertificate(certificateHolder); + + KeyStore trustStore = KeyStore.getInstance("JKS"); + trustStore.load(null); + trustStore.setCertificateEntry("ca", caCertificate); + return trustStore; + + } + finally { + if(pemParser != null) { + IOUtils.closeQuietly(pemParser); + } + + if(reader != null) { + IOUtils.closeQuietly(reader); + } + } + + } + + private static Certificate loadCertificate(final String dockerCertPath) throws IOException, CertificateException { + File certificate = new File(dockerCertPath, "cert.pem"); + BufferedReader reader = new BufferedReader(new FileReader(certificate)); + PEMParser pemParser = null; + + try { + pemParser = new PEMParser(reader); + X509CertificateHolder certificateHolder = (X509CertificateHolder) pemParser.readObject(); + return new JcaX509CertificateConverter().setProvider("BC").getCertificate(certificateHolder); + } + finally { + if(pemParser != null) { + IOUtils.closeQuietly(pemParser); + } + + if(reader != null) { + IOUtils.closeQuietly(reader); + } + } + + } + + private static KeyPair loadPrivateKey(final String dockerCertPath) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { + File certificate = new File(dockerCertPath, "key.pem"); + BufferedReader reader = new BufferedReader(new FileReader(certificate)); + + PEMParser pemParser = null; + + try { + pemParser = new PEMParser(reader); + + PEMKeyPair pemKeyPair = (PEMKeyPair) pemParser.readObject(); + + byte[] pemPrivateKeyEncoded = pemKeyPair.getPrivateKeyInfo().getEncoded(); + byte[] pemPublicKeyEncoded = pemKeyPair.getPublicKeyInfo().getEncoded(); + + KeyFactory factory = KeyFactory.getInstance("RSA"); + + X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(pemPublicKeyEncoded); + PublicKey publicKey = factory.generatePublic(publicKeySpec); + + PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(pemPrivateKeyEncoded); + PrivateKey privateKey = factory.generatePrivate(privateKeySpec); + + return new KeyPair(publicKey, privateKey); + + } + finally { + if(pemParser != null) { + IOUtils.closeQuietly(pemParser); + } + + if(reader != null) { + IOUtils.closeQuietly(reader); + } + } + + + } + +} diff --git a/src/main/java/com/kpelykh/docker/client/utils/CompressArchiveUtil.java b/src/main/java/com/github/dockerjava/core/CompressArchiveUtil.java similarity index 78% rename from src/main/java/com/kpelykh/docker/client/utils/CompressArchiveUtil.java rename to src/main/java/com/github/dockerjava/core/CompressArchiveUtil.java index aabf4cbb..a9a97238 100644 --- a/src/main/java/com/kpelykh/docker/client/utils/CompressArchiveUtil.java +++ b/src/main/java/com/github/dockerjava/core/CompressArchiveUtil.java @@ -1,4 +1,4 @@ -package com.kpelykh.docker.client.utils; +package com.github.dockerjava.core; import org.apache.commons.compress.archivers.tar.TarArchiveEntry; import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream; @@ -15,7 +15,13 @@ public static File archiveTARFiles(File base, Iterable files, String archi tos.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU); for (File file : files) { TarArchiveEntry tarEntry = new TarArchiveEntry(file); - tarEntry.setName(relativize(base, file)); + tarEntry.setName(relativize(base.getCanonicalFile(), file.getCanonicalFile())); + + if (!file.isDirectory()) { + if (file.canExecute()) { + tarEntry.setMode(tarEntry.getMode() | 0755); + } + } tos.putArchiveEntry(tarEntry); diff --git a/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java b/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java new file mode 100644 index 00000000..80028a10 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java @@ -0,0 +1,64 @@ +package com.github.dockerjava.core; + +import java.util.ServiceLoader; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.command.DockerCmdExecFactory; +import com.github.dockerjava.core.DockerClientConfig.DockerClientConfigBuilder; + +public class DockerClientBuilder { + + private static ServiceLoader serviceLoader = ServiceLoader.load(DockerCmdExecFactory.class); + + private DockerClientImpl dockerClient = null; + + private DockerClientBuilder(DockerClientImpl dockerClient) { + this.dockerClient = dockerClient; + } + + public static DockerClientBuilder getInstance() { + return new DockerClientBuilder(withDefaultDockerCmdExecFactory(DockerClientImpl.getInstance())); + } + + public static DockerClientBuilder getInstance(DockerClientConfigBuilder dockerClientConfigBuilder) { + return getInstance(dockerClientConfigBuilder.build()); + } + + public static DockerClientBuilder getInstance(DockerClientConfig dockerClientConfig) { + return new DockerClientBuilder(withDefaultDockerCmdExecFactory(DockerClientImpl + .getInstance(dockerClientConfig))); + } + + public static DockerClientBuilder getInstance(String serverUrl) { + return new DockerClientBuilder(withDefaultDockerCmdExecFactory(DockerClientImpl + .getInstance(serverUrl))); + } + + private static DockerClientImpl withDefaultDockerCmdExecFactory( + DockerClientImpl dockerClient) { + + DockerCmdExecFactory dockerCmdExecFactory = getDefaultDockerCmdExecFactory(); + + return dockerClient + .withDockerCmdExecFactory(dockerCmdExecFactory); + } + + public static DockerCmdExecFactory getDefaultDockerCmdExecFactory() { + if(!serviceLoader.iterator().hasNext()) { + throw new RuntimeException("Fatal: Can't find any implementation of '" + DockerCmdExecFactory.class.getName() + "' in the current classpath."); + } + + return serviceLoader.iterator().next(); + } + + public DockerClientBuilder withDockerCmdExecFactory( + DockerCmdExecFactory dockerCmdExecFactory) { + dockerClient = dockerClient + .withDockerCmdExecFactory(dockerCmdExecFactory); + return this; + } + + public DockerClient build() { + return dockerClient; + } +} diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java new file mode 100644 index 00000000..c12585a5 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java @@ -0,0 +1,331 @@ +package com.github.dockerjava.core; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableMap; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.net.URI; +import java.util.Map; +import java.util.Properties; + +public class DockerClientConfig { + private static final String DOCKER_HOST_PROPERTY = "DOCKER_HOST"; + private static final String DOCKER_CERT_PATH_PROPERTY = "DOCKER_CERT_PATH"; + private static final String DOCKER_IO_URL_PROPERTY = "docker.io.url"; + private static final String DOCKER_IO_VERSION_PROPERTY = "docker.io.version"; + private static final String DOCKER_IO_USERNAME_PROPERTY = "docker.io.username"; + private static final String DOCKER_IO_PASSWORD_PROPERTY = "docker.io.password"; + private static final String DOCKER_IO_EMAIL_PROPERTY = "docker.io.email"; + private static final String DOCKER_IO_READ_TIMEOUT_PROPERTY = "docker.io.readTimeout"; + // this is really confusing, as there are two ways to spell it + private static final String DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY = "docker.io.enableLoggingFilter"; + private static final String DOCKER_IO_DOCKER_CERT_PATH_PROPERTY = "docker.io.dockerCertPath"; + /** + * A map from the environment name to the interval name. + */ + private static final Map ENV_NAME_TO_IO_NAME = ImmutableMap.builder() + .put("DOCKER_URL", DOCKER_IO_URL_PROPERTY) + .put("DOCKER_VERSION", DOCKER_IO_VERSION_PROPERTY) + .put("DOCKER_USERNAME", DOCKER_IO_USERNAME_PROPERTY) + .put("DOCKER_PASSWORD", DOCKER_IO_PASSWORD_PROPERTY) + .put("DOCKER_EMAIL", DOCKER_IO_EMAIL_PROPERTY) + .put("DOCKER_READ_TIMEOUT", DOCKER_IO_READ_TIMEOUT_PROPERTY) + .put("DOCKER_LOGGING_FILTER_ENABLED", DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY) + .put(DOCKER_CERT_PATH_PROPERTY, DOCKER_IO_DOCKER_CERT_PATH_PROPERTY) + .build(); + private static final String DOCKER_IO_PROPERTIES_PROPERTY = "docker.io.properties"; + private final URI uri; + private final String version, username, password, email, dockerCertPath; + private final Integer readTimeout; + private final boolean loggingFilterEnabled; + + DockerClientConfig(URI uri, String version, String username, String password, String email, String dockerCertPath, Integer readTimeout, boolean loggingFilterEnabled) { + this.uri = uri; + this.version = version; + this.username = username; + this.password = password; + this.email = email; + this.dockerCertPath = dockerCertPath; + this.readTimeout = readTimeout; + this.loggingFilterEnabled = loggingFilterEnabled; + } + + private static Properties loadIncludedDockerProperties(Properties systemProperties) { + try { + Properties p = new Properties(); + p.load(DockerClientConfig.class.getResourceAsStream("/" + DOCKER_IO_PROPERTIES_PROPERTY)); + replaceProperties(p, systemProperties); + return p; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static void replaceProperties(Properties properties, Properties replacements) { + for (Object objectKey : properties.keySet()) { + String key = objectKey.toString(); + properties.setProperty(key, replaceProperties(properties.getProperty(key), replacements)); + } + } + + private static String replaceProperties(String s, Properties replacements) { + for (Map.Entry entry : replacements.entrySet()) { + String key = "${" + entry.getKey() + "}"; + while (s.contains(key)) { + s = s.replace(key, String.valueOf(entry.getValue())); + } + } + return s; + } + + /** + * Creates a new Properties object containing values overridden from ${user.home}/.docker.io.properties + * + * @param p The original set of properties to override + * @return A copy of the original Properties with overridden values + */ + private static Properties overrideDockerPropertiesWithSettingsFromUserHome(Properties p, Properties systemProperties) { + Properties overriddenProperties = new Properties(); + overriddenProperties.putAll(p); + + final File usersDockerPropertiesFile = new File(systemProperties.getProperty("user.home"), "." + DOCKER_IO_PROPERTIES_PROPERTY); + if (usersDockerPropertiesFile.isFile()) { + try { + final FileInputStream in = new FileInputStream(usersDockerPropertiesFile); + try { + overriddenProperties.load(in); + } finally { + in.close(); + } + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return overriddenProperties; + } + + private static Properties overrideDockerPropertiesWithEnv(Properties properties, Map env) { + Properties overriddenProperties = new Properties(); + overriddenProperties.putAll(properties); + + // special case which is a sensible default + if (env.containsKey(DOCKER_HOST_PROPERTY)) { + overriddenProperties.setProperty(DOCKER_IO_URL_PROPERTY, env.get(DOCKER_HOST_PROPERTY).replace("tcp", protocol(env))); + } + + for (Map.Entry envEntry : env.entrySet()) { + String envKey = envEntry.getKey(); + if (ENV_NAME_TO_IO_NAME.containsKey(envKey)) { + overriddenProperties.setProperty(ENV_NAME_TO_IO_NAME.get(envKey), envEntry.getValue()); + } + } + + return overriddenProperties; + } + + private static String protocol(Map env) { + // if this is set, we assume we need SSL + return env.containsKey(DOCKER_CERT_PATH_PROPERTY) ? "https" : "http"; + } + + /** + * Creates a new Properties object containing values overridden from the System properties + * + * @param p The original set of properties to override + * @return A copy of the original Properties with overridden values + */ + private static Properties overrideDockerPropertiesWithSystemProperties(Properties p, Properties systemProperties) { + Properties overriddenProperties = new Properties(); + overriddenProperties.putAll(p); + + for (String key : new String[]{ + DOCKER_IO_URL_PROPERTY, + DOCKER_IO_VERSION_PROPERTY, + DOCKER_IO_USERNAME_PROPERTY, + DOCKER_IO_PASSWORD_PROPERTY, + DOCKER_IO_EMAIL_PROPERTY, + DOCKER_IO_READ_TIMEOUT_PROPERTY, + DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY, + DOCKER_IO_DOCKER_CERT_PATH_PROPERTY, + }) { + if (systemProperties.containsKey(key)) { + overriddenProperties.setProperty(key, systemProperties.getProperty(key)); + } + } + return overriddenProperties; + } + + public static DockerClientConfigBuilder createDefaultConfigBuilder() { + return createDefaultConfigBuilder(System.getenv(), System.getProperties()); + } + + /** + * Allows you to build the config without system environment interfering for more robust testing + */ + static DockerClientConfigBuilder createDefaultConfigBuilder(Map env, Properties systemProperties) { + Properties properties = loadIncludedDockerProperties(systemProperties); + properties = overrideDockerPropertiesWithSettingsFromUserHome(properties, systemProperties); + properties = overrideDockerPropertiesWithEnv(properties, env); + properties = overrideDockerPropertiesWithSystemProperties(properties, systemProperties); + return new DockerClientConfigBuilder().withProperties(properties); + } + + public URI getUri() { + return uri; + } + + public String getVersion() { + return version; + } + + public String getUsername() { + return username; + } + + public String getPassword() { + return password; + } + + public String getEmail() { + return email; + } + + public Integer getReadTimeout() { + return readTimeout; + } + + public boolean isLoggingFilterEnabled() { + return loggingFilterEnabled; + } + + public String getDockerCertPath() { + return dockerCertPath; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + DockerClientConfig that = (DockerClientConfig) o; + + if (loggingFilterEnabled != that.loggingFilterEnabled) return false; + if (dockerCertPath != null ? !dockerCertPath.equals(that.dockerCertPath) : that.dockerCertPath != null) + return false; + if (email != null ? !email.equals(that.email) : that.email != null) return false; + if (password != null ? !password.equals(that.password) : that.password != null) return false; + if (readTimeout != null ? !readTimeout.equals(that.readTimeout) : that.readTimeout != null) return false; + if (uri != null ? !uri.equals(that.uri) : that.uri != null) return false; + if (username != null ? !username.equals(that.username) : that.username != null) return false; + if (version != null ? !version.equals(that.version) : that.version != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = uri != null ? uri.hashCode() : 0; + result = 31 * result + (version != null ? version.hashCode() : 0); + result = 31 * result + (username != null ? username.hashCode() : 0); + result = 31 * result + (password != null ? password.hashCode() : 0); + result = 31 * result + (email != null ? email.hashCode() : 0); + result = 31 * result + (dockerCertPath != null ? dockerCertPath.hashCode() : 0); + result = 31 * result + (readTimeout != null ? readTimeout.hashCode() : 0); + result = 31 * result + (loggingFilterEnabled ? 1 : 0); + return result; + } + + @Override + public String toString() { + return "DockerClientConfig{" + + "uri=" + uri + + ", version='" + version + '\'' + + ", username='" + username + '\'' + + ", password='" + password + '\'' + + ", email='" + email + '\'' + + ", dockerCertPath='" + dockerCertPath + '\'' + + ", readTimeout=" + readTimeout + + ", loggingFilterEnabled=" + loggingFilterEnabled + + '}'; + } + + public static class DockerClientConfigBuilder { + private URI uri; + private String version, username, password, email, dockerCertPath; + private Integer readTimeout; + private boolean loggingFilterEnabled; + + /** + * This will set all fields in the builder to those contained in the Properties object. The Properties object + * should contain the following docker.io.* keys: url, version, username, password, email, and dockerCertPath. If + * docker.io.readTimeout or docker.io.enableLoggingFilter are not contained, they will be set to 1000 and true, + * respectively. + */ + public DockerClientConfigBuilder withProperties(Properties p) { + return withUri(p.getProperty(DOCKER_IO_URL_PROPERTY)) + .withVersion(p.getProperty(DOCKER_IO_VERSION_PROPERTY)) + .withUsername(p.getProperty(DOCKER_IO_USERNAME_PROPERTY)) + .withPassword(p.getProperty(DOCKER_IO_PASSWORD_PROPERTY)) + .withEmail(p.getProperty(DOCKER_IO_EMAIL_PROPERTY)) + .withReadTimeout(Integer.valueOf(p.getProperty(DOCKER_IO_READ_TIMEOUT_PROPERTY, "0"))) + .withLoggingFilter(Boolean.valueOf(p.getProperty(DOCKER_IO_ENABLE_LOGGING_FILTER_PROPERTY, "true"))) + .withDockerCertPath(p.getProperty(DOCKER_IO_DOCKER_CERT_PATH_PROPERTY)); + } + + public final DockerClientConfigBuilder withUri(String uri) { + Preconditions.checkNotNull(uri, "uri was not specified"); + this.uri = URI.create(uri); + return this; + } + + public final DockerClientConfigBuilder withVersion(String version) { + this.version = version; + return this; + } + + public final DockerClientConfigBuilder withUsername(String username) { + this.username = username; + return this; + } + + public final DockerClientConfigBuilder withPassword(String password) { + this.password = password; + return this; + } + + public final DockerClientConfigBuilder withEmail(String email) { + this.email = email; + return this; + } + + public final DockerClientConfigBuilder withReadTimeout(Integer readTimeout) { + this.readTimeout = readTimeout; + return this; + } + + public final DockerClientConfigBuilder withLoggingFilter(boolean loggingFilterEnabled) { + this.loggingFilterEnabled = loggingFilterEnabled; + return this; + } + + public final DockerClientConfigBuilder withDockerCertPath(String dockerCertPath) { + this.dockerCertPath = dockerCertPath; + return this; + } + + public DockerClientConfig build() { + return new DockerClientConfig( + uri, + version, + username, + password, + email, + dockerCertPath, + readTimeout, + loggingFilterEnabled + ); + } + } +} diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java new file mode 100644 index 00000000..7692bdd2 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -0,0 +1,265 @@ +package com.github.dockerjava.core; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.command.*; +import com.github.dockerjava.api.model.AuthConfig; +import com.github.dockerjava.core.command.*; +import com.google.common.base.Preconditions; + +/** + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + * @see https://github.com/docker/docker/blob/master/api/client/commands.go + */ +public class DockerClientImpl implements Closeable, DockerClient { + + protected final DockerClientConfig dockerClientConfig; + + protected DockerCmdExecFactory dockerCmdExecFactory; + + private DockerClientImpl() { + this(DockerClientConfig.createDefaultConfigBuilder().build()); + } + + private DockerClientImpl(String serverUrl) { + this(configWithServerUrl(serverUrl)); + } + + protected DockerClientImpl(DockerClientConfig dockerClientConfig) { + Preconditions.checkNotNull(dockerClientConfig, "config was not specified"); + this.dockerClientConfig = dockerClientConfig; + } + + private static DockerClientConfig configWithServerUrl(String serverUrl) { + return DockerClientConfig.createDefaultConfigBuilder() + .withUri(serverUrl) + .build(); + } + + public static DockerClientImpl getInstance() { + return new DockerClientImpl(); + } + + public static DockerClientImpl getInstance(DockerClientConfig dockerClientConfig) { + return new DockerClientImpl(dockerClientConfig); + } + + public static DockerClientImpl getInstance(String serverUrl) { + return new DockerClientImpl(serverUrl); + } + + public DockerClientImpl withDockerCmdExecFactory( + DockerCmdExecFactory dockerCmdExecFactory) { + Preconditions.checkNotNull(dockerCmdExecFactory, "dockerCmdExecFactory was not specified"); + this.dockerCmdExecFactory = dockerCmdExecFactory; + this.dockerCmdExecFactory.init(dockerClientConfig); + return this; + } + + protected DockerCmdExecFactory getDockerCmdExecFactory() { + Preconditions.checkNotNull(dockerCmdExecFactory, "dockerCmdExecFactory was not specified"); + return dockerCmdExecFactory; + } + + + public AuthConfig authConfig() { + checkNotNull(dockerClientConfig.getUsername(), "Configured username is null."); + checkNotNull(dockerClientConfig.getPassword(), "Configured password is null."); + checkNotNull(dockerClientConfig.getEmail(), "Configured email is null."); + + AuthConfig authConfig = new AuthConfig(); + authConfig.setUsername(dockerClientConfig.getUsername()); + authConfig.setPassword(dockerClientConfig.getPassword()); + authConfig.setEmail(dockerClientConfig.getEmail()); + // TODO Make the registry address configurable + return authConfig; + } + + /** + * * MISC API * + */ + + /** + * Authenticate with the server, useful for checking authentication. + */ + @Override + public AuthCmd authCmd() { + return new AuthCmdImpl(getDockerCmdExecFactory().createAuthCmdExec(), authConfig()); + } + + @Override + public InfoCmd infoCmd() { + return new InfoCmdImpl(getDockerCmdExecFactory().createInfoCmdExec()); + } + + @Override + public PingCmd pingCmd() { + return new PingCmdImpl(getDockerCmdExecFactory().createPingCmdExec()); + } + + @Override + public VersionCmd versionCmd() { + return new VersionCmdImpl(getDockerCmdExecFactory().createVersionCmdExec()); + } + + /** + * * IMAGE API * + */ + + @Override + public PullImageCmd pullImageCmd(String repository) { + return new PullImageCmdImpl(getDockerCmdExecFactory().createPullImageCmdExec(), repository); + } + + @Override + public PushImageCmd pushImageCmd(String name) { + return new PushImageCmdImpl(getDockerCmdExecFactory().createPushImageCmdExec(), name); + } + + @Override + public CreateImageCmd createImageCmd(String repository, InputStream imageStream) { + return new CreateImageCmdImpl(getDockerCmdExecFactory().createCreateImageCmdExec(), repository, imageStream); + } + + @Override + public SearchImagesCmd searchImagesCmd(String term) { + return new SearchImagesCmdImpl(getDockerCmdExecFactory().createSearchImagesCmdExec(), term); + } + + @Override + public RemoveImageCmd removeImageCmd(String imageId) { + return new RemoveImageCmdImpl(getDockerCmdExecFactory().createRemoveImageCmdExec(), imageId); + } + + @Override + public ListImagesCmd listImagesCmd() { + return new ListImagesCmdImpl(getDockerCmdExecFactory().createListImagesCmdExec()); + } + + @Override + public InspectImageCmd inspectImageCmd(String imageId) { + return new InspectImageCmdImpl(getDockerCmdExecFactory().createInspectImageCmdExec(), imageId); + } + + /** + * * CONTAINER API * + */ + + @Override + public ListContainersCmd listContainersCmd() { + return new ListContainersCmdImpl(getDockerCmdExecFactory().createListContainersCmdExec()); + } + + @Override + public CreateContainerCmd createContainerCmd(String image) { + return new CreateContainerCmdImpl(getDockerCmdExecFactory().createCreateContainerCmdExec(), image); + } + + @Override + public StartContainerCmd startContainerCmd(String containerId) { + return new StartContainerCmdImpl(getDockerCmdExecFactory().createStartContainerCmdExec(), containerId); + } + + @Override + public InspectContainerCmd inspectContainerCmd(String containerId) { + return new InspectContainerCmdImpl(getDockerCmdExecFactory().createInspectContainerCmdExec(), containerId); + } + + @Override + public RemoveContainerCmd removeContainerCmd(String containerId) { + return new RemoveContainerCmdImpl(getDockerCmdExecFactory().createRemoveContainerCmdExec(), containerId); + } + + @Override + public WaitContainerCmd waitContainerCmd(String containerId) { + return new WaitContainerCmdImpl(getDockerCmdExecFactory().createWaitContainerCmdExec(), containerId); + } + + @Override + public AttachContainerCmd attachContainerCmd(String containerId) { + return new AttachContainerCmdImpl(getDockerCmdExecFactory().createAttachContainerCmdExec(), containerId); + } + + @Override + public LogContainerCmd logContainerCmd(String containerId) { + return new LogContainerCmdImpl(getDockerCmdExecFactory().createLogContainerCmdExec(), containerId); + } + + @Override + public CopyFileFromContainerCmd copyFileFromContainerCmd(String containerId, String resource) { + return new CopyFileFromContainerCmdImpl(getDockerCmdExecFactory().createCopyFileFromContainerCmdExec(), containerId, resource); + } + + @Override + public ContainerDiffCmd containerDiffCmd(String containerId) { + return new ContainerDiffCmdImpl(getDockerCmdExecFactory().createContainerDiffCmdExec(), containerId); + } + + @Override + public StopContainerCmd stopContainerCmd(String containerId) { + return new StopContainerCmdImpl(getDockerCmdExecFactory().createStopContainerCmdExec(), containerId); + } + + @Override + public KillContainerCmd killContainerCmd(String containerId) { + return new KillContainerCmdImpl(getDockerCmdExecFactory().createKillContainerCmdExec(), containerId); + } + + @Override + public RestartContainerCmd restartContainerCmd(String containerId) { + return new RestartContainerCmdImpl(getDockerCmdExecFactory().createRestartContainerCmdExec(), containerId); + } + + @Override + public CommitCmd commitCmd(String containerId) { + return new CommitCmdImpl(getDockerCmdExecFactory().createCommitCmdExec(), containerId); + } + + @Override + public BuildImageCmd buildImageCmd(File dockerFolder) { + return new BuildImageCmdImpl(getDockerCmdExecFactory().createBuildImageCmdExec(), dockerFolder); + } + + @Override + public BuildImageCmd buildImageCmd(InputStream tarInputStream) { + return new BuildImageCmdImpl(getDockerCmdExecFactory().createBuildImageCmdExec(), tarInputStream); + } + + @Override + public TopContainerCmd topContainerCmd(String containerId) { + return new TopContainerCmdImpl(getDockerCmdExecFactory().createTopContainerCmdExec(), containerId); + } + + @Override + public TagImageCmd tagImageCmd(String imageId, String repository, String tag) { + return new TagImageCmdImpl(getDockerCmdExecFactory().createTagImageCmdExec(), imageId, repository, tag); + } + + @Override + public PauseContainerCmd pauseContainerCmd(String containerId) { + return new PauseContainerCmdImpl(getDockerCmdExecFactory().createPauseContainerCmdExec(), containerId); + } + + @Override + public UnpauseContainerCmd unpauseContainerCmd(String containerId) { + return new UnpauseContainerCmdImpl(getDockerCmdExecFactory().createUnpauseContainerCmdExec(), containerId); + } + + @Override + public EventsCmd eventsCmd(EventCallback eventCallback) { + return new EventsCmdImpl(getDockerCmdExecFactory().createEventsCmdExec(), eventCallback); + } + + @Override + public void close() throws IOException { + getDockerCmdExecFactory().close(); + } + +} diff --git a/src/main/java/com/github/dockerjava/core/EnhancedDockerClientBuilder.java b/src/main/java/com/github/dockerjava/core/EnhancedDockerClientBuilder.java new file mode 100644 index 00000000..c6321f58 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/EnhancedDockerClientBuilder.java @@ -0,0 +1,65 @@ +package com.github.dockerjava.core; + +import java.util.ServiceLoader; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.EnhancedDockerClient; +import com.github.dockerjava.api.command.DockerCmdExecFactory; +import com.github.dockerjava.core.DockerClientConfig.DockerClientConfigBuilder; + +public class EnhancedDockerClientBuilder { + + private static ServiceLoader serviceLoader = ServiceLoader.load(DockerCmdExecFactory.class); + + private EnhancedDockerClientImpl dockerClient = null; + + private EnhancedDockerClientBuilder(EnhancedDockerClientImpl dockerClient) { + this.dockerClient = dockerClient; + } + + public static EnhancedDockerClientBuilder getInstance() { + return new EnhancedDockerClientBuilder(withDefaultDockerCmdExecFactory(EnhancedDockerClientImpl.getInstance())); + } + + public static EnhancedDockerClientBuilder getInstance(DockerClientConfigBuilder dockerClientConfigBuilder) { + return getInstance(dockerClientConfigBuilder.build()); + } + + public static EnhancedDockerClientBuilder getInstance(DockerClientConfig dockerClientConfig) { + return new EnhancedDockerClientBuilder(withDefaultDockerCmdExecFactory(EnhancedDockerClientImpl + .getInstance(dockerClientConfig))); + } + + public static EnhancedDockerClientBuilder getInstance(String serverUrl) { + return new EnhancedDockerClientBuilder(withDefaultDockerCmdExecFactory(EnhancedDockerClientImpl + .getInstance(serverUrl))); + } + + private static EnhancedDockerClientImpl withDefaultDockerCmdExecFactory( + EnhancedDockerClientImpl dockerClient) { + + DockerCmdExecFactory dockerCmdExecFactory = getDefaultDockerCmdExecFactory(); + + return dockerClient + .withDockerCmdExecFactory(dockerCmdExecFactory); + } + + public static DockerCmdExecFactory getDefaultDockerCmdExecFactory() { + if(!serviceLoader.iterator().hasNext()) { + throw new RuntimeException("Fatal: Can't find any implementation of '" + DockerCmdExecFactory.class.getName() + "' in the current classpath."); + } + + return serviceLoader.iterator().next(); + } + + public EnhancedDockerClientBuilder withDockerCmdExecFactory( + DockerCmdExecFactory dockerCmdExecFactory) { + dockerClient = dockerClient + .withDockerCmdExecFactory(dockerCmdExecFactory); + return this; + } + + public EnhancedDockerClient build() { + return dockerClient; + } +} diff --git a/src/main/java/com/github/dockerjava/core/EnhancedDockerClientImpl.java b/src/main/java/com/github/dockerjava/core/EnhancedDockerClientImpl.java new file mode 100644 index 00000000..bf5a4cae --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/EnhancedDockerClientImpl.java @@ -0,0 +1,115 @@ +package com.github.dockerjava.core; + +import com.github.dockerjava.api.EnhancedDockerClient; +import com.github.dockerjava.api.command.CgroupContainerCmd; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateExecCmd; +import com.github.dockerjava.api.command.DockerCmdExecFactory; +import com.github.dockerjava.api.command.ExecContainerCmd; +import com.github.dockerjava.api.command.LimitContainerCmd; +import com.github.dockerjava.api.command.MetricContainerCmd; +import com.github.dockerjava.api.command.StartContainerCmd; +import com.github.dockerjava.api.command.StartExecCmd; +import com.github.dockerjava.api.command.SweepContainerCmd; +import com.github.dockerjava.api.model.CreateContainerConfig; +import com.github.dockerjava.api.model.LimitationConfig; +import com.github.dockerjava.api.model.StartContainerConfig; +import com.github.dockerjava.core.command.CgroupContainerCmdImpl; +import com.github.dockerjava.core.command.CreateExecCmdImpl; +import com.github.dockerjava.core.command.ExecContainerCmdImpl; +import com.github.dockerjava.core.command.LimitContainerCmdImpl; +import com.github.dockerjava.core.command.MetricContainerCmdImpl; +import com.github.dockerjava.core.command.StartExecCmdImpl; +import com.github.dockerjava.core.command.SweepContainerCmdImpl; +import com.github.dockerjava.jaxrs.util.CommandUtils; + + + +public class EnhancedDockerClientImpl extends DockerClientImpl implements EnhancedDockerClient { + + private EnhancedDockerClientImpl() { + this(DockerClientConfig.createDefaultConfigBuilder().build()); + } + + private EnhancedDockerClientImpl(String serverUrl) { + this(configWithServerUrl(serverUrl)); + } + + private EnhancedDockerClientImpl(DockerClientConfig dockerClientConfig) { + super(dockerClientConfig); + } + + private static DockerClientConfig configWithServerUrl(String serverUrl) { + return DockerClientConfig.createDefaultConfigBuilder() + .withUri(serverUrl) + .build(); + } + + public EnhancedDockerClientImpl withDockerCmdExecFactory(DockerCmdExecFactory dockerCmdExecFactory) { + super.withDockerCmdExecFactory(dockerCmdExecFactory); + return this; + } + + public static EnhancedDockerClientImpl getInstance() { + return new EnhancedDockerClientImpl(); + } + + public static EnhancedDockerClientImpl getInstance(DockerClientConfig dockerClientConfig) { + return new EnhancedDockerClientImpl(dockerClientConfig); + } + + public static EnhancedDockerClientImpl getInstance(String serverUrl) { + return new EnhancedDockerClientImpl(serverUrl); + } + + @Override + public CgroupContainerCmd cgroupContainerCmd(String containerId) { + return new CgroupContainerCmdImpl(getDockerCmdExecFactory().createCgroupContainerCmdExec(), containerId); + } + + @Override + public SweepContainerCmd sweepContainerCmd(String containerId) { + return new SweepContainerCmdImpl(getDockerCmdExecFactory().createSweepContainerCmdExec(), containerId); + } + + @Override + public MetricContainerCmd metricContainerCmd(String containerId) { + return new MetricContainerCmdImpl(getDockerCmdExecFactory().createMetricContainerCmdExec(), containerId); + } + + @Override + public CreateExecCmd createExecCmd(String containerId) { + return new CreateExecCmdImpl(getDockerCmdExecFactory().createCreateExecCmdExec(), containerId); + } + + @Override + public StartExecCmd startExecCmd(String execId) { + return new StartExecCmdImpl(getDockerCmdExecFactory().createStartExecCmdExec(), execId); + } + + public ExecContainerCmd execContainerCmd(String containerId) { + CreateExecCmd createExecCmd = createExecCmd(containerId); + StartExecCmd startExecCmd = startExecCmd(containerId); + return new ExecContainerCmdImpl(getDockerCmdExecFactory().createExecContainerCmdExec(createExecCmd, startExecCmd), containerId); + } + + @Override + public CreateContainerCmd createContainerCmd(CreateContainerConfig createContainerConfig) { + CreateContainerCmd cmd = createContainerCmd(createContainerConfig.getImage()); + CommandUtils.popuateCreateContainerCmd(cmd, createContainerConfig); + return cmd; + } + + @Override + public StartContainerCmd startContainerCmd(String containerId, StartContainerConfig startContainerConfig) { + StartContainerCmd cmd = startContainerCmd(containerId); + CommandUtils.popuateStartContainerCmd(cmd, startContainerConfig); + return cmd; + } + + @Override + public LimitContainerCmd limitContainerCmd( + LimitationConfig limitationConfig, String containerId) { + return new LimitContainerCmdImpl(getDockerCmdExecFactory().createLimitContainerCmdExec(), limitationConfig, containerId); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/AbstrAuthCfgDockerCmd.java b/src/main/java/com/github/dockerjava/core/command/AbstrAuthCfgDockerCmd.java new file mode 100644 index 00000000..72aa94d8 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/AbstrAuthCfgDockerCmd.java @@ -0,0 +1,43 @@ +package com.github.dockerjava.core.command; + +import java.io.IOException; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import com.github.dockerjava.api.command.DockerCmd; +import com.github.dockerjava.api.command.DockerCmdExec; +import com.github.dockerjava.api.model.AuthConfig; + +import com.google.common.base.Preconditions; + +import org.apache.commons.codec.binary.Base64; + +public abstract class AbstrAuthCfgDockerCmd, RES_T> extends + AbstrDockerCmd { + + public AbstrAuthCfgDockerCmd(DockerCmdExec execution) { + super(execution); + } + + private AuthConfig authConfig; + + public AuthConfig getAuthConfig() { + return authConfig; + } + + @SuppressWarnings("unchecked") + public T withAuthConfig(AuthConfig authConfig) { + Preconditions.checkNotNull(authConfig, "authConfig was not specified"); + this.authConfig = authConfig; + return (T)this; + } + + protected String registryAuth() { + try { + return Base64.encodeBase64String(new ObjectMapper().writeValueAsString(authConfig).getBytes()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/core/command/AbstrDockerCmd.java b/src/main/java/com/github/dockerjava/core/command/AbstrDockerCmd.java new file mode 100644 index 00000000..00c89159 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/AbstrDockerCmd.java @@ -0,0 +1,28 @@ +package com.github.dockerjava.core.command; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.command.DockerCmd; +import com.github.dockerjava.api.command.DockerCmdExec; +import com.google.common.base.Preconditions; + +public abstract class AbstrDockerCmd, RES_T> implements DockerCmd { + + private final static Logger LOGGER = LoggerFactory.getLogger(AbstrDockerCmd.class); + + protected DockerCmdExec execution; + + public AbstrDockerCmd(DockerCmdExec execution) { + Preconditions.checkNotNull(execution, "execution was not specified"); + this.execution = execution; + } + + @Override + @SuppressWarnings("unchecked") + public RES_T exec() throws DockerException { + LOGGER.debug("Cmd: {}", this); + return execution.exec((CMD_T)this); + } +} \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/core/command/AttachContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/AttachContainerCmdImpl.java new file mode 100644 index 00000000..d52ceabe --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/AttachContainerCmdImpl.java @@ -0,0 +1,126 @@ +package com.github.dockerjava.core.command; + +import java.io.InputStream; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.AttachContainerCmd; + +import com.google.common.base.Preconditions; + +/** + * Attach to container + * + * @param logs + * - true or false, includes logs. Defaults to false. + * + * @param followStream + * - true or false, return stream. Defaults to false. + * @param stdout + * - true or false, includes stdout log. Defaults to false. + * @param stderr + * - true or false, includes stderr log. Defaults to false. + * @param timestamps + * - true or false, if true, print timestamps for every log line. + * Defaults to false. + */ +public class AttachContainerCmdImpl extends AbstrDockerCmd implements AttachContainerCmd { + + private String containerId; + + private boolean logs, followStream, timestamps, stdout, stderr; + + public AttachContainerCmdImpl(AttachContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public boolean hasLogsEnabled() { + return logs; + } + + @Override + public boolean hasFollowStreamEnabled() { + return followStream; + } + + @Override + public boolean hasTimestampsEnabled() { + return timestamps; + } + + @Override + public boolean hasStdoutEnabled() { + return stdout; + } + + @Override + public boolean hasStderrEnabled() { + return stderr; + } + + @Override + public AttachContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public AttachContainerCmd withFollowStream() { + return withFollowStream(true); + } + + @Override + public AttachContainerCmd withFollowStream(boolean followStream) { + this.followStream = followStream; + return this; + } + + @Override + public AttachContainerCmd withTimestamps(boolean timestamps) { + this.timestamps = timestamps; + return this; + } + + @Override + public AttachContainerCmd withStdOut() { + return withStdOut(true); + } + + @Override + public AttachContainerCmd withStdOut(boolean stdout) { + this.stdout = stdout; + return this; + } + + @Override + public AttachContainerCmd withStdErr() { + return withStdErr(true); + } + + @Override + public AttachContainerCmd withStdErr(boolean stderr) { + this.stderr = stderr; + return this; + } + + @Override + public AttachContainerCmd withLogs(boolean logs) { + this.logs = logs; + return this; + } + + /** + * @throws NotFoundException No such container + */ + @Override + public InputStream exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/AuthCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/AuthCmdImpl.java new file mode 100644 index 00000000..259333e5 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/AuthCmdImpl.java @@ -0,0 +1,28 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.UnauthorizedException; +import com.github.dockerjava.api.command.AuthCmd; +import com.github.dockerjava.api.model.AuthConfig; + +/** + * + * Authenticate with the server, useful for checking authentication. + * + */ +public class AuthCmdImpl extends AbstrAuthCfgDockerCmd implements AuthCmd { + + public AuthCmdImpl(AuthCmd.Exec exec, AuthConfig authConfig) { + super(exec); + withAuthConfig(authConfig); + } + + @Override + public Void exec() throws UnauthorizedException { + return super.exec(); + } + + @Override + public String toString() { + return "authenticate using " + this.getAuthConfig(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/BaseExecCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/BaseExecCmdImpl.java new file mode 100644 index 00000000..cefc4355 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/BaseExecCmdImpl.java @@ -0,0 +1,112 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.BaseExecCmd; +import com.github.dockerjava.api.command.DockerCmd; +import com.github.dockerjava.api.command.DockerCmdExec; +import com.github.dockerjava.api.model.ExecConfig; + +public abstract class BaseExecCmdImpl, RES_T> extends AbstrDockerCmd implements BaseExecCmd { + + protected ExecConfig execConfig; + + public BaseExecCmdImpl(DockerCmdExec execution) { + super(execution); + this.execConfig = new ExecConfig(); + } + + @Override + public String getContainerId() { + return execConfig.getContainerId(); + } + + @Override + @SuppressWarnings("unchecked") + public CMD_T withContainerId(String containerId) { + execConfig.setContainerId(containerId); + return (CMD_T) this; + } + + @Override + public boolean isTty() { + return execConfig.isTty(); + } + + @Override + @SuppressWarnings("unchecked") + public CMD_T withTty(boolean tty) { + execConfig.setTty(tty); + return (CMD_T) this; + } + + @Override + public boolean isAttachStdin() { + return execConfig.isAttachStdin(); + } + + @Override + @SuppressWarnings("unchecked") + public CMD_T withAttachStdin(boolean attachStdin) { + execConfig.setAttachStdin(attachStdin); + return (CMD_T) this; + } + + @Override + public boolean isAttachStdout() { + return execConfig.isAttachStdout(); + } + + @Override + public boolean isAttachStderr() { + return execConfig.isAttachStderr(); + } + + @Override + public boolean isDetach() { + return execConfig.isDetach(); + } + + @Override + @SuppressWarnings("unchecked") + public CMD_T withDetach(boolean detach) { + execConfig.setDetach(detach); + execConfig.setAttachStdout(!detach); + execConfig.setAttachStderr(!detach); + return (CMD_T) this; + } + + @Override + public String[] getCmd() { + return execConfig.getCmd(); + } + + @Override + @SuppressWarnings("unchecked") + public CMD_T withCmd(String... cmd) { + execConfig.setCmd(cmd); + return (CMD_T) this; + } + + @Override + public ExecConfig getExecConfig() { + return execConfig; + } + + @Override + @SuppressWarnings("unchecked") + public CMD_T withExecConfig(ExecConfig execConfig) { + this.execConfig = execConfig; + return (CMD_T) this; + } + + @Override + public boolean isPrivileged() { + return execConfig.isPrivileged(); + } + + @Override + @SuppressWarnings("unchecked") + public CMD_T withPrivileged(boolean privileged) { + this.execConfig.setPrivileged(privileged); + return (CMD_T) this; + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java new file mode 100644 index 00000000..4948ce45 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java @@ -0,0 +1,274 @@ +package com.github.dockerjava.core.command; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.io.FileUtils; + +import com.github.dockerjava.api.DockerClientException; +import com.github.dockerjava.api.command.BuildImageCmd; +import com.github.dockerjava.core.CompressArchiveUtil; + +import com.google.common.base.Preconditions; + +/** + * + * Build an image from Dockerfile. + * + * TODO: http://docs.docker.com/reference/builder/#dockerignore + * + */ +public class BuildImageCmdImpl extends AbstrDockerCmd implements BuildImageCmd { + + private static final Pattern ADD_OR_COPY_PATTERN = Pattern + .compile("^(ADD|COPY)\\s+(.*)\\s+(.*)$"); + + private static final Pattern ENV_PATTERN = Pattern + .compile("^ENV\\s+(.*)\\s+(.*)$"); + + private InputStream tarInputStream = null; + private String tag; + private boolean noCache; + private boolean remove = true; + private boolean quiet; + + public BuildImageCmdImpl(BuildImageCmd.Exec exec, File dockerFolder) { + super(exec); + Preconditions.checkNotNull(dockerFolder, "dockerFolder is null"); + withTarInputStream(buildDockerFolderTar(dockerFolder)); + } + + public BuildImageCmdImpl(BuildImageCmd.Exec exec, InputStream tarInputStream) { + super(exec); + Preconditions.checkNotNull(tarInputStream, "tarInputStream is null"); + withTarInputStream(tarInputStream); + } + + @Override + public InputStream getTarInputStream() { + return tarInputStream; + } + + @Override + public BuildImageCmdImpl withTarInputStream(InputStream tarInputStream) { + Preconditions.checkNotNull(tarInputStream, "tarInputStream is null"); + this.tarInputStream = tarInputStream; + return this; + } + + @Override + public BuildImageCmdImpl withTag(String tag) { + Preconditions.checkNotNull(tag, "Tag is null"); + this.tag = tag; + return this; + } + + @Override + public String getTag() { + return tag; + } + + @Override + public boolean hasNoCacheEnabled() { + return noCache; + } + + @Override + public boolean hasRemoveEnabled() { + return remove; + } + + @Override + public boolean isQuiet() { + return quiet; + } + + @Override + public BuildImageCmdImpl withNoCache() { + return withNoCache(true); + } + + @Override + public BuildImageCmdImpl withNoCache(boolean noCache) { + this.noCache = noCache; + return this; + } + + @Override + public BuildImageCmdImpl withRemove() { + return withRemove(true); + } + + @Override + public BuildImageCmdImpl withRemove(boolean rm) { + this.remove = rm; + return this; + } + + @Override + public BuildImageCmdImpl withQuiet() { + return withQuiet(true); + } + + @Override + public BuildImageCmdImpl withQuiet(boolean quiet) { + this.quiet = quiet; + return this; + } + + @Override + public String toString() { + return new StringBuilder("build ") + .append(tag != null ? "-t " + tag + " " : "") + .append(noCache ? "--nocache=true " : "") + .append(quiet ? "--quiet=true " : "") + .append(!remove ? "--rm=false " : "") + .toString(); + } + + protected InputStream buildDockerFolderTar(File dockerFolder) { + Preconditions.checkArgument(dockerFolder.exists(), + "Path %s doesn't exist", dockerFolder); + Preconditions.checkArgument(dockerFolder.isDirectory(), + "Folder %s doesn't exist", dockerFolder); + Preconditions.checkState(new File(dockerFolder, "Dockerfile").exists(), + "Dockerfile doesn't exist in " + dockerFolder); + + // ARCHIVE TAR + String archiveNameWithOutExtension = UUID.randomUUID().toString(); + + File dockerFolderTar = null; + + try { + File dockerFile = new File(dockerFolder, "Dockerfile"); + List dockerFileContent = FileUtils.readLines(dockerFile); + + if (dockerFileContent.size() <= 0) { + throw new DockerClientException(String.format( + "Dockerfile %s is empty", dockerFile)); + } + + List filesToAdd = new ArrayList(); + filesToAdd.add(dockerFile); + + Map environmentMap = new HashMap(); + + int lineNumber = 0; + + for (String cmd : dockerFileContent) { + + lineNumber++; + + if (cmd.trim().isEmpty() || cmd.startsWith("#")) + continue; // skip emtpy and commend lines + + final Matcher envMatcher = ENV_PATTERN.matcher(cmd.trim()); + + if (envMatcher.find()) { + if (envMatcher.groupCount() != 2) + throw new DockerClientException(String.format( + "Wrong ENV format on line [%d]", lineNumber)); + + String variable = envMatcher.group(1).trim(); + + String value = envMatcher.group(2).trim(); + + environmentMap.put(variable, value); + } + + final Matcher matcher = ADD_OR_COPY_PATTERN.matcher(cmd.trim()); + if (matcher.find()) { + if (matcher.groupCount() != 3) { + throw new DockerClientException(String.format( + "Wrong ADD or COPY format on line [%d]", + lineNumber)); + } + + String extractedResource = matcher.group(2); + + String resource = filterForEnvironmentVars( + extractedResource, environmentMap).trim(); + + if (isFileResource(resource)) { + File src = new File(resource); + if (!src.isAbsolute()) { + src = new File(dockerFolder, resource) + .getCanonicalFile(); + } else { + throw new DockerClientException(String.format( + "Source file %s must be relative to %s", + src, dockerFolder)); + } + + if (!src.exists()) { + throw new DockerClientException(String.format( + "Source file %s doesn't exist", src)); + } + if (src.isDirectory()) { + filesToAdd.addAll(FileUtils.listFiles(src, null, + true)); + } else { + filesToAdd.add(src); + } + } + } + } + + dockerFolderTar = CompressArchiveUtil.archiveTARFiles(dockerFolder, + filesToAdd, archiveNameWithOutExtension); + return FileUtils.openInputStream(dockerFolderTar); + } catch (IOException ex) { + FileUtils.deleteQuietly(dockerFolderTar); + throw new DockerClientException( + "Error occurred while preparing Docker context folder.", ex); + } + } + + private String filterForEnvironmentVars(String extractedResource, + Map environmentMap) { + + if (environmentMap.size() > 0) { + + String currentResourceContent = extractedResource; + + for (Map.Entry entry : environmentMap.entrySet()) { + + String variable = entry.getKey(); + + String replacementValue = entry.getValue(); + + // handle: $VARIABLE case + currentResourceContent = currentResourceContent.replaceAll( + "\\$" + variable, replacementValue); + + // handle ${VARIABLE} case + currentResourceContent = currentResourceContent.replaceAll( + "\\$\\{" + variable + "\\}", replacementValue); + + } + + return currentResourceContent; + } else + return extractedResource; + } + + private static boolean isFileResource(String resource) { + URI uri; + try { + uri = new URI(resource); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + return uri.getScheme() == null || "file".equals(uri.getScheme()); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/CgroupContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CgroupContainerCmdImpl.java new file mode 100644 index 00000000..01f29fa0 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/CgroupContainerCmdImpl.java @@ -0,0 +1,60 @@ +package com.github.dockerjava.core.command; + +import java.util.List; + +import com.github.dockerjava.api.command.CgroupContainerCmd; +import com.github.dockerjava.api.model.Subsystem; +import com.github.dockerjava.api.model.WriteSubsystem; +import com.google.common.base.Preconditions; + +public class CgroupContainerCmdImpl extends AbstrDockerCmd> implements CgroupContainerCmd { + + private String containerId; + private List toRead; + private List toWrite; + + public CgroupContainerCmdImpl(CgroupContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public List getReadSubsystem() { + return toRead; + } + + @Override + public List getWriteSubsystem() { + return toWrite; + } + + @Override + public CgroupContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public CgroupContainerCmd withReadSubsystem(List toRead) { + this.toRead = toRead; + return this; + } + + @Override + public CgroupContainerCmd withWriteSubsystem(List toWrite) { + this.toWrite = toWrite; + return this; + } + + @Override + public String toString() { + return "cgroup " + containerId; + } + +} diff --git a/src/main/java/com/github/dockerjava/core/command/CommitCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CommitCmdImpl.java new file mode 100644 index 00000000..ee9c4db6 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/CommitCmdImpl.java @@ -0,0 +1,371 @@ +package com.github.dockerjava.core.command; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CommitCmd; +import com.github.dockerjava.api.model.ExposedPorts; +import com.github.dockerjava.api.model.Volumes; + +import com.google.common.base.Preconditions; + +/** + * + * Create a new image from a container's changes. Returns the new image ID. + * + */ +public class CommitCmdImpl extends AbstrDockerCmd implements CommitCmd { + + private String containerId, repository, tag, message, author; + + private boolean pause = true; + + @JsonProperty("AttachStdin") + private boolean attachStdin; + + @JsonProperty("AttachStdout") + private boolean attachStdout; + + @JsonProperty("AttachStderr") + private boolean attachStderr; + + @JsonProperty("Cmd") + private String[] cmd; + + @JsonProperty("DisableNetwork") + private boolean disableNetwork; + + @JsonProperty("Env") + private String[] env; + + @JsonProperty("ExposedPorts") + private ExposedPorts exposedPorts; + + @JsonProperty("Hostname") + private String hostname; + + @JsonProperty("Memory") + private Integer memory; + + @JsonProperty("MemorySwap") + private Integer memorySwap; + + @JsonProperty("OpenStdin") + private boolean openStdin; + + @JsonProperty("PortSpecs") + private String[] portSpecs; + + @JsonProperty("StdinOnce") + private boolean stdinOnce; + + @JsonProperty("Tty") + private boolean tty; + + @JsonProperty("User") + private String user; + + @JsonProperty("Volumes") + private Volumes volumes; + + @JsonProperty("WorkingDir") + private String workingDir; + + + public CommitCmdImpl(CommitCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public CommitCmdImpl withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + + @Override + public String getRepository() { + return repository; + } + + @Override + public String getTag() { + return tag; + } + + @Override + public String getMessage() { + return message; + } + + @Override + public String getAuthor() { + return author; + } + + @Override + public boolean hasPauseEnabled() { + return pause; + } + + @Override + public CommitCmdImpl withAttachStderr(boolean attachStderr) { + this.attachStderr = attachStderr; + return this; + } + + @Override + public CommitCmdImpl withAttachStderr() { + return withAttachStderr(true); + } + + @Override + public CommitCmdImpl withAttachStdin(boolean attachStdin) { + this.attachStdin = attachStdin; + return this; + } + + @Override + public CommitCmdImpl withAttachStdin() { + return withAttachStdin(true); + } + + @Override + public CommitCmdImpl withAttachStdout(boolean attachStdout) { + this.attachStdout = attachStdout; + return this; + } + + @Override + public CommitCmdImpl withAttachStdout() { + return withAttachStdout(true); + } + + @Override + public CommitCmdImpl withCmd(String... cmd) { + Preconditions.checkNotNull(cmd, "cmd was not specified"); + this.cmd = cmd; + return this; + } + + @Override + public CommitCmdImpl withDisableNetwork(boolean disableNetwork) { + this.disableNetwork = disableNetwork; + return this; + } + + @Override + public CommitCmdImpl withAuthor(String author) { + Preconditions.checkNotNull(author, "author was not specified"); + this.author = author; + return this; + } + + @Override + public CommitCmdImpl withMessage(String message) { + Preconditions.checkNotNull(message, "message was not specified"); + this.message = message; + return this; + } + + @Override + public CommitCmdImpl withTag(String tag) { + Preconditions.checkNotNull(tag, "tag was not specified"); + this.tag = tag; + return this; + } + + @Override + public CommitCmdImpl withRepository(String repository) { + Preconditions.checkNotNull(repository, "repository was not specified"); + this.repository = repository; + return this; + } + + @Override + public CommitCmdImpl withPause(boolean pause) { + this.pause = pause; + return this; + } + + @Override + public String[] getEnv() { + return env; + } + + @Override + public CommitCmdImpl withEnv(String... env) { + Preconditions.checkNotNull(env, "env was not specified"); + this.env = env; + return this; + } + + @Override + public ExposedPorts getExposedPorts() { + return exposedPorts; + } + + @Override + public CommitCmdImpl withExposedPorts(ExposedPorts exposedPorts) { + Preconditions.checkNotNull(exposedPorts, "exposedPorts was not specified"); + this.exposedPorts = exposedPorts; + return this; + } + + @Override + public String getHostname() { + return hostname; + } + + @Override + public CommitCmdImpl withHostname(String hostname) { + Preconditions.checkNotNull(hostname, "hostname was not specified"); + this.hostname = hostname; + return this; + } + + @Override + public Integer getMemory() { + return memory; + } + + @Override + public CommitCmdImpl withMemory(Integer memory) { + Preconditions.checkNotNull(memory, "memory was not specified"); + this.memory = memory; + return this; + } + + @Override + public Integer getMemorySwap() { + return memorySwap; + } + + @Override + public CommitCmdImpl withMemorySwap(Integer memorySwap) { + Preconditions.checkNotNull(memorySwap, "memorySwap was not specified"); + this.memorySwap = memorySwap; + return this; + } + + @Override + public boolean isOpenStdin() { + return openStdin; + } + + @Override + public CommitCmdImpl withOpenStdin(boolean openStdin) { + Preconditions.checkNotNull(openStdin, "openStdin was not specified"); + this.openStdin = openStdin; + return this; + } + + @Override + public String[] getPortSpecs() { + return portSpecs; + } + + @Override + public CommitCmdImpl withPortSpecs(String... portSpecs) { + Preconditions.checkNotNull(portSpecs, "portSpecs was not specified"); + this.portSpecs = portSpecs; + return this; + } + + @Override + public boolean isStdinOnce() { + return stdinOnce; + } + + @Override + public CommitCmdImpl withStdinOnce(boolean stdinOnce) { + this.stdinOnce = stdinOnce; + return this; + } + + @Override + public CommitCmdImpl withStdinOnce() { + return withStdinOnce(true); + } + + @Override + public boolean isTty() { + return tty; + } + + @Override + public CommitCmdImpl withTty(boolean tty) { + this.tty = tty; + return this; + } + + @Override + public CommitCmdImpl withTty() { + return withTty(true); + } + + @Override + public String getUser() { + return user; + } + + @Override + public CommitCmdImpl withUser(String user) { + Preconditions.checkNotNull(user, "user was not specified"); + this.user = user; + return this; + } + + @Override + public Volumes getVolumes() { + return volumes; + } + + @Override + public CommitCmdImpl withVolumes(Volumes volumes) { + Preconditions.checkNotNull(volumes, "volumes was not specified"); + this.volumes = volumes; + return this; + } + + @Override + public String getWorkingDir() { + return workingDir; + } + + @Override + public CommitCmdImpl withWorkingDir(String workingDir) { + Preconditions.checkNotNull(workingDir, "workingDir was not specified"); + this.workingDir = workingDir; + return this; + } + + + @Override + public String toString() { + return new ToStringBuilder(this).append("commit ") + .append(author != null ? "--author " + author + " " : "") + .append(message != null ? "--message " + message + " " : "") + .append(containerId) + .append(repository != null ? " " + repository + ":" : " ") + .append(tag != null ? tag : "") + .toString(); + } + + /** + * @throws NotFoundException No such container + */ + @Override + public String exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/ContainerDiffCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/ContainerDiffCmdImpl.java new file mode 100644 index 00000000..f6a414b1 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/ContainerDiffCmdImpl.java @@ -0,0 +1,54 @@ +package com.github.dockerjava.core.command; + +import java.util.List; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.InternalServerErrorException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.ContainerDiffCmd; +import com.github.dockerjava.api.model.ChangeLog; + +import com.google.common.base.Preconditions; + +/** + * Inspect changes on a container's filesystem + * + * @param containerId - Id of the container + * + */ +public class ContainerDiffCmdImpl extends AbstrDockerCmd> implements ContainerDiffCmd { + + private String containerId; + + public ContainerDiffCmdImpl(ContainerDiffCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public ContainerDiffCmdImpl withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public String toString() { + return new StringBuilder("diff ").append(containerId).toString(); + } + + /** + * @throws NotFoundException No such container + * @throws InternalServerErrorException server error + * @throws DockerException unexpected http status code + */ + @Override + public List exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImpl.java new file mode 100644 index 00000000..929b6bf5 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImpl.java @@ -0,0 +1,101 @@ +package com.github.dockerjava.core.command; + +import java.io.InputStream; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CopyFileFromContainerCmd; + +import com.google.common.base.Preconditions; + +/** + * + * Copy files or folders from a container. + * + */ +public class CopyFileFromContainerCmdImpl extends AbstrDockerCmd implements CopyFileFromContainerCmd { + + private String containerId; + + @JsonProperty("HostPath") + private String hostPath = "."; + + @JsonProperty("Resource") + private String resource; + + public CopyFileFromContainerCmdImpl(CopyFileFromContainerCmd.Exec exec, String containerId, String resource) { + super(exec); + withContainerId(containerId); + withResource(resource); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public String getResource() { + return resource; + } + + @Override + public CopyFileFromContainerCmdImpl withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public CopyFileFromContainerCmdImpl withResource(String resource) { + Preconditions.checkNotNull(resource, "resource was not specified"); + this.resource = resource; + return this; + } + + @Override + public String getHostPath() { + return hostPath; + } + + @Override + public CopyFileFromContainerCmdImpl withHostPath(String hostPath) { + Preconditions.checkNotNull(hostPath, "hostPath was not specified"); + this.hostPath = hostPath; + return this; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("cp ") + .append(containerId) + .append(":") + .append(resource) + .toString(); + } + + /** + * @throws NotFoundException No such container + */ + @Override + public InputStream exec() throws NotFoundException { + return super.exec(); + } + +// protected InputStream impl() throws DockerException { +// +// CopyFileFromContainerCmd command = this; +// +// WebTarget webResource = +// baseResource.path("/containers/{id}/copy").resolveTemplate("id", command.getContainerId()); +// +// LOGGER.trace("POST: " + webResource.toString()); +// +// return webResource.request().accept(MediaType.APPLICATION_OCTET_STREAM_TYPE).post(entity(command, MediaType.APPLICATION_JSON), Response.class).readEntity(InputStream.class); +// } + + +} diff --git a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java new file mode 100644 index 00000000..190e0dec --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java @@ -0,0 +1,341 @@ +package com.github.dockerjava.core.command; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.dockerjava.api.ConflictException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.model.ExposedPort; +import com.github.dockerjava.api.model.ExposedPorts; +import com.github.dockerjava.api.model.Volume; +import com.github.dockerjava.api.model.Volumes; +import com.google.common.base.Preconditions; + +/** + * + * Creates a new container. + * + */ +public class CreateContainerCmdImpl extends AbstrDockerCmd implements CreateContainerCmd { + + private String name; + + @JsonProperty("Hostname") private String hostName = ""; + @JsonProperty("User") private String user = ""; + @JsonProperty("Memory") private long memoryLimit = 0; + @JsonProperty("MemorySwap") private long memorySwap = 0; + @JsonProperty("CpuShares") private int cpuShares = 0; + @JsonProperty("Cpuset") private String cpuset = ""; + @JsonProperty("AttachStdin") private boolean attachStdin = false; + @JsonProperty("AttachStdout") private boolean attachStdout = false; + @JsonProperty("AttachStderr") private boolean attachStderr = false; + @JsonProperty("PortSpecs") private String[] portSpecs; + @JsonProperty("Tty") private boolean tty = false; + @JsonProperty("OpenStdin") private boolean stdinOpen = false; + @JsonProperty("StdinOnce") private boolean stdInOnce = false; + @JsonProperty("Env") private String[] env; + @JsonProperty("Cmd") private String[] cmd; + @JsonProperty("Dns") private String[] dns; + @JsonProperty("Image") private String image; + @JsonProperty("Volumes") private Volumes volumes = new Volumes(); + @JsonProperty("VolumesFrom") private String[] volumesFrom = new String[]{}; + @JsonProperty("WorkingDir") private String workingDir = ""; + @JsonProperty("DisableNetwork") private boolean disableNetwork = false; + @JsonProperty("ExposedPorts") private ExposedPorts exposedPorts = new ExposedPorts(); + @JsonProperty("Ip") private String ip = ""; + + public CreateContainerCmdImpl(CreateContainerCmd.Exec exec, String image) { + super(exec); + Preconditions.checkNotNull(image, "image was not specified"); + withImage(image); + } + + @Override + public CreateContainerCmdImpl withName(String name) { + Preconditions.checkNotNull(name, "name was not specified"); + this.name = name; + return this; + } + + @Override + public String getName() { + return name; + } + + @Override + public CreateContainerCmdImpl withExposedPorts(ExposedPort... exposedPorts) { + this.exposedPorts = new ExposedPorts(exposedPorts); + return this; + } + + @Override + @JsonIgnore + public ExposedPort[] getExposedPorts() { + return exposedPorts.getExposedPorts(); + } + + + @Override + public boolean isDisableNetwork() { + return disableNetwork; + } + + @Override + public String getWorkingDir() { + return workingDir; + } + + @Override + public CreateContainerCmdImpl withWorkingDir(String workingDir) { + this.workingDir = workingDir; + return this; + } + + + @Override + public String getHostName() { + return hostName; + } + + @Override + public CreateContainerCmdImpl withDisableNetwork(boolean disableNetwork) { + this.disableNetwork = disableNetwork; + return this; + } + + @Override + public CreateContainerCmdImpl withHostName(String hostName) { + this.hostName = hostName; + return this; + } + + @Override + public String[] getPortSpecs() { + return portSpecs; + } + + @Override + public CreateContainerCmdImpl withPortSpecs(String... portSpecs) { + this.portSpecs = portSpecs; + return this; + } + + @Override + public String getUser() { + return user; + } + + @Override + public CreateContainerCmdImpl withUser(String user) { + this.user = user; + return this; + } + + @Override + public boolean isTty() { + return tty; + } + + @Override + public CreateContainerCmdImpl withTty(boolean tty) { + this.tty = tty; + return this; + } + + @Override + public boolean isStdinOpen() { + return stdinOpen; + } + + @Override + public CreateContainerCmdImpl withStdinOpen(boolean stdinOpen) { + this.stdinOpen = stdinOpen; + return this; + } + + @Override + public boolean isStdInOnce() { + return stdInOnce; + } + + @Override + public CreateContainerCmdImpl withStdInOnce(boolean stdInOnce) { + this.stdInOnce = stdInOnce; + return this; + } + + @Override + public long getMemoryLimit() { + return memoryLimit; + } + + @Override + public CreateContainerCmdImpl withMemoryLimit(long memoryLimit) { + this.memoryLimit = memoryLimit; + return this; + } + + @Override + public long getMemorySwap() { + return memorySwap; + } + + @Override + public CreateContainerCmdImpl withMemorySwap(long memorySwap) { + this.memorySwap = memorySwap; + return this; + } + + @Override + public int getCpuShares() { + return cpuShares; + } + + @Override + public CreateContainerCmdImpl withCpuShares(int cpuShares) { + this.cpuShares = cpuShares; + return this; + } + + @Override + public boolean isAttachStdin() { + return attachStdin; + } + + @Override + public CreateContainerCmdImpl withAttachStdin(boolean attachStdin) { + this.attachStdin = attachStdin; + return this; + } + + @Override + public boolean isAttachStdout() { + return attachStdout; + } + + @Override + public CreateContainerCmdImpl withAttachStdout(boolean attachStdout) { + this.attachStdout = attachStdout; + return this; + } + + @Override + public boolean isAttachStderr() { + return attachStderr; + } + + @Override + public CreateContainerCmdImpl withAttachStderr(boolean attachStderr) { + this.attachStderr = attachStderr; + return this; + } + + @Override + public String[] getEnv() { + return env; + } + + @Override + public CreateContainerCmdImpl withEnv(String... env) { + this.env = env; + return this; + } + + @Override + public String[] getCmd() { + return cmd; + } + + @Override + public CreateContainerCmdImpl withCmd(String... cmd) { + this.cmd = cmd; + return this; + } + + @Override + public String[] getDns() { + return dns; + } + + @Override + public CreateContainerCmdImpl withDns(String... dns) { + this.dns = dns; + return this; + } + + @Override + public String getImage() { + return image; + } + + @Override + public CreateContainerCmdImpl withImage(String image) { + this.image = image; + return this; + } + + @Override + @JsonIgnore + public Volume[] getVolumes() { + return volumes.getVolumes(); + } + + @Override + public CreateContainerCmdImpl withVolumes(Volume... volumes) { + this.volumes = new Volumes(volumes); + return this; + } + + @Override + public String[] getVolumesFrom() { + return volumesFrom; + } + + @Override + public CreateContainerCmdImpl withVolumesFrom(String... volumesFrom) { + this.volumesFrom = volumesFrom; + return this; + } + + @Override + public String getCpuset() { + return cpuset; + } + + @Override + public CreateContainerCmd withCpuset(String cpuset) { + this.cpuset = cpuset; + return this; + } + + @Override + public String getIp() { + return ip; + } + + @Override + public CreateContainerCmd withIp(String ip) { + this.ip = ip; + return this; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("create container ") + .append(name != null ? "name=" + name + " " : "") + .append(this) + .toString(); + } + + /** + * @throws NotFoundException No such container + * @throws ConflictException Named container already exists + */ + @Override + public CreateContainerResponse exec() throws NotFoundException, ConflictException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/CreateExecCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateExecCmdImpl.java new file mode 100644 index 00000000..7cb07218 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/CreateExecCmdImpl.java @@ -0,0 +1,12 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.CreateExecCmd; +import com.github.dockerjava.api.command.CreateExecResponse; + +public class CreateExecCmdImpl extends BaseExecCmdImpl implements CreateExecCmd { + + public CreateExecCmdImpl(CreateExecCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/CreateImageCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateImageCmdImpl.java new file mode 100644 index 00000000..99a570ff --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/CreateImageCmdImpl.java @@ -0,0 +1,84 @@ +package com.github.dockerjava.core.command; + +import java.io.InputStream; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.github.dockerjava.api.command.CreateImageCmd; +import com.github.dockerjava.api.command.CreateImageResponse; + +import com.google.common.base.Preconditions; + +/** + * Create an image by importing the given stream of a tar file. + */ +public class CreateImageCmdImpl extends AbstrDockerCmd implements CreateImageCmd { + + private String repository, tag; + + private InputStream imageStream; + + /** + * @param repository the repository to import to + * @param imageStream the InputStream of the tar file + */ + public CreateImageCmdImpl(CreateImageCmd.Exec exec, String repository, InputStream imageStream) { + super(exec); + withRepository(repository); + withImageStream(imageStream); + } + + @Override + public String getRepository() { + return repository; + } + + @Override + public String getTag() { + return tag; + } + + @Override + public InputStream getImageStream() { + return imageStream; + } + + /** + * @param repository the repository to import to + */ + @Override + public CreateImageCmdImpl withRepository(String repository) { + Preconditions.checkNotNull(repository, "repository was not specified"); + this.repository = repository; + return this; + } + + /** + * @param imageStream the InputStream of the tar file + */ + @Override + public CreateImageCmdImpl withImageStream(InputStream imageStream) { + Preconditions + .checkNotNull(imageStream, "imageStream was not specified"); + this.imageStream = imageStream; + return this; + } + + /** + * @param tag any tag for this image + */ + @Override + public CreateImageCmdImpl withTag(String tag) { + Preconditions.checkNotNull(tag, "tag was not specified"); + this.tag = tag; + return this; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("import - ") + .append(repository != null ? repository + ":" : "") + .append(tag != null ? tag : "") + .toString(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/EventsCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/EventsCmdImpl.java new file mode 100644 index 00000000..ac55de71 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/EventsCmdImpl.java @@ -0,0 +1,67 @@ +package com.github.dockerjava.core.command; + +import java.util.concurrent.ExecutorService; + +import com.github.dockerjava.api.command.EventCallback; +import com.github.dockerjava.api.command.EventsCmd; + +/** + * Stream docker events + */ +public class EventsCmdImpl extends AbstrDockerCmd implements EventsCmd { + + private String since; + private String until; + private EventCallback eventCallback; + + public EventsCmdImpl(EventsCmd.Exec exec, EventCallback eventCallback) { + super(exec); + withEventCallback(eventCallback); + } + + @Override + public EventsCmd withSince(String since) { + this.since = since; + return this; + } + + @Override + public EventsCmd withUntil(String until) { + this.until = until; + return this; + } + + @Override + public EventsCmd withEventCallback(EventCallback eventCallback) { + this.eventCallback = eventCallback; + return this; + } + + @Override + public String getSince() { + return since; + } + + @Override + public String getUntil() { + return until; + } + + @Override + public EventCallback getEventCallback() { + return eventCallback; + } + + @Override + public ExecutorService exec() { + return super.exec(); + } + + @Override + public String toString() { + return new StringBuilder("events") + .append(since != null ? " --since=" + since : "") + .append(until != null ? " --until=" + until : "") + .toString(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/ExecContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/ExecContainerCmdImpl.java new file mode 100644 index 00000000..bf048371 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/ExecContainerCmdImpl.java @@ -0,0 +1,12 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.ExecContainerCmd; + +public class ExecContainerCmdImpl extends BaseExecCmdImpl implements ExecContainerCmd { + + public ExecContainerCmdImpl(ExecContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + +} diff --git a/src/main/java/com/github/dockerjava/core/command/InfoCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/InfoCmdImpl.java new file mode 100644 index 00000000..767da204 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/InfoCmdImpl.java @@ -0,0 +1,19 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.InfoCmd; +import com.github.dockerjava.api.model.Info; + +/** + * Return Docker server info + */ +public class InfoCmdImpl extends AbstrDockerCmd implements InfoCmd { + + public InfoCmdImpl(InfoCmd.Exec exec) { + super(exec); + } + + @Override + public String toString() { + return "info"; + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/InspectContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/InspectContainerCmdImpl.java new file mode 100644 index 00000000..0fd55b76 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/InspectContainerCmdImpl.java @@ -0,0 +1,45 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.InspectContainerCmd; +import com.github.dockerjava.api.command.InspectContainerResponse; + +import com.google.common.base.Preconditions; + +/** + * Inspect the details of a container. + */ +public class InspectContainerCmdImpl extends AbstrDockerCmd implements InspectContainerCmd { + + private String containerId; + + public InspectContainerCmdImpl(InspectContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public InspectContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public String toString() { + return "inspect " + containerId; + } + + /** + * @throws NotFoundException No such container + */ + @Override + public InspectContainerResponse exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/InspectImageCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/InspectImageCmdImpl.java new file mode 100644 index 00000000..b52b15d5 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/InspectImageCmdImpl.java @@ -0,0 +1,45 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.InspectImageCmd; +import com.github.dockerjava.api.command.InspectImageResponse; + +import com.google.common.base.Preconditions; + +/** + * Inspect the details of an image. + */ +public class InspectImageCmdImpl extends AbstrDockerCmd implements InspectImageCmd { + + private String imageId; + + public InspectImageCmdImpl(InspectImageCmd.Exec exec, String imageId) { + super(exec); + withImageId(imageId); + } + + @Override + public String getImageId() { + return imageId; + } + + @Override + public InspectImageCmd withImageId(String imageId) { + Preconditions.checkNotNull(imageId, "imageId was not specified"); + this.imageId = imageId; + return this; + } + + @Override + public String toString() { + return "inspect " + imageId; + } + + /** + * @throws NotFoundException No such image + */ + @Override + public InspectImageResponse exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/KillContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/KillContainerCmdImpl.java new file mode 100644 index 00000000..f8ca070f --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/KillContainerCmdImpl.java @@ -0,0 +1,56 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.KillContainerCmd; + +import com.google.common.base.Preconditions; + +/** + * Kill a running container. + */ +public class KillContainerCmdImpl extends AbstrDockerCmd implements KillContainerCmd { + + private String containerId, signal; + + public KillContainerCmdImpl(KillContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public String getSignal() { + return signal; + } + + @Override + public KillContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public KillContainerCmd withSignal(String signal) { + Preconditions.checkNotNull(signal, "signal was not specified"); + this.signal = signal; + return this; + } + + @Override + public String toString() { + return "kill " + containerId; + } + + /** + * @throws NotFoundException No such container + */ + @Override + public Void exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/LimitContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/LimitContainerCmdImpl.java new file mode 100644 index 00000000..57467765 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/LimitContainerCmdImpl.java @@ -0,0 +1,86 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.LimitContainerCmd; +import com.github.dockerjava.api.model.LimitationConfig; +import com.google.common.base.Preconditions; + +public class LimitContainerCmdImpl extends AbstrDockerCmd implements LimitContainerCmd { + + private String containerId; + private LimitationConfig limitationConfig; + + public LimitContainerCmdImpl(LimitContainerCmd.Exec exec, LimitationConfig limitationConfig, String containerId) { + super(exec); + withContainerId(containerId); + Preconditions.checkNotNull(limitationConfig, "limitation config was not specified"); + withLimitationConfig(limitationConfig); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public long getMemoryLimit() { + return limitationConfig.getMemoryLimit(); + } + + @Override + public int getCpuShares() { + return limitationConfig.getCpuShares(); + } + + @Override + public String getCpuset() { + return limitationConfig.getCpuset(); + } + + @Override + public LimitationConfig getLimitationConfig() { + return limitationConfig; + } + + @Override + public LimitContainerCmd withCpuShares(int cpuShares) { + limitationConfig.setCpuShares(cpuShares); + return this; + } + + @Override + public LimitContainerCmd withCpuset(String cpuset) { + limitationConfig.setCpuset(cpuset); + return this; + } + + @Override + public LimitContainerCmd withMemoryLimit(long memoryLimit) { + limitationConfig.setMemoryLimit(memoryLimit); + return this; + } + + @Override + public LimitContainerCmd withContainerId(String containerId) { + this.containerId = containerId; + return this; + } + + @Override + public LimitContainerCmd withLimitationConfig( + LimitationConfig limitationConfig) { + this.limitationConfig = limitationConfig; + return this; + } + + @Override + public boolean isSaveChanges() { + return limitationConfig.isSaveChanges(); + } + + @Override + public LimitContainerCmd withSaveChanges(boolean saveChanges) { + this.limitationConfig.setSaveChanges(saveChanges); + return this; + } + +} diff --git a/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java new file mode 100644 index 00000000..c2ebd491 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/ListContainersCmdImpl.java @@ -0,0 +1,100 @@ +package com.github.dockerjava.core.command; + +import java.util.List; + +import com.github.dockerjava.api.command.ListContainersCmd; +import com.github.dockerjava.api.model.Container; + +import com.google.common.base.Preconditions; + +/** + * List containers + * + * @param showAll - true or false, Show all containers. Only running containers are shown by default. + * @param showSize - true or false, Show the containers sizes. This is false by default. + * @param limit - Show `limit` last created containers, include non-running ones. There is no limit by default. + * @param sinceId - Show only containers created since Id, include non-running ones. + * @param beforeId - Show only containers created before Id, include non-running ones. + * + */ +public class ListContainersCmdImpl extends AbstrDockerCmd> implements ListContainersCmd { + + private int limit = -1; + + private boolean showSize, showAll = false; + + private String sinceId, beforeId; + + public ListContainersCmdImpl(ListContainersCmd.Exec exec) { + super(exec); + } + + @Override + public int getLimit() { + return limit; + } + + @Override + public boolean hasShowSizeEnabled() { + return showSize; + } + + @Override + public boolean hasShowAllEnabled() { + return showAll; + } + + @Override + public String getSinceId() { + return sinceId; + } + + @Override + public String getBeforeId() { + return beforeId; + } + + @Override + public ListContainersCmd withShowAll(boolean showAll) { + this.showAll = showAll; + return this; + } + + @Override + public ListContainersCmd withShowSize(boolean showSize) { + this.showSize = showSize; + return this; + } + + @Override + public ListContainersCmd withLimit(int limit) { + Preconditions.checkArgument(limit > 0, "limit must be greater 0"); + this.limit = limit; + return this; + } + + @Override + public ListContainersCmd withSince(String since) { + Preconditions.checkNotNull(since, "since was not specified"); + this.sinceId = since; + return this; + } + + @Override + public ListContainersCmd withBefore(String before) { + Preconditions.checkNotNull(before, "before was not specified"); + this.beforeId = before; + return this; + } + + @Override + public String toString() { + return new StringBuilder("ps ") + .append(showAll ? "--all=true" : "") + .append(showSize ? "--size=true" : "") + .append(sinceId != null ? "--since " + sinceId : "") + .append(beforeId != null ? "--before " + beforeId : "") + .append(limit != -1 ? "-n " + limit : "") + .toString(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/ListImagesCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/ListImagesCmdImpl.java new file mode 100644 index 00000000..95e36af8 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/ListImagesCmdImpl.java @@ -0,0 +1,56 @@ +package com.github.dockerjava.core.command; + +import java.util.List; + +import com.github.dockerjava.api.command.ListImagesCmd; +import com.github.dockerjava.api.model.Image; + +import com.google.common.base.Preconditions; + +/** + * List images + * + * @param showAll - Show all images (by default filter out the intermediate images used to build) + * @param filter - TODO: undocumented in docker remote api reference + */ +public class ListImagesCmdImpl extends AbstrDockerCmd> implements ListImagesCmd { + + private String filter; + + private boolean showAll = false; + + public ListImagesCmdImpl(ListImagesCmd.Exec exec) { + super(exec); + } + + @Override + public String getFilter() { + return filter; + } + + @Override + public boolean hasShowAllEnabled() { + return showAll; + } + + @Override + public ListImagesCmd withShowAll(boolean showAll) { + this.showAll = showAll; + return this; + } + + @Override + public ListImagesCmd withFilter(String filter) { + Preconditions.checkNotNull(filter, "filter was not specified"); + this.filter = filter; + return this; + } + + @Override + public String toString() { + return new StringBuilder("images ") + .append(showAll ? "--all=true" : "") + .append(filter != null ? "--filter " + filter : "") + .toString(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/LogContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/LogContainerCmdImpl.java new file mode 100644 index 00000000..26c9a3b0 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/LogContainerCmdImpl.java @@ -0,0 +1,148 @@ +package com.github.dockerjava.core.command; + +import java.io.InputStream; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.LogContainerCmd; + +import com.google.common.base.Preconditions; + +/** + * Get container logs + * + * @param followStream + * - true or false, return stream. Defaults to false. + * @param stdout + * - true or false, includes stdout log. Defaults to false. + * @param stderr + * - true or false, includes stderr log. Defaults to false. + * @param timestamps + * - true or false, if true, print timestamps for every log line. + * Defaults to false. + * @param tail + * - `all` or ``, Output specified number of lines at the end of logs + */ +public class LogContainerCmdImpl extends AbstrDockerCmd implements LogContainerCmd { + + private String containerId; + + private int tail = -1; + + private boolean followStream, timestamps, stdout, stderr; + + public LogContainerCmdImpl(LogContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public int getTail() { + return tail; + } + + @Override + public boolean hasFollowStreamEnabled() { + return followStream; + } + + @Override + public boolean hasTimestampsEnabled() { + return timestamps; + } + + @Override + public boolean hasStdoutEnabled() { + return stdout; + } + + @Override + public boolean hasStderrEnabled() { + return stderr; + } + + @Override + public LogContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public LogContainerCmd withFollowStream() { + return withFollowStream(true); + } + + @Override + public LogContainerCmd withFollowStream(boolean followStream) { + this.followStream = followStream; + return this; + } + + @Override + public LogContainerCmd withTimestamps() { + return withTimestamps(true); + } + + @Override + public LogContainerCmd withTimestamps(boolean timestamps) { + this.timestamps = timestamps; + return this; + } + + @Override + public LogContainerCmd withStdOut() { + return withStdOut(true); + } + + @Override + public LogContainerCmd withStdOut(boolean stdout) { + this.stdout = stdout; + return this; + } + + @Override + public LogContainerCmd withStdErr() { + return withStdErr(true); + } + + @Override + public LogContainerCmd withStdErr(boolean stderr) { + this.stderr = stderr; + return this; + } + + @Override + public LogContainerCmd withTailAll() { + this.tail = -1; + return this; + } + + + @Override + public LogContainerCmd withTail(int tail) { + this.tail = tail; + return this; + } + + @Override + public String toString() { + return new StringBuilder("logs ") + .append(followStream ? "--follow=true" : "") + .append(timestamps ? "--timestamps=true" : "") + .append(containerId) + .toString(); + } + + /** + * @throws NotFoundException No such container + */ + @Override + public InputStream exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/MetricContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/MetricContainerCmdImpl.java new file mode 100644 index 00000000..400d9015 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/MetricContainerCmdImpl.java @@ -0,0 +1,27 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.MetricContainerCmd; +import com.github.dockerjava.api.model.metric.Metric; +import com.google.common.base.Preconditions; + +public class MetricContainerCmdImpl extends AbstrDockerCmd implements MetricContainerCmd { + + private String containerId; + + public MetricContainerCmdImpl(MetricContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + public String getContainerId() { + return containerId; + } + + @Override + public MetricContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + +} diff --git a/src/main/java/com/github/dockerjava/core/command/PauseContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/PauseContainerCmdImpl.java new file mode 100644 index 00000000..fa6b816f --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/PauseContainerCmdImpl.java @@ -0,0 +1,49 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.PauseContainerCmd; + +import com.google.common.base.Preconditions; + +/** + * Pause a container. + * + * @param containerId - Id of the container + * + */ +public class PauseContainerCmdImpl extends AbstrDockerCmd implements PauseContainerCmd { + + private String containerId; + + public PauseContainerCmdImpl(PauseContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public PauseContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public String toString() { + return new StringBuilder("pause ") + .append(containerId) + .toString(); + } + + /** + * @throws NotFoundException No such container + */ + @Override + public Void exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/PingCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/PingCmdImpl.java new file mode 100644 index 00000000..15cc1f5b --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/PingCmdImpl.java @@ -0,0 +1,14 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.PingCmd; + +/** + * Ping the Docker server + * + */ +public class PingCmdImpl extends AbstrDockerCmd implements PingCmd { + + public PingCmdImpl(PingCmd.Exec exec) { + super(exec); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/PullImageCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/PullImageCmdImpl.java new file mode 100644 index 00000000..b0ec0251 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/PullImageCmdImpl.java @@ -0,0 +1,66 @@ +package com.github.dockerjava.core.command; + +import java.io.InputStream; + +import com.github.dockerjava.api.command.PullImageCmd; + +import com.google.common.base.Preconditions; + +/** + * + * Pull image from repository. + * + */ +public class PullImageCmdImpl extends AbstrDockerCmd implements PullImageCmd { + + private String repository, tag, registry; + + public PullImageCmdImpl(PullImageCmd.Exec exec, String repository) { + super(exec); + withRepository(repository); + } + + @Override + public String getRepository() { + return repository; + } + + @Override + public String getTag() { + return tag; + } + + @Override + public String getRegistry() { + return registry; + } + + @Override + public PullImageCmd withRepository(String repository) { + Preconditions.checkNotNull(repository, "repository was not specified"); + this.repository = repository; + return this; + } + + @Override + public PullImageCmd withTag(String tag) { + Preconditions.checkNotNull(tag, "tag was not specified"); + this.tag = tag; + return this; + } + + @Override + public PullImageCmd withRegistry(String registry) { + Preconditions.checkNotNull(registry, "registry was not specified"); + this.registry = registry; + return this; + } + + @Override + public String toString() { + return new StringBuilder("pull ") + .append(repository) + .append(tag != null ? ":" + tag : "") + .toString(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/PushImageCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/PushImageCmdImpl.java new file mode 100644 index 00000000..65ea843f --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/PushImageCmdImpl.java @@ -0,0 +1,53 @@ +package com.github.dockerjava.core.command; + +import java.io.InputStream; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.PushImageCmd; + +import com.google.common.base.Preconditions; + +/** + * Push the latest image to the repository. + * + * @param name The name, e.g. "alexec/busybox" or just "busybox" if you want to default. Not null. + */ +public class PushImageCmdImpl extends AbstrAuthCfgDockerCmd implements PushImageCmd { + + private String name; + + public PushImageCmdImpl(PushImageCmd.Exec exec, String name) { + super(exec); + withName(name); + } + + @Override + public String getName() { + return name; + } + + /** + * @param name The name, e.g. "alexec/busybox" or just "busybox" if you want to default. Not null. + */ + @Override + public PushImageCmd withName(String name) { + Preconditions.checkNotNull(name, "name was not specified"); + this.name = name; + return this; + } + + @Override + public String toString() { + return new StringBuilder("push ") + .append(name) + .toString(); + } + + /** + * @throws NotFoundException No such image + */ + @Override + public InputStream exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/RemoveContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/RemoveContainerCmdImpl.java new file mode 100644 index 00000000..c6f9cff1 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/RemoveContainerCmdImpl.java @@ -0,0 +1,97 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.RemoveContainerCmd; + +import com.google.common.base.Preconditions; + +/** + * Remove a container. + * + * @param removeVolumes - true or false, Remove the volumes associated to the container. Defaults to false + * @param force - true or false, Removes the container even if it was running. Defaults to false + */ +public class RemoveContainerCmdImpl extends AbstrDockerCmd implements RemoveContainerCmd { + + private String containerId; + + private boolean removeVolumes, force, checkDevice; + + public RemoveContainerCmdImpl(RemoveContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public boolean hasRemoveVolumesEnabled() { + return removeVolumes; + } + + @Override + public boolean hasForceEnabled() { + return force; + } + + @Override + public RemoveContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public RemoveContainerCmd withRemoveVolumes(boolean removeVolumes) { + this.removeVolumes = removeVolumes; + return this; + } + + @Override + public RemoveContainerCmd withForce() { + return withForce(true); + } + + @Override + public RemoveContainerCmd withForce(boolean force) { + this.force = force; + return this; + } + + @Override + public String toString() { + return new StringBuilder("rm ") + .append(removeVolumes ? "--volumes=true" : "") + .append(force ? "--force=true" : "") + .append(checkDevice ? "--checkDevice=true" : "") + .append(containerId) + .toString(); + } + + /** + * @throws NotFoundException No such container + */ + @Override + public Void exec() throws NotFoundException { + return super.exec(); + } + + @Override + public boolean hasCheckDevice() { + return checkDevice; + } + + @Override + public RemoveContainerCmd withCheckDevice() { + return withCheckDevice(true); + } + + @Override + public RemoveContainerCmd withCheckDevice(boolean checkDevice) { + this.checkDevice = checkDevice; + return this; + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/RemoveImageCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/RemoveImageCmdImpl.java new file mode 100644 index 00000000..dda905fe --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/RemoveImageCmdImpl.java @@ -0,0 +1,84 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.RemoveImageCmd; + +import com.google.common.base.Preconditions; + +/** + * + * Remove an image, deleting any tags it might have. + * + */ +public class RemoveImageCmdImpl extends AbstrDockerCmd implements RemoveImageCmd { + + private String imageId; + + private boolean force, noPrune; + + public RemoveImageCmdImpl(RemoveImageCmd.Exec exec, String imageId) { + super(exec); + withImageId(imageId); + } + + @Override + public String getImageId() { + return imageId; + } + + @Override + public boolean hasForceEnabled() { + return force; + } + + @Override + public boolean hasNoPruneEnabled() { + return noPrune; + } + + @Override + public RemoveImageCmd withImageId(String imageId) { + Preconditions.checkNotNull(imageId, "imageId was not specified"); + this.imageId = imageId; + return this; + } + + @Override + public RemoveImageCmd withForce() { + return withForce(true); + } + + @Override + public RemoveImageCmd withForce(boolean force) { + this.force = force; + return this; + } + + @Override + public RemoveImageCmd withNoPrune() { + return withNoPrune(true); + } + + @Override + public RemoveImageCmd withNoPrune(boolean noPrune) { + this.noPrune = noPrune; + return this; + } + + @Override + public String toString() { + return new StringBuilder("rmi ") + .append(noPrune ? "--no-prune=true" : "") + .append(force ? "--force=true" : "") + .append(imageId) + .toString(); + } + + /** + * @throws NotFoundException No such image + */ + @Override + public Void exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/RestartContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/RestartContainerCmdImpl.java new file mode 100644 index 00000000..f82a65b6 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/RestartContainerCmdImpl.java @@ -0,0 +1,64 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.RestartContainerCmd; + +import com.google.common.base.Preconditions; + +/** + * Restart a running container. + * + * @param timeout - Timeout in seconds before killing the container. Defaults to 10 seconds. + * + */ +public class RestartContainerCmdImpl extends AbstrDockerCmd implements RestartContainerCmd { + + private String containerId; + + private int timeout = 10; + + public RestartContainerCmdImpl(RestartContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public int getTimeout() { + return timeout; + } + + @Override + public RestartContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public RestartContainerCmd withtTimeout(int timeout) { + Preconditions.checkArgument(timeout >= 0, "timeout must be greater or equal 0"); + this.timeout = timeout; + return this; + } + + @Override + public String toString() { + return new StringBuilder("restart ") + .append("--time=" + timeout + " ") + .append(containerId) + .toString(); + } + + /** + * @throws NotFoundException No such container + */ + @Override + public Void exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/SearchImagesCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/SearchImagesCmdImpl.java new file mode 100644 index 00000000..3ca878f1 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/SearchImagesCmdImpl.java @@ -0,0 +1,43 @@ +package com.github.dockerjava.core.command; + +import java.util.List; + +import com.github.dockerjava.api.command.SearchImagesCmd; +import com.github.dockerjava.api.model.SearchItem; + +import com.google.common.base.Preconditions; + +/** + * Search images + * + * @param term - search term + * + */ +public class SearchImagesCmdImpl extends AbstrDockerCmd> implements SearchImagesCmd { + + private String term; + + public SearchImagesCmdImpl(SearchImagesCmd.Exec exec, String term) { + super(exec); + withTerm(term); + } + + @Override + public String getTerm() { + return term; + } + + @Override + public SearchImagesCmd withTerm(String term) { + Preconditions.checkNotNull(term, "term was not specified"); + this.term = term; + return this; + } + + @Override + public String toString() { + return new StringBuilder("search ") + .append(term) + .toString(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/StartContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/StartContainerCmdImpl.java new file mode 100644 index 00000000..3fee8128 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/StartContainerCmdImpl.java @@ -0,0 +1,273 @@ +package com.github.dockerjava.core.command; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.NotModifiedException; +import com.github.dockerjava.api.command.StartContainerCmd; +import com.github.dockerjava.api.model.Bind; +import com.github.dockerjava.api.model.Binds; +import com.github.dockerjava.api.model.Device; +import com.github.dockerjava.api.model.Link; +import com.github.dockerjava.api.model.Links; +import com.github.dockerjava.api.model.LxcConf; +import com.github.dockerjava.api.model.Ports; +import com.github.dockerjava.api.model.RestartPolicy; +import com.google.common.base.Preconditions; + +/** + * Start a container + */ +public class StartContainerCmdImpl extends AbstrDockerCmd implements StartContainerCmd { + + private String containerId; + + @JsonProperty("Binds") + private Binds binds = new Binds(); + + @JsonProperty("Links") + private Links links = new Links(); + + @JsonProperty("LxcConf") + private LxcConf[] lxcConf; + + @JsonProperty("PortBindings") + private Ports portBindings; + + @JsonProperty("PublishAllPorts") + private boolean publishAllPorts; + + @JsonProperty("Privileged") + private boolean privileged; + + @JsonProperty("Dns") + private String[] dns; + + @JsonProperty("DnsSearch") + private String[] dnsSearch; + + @JsonProperty("VolumesFrom") + private String[] volumesFrom; + + @JsonProperty("NetworkMode") + private String networkMode = "bridge"; + + @JsonProperty("Devices") + private Device[] devices; + + @JsonProperty("RestartPolicy") + private RestartPolicy restartPolicy; + + @JsonProperty("CapAdd") + private String[] capAdd; + + @JsonProperty("CapDrop") + private String[] capDrop; + + public StartContainerCmdImpl(StartContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + @JsonIgnore + public Bind[] getBinds() { + return binds.getBinds(); + } + + @Override + @JsonIgnore + public Link[] getLinks() { + return links.getLinks(); + } + + @Override + public LxcConf[] getLxcConf() { + return lxcConf; + } + + @Override + public Ports getPortBindings() { + return portBindings; + } + + @Override + public boolean isPublishAllPorts() { + return publishAllPorts; + } + + @Override + public boolean isPrivileged() { + return privileged; + } + + @Override + public String[] getDns() { + return dns; + } + + @Override + public String[] getDnsSearch() { + return dnsSearch; + } + + @Override + public String[] getVolumesFrom() { + return volumesFrom; + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public String getNetworkMode() { + return networkMode; + } + + @Override + public Device[] getDevices() { + return devices; + } + + @Override + public RestartPolicy getRestartPolicy() { + return restartPolicy; + } + + @Override + public String[] getCapAdd() { + return capAdd; + } + + @Override + public String[] getCapDrop() { + return capDrop; + } + + @Override + @JsonIgnore + public StartContainerCmd withBinds(Bind... binds) { + Preconditions.checkNotNull(binds, "binds was not specified"); + this.binds = new Binds(binds); + return this; + } + + @Override + @JsonIgnore + public StartContainerCmd withLinks(Link... links) { + Preconditions.checkNotNull(links, "links was not specified"); + this.links = new Links(links); + return this; + } + + @Override + public StartContainerCmd withLxcConf(LxcConf... lxcConf) { + Preconditions.checkNotNull(lxcConf, "lxcConf was not specified"); + this.lxcConf = lxcConf; + return this; + } + + @Override + public StartContainerCmd withPortBindings(Ports portBindings) { + Preconditions.checkNotNull(portBindings, + "portBindings was not specified"); + this.portBindings = portBindings; + return this; + } + + @Override + public StartContainerCmd withPrivileged(boolean privileged) { + this.privileged = privileged; + return this; + } + + @Override + public StartContainerCmd withPublishAllPorts(boolean publishAllPorts) { + this.publishAllPorts = publishAllPorts; + return this; + } + + @Override + public StartContainerCmd withDns(String... dns) { + Preconditions.checkNotNull(dns, "dns was not specified"); + this.dns = dns; + return this; + } + + @Override + public StartContainerCmd withDnsSearch(String... dnsSearch) { + Preconditions.checkNotNull(dnsSearch, "dnsSearch was not specified"); + this.dnsSearch = dnsSearch; + return this; + } + + @Override + public StartContainerCmd withVolumesFrom(String... volumesFrom) { + Preconditions + .checkNotNull(volumesFrom, "volumesFrom was not specified"); + this.volumesFrom = volumesFrom; + return this; + } + + @Override + public StartContainerCmd withContainerId(String containerId) { + Preconditions + .checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public StartContainerCmd withNetworkMode(String networkMode) { + Preconditions.checkNotNull(networkMode, "networkMode was not specified"); + this.networkMode = networkMode; + return this; + } + + @Override + public StartContainerCmd withDevices(Device... devices) { + Preconditions.checkNotNull(devices, "devices was not specified"); + this.devices = devices; + return this; + } + + @Override + public StartContainerCmd withRestartPolicy(RestartPolicy restartPolicy) { + Preconditions.checkNotNull(restartPolicy, "restartPolicy was not specified"); + this.restartPolicy = restartPolicy; + return this; + } + + @Override + public StartContainerCmd withCapAdd(String... capAdd) { + Preconditions.checkNotNull(capAdd, "capAdd was not specified"); + this.capAdd = capAdd; + return this; + } + + @Override + public StartContainerCmd withCapDrop(String... capDrop) { + Preconditions.checkNotNull(capDrop, "capDrop was not specified"); + this.capDrop = capDrop; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this).toString(); + } + + /** + * @throws NotFoundException No such container + * @throws NotModifiedException Container already started + */ + @Override + public Void exec() throws NotFoundException, NotModifiedException { + return super.exec(); + } + +} diff --git a/src/main/java/com/github/dockerjava/core/command/StartExecCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/StartExecCmdImpl.java new file mode 100644 index 00000000..c183770d --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/StartExecCmdImpl.java @@ -0,0 +1,25 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.StartExecCmd; + +public class StartExecCmdImpl extends BaseExecCmdImpl implements StartExecCmd { + + private String execId; + + public StartExecCmdImpl(StartExecCmd.Exec exec, String execId) { + super(exec); + withExecId(execId); + } + + @Override + public String getExecId() { + return this.execId; + } + + @Override + public StartExecCmd withExecId(String execId) { + this.execId = execId; + return this; + } + +} diff --git a/src/main/java/com/github/dockerjava/core/command/StopContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/StopContainerCmdImpl.java new file mode 100644 index 00000000..7033cad6 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/StopContainerCmdImpl.java @@ -0,0 +1,67 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.NotModifiedException; +import com.github.dockerjava.api.command.StopContainerCmd; + +import com.google.common.base.Preconditions; + +/** + * Stop a running container. + * + * @param containerId - Id of the container + * @param timeout - Timeout in seconds before killing the container. Defaults to 10 seconds. + * + */ +public class StopContainerCmdImpl extends AbstrDockerCmd implements StopContainerCmd { + + private String containerId; + + private int timeout = 10; + + public StopContainerCmdImpl(StopContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public int getTimeout() { + return timeout; + } + + @Override + public StopContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public StopContainerCmd withTimeout(int timeout) { + Preconditions.checkArgument(timeout >= 0, "timeout must be greater or equal 0"); + this.timeout = timeout; + return this; + } + + @Override + public String toString() { + return new StringBuilder("stop ") + .append("--time=" + timeout + " ") + .append(containerId) + .toString(); + } + + /** + * @throws NotFoundException No such container + * @throws NotModifiedException Container already stopped + */ + @Override + public Void exec() throws NotFoundException, NotModifiedException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/SweepContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/SweepContainerCmdImpl.java new file mode 100644 index 00000000..bc429c18 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/SweepContainerCmdImpl.java @@ -0,0 +1,41 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.SweepContainerCmd; +import com.google.common.base.Preconditions; + +public class SweepContainerCmdImpl extends AbstrDockerCmd implements SweepContainerCmd { + + private String containerId; + + public SweepContainerCmdImpl(SweepContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public SweepContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public String toString() { + return "sweep " + containerId; + } + + /** + * @throws NotFoundException No such container + */ + @Override + public Void exec() throws NotFoundException { + return super.exec(); + } + +} diff --git a/src/main/java/com/github/dockerjava/core/command/TagImageCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/TagImageCmdImpl.java new file mode 100644 index 00000000..fe981218 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/TagImageCmdImpl.java @@ -0,0 +1,89 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.TagImageCmd; + +import com.google.common.base.Preconditions; + +/** + * Tag an image into a repository + * + * @param image The local image to tag (either a name or an id) + * @param repository The repository to tag in + * @param force (not documented) + * + */ +public class TagImageCmdImpl extends AbstrDockerCmd implements TagImageCmd { + + private String imageId, repository, tag; + + private boolean force; + + public TagImageCmdImpl(TagImageCmd.Exec exec, String imageId, String repository, String tag) { + super(exec); + withImageId(imageId); + withRepository(repository); + withTag(tag); + } + + @Override + public String getImageId() { + return imageId; + } + + @Override + public String getRepository() { + return repository; + } + + @Override + public String getTag() { + return tag; + } + + @Override + public boolean hasForceEnabled() { + return force; + } + + @Override + public TagImageCmd withImageId(String imageId) { + Preconditions.checkNotNull(imageId, "imageId was not specified"); + this.imageId = imageId; + return this; + } + + @Override + public TagImageCmd withRepository(String repository) { + Preconditions.checkNotNull(repository, "repository was not specified"); + this.repository = repository; + return this; + } + + @Override + public TagImageCmd withTag(String tag) { + Preconditions.checkNotNull(tag, "tag was not specified"); + this.tag = tag; + return this; + } + + @Override + public TagImageCmd withForce() { + return withForce(true); + } + + @Override + public TagImageCmd withForce(boolean force) { + this.force = force; + return this; + } + + @Override + public String toString() { + return new StringBuilder("tag ") + .append(force ? "--force=true " : "") + .append(repository != null ? repository + "/" : "") + .append(imageId) + .append(tag != null ? ":" + tag : "") + .toString(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/TopContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/TopContainerCmdImpl.java new file mode 100644 index 00000000..92b82523 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/TopContainerCmdImpl.java @@ -0,0 +1,63 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.TopContainerCmd; +import com.github.dockerjava.api.command.TopContainerResponse; + +import com.google.common.base.Preconditions; + +/** + * List processes running inside a container + */ +public class TopContainerCmdImpl extends AbstrDockerCmd implements TopContainerCmd { + + private String containerId; + + private String psArgs; + + public TopContainerCmdImpl(TopContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public String getPsArgs() { + return psArgs; + } + + @Override + public TopContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + + @Override + public TopContainerCmd withPsArgs(String psArgs) { + Preconditions.checkNotNull(psArgs, "psArgs was not specified"); + this.psArgs = psArgs; + return this; + } + + @Override + public String toString() { + return new StringBuilder("top ") + .append(containerId) + .append(psArgs != null ? " " + psArgs : "") + .toString(); + } + + /** + * @throws NotFoundException No such container + */ + @Override + public TopContainerResponse exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/UnpauseContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/UnpauseContainerCmdImpl.java new file mode 100644 index 00000000..3ecc0acb --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/UnpauseContainerCmdImpl.java @@ -0,0 +1,49 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.UnpauseContainerCmd; + +import com.google.common.base.Preconditions; + +/** + * Unpause a container. + * + * @param containerId - Id of the container + * + */ +public class UnpauseContainerCmdImpl extends AbstrDockerCmd implements UnpauseContainerCmd { + + private String containerId; + + public UnpauseContainerCmdImpl(UnpauseContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public UnpauseContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public String toString() { + return new StringBuilder("pause ") + .append(containerId) + .toString(); + } + + /** + * @throws NotFoundException No such container + */ + @Override + public Void exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/VersionCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/VersionCmdImpl.java new file mode 100644 index 00000000..211ed140 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/VersionCmdImpl.java @@ -0,0 +1,19 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.VersionCmd; +import com.github.dockerjava.api.model.Version; + +/** + * Returns the Docker version info. + */ +public class VersionCmdImpl extends AbstrDockerCmd implements VersionCmd { + + @Override + public String toString() { + return "version"; + } + + public VersionCmdImpl(VersionCmd.Exec exec) { + super(exec); + } +} diff --git a/src/main/java/com/github/dockerjava/core/command/WaitContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/WaitContainerCmdImpl.java new file mode 100644 index 00000000..80baf2cc --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/WaitContainerCmdImpl.java @@ -0,0 +1,36 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.WaitContainerCmd; +import com.google.common.base.Preconditions; + +/** + * Wait a container + * + * Block until container stops, then returns its exit code + */ +public class WaitContainerCmdImpl extends AbstrDockerCmd implements WaitContainerCmd { + + private String containerId; + + public WaitContainerCmdImpl(WaitContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public WaitContainerCmd withContainerId(String containerId) { + Preconditions.checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public String toString() { + return "wait " + containerId; + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java new file mode 100644 index 00000000..34414d73 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java @@ -0,0 +1,59 @@ +package com.github.dockerjava.jaxrs; + +import java.io.IOException; + +import javax.ws.rs.ProcessingException; +import javax.ws.rs.client.WebTarget; + +import org.apache.commons.codec.binary.Base64; + +import com.fasterxml.jackson.databind.ObjectMapper; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.command.DockerCmd; +import com.github.dockerjava.api.command.DockerCmdExec; +import com.github.dockerjava.api.model.AuthConfig; + +import com.google.common.base.Preconditions; + +public abstract class AbstrDockerCmdExec, RES_T> + implements DockerCmdExec { + + private WebTarget baseResource; + + public AbstrDockerCmdExec(WebTarget baseResource) { + Preconditions.checkNotNull(baseResource, + "baseResource was not specified"); + this.baseResource = baseResource; + } + + protected WebTarget getBaseResource() { + return baseResource; + } + + protected String registryAuth(AuthConfig authConfig) { + try { + return Base64.encodeBase64String(new ObjectMapper() + .writeValueAsString(authConfig).getBytes()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public RES_T exec(CMD_T command) { + // this hack works because of ResponseStatusExceptionFilter + RES_T result; + try { + result = execute(command); + } catch (ProcessingException e) { + if(e.getCause() instanceof DockerException) { + throw (DockerException)e.getCause(); + } else { + throw e; + } + } + return result; + } + + protected abstract RES_T execute(CMD_T command); +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/AttachContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/AttachContainerCmdExec.java new file mode 100644 index 00000000..5ed84c34 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/AttachContainerCmdExec.java @@ -0,0 +1,41 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import java.io.InputStream; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.AttachContainerCmd; + +public class AttachContainerCmdExec extends AbstrDockerCmdExec implements AttachContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(AttachContainerCmdExec.class); + + public AttachContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected InputStream execute(AttachContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/attach") + .resolveTemplate("id", command.getContainerId()) + .queryParam("logs", command.hasLogsEnabled() ? "1" : "0") + // .queryParam("stdin", command.hasStdinEnabled() ? "1" : "0") + .queryParam("stdout", command.hasStdoutEnabled() ? "1" : "0") + .queryParam("stderr", command.hasStderrEnabled() ? "1" : "0") + .queryParam("stream", command.hasFollowStreamEnabled() ? "1" : "0"); + + LOGGER.trace("POST: {}", webResource); + + return webResource.request().accept(MediaType.APPLICATION_OCTET_STREAM_TYPE) + .post(entity(null, MediaType.APPLICATION_JSON), Response.class).readEntity(InputStream.class); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/AuthCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/AuthCmdExec.java new file mode 100644 index 00000000..d73487bb --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/AuthCmdExec.java @@ -0,0 +1,37 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.UnauthorizedException; +import com.github.dockerjava.api.command.AuthCmd; + +public class AuthCmdExec extends AbstrDockerCmdExec implements AuthCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(AuthCmdExec.class); + + public AuthCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(AuthCmd command) { + WebTarget webResource = getBaseResource().path("/auth"); + LOGGER.trace("POST: {}", webResource); + Response response = webResource.request().accept(MediaType.APPLICATION_JSON).post(entity(command.getAuthConfig(), MediaType.APPLICATION_JSON)); + + if(response.getStatus() == 401) { + throw new UnauthorizedException("Unauthorized"); + }; + + return null; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java new file mode 100644 index 00000000..71d3f902 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java @@ -0,0 +1,50 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import java.io.InputStream; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.BuildImageCmd; + +public class BuildImageCmdExec extends AbstrDockerCmdExec implements BuildImageCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(BuildImageCmdExec.class); + + public BuildImageCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected InputStream execute(BuildImageCmd command) { + WebTarget webResource = getBaseResource().path("/build"); + + if(command.getTag() != null) { + webResource = webResource.queryParam("t", command.getTag()); + } + if (command.hasNoCacheEnabled()) { + webResource = webResource.queryParam("nocache", "true"); + } + if (command.hasRemoveEnabled()) { + webResource = webResource.queryParam("rm", "true"); + } + if (command.isQuiet()) { + webResource = webResource.queryParam("q", "true"); + } + + LOGGER.debug("POST: {}", webResource); + return webResource + .request() + .accept(MediaType.TEXT_PLAIN) + .post(entity(command.getTarInputStream(), "application/tar"), Response.class).readEntity(InputStream.class); + + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/CgroupContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/CgroupContainerCmdExec.java new file mode 100644 index 00000000..64a03ab5 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/CgroupContainerCmdExec.java @@ -0,0 +1,46 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.CgroupContainerCmd; +import com.github.dockerjava.api.model.Subsystem; +import com.github.dockerjava.api.model.WriteSubsystem; + +public class CgroupContainerCmdExec extends AbstrDockerCmdExec> implements CgroupContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(CgroupContainerCmdExec.class); + + public CgroupContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected List execute(CgroupContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/cgroup").resolveTemplate("id", command.getContainerId()); + Map data = new HashMap(); + List toRead = command.getReadSubsystem(); + List toWrite = command.getWriteSubsystem(); + if (toRead != null && toRead.size() > 0) { + data.put("ReadSubsystem", toRead); + } + if (toWrite != null && toWrite.size() > 0) { + data.put("WriteSubsystem", toWrite); + } + LOGGER.trace("POST: {}", webResource); + List response = webResource.request().accept(MediaType.APPLICATION_JSON).post(entity(data, MediaType.APPLICATION_JSON), new GenericType>() { + }); + return response; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/CommitCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/CommitCmdExec.java new file mode 100644 index 00000000..f1f4fe33 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/CommitCmdExec.java @@ -0,0 +1,38 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.github.dockerjava.api.command.CommitCmd; + +public class CommitCmdExec extends AbstrDockerCmdExec implements CommitCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(CommitCmdExec.class); + + public CommitCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected String execute(CommitCmd command) { + WebTarget webResource = getBaseResource().path("/commit") + .queryParam("container", command.getContainerId()) + .queryParam("repo", command.getRepository()) + .queryParam("tag", command.getTag()) + .queryParam("m", command.getMessage()) + .queryParam("author", command.getAuthor()) + .queryParam("pause", command.hasPauseEnabled() ? "1" : "0"); + + LOGGER.trace("POST: {}", webResource); + ObjectNode objectNode = webResource.request().accept("application/vnd.docker.raw-stream").post(entity(command, MediaType.APPLICATION_JSON), ObjectNode.class); + return objectNode.get("Id").asText(); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/ContainerDiffCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/ContainerDiffCmdExec.java new file mode 100644 index 00000000..0a657ed9 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/ContainerDiffCmdExec.java @@ -0,0 +1,33 @@ +package com.github.dockerjava.jaxrs; + +import java.util.List; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.ContainerDiffCmd; +import com.github.dockerjava.api.model.ChangeLog; + +public class ContainerDiffCmdExec extends AbstrDockerCmdExec> implements ContainerDiffCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(ContainerDiffCmdExec.class); + + public ContainerDiffCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected List execute(ContainerDiffCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/changes").resolveTemplate("id", command.getContainerId()); + + LOGGER.trace("GET: {}", webResource); + return webResource.request().accept(MediaType.APPLICATION_JSON).get(new GenericType>() { + }); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/CopyFileFromContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/CopyFileFromContainerCmdExec.java new file mode 100644 index 00000000..27b4d5bd --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/CopyFileFromContainerCmdExec.java @@ -0,0 +1,36 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import java.io.InputStream; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.CopyFileFromContainerCmd; + +public class CopyFileFromContainerCmdExec extends AbstrDockerCmdExec implements CopyFileFromContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(CopyFileFromContainerCmdExec.class); + + public CopyFileFromContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected InputStream execute(CopyFileFromContainerCmd command) { + WebTarget webResource = getBaseResource() + .path("/containers/{id}/copy") + .resolveTemplate("id", command.getContainerId()); + + LOGGER.trace("POST: " + webResource.toString()); + + return webResource.request().accept(MediaType.APPLICATION_OCTET_STREAM_TYPE).post(entity(command, MediaType.APPLICATION_JSON), Response.class).readEntity(InputStream.class); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/CreateContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/CreateContainerCmdExec.java new file mode 100644 index 00000000..26dc25cd --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/CreateContainerCmdExec.java @@ -0,0 +1,35 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateContainerResponse; + +public class CreateContainerCmdExec extends AbstrDockerCmdExec implements CreateContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(CreateContainerCmdExec.class); + + public CreateContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected CreateContainerResponse execute(CreateContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/create"); + + if (command.getName() != null) { + webResource = webResource.queryParam("name", command.getName()); + } + + LOGGER.trace("POST: {} ", webResource); + return webResource.request().accept(MediaType.APPLICATION_JSON) + .post(entity(command, MediaType.APPLICATION_JSON), CreateContainerResponse.class); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/CreateExecCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/CreateExecCmdExec.java new file mode 100644 index 00000000..6c61d0e7 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/CreateExecCmdExec.java @@ -0,0 +1,31 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.CreateExecCmd; +import com.github.dockerjava.api.command.CreateExecResponse; + +public class CreateExecCmdExec extends AbstrDockerCmdExec implements CreateExecCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(CreateExecCmdExec.class); + + public CreateExecCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected CreateExecResponse execute(CreateExecCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/exec").resolveTemplate("id", command.getContainerId()); + + LOGGER.trace("POST: {} ", webResource); + return webResource.request().accept(MediaType.APPLICATION_JSON) + .post(entity(command.getExecConfig(), MediaType.APPLICATION_JSON), CreateExecResponse.class); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/CreateImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/CreateImageCmdExec.java new file mode 100644 index 00000000..4c7bae8b --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/CreateImageCmdExec.java @@ -0,0 +1,35 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.CreateImageCmd; +import com.github.dockerjava.api.command.CreateImageResponse; + +public class CreateImageCmdExec extends AbstrDockerCmdExec implements CreateImageCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(CreateImageCmdExec.class); + + public CreateImageCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected CreateImageResponse execute(CreateImageCmd command) { + WebTarget webResource = getBaseResource() + .path("/images/create") + .queryParam("repo", command.getRepository()) + .queryParam("tag", command.getTag()) + .queryParam("fromSrc", "-"); + + LOGGER.trace("POST: {}", webResource); + return webResource.request().accept(MediaType.APPLICATION_OCTET_STREAM_TYPE) + .post(entity(command.getImageStream(), MediaType.APPLICATION_OCTET_STREAM), CreateImageResponse.class); + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java new file mode 100644 index 00000000..12c86cff --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -0,0 +1,347 @@ +package com.github.dockerjava.jaxrs; + +import java.io.IOException; +import java.security.KeyStore; +import java.security.Security; +import java.util.logging.Logger; + +import javax.net.ssl.SSLContext; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.WebTarget; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.glassfish.jersey.CommonProperties; +import org.glassfish.jersey.SslConfigurator; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; + +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; +import com.github.dockerjava.api.DockerClientException; +import com.github.dockerjava.api.command.AttachContainerCmd; +import com.github.dockerjava.api.command.AuthCmd; +import com.github.dockerjava.api.command.BuildImageCmd; +import com.github.dockerjava.api.command.CgroupContainerCmd; +import com.github.dockerjava.api.command.CommitCmd; +import com.github.dockerjava.api.command.ContainerDiffCmd; +import com.github.dockerjava.api.command.CopyFileFromContainerCmd; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateExecCmd; +import com.github.dockerjava.api.command.CreateImageCmd; +import com.github.dockerjava.api.command.DockerCmdExecFactory; +import com.github.dockerjava.api.command.EventsCmd; +import com.github.dockerjava.api.command.ExecContainerCmd; +import com.github.dockerjava.api.command.InfoCmd; +import com.github.dockerjava.api.command.InspectContainerCmd; +import com.github.dockerjava.api.command.InspectImageCmd; +import com.github.dockerjava.api.command.KillContainerCmd; +import com.github.dockerjava.api.command.LimitContainerCmd; +import com.github.dockerjava.api.command.ListContainersCmd; +import com.github.dockerjava.api.command.ListImagesCmd; +import com.github.dockerjava.api.command.LogContainerCmd; +import com.github.dockerjava.api.command.MetricContainerCmd; +import com.github.dockerjava.api.command.PauseContainerCmd; +import com.github.dockerjava.api.command.PingCmd; +import com.github.dockerjava.api.command.PullImageCmd; +import com.github.dockerjava.api.command.PushImageCmd; +import com.github.dockerjava.api.command.RemoveContainerCmd; +import com.github.dockerjava.api.command.RemoveImageCmd; +import com.github.dockerjava.api.command.RestartContainerCmd; +import com.github.dockerjava.api.command.SearchImagesCmd; +import com.github.dockerjava.api.command.StartContainerCmd; +import com.github.dockerjava.api.command.StartExecCmd; +import com.github.dockerjava.api.command.StartExecCmd.Exec; +import com.github.dockerjava.api.command.StopContainerCmd; +import com.github.dockerjava.api.command.SweepContainerCmd; +import com.github.dockerjava.api.command.TagImageCmd; +import com.github.dockerjava.api.command.TopContainerCmd; +import com.github.dockerjava.api.command.UnpauseContainerCmd; +import com.github.dockerjava.api.command.VersionCmd; +import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.core.CertificateUtils; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.jaxrs.util.JsonClientFilter; +import com.github.dockerjava.jaxrs.util.ResponseStatusExceptionFilter; +import com.github.dockerjava.jaxrs.util.SelectiveLoggingFilter; +import com.google.common.base.Preconditions; + +public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { + + private static final Logger LOGGER = Logger.getLogger(DockerCmdExecFactoryImpl.class.getName()); + private Client client; + private WebTarget baseResource; + + @Override + public void init(DockerClientConfig dockerClientConfig) { + Preconditions.checkNotNull(dockerClientConfig, "config was not specified"); + + ClientConfig clientConfig = new ClientConfig(); + clientConfig.property(CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true); + + clientConfig.register(ResponseStatusExceptionFilter.class); + clientConfig.register(JsonClientFilter.class); + clientConfig.register(JacksonJsonProvider.class); + + if (dockerClientConfig.isLoggingFilterEnabled()) { + clientConfig.register(new SelectiveLoggingFilter(LOGGER, true)); + } + + if (dockerClientConfig.getReadTimeout() != null) { + int readTimeout = dockerClientConfig.getReadTimeout(); + clientConfig.property(ClientProperties.READ_TIMEOUT, readTimeout); + } + + ClientBuilder clientBuilder = ClientBuilder.newBuilder().withConfig(clientConfig); + + String dockerCertPath = dockerClientConfig.getDockerCertPath(); + + if (dockerCertPath != null) { + boolean certificatesExist = CertificateUtils.verifyCertificatesExist(dockerCertPath); + + if (certificatesExist) { + + try { + + Security.addProvider(new BouncyCastleProvider()); + + KeyStore keyStore = CertificateUtils.createKeyStore(dockerCertPath); + KeyStore trustStore = CertificateUtils.createTrustStore(dockerCertPath); + + // properties acrobatics not needed for java > 1.6 + String httpProtocols = System.getProperty("https.protocols"); + System.setProperty("https.protocols", "TLSv1"); + SslConfigurator sslConfig = SslConfigurator.newInstance(true); + if (httpProtocols != null) System.setProperty("https.protocols", httpProtocols); + + sslConfig.keyStore(keyStore); + sslConfig.keyStorePassword("docker"); + sslConfig.trustStore(trustStore); + + SSLContext sslContext = sslConfig.createSSLContext(); + + + clientBuilder.sslContext(sslContext); + + } catch (Exception e) { + throw new DockerClientException(e.getMessage(), e); + } + + } + + } + + client = clientBuilder.build(); + + WebTarget webResource = client.target(dockerClientConfig.getUri()); + + if (dockerClientConfig.getVersion() == null || dockerClientConfig.getVersion().isEmpty()) { + baseResource = webResource; + } else { + baseResource = webResource.path("v" + dockerClientConfig.getVersion()); + } + + } + + protected WebTarget getBaseResource() { + Preconditions.checkNotNull(baseResource, "Factory not initialized. You probably forgot to call init()!"); + return baseResource; + } + + @Override + public AuthCmd.Exec createAuthCmdExec() { + return new AuthCmdExec(getBaseResource()); + } + + @Override + public InfoCmd.Exec createInfoCmdExec() { + return new InfoCmdExec(getBaseResource()); + } + + @Override + public PingCmd.Exec createPingCmdExec() { + return new PingCmdExec(getBaseResource()); + } + + @Override + public VersionCmd.Exec createVersionCmdExec() { + return new VersionCmdExec(getBaseResource()); + } + + @Override + public PullImageCmd.Exec createPullImageCmdExec() { + return new PullImageCmdExec(getBaseResource()); + } + + @Override + public PushImageCmd.Exec createPushImageCmdExec() { + return new PushImageCmdExec(getBaseResource()); + } + + @Override + public CreateImageCmd.Exec createCreateImageCmdExec() { + return new CreateImageCmdExec(getBaseResource()); + } + + @Override + public SearchImagesCmd.Exec createSearchImagesCmdExec() { + return new SearchImagesCmdExec(getBaseResource()); + } + + @Override + public RemoveImageCmd.Exec createRemoveImageCmdExec() { + return new RemoveImageCmdExec(getBaseResource()); + } + + @Override + public ListImagesCmd.Exec createListImagesCmdExec() { + return new ListImagesCmdExec(getBaseResource()); + } + + @Override + public InspectImageCmd.Exec createInspectImageCmdExec() { + return new InspectImageCmdExec(getBaseResource()); + } + + @Override + public ListContainersCmd.Exec createListContainersCmdExec() { + return new ListContainersCmdExec(getBaseResource()); + } + + @Override + public CreateContainerCmd.Exec createCreateContainerCmdExec() { + return new CreateContainerCmdExec(getBaseResource()); + } + + @Override + public StartContainerCmd.Exec createStartContainerCmdExec() { + return new StartContainerCmdExec(getBaseResource()); + } + + @Override + public InspectContainerCmd.Exec createInspectContainerCmdExec() { + return new InspectContainerCmdExec(getBaseResource()); + } + + @Override + public RemoveContainerCmd.Exec createRemoveContainerCmdExec() { + return new RemoveContainerCmdExec(getBaseResource()); + } + + @Override + public WaitContainerCmd.Exec createWaitContainerCmdExec() { + return new WaitContainerCmdExec(getBaseResource()); + } + + @Override + public AttachContainerCmd.Exec createAttachContainerCmdExec() { + return new AttachContainerCmdExec(getBaseResource()); + } + + @Override + public LogContainerCmd.Exec createLogContainerCmdExec() { + return new LogContainerCmdExec(getBaseResource()); + } + + @Override + public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec() { + return new CopyFileFromContainerCmdExec(getBaseResource()); + } + + @Override + public StopContainerCmd.Exec createStopContainerCmdExec() { + return new StopContainerCmdExec(getBaseResource()); + } + + @Override + public ContainerDiffCmd.Exec createContainerDiffCmdExec() { + return new ContainerDiffCmdExec(getBaseResource()); + } + + @Override + public KillContainerCmd.Exec createKillContainerCmdExec() { + return new KillContainerCmdExec(getBaseResource()); + } + + @Override + public RestartContainerCmd.Exec createRestartContainerCmdExec() { + return new RestartContainerCmdExec(getBaseResource()); + } + + @Override + public CommitCmd.Exec createCommitCmdExec() { + return new CommitCmdExec(getBaseResource()); + } + + @Override + public BuildImageCmd.Exec createBuildImageCmdExec() { + return new BuildImageCmdExec(getBaseResource()); + } + + @Override + public TopContainerCmd.Exec createTopContainerCmdExec() { + return new TopContainerCmdExec(getBaseResource()); + } + + @Override + public TagImageCmd.Exec createTagImageCmdExec() { + return new TagImageCmdExec(getBaseResource()); + } + + @Override + public PauseContainerCmd.Exec createPauseContainerCmdExec() { + return new PauseContainerCmdExec(getBaseResource()); + } + + @Override + public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec() { + return new UnpauseContainerCmdExec(baseResource); + } + + @Override + public EventsCmd.Exec createEventsCmdExec() { + return new EventsCmdExec(getBaseResource()); + } + + @Override + public CgroupContainerCmd.Exec createCgroupContainerCmdExec() { + return new CgroupContainerCmdExec(getBaseResource()); + } + + @Override + public SweepContainerCmd.Exec createSweepContainerCmdExec() { + return new SweepContainerCmdExec(getBaseResource()); + } + + @Override + public MetricContainerCmd.Exec createMetricContainerCmdExec() { + return new MetricContainerCmdExec(getBaseResource()); + } + + @Override + public CreateExecCmd.Exec createCreateExecCmdExec() { + return new CreateExecCmdExec(getBaseResource()); + } + + @Override + public Exec createStartExecCmdExec() { + return new StartExecCmdExec(getBaseResource()); + } + + @Override + public ExecContainerCmd.Exec createExecContainerCmdExec(CreateExecCmd createExecCmd, + StartExecCmd startExecCmd) { + return new ExecContainerCmdExec(createExecCmd, startExecCmd, getBaseResource()); + } + + @Override + public LimitContainerCmd.Exec createLimitContainerCmdExec() { + return new LimitContainerCmdExec(getBaseResource()); + } + + @Override + public void close() throws IOException { + Preconditions.checkNotNull(client, "Factory not initialized. You probably forgot to call init()!"); + client.close(); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/EventsCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/EventsCmdExec.java new file mode 100644 index 00000000..545d7db9 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/EventsCmdExec.java @@ -0,0 +1,87 @@ +package com.github.dockerjava.jaxrs; + +import java.io.InputStream; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.api.command.EventCallback; +import com.github.dockerjava.api.command.EventsCmd; +import com.github.dockerjava.api.model.Event; +import com.google.common.base.Preconditions; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +public class EventsCmdExec extends AbstrDockerCmdExec implements EventsCmd.Exec { + private static final Logger LOGGER = LoggerFactory.getLogger(EventsCmdExec.class); + + public EventsCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected ExecutorService execute(EventsCmd command) { + ExecutorService executorService = Executors.newSingleThreadExecutor(); + + WebTarget webResource = getBaseResource().path("/events") + .queryParam("since", command.getSince()) + .queryParam("until", command.getUntil()); + + LOGGER.trace("GET: {}", webResource); + EventNotifier eventNotifier = EventNotifier.create(command.getEventCallback(), webResource); + executorService.submit(eventNotifier); + return executorService; + } + + private static class EventNotifier implements Callable { + private static final JsonFactory JSON_FACTORY = new JsonFactory(); + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + private final EventCallback eventCallback; + private final WebTarget webTarget; + + private EventNotifier(EventCallback eventCallback, WebTarget webTarget) { + this.eventCallback = eventCallback; + this.webTarget = webTarget; + } + + public static EventNotifier create(EventCallback eventCallback, WebTarget webTarget) { + Preconditions.checkNotNull(eventCallback, "An EventCallback must be provided"); + Preconditions.checkNotNull(webTarget, "An WebTarget must be provided"); + return new EventNotifier(eventCallback, webTarget); + } + + @Override + public Void call() throws Exception { + int numEvents=0; + Response response = null; + try { + response = webTarget.request().get(Response.class); + InputStream inputStream = response.readEntity(InputStream.class); + JsonParser jp = JSON_FACTORY.createParser(inputStream); + while (jp.nextToken() != JsonToken.END_OBJECT && !jp.isClosed()) { + eventCallback.onEvent(OBJECT_MAPPER.readValue(jp, Event.class)); + numEvents++; + } + } + catch(Exception e) { + eventCallback.onException(e); + } + finally { + if (response != null) { + response.close(); + } + } + eventCallback.onCompletion(numEvents); + return null; + } + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/ExecContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/ExecContainerCmdExec.java new file mode 100644 index 00000000..8a78279d --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/ExecContainerCmdExec.java @@ -0,0 +1,39 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.CreateExecCmd; +import com.github.dockerjava.api.command.CreateExecResponse; +import com.github.dockerjava.api.command.ExecContainerCmd; +import com.github.dockerjava.api.command.StartExecCmd; +import com.github.dockerjava.api.model.ExecConfig; +import com.google.common.base.Preconditions; + +public class ExecContainerCmdExec extends AbstrDockerCmdExec implements ExecContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(ExecContainerCmdExec.class); + + private CreateExecCmd createExecCmd; + private StartExecCmd startExecCmd; + + public ExecContainerCmdExec(CreateExecCmd createExecCmd, StartExecCmd startExecCmd, WebTarget baseResource) { + super(baseResource); + Preconditions.checkNotNull(createExecCmd, "execution was not specified"); + Preconditions.checkNotNull(startExecCmd, "execution was not specified"); + this.createExecCmd = createExecCmd; + this.startExecCmd = startExecCmd; + } + + @Override + protected String execute(ExecContainerCmd command) { + LOGGER.trace("ExecContainerCmdExec"); + ExecConfig execConfig = command.getExecConfig(); + CreateExecResponse cer = createExecCmd.withExecConfig(execConfig).withContainerId(command.getContainerId()).exec(); + String execId = cer.getId(); + return startExecCmd.withExecConfig(execConfig).withExecId(execId).exec(); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/InfoCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/InfoCmdExec.java new file mode 100644 index 00000000..aff72fab --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/InfoCmdExec.java @@ -0,0 +1,28 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.InfoCmd; +import com.github.dockerjava.api.model.Info; + +public class InfoCmdExec extends AbstrDockerCmdExec implements InfoCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(InfoCmdExec.class); + + public InfoCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Info execute(InfoCmd command) { + WebTarget webResource = getBaseResource().path("/info"); + + LOGGER.trace("GET: {}", webResource); + return webResource.request().accept(MediaType.APPLICATION_JSON).get(Info.class); } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/InspectContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/InspectContainerCmdExec.java new file mode 100644 index 00000000..664a67c5 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/InspectContainerCmdExec.java @@ -0,0 +1,30 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.InspectContainerCmd; +import com.github.dockerjava.api.command.InspectContainerResponse; + +public class InspectContainerCmdExec extends AbstrDockerCmdExec implements InspectContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(InspectContainerCmdExec.class); + + public InspectContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected InspectContainerResponse execute(InspectContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/json").resolveTemplate("id", command.getContainerId()); + + LOGGER.debug("GET: {}", webResource); + return webResource.request().accept(MediaType.APPLICATION_JSON).get(InspectContainerResponse.class); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/InspectImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/InspectImageCmdExec.java new file mode 100644 index 00000000..78426609 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/InspectImageCmdExec.java @@ -0,0 +1,29 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.InspectImageCmd; +import com.github.dockerjava.api.command.InspectImageResponse; + +public class InspectImageCmdExec extends AbstrDockerCmdExec implements InspectImageCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(InspectImageCmdExec.class); + + public InspectImageCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected InspectImageResponse execute(InspectImageCmd command) { + WebTarget webResource = getBaseResource().path("/images/{id}/json").resolveTemplate("id", command.getImageId()); + + LOGGER.trace("GET: {}", webResource); + return webResource.request().accept(MediaType.APPLICATION_JSON).get(InspectImageResponse.class); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/KillContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/KillContainerCmdExec.java new file mode 100644 index 00000000..28496edc --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/KillContainerCmdExec.java @@ -0,0 +1,36 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.KillContainerCmd; + +public class KillContainerCmdExec extends AbstrDockerCmdExec implements KillContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(KillContainerCmdExec.class); + + public KillContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(KillContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/kill").resolveTemplate("id", command.getContainerId()); + + if(command.getSignal() != null) { + webResource = webResource.queryParam("signal", command.getSignal()); + } + + LOGGER.trace("POST: {}", webResource); + webResource.request().accept(MediaType.APPLICATION_JSON).post(entity(null, MediaType.APPLICATION_JSON)); + + return null; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/LimitContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/LimitContainerCmdExec.java new file mode 100644 index 00000000..b886d4e5 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/LimitContainerCmdExec.java @@ -0,0 +1,31 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.LimitContainerCmd; + +public class LimitContainerCmdExec extends AbstrDockerCmdExec implements LimitContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(LimitContainerCmdExec.class); + + public LimitContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(LimitContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/limit") + .resolveTemplate("id", command.getContainerId()) + .queryParam("saveChanges", command.isSaveChanges() ? "1" : "0"); + LOGGER.trace("POST: {}", webResource); + webResource.request().accept(MediaType.APPLICATION_JSON).post(entity(command.getLimitationConfig(), MediaType.APPLICATION_JSON)); + return null; + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java new file mode 100644 index 00000000..018db9a5 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java @@ -0,0 +1,43 @@ +package com.github.dockerjava.jaxrs; + +import java.util.List; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.ListContainersCmd; +import com.github.dockerjava.api.model.Container; + +public class ListContainersCmdExec extends AbstrDockerCmdExec> implements ListContainersCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(ListContainersCmdExec.class); + + public ListContainersCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected List execute(ListContainersCmd command) { + WebTarget webResource = getBaseResource().path("/containers/json") + .queryParam("all", command.hasShowAllEnabled() ? "1" : "0") + .queryParam("since", command.getSinceId()) + .queryParam("before", command.getBeforeId()) + .queryParam("size", command.hasShowSizeEnabled() ? "1" : "0"); + + if (command.getLimit() >= 0) { + webResource = webResource.queryParam("limit", String.valueOf(command.getLimit())); + } + + LOGGER.trace("GET: {}", webResource); + List containers = webResource.request().accept(MediaType.APPLICATION_JSON).get(new GenericType>() { + }); + LOGGER.trace("Response: {}", containers); + + return containers; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/ListImagesCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/ListImagesCmdExec.java new file mode 100644 index 00000000..5a000a29 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/ListImagesCmdExec.java @@ -0,0 +1,39 @@ +package com.github.dockerjava.jaxrs; + +import java.util.List; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.ListImagesCmd; +import com.github.dockerjava.api.model.Image; + +public class ListImagesCmdExec extends AbstrDockerCmdExec> implements ListImagesCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(ListImagesCmdExec.class); + + public ListImagesCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected List execute(ListImagesCmd command) { + WebTarget webResource = getBaseResource() + .path("/images/json") + .queryParam("filter", command.getFilter()) + .queryParam("all", command.hasShowAllEnabled() ? "1" : "0"); + + LOGGER.trace("GET: {}", webResource); + + List images = webResource.request().accept(MediaType.APPLICATION_JSON).get(new GenericType>() { + }); + LOGGER.trace("Response: {}", images); + + return images; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/LogContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/LogContainerCmdExec.java new file mode 100644 index 00000000..46d25942 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/LogContainerCmdExec.java @@ -0,0 +1,35 @@ +package com.github.dockerjava.jaxrs; + +import java.io.InputStream; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.LogContainerCmd; + +public class LogContainerCmdExec extends AbstrDockerCmdExec implements LogContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(LogContainerCmdExec.class); + + public LogContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected InputStream execute(LogContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/logs") + .resolveTemplate("id", command.getContainerId()) + .queryParam("timestamps", command.hasTimestampsEnabled() ? "1" : "0") + .queryParam("stdout", command.hasStdoutEnabled() ? "1" : "0") + .queryParam("stderr", command.hasStderrEnabled() ? "1" : "0") + .queryParam("follow", command.hasFollowStreamEnabled() ? "1" : "0") + .queryParam("tail", command.getTail() < 0 ? "all" : "" + command.getTail()); + + LOGGER.trace("GET: {}", webResource); + return webResource.request().get(Response.class).readEntity(InputStream.class); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/MetricContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/MetricContainerCmdExec.java new file mode 100644 index 00000000..00b71a81 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/MetricContainerCmdExec.java @@ -0,0 +1,29 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.MetricContainerCmd; +import com.github.dockerjava.api.model.metric.Metric; + +public class MetricContainerCmdExec extends AbstrDockerCmdExec implements MetricContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(MetricContainerCmdExec.class); + + public MetricContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Metric execute(MetricContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/metric").resolveTemplate("id", command.getContainerId()); + LOGGER.trace("GET: {}", webResource); + Metric response = webResource.request().accept(MediaType.APPLICATION_JSON).get(Metric.class); + return response; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/PauseContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/PauseContainerCmdExec.java new file mode 100644 index 00000000..ee84a320 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/PauseContainerCmdExec.java @@ -0,0 +1,35 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.PauseContainerCmd; + +public class PauseContainerCmdExec extends AbstrDockerCmdExec implements PauseContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(PauseContainerCmdExec.class); + + public PauseContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(PauseContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/pause") + .resolveTemplate("id", command.getContainerId()); + + LOGGER.trace("POST: {}", webResource); + webResource.request() + .accept(MediaType.APPLICATION_JSON) + .post(entity(null, MediaType.APPLICATION_JSON), Response.class); + + return null; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/PingCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/PingCmdExec.java new file mode 100644 index 00000000..abfb0f4c --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/PingCmdExec.java @@ -0,0 +1,29 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.PingCmd; + +public class PingCmdExec extends AbstrDockerCmdExec implements PingCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(PingCmdExec.class); + + public PingCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(PingCmd command) { + WebTarget webResource = getBaseResource().path("/_ping"); + + LOGGER.trace("GET: {}", webResource); + webResource.request().get(Response.class); + + return null; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/PullImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/PullImageCmdExec.java new file mode 100644 index 00000000..4ac190be --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/PullImageCmdExec.java @@ -0,0 +1,37 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import java.io.InputStream; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.PullImageCmd; + +public class PullImageCmdExec extends AbstrDockerCmdExec implements PullImageCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(PullImageCmdExec.class); + + public PullImageCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected InputStream execute(PullImageCmd command) { + WebTarget webResource = getBaseResource().path("/images/create") + .queryParam("tag", command.getTag()) + .queryParam("fromImage", command.getRepository()) + .queryParam("registry", command.getRegistry()); + + LOGGER.trace("POST: {}", webResource); + return webResource.request() + .accept(MediaType.APPLICATION_OCTET_STREAM_TYPE) + .post(entity(Response.class, MediaType.APPLICATION_JSON)).readEntity(InputStream.class); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/PushImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/PushImageCmdExec.java new file mode 100644 index 00000000..8d5aabef --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/PushImageCmdExec.java @@ -0,0 +1,44 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import java.io.InputStream; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.PushImageCmd; +import com.github.dockerjava.api.model.AuthConfig; + +public class PushImageCmdExec extends AbstrDockerCmdExec implements PushImageCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(PushImageCmdExec.class); + + public PushImageCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected InputStream execute(PushImageCmd command) { + WebTarget webResource = getBaseResource().path("/images/" + name(command) + "/push"); + + final String registryAuth = registryAuth(command.getAuthConfig()); + LOGGER.trace("POST: {}", webResource); + return webResource + .request() + .header("X-Registry-Auth", registryAuth) + .accept(MediaType.APPLICATION_JSON) + .post(entity(Response.class, MediaType.APPLICATION_JSON)).readEntity(InputStream.class); + } + + private String name(PushImageCmd command) { + String name = command.getName(); + AuthConfig authConfig = command.getAuthConfig(); + return name.contains("/") ? name : authConfig.getUsername(); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/RemoveContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/RemoveContainerCmdExec.java new file mode 100644 index 00000000..a4d81b17 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/RemoveContainerCmdExec.java @@ -0,0 +1,33 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.RemoveContainerCmd; + +public class RemoveContainerCmdExec extends AbstrDockerCmdExec implements RemoveContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(RemoveContainerCmdExec.class); + + public RemoveContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(RemoveContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/" + command.getContainerId()) + .queryParam("v", command.hasRemoveVolumesEnabled() ? "1" : "0") + .queryParam("force", command.hasForceEnabled() ? "1" : "0") + .queryParam("checkDevice", command.hasCheckDevice() ? "1" : "0"); + + LOGGER.trace("DELETE: {}", webResource); + String response = webResource.request().accept(MediaType.APPLICATION_JSON).delete(String.class); + LOGGER.trace("Response: {}", response); + + return null; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/RemoveImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/RemoveImageCmdExec.java new file mode 100644 index 00000000..54fb327b --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/RemoveImageCmdExec.java @@ -0,0 +1,31 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.RemoveImageCmd; + +public class RemoveImageCmdExec extends AbstrDockerCmdExec implements RemoveImageCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(RemoveImageCmdExec.class); + + public RemoveImageCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(RemoveImageCmd command) { + WebTarget webResource = getBaseResource().path("/images/" + command.getImageId()) + .queryParam("force", command.hasForceEnabled() ? "1" : "0") + .queryParam("noprune", command.hasNoPruneEnabled() ? "1" : "0"); + + LOGGER.trace("DELETE: {}", webResource); + webResource.request().delete(Response.class); + + return null; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/RestartContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/RestartContainerCmdExec.java new file mode 100644 index 00000000..fe544f13 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/RestartContainerCmdExec.java @@ -0,0 +1,33 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.RestartContainerCmd; + +public class RestartContainerCmdExec extends AbstrDockerCmdExec implements RestartContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(RestartContainerCmdExec.class); + + public RestartContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(RestartContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/restart") + .resolveTemplate("id", command.getContainerId()) + .queryParam("t", String.valueOf(command.getTimeout())); + + LOGGER.trace("POST: {}", webResource); + webResource.request().accept(MediaType.APPLICATION_JSON).post(entity(null, MediaType.APPLICATION_JSON_TYPE)); + + return null; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/SearchImagesCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/SearchImagesCmdExec.java new file mode 100644 index 00000000..a7b6ddbc --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/SearchImagesCmdExec.java @@ -0,0 +1,32 @@ +package com.github.dockerjava.jaxrs; + +import java.util.List; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.GenericType; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.SearchImagesCmd; +import com.github.dockerjava.api.model.SearchItem; + +public class SearchImagesCmdExec extends AbstrDockerCmdExec> implements SearchImagesCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(SearchImagesCmdExec.class); + + public SearchImagesCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected List execute(SearchImagesCmd command) { + WebTarget webResource = getBaseResource().path("/images/search").queryParam("term", command.getTerm()); + + LOGGER.trace("GET: {}", webResource); + return webResource.request().accept(MediaType.APPLICATION_JSON).get(new GenericType>() { + }); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/StartContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/StartContainerCmdExec.java new file mode 100644 index 00000000..8a2c09a4 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/StartContainerCmdExec.java @@ -0,0 +1,32 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.StartContainerCmd; + +public class StartContainerCmdExec extends AbstrDockerCmdExec implements StartContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(StartContainerCmdExec.class); + + public StartContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(StartContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/start") + .resolveTemplate("id", command.getContainerId()); + + LOGGER.trace("POST: {}", webResource); + webResource.request().accept(MediaType.APPLICATION_JSON).post(entity(command, MediaType.APPLICATION_JSON)); + + return null; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/StartExecCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/StartExecCmdExec.java new file mode 100644 index 00000000..d8e98f8a --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/StartExecCmdExec.java @@ -0,0 +1,37 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.StartExecCmd; + +public class StartExecCmdExec extends AbstrDockerCmdExec implements StartExecCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(StartExecCmdExec.class); + + public StartExecCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected String execute(StartExecCmd command) { + WebTarget webResource = getBaseResource().path("/exec/{id}/start").resolveTemplate("id", command.getExecId()); + + LOGGER.trace("POST: {} ", webResource); + String response = webResource.request().accept(MediaType.APPLICATION_JSON) + .post(entity(command.getExecConfig(), MediaType.APPLICATION_JSON), String.class); + + // TODO find a better way to handle it + // The starting eight characters are always 1,0,0,0,0,0,0,0,(length of content), remove it + if (response != null && response.length() > 8) { + response = response.substring(8); + } + return response; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/StopContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/StopContainerCmdExec.java new file mode 100644 index 00000000..337c71b2 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/StopContainerCmdExec.java @@ -0,0 +1,32 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.StopContainerCmd; + +public class StopContainerCmdExec extends AbstrDockerCmdExec implements StopContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(StopContainerCmdExec.class); + + public StopContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(StopContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/stop") + .resolveTemplate("id", command.getContainerId()) + .queryParam("t", String.valueOf(command.getTimeout())); + + LOGGER.trace("POST: {}", webResource); + webResource.request().accept(MediaType.APPLICATION_JSON).post(entity(null, MediaType.APPLICATION_JSON)); + + return null; + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/SweepContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/SweepContainerCmdExec.java new file mode 100644 index 00000000..5e12f5d3 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/SweepContainerCmdExec.java @@ -0,0 +1,30 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.SweepContainerCmd; + +public class SweepContainerCmdExec extends AbstrDockerCmdExec implements SweepContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(SweepContainerCmdExec.class); + + public SweepContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(SweepContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/sweep").resolveTemplate("id", command.getContainerId()); + LOGGER.trace("POST: {}", webResource); + webResource.request().accept(MediaType.APPLICATION_JSON).post(entity(null, MediaType.APPLICATION_JSON)); + return null; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/TagImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/TagImageCmdExec.java new file mode 100644 index 00000000..d8545e33 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/TagImageCmdExec.java @@ -0,0 +1,37 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.TagImageCmd; + +public class TagImageCmdExec extends AbstrDockerCmdExec implements TagImageCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(TagImageCmdExec.class); + + public TagImageCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(TagImageCmd command) { + WebTarget webResource = getBaseResource().path("/images/" + command.getImageId() + "/tag") + .queryParam("repo", command.getRepository()) + .queryParam("tag", command.getTag()) + .queryParam("force", command.hasForceEnabled() ? "1" : "0"); + + LOGGER.trace("POST: {}", webResource); + webResource.request().post(entity(null, MediaType.APPLICATION_JSON), Response.class); + return null; + } + + + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/TopContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/TopContainerCmdExec.java new file mode 100644 index 00000000..55c431cc --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/TopContainerCmdExec.java @@ -0,0 +1,34 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.apache.commons.lang.StringUtils; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.TopContainerCmd; +import com.github.dockerjava.api.command.TopContainerResponse; + +public class TopContainerCmdExec extends AbstrDockerCmdExec implements TopContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(TopContainerCmdExec.class); + + public TopContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected TopContainerResponse execute(TopContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/top") + .resolveTemplate("id", command.getContainerId()); + + if(!StringUtils.isEmpty(command.getPsArgs())) + webResource = webResource.queryParam("ps_args", command.getPsArgs()); + + LOGGER.trace("GET: {}", webResource); + return webResource.request().accept(MediaType.APPLICATION_JSON).get(TopContainerResponse.class); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/UnpauseContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/UnpauseContainerCmdExec.java new file mode 100644 index 00000000..361f9adc --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/UnpauseContainerCmdExec.java @@ -0,0 +1,33 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.UnpauseContainerCmd; + +public class UnpauseContainerCmdExec extends AbstrDockerCmdExec implements UnpauseContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(UnpauseContainerCmdExec.class); + + public UnpauseContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Void execute(UnpauseContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/unpause") + .resolveTemplate("id", command.getContainerId()); + + LOGGER.trace("POST: {}", webResource); + webResource.request().accept(MediaType.APPLICATION_JSON) + .post(Entity.entity(Response.class, MediaType.APPLICATION_JSON)); + + return null; + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/VersionCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/VersionCmdExec.java new file mode 100644 index 00000000..9b4ac817 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/VersionCmdExec.java @@ -0,0 +1,30 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.VersionCmd; +import com.github.dockerjava.api.model.Version; + +public class VersionCmdExec extends AbstrDockerCmdExec implements VersionCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(VersionCmdExec.class); + + public VersionCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Version execute(VersionCmd command) { + WebTarget webResource = getBaseResource().path("/version"); + + LOGGER.trace("GET: {}", webResource); + return webResource.request().accept(MediaType.APPLICATION_JSON) + .get(Version.class); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/WaitContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/WaitContainerCmdExec.java new file mode 100644 index 00000000..e6f95586 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/WaitContainerCmdExec.java @@ -0,0 +1,35 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.github.dockerjava.api.command.WaitContainerCmd; + +public class WaitContainerCmdExec extends AbstrDockerCmdExec implements WaitContainerCmd.Exec { + + private static final Logger LOGGER = LoggerFactory + .getLogger(WaitContainerCmdExec.class); + + public WaitContainerCmdExec(WebTarget baseResource) { + super(baseResource); + } + + @Override + protected Integer execute(WaitContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/wait") + .resolveTemplate("id", command.getContainerId()); + + LOGGER.trace("POST: {}", webResource); + ObjectNode ObjectNode = webResource.request().accept(MediaType.APPLICATION_JSON) + .post(entity(null, MediaType.TEXT_PLAIN), ObjectNode.class); + + return ObjectNode.get("StatusCode").asInt(); + } + +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/util/CommandUtils.java b/src/main/java/com/github/dockerjava/jaxrs/util/CommandUtils.java new file mode 100644 index 00000000..93117fc1 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/util/CommandUtils.java @@ -0,0 +1,52 @@ +package com.github.dockerjava.jaxrs.util; + +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.StartContainerCmd; +import com.github.dockerjava.api.model.CreateContainerConfig; +import com.github.dockerjava.api.model.StartContainerConfig; + +public class CommandUtils { + + public static void popuateCreateContainerCmd(CreateContainerCmd cmd, CreateContainerConfig config) { + cmd.withHostName(config.getHostName()) + .withUser(config.getUser()) + .withMemoryLimit(config.getMemoryLimit()) + .withMemorySwap(config.getMemorySwap()) + .withCpuShares(config.getCpuShares()) + .withCpuset(config.getCpuset()) + .withAttachStdin(config.isAttachStdin()) + .withAttachStdout(config.isAttachStdout()) + .withAttachStderr(config.isAttachStderr()) + .withPortSpecs(config.getPortSpecs()) + .withTty(config.isTty()) + .withStdinOpen(config.isStdInOnce()) + .withStdInOnce(config.isStdInOnce()) + .withEnv(config.getEnv().toArray(new String[config.getEnv().size()])) + .withCmd(config.getCmd()) + .withDns(config.getDns()) + .withImage(config.getImage()) + .withVolumes(config.getVolumes()) + .withVolumesFrom(config.getVolumesFrom()) + .withWorkingDir(config.getWorkingDir()) + .withDisableNetwork(config.isDisableNetwork()) + .withExposedPorts(config.getExposedPorts()) + .withIp(config.getIp()); + } + + public static void popuateStartContainerCmd(StartContainerCmd cmd, StartContainerConfig config) { + cmd.withBinds(config.getBinds()) + .withLinks(config.getLinks()) + .withLxcConf(config.getLxcConf()) + .withPortBindings(config.getPortBindings()) + .withPublishAllPorts(config.isPublishAllPorts()) + .withPrivileged(config.isPrivileged()) + .withDns(config.getDns()) + .withDnsSearch(config.getDnsSearch()) + .withVolumesFrom(config.getVolumesFrom()) + .withNetworkMode(config.getNetworkMode()) + .withDevices(config.getDevices()) + .withRestartPolicy(config.getRestartPolicy()) + .withCapAdd(config.getCapAdd()) + .withCapDrop(config.getCapDrop()); + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/util/HostConfigUtils.java b/src/main/java/com/github/dockerjava/jaxrs/util/HostConfigUtils.java new file mode 100644 index 00000000..fadb951b --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/util/HostConfigUtils.java @@ -0,0 +1,39 @@ +package com.github.dockerjava.jaxrs.util; + +import com.github.dockerjava.api.command.InspectContainerResponse.HostConfig; +import com.github.dockerjava.api.model.Bind; +import com.github.dockerjava.api.model.Link; +import com.github.dockerjava.api.model.StartContainerConfig; + +public class HostConfigUtils { + public static StartContainerConfig convertToStartContainerConfig(HostConfig hostConfig) { + if (hostConfig == null) { + return null; + } + StartContainerConfig startContainerConfig = new StartContainerConfig(); + startContainerConfig.setDns(hostConfig.getDns()); + startContainerConfig.setLxcConf(hostConfig.getLxcConf()); + startContainerConfig.setPortBindings(hostConfig.getPortBindings()); + startContainerConfig.setPrivileged(hostConfig.isPrivileged()); + startContainerConfig.setPublishAllPorts(hostConfig.isPublishAllPorts()); + startContainerConfig.setVolumesFrom(hostConfig.getVolumesFrom()); + + if (hostConfig.getBinds() != null) { + Bind[] binds = new Bind[hostConfig.getBinds().length]; + for (int i = 0; i < hostConfig.getBinds().length; i++) { + binds[i] = Bind.parse(hostConfig.getBinds()[i]); + } + startContainerConfig.setBinds(binds); + } + + if (hostConfig.getLinks() != null) { + Link[] links = new Link[hostConfig.getLinks().length]; + for (int i = 0; i < hostConfig.getLinks().length; i++) { + links[i] = Link.parse(hostConfig.getLinks()[i]); + } + startContainerConfig.setLinks(links); + } + + return startContainerConfig; + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/util/JsonClientFilter.java b/src/main/java/com/github/dockerjava/jaxrs/util/JsonClientFilter.java new file mode 100644 index 00000000..e0eaa4a4 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/util/JsonClientFilter.java @@ -0,0 +1,25 @@ +package com.github.dockerjava.jaxrs.util; + + +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.client.ClientResponseContext; +import javax.ws.rs.client.ClientResponseFilter; +import javax.ws.rs.core.MediaType; +import java.io.IOException; + +/** + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + * + */ +public class JsonClientFilter implements ClientResponseFilter { + + + @Override + public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { + if (responseContext.getMediaType() != null && responseContext.getMediaType().isCompatible(MediaType.TEXT_PLAIN_TYPE)) { + String newContentType = "application/json" + responseContext.getMediaType().toString().substring(10); + responseContext.getHeaders().putSingle("Content-Type", newContentType); + } + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/util/ResponseStatusExceptionFilter.java b/src/main/java/com/github/dockerjava/jaxrs/util/ResponseStatusExceptionFilter.java new file mode 100644 index 00000000..102781a2 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/util/ResponseStatusExceptionFilter.java @@ -0,0 +1,96 @@ +package com.github.dockerjava.jaxrs.util; + +import java.io.EOFException; +import java.io.IOException; +import java.nio.charset.Charset; + +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.client.ClientResponseContext; +import javax.ws.rs.client.ClientResponseFilter; +import javax.ws.rs.core.MediaType; + +import org.apache.commons.io.IOUtils; + +import com.github.dockerjava.api.BadRequestException; +import com.github.dockerjava.api.ConflictException; +import com.github.dockerjava.api.DeviceIsBusyException; +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.InternalServerErrorException; +import com.github.dockerjava.api.NotAcceptableException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.NotModifiedException; +import com.github.dockerjava.api.UnauthorizedException; + +/** + * This {@link ClientResponseFilter} implementation detects http status codes and throws {@link DockerException}s + * + * @author marcus + * + */ +public class ResponseStatusExceptionFilter implements ClientResponseFilter { + + + @Override + public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException { + int status = responseContext.getStatus(); + switch (status) { + case 200: + case 201: + case 204: + return; + case 304: + throw new NotModifiedException(getBodyAsMessage(responseContext)); + case 400: + throw new BadRequestException(getBodyAsMessage(responseContext)); + case 401: + throw new UnauthorizedException(getBodyAsMessage(responseContext)); + case 404: + throw new NotFoundException(getBodyAsMessage(responseContext)); + case 406: + throw new NotAcceptableException(getBodyAsMessage(responseContext)); + case 409: + throw new ConflictException(getBodyAsMessage(responseContext)); + case 500: + throw new InternalServerErrorException(getBodyAsMessage(responseContext)); + case 599: + throw new DeviceIsBusyException(getBodyAsMessage(responseContext)); + default: + throw new DockerException(getBodyAsMessage(responseContext), status); + } + } + + public String getBodyAsMessage(ClientResponseContext responseContext) + throws IOException { + if (responseContext.hasEntity()) { + int contentLength = responseContext.getLength(); + if (contentLength != -1) { + byte[] buffer = new byte[contentLength]; + try { + IOUtils.readFully(responseContext.getEntityStream(), buffer); + } + catch (EOFException e) { + return null; + } + Charset charset = null; + MediaType mediaType = responseContext.getMediaType(); + if (mediaType != null) { + String charsetName = mediaType.getParameters().get("charset"); + if (charsetName != null) { + try { + charset = Charset.forName(charsetName); + } + catch (Exception e) { + //Do noting... + } + } + } + if (charset == null) { + charset = Charset.defaultCharset(); + } + String message = new String(buffer, charset); + return message; + } + } + return null; + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/util/SelectiveLoggingFilter.java b/src/main/java/com/github/dockerjava/jaxrs/util/SelectiveLoggingFilter.java new file mode 100644 index 00000000..7f7e06c7 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/util/SelectiveLoggingFilter.java @@ -0,0 +1,43 @@ +package com.github.dockerjava.jaxrs.util; + +import java.io.IOException; +import java.util.Set; +import java.util.logging.Logger; + +import javax.ws.rs.client.ClientRequestContext; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; + +import com.google.common.collect.ImmutableSet; + +import org.glassfish.jersey.filter.LoggingFilter; + +/** + * A version of the logging filter that will avoid trying to log entities which can cause + * issues with the console. + * + * @author sfitts + * + */ +public class SelectiveLoggingFilter extends LoggingFilter { + + private static final Set SKIPPED_CONTENT = ImmutableSet.builder() + .add(MediaType.APPLICATION_OCTET_STREAM) + .add("application/tar") + .build(); + + public SelectiveLoggingFilter(Logger logger, boolean b) { + super(logger, b); + } + + @Override + public void filter(ClientRequestContext context) throws IOException { + // Unless the content type is in the list of those we want to ellide, then just have + // our super-class handle things. + Object contentType = context.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE); + if (contentType == null || !SKIPPED_CONTENT.contains(contentType.toString())) { + super.filter(context); + } + } + +} diff --git a/src/main/java/com/google/common/base/Preconditions.java b/src/main/java/com/google/common/base/Preconditions.java deleted file mode 100644 index 6a15fb4d..00000000 --- a/src/main/java/com/google/common/base/Preconditions.java +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright (C) 2007 The Guava Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.google.common.base; - - -import java.util.NoSuchElementException; - -/** - * Simple static methods to be called at the start of your own methods to verify - * correct arguments and state. This allows constructs such as - *
- *     if (count <= 0) {
- *       throw new IllegalArgumentException("must be positive: " + count);
- *     }
- * - * to be replaced with the more compact - *
- *     checkArgument(count > 0, "must be positive: %s", count);
- * - * Note that the sense of the expression is inverted; with {@code Preconditions} - * you declare what you expect to be true, just as you do with an - * - * {@code assert} or a JUnit {@code assertTrue} call. - * - *

Warning: only the {@code "%s"} specifier is recognized as a - * placeholder in these messages, not the full range of {@link - * String#format(String, Object[])} specifiers. - * - *

Take care not to confuse precondition checking with other similar types - * of checks! Precondition exceptions -- including those provided here, but also - * {@link IndexOutOfBoundsException}, {@link NoSuchElementException}, {@link - * UnsupportedOperationException} and others -- are used to signal that the - * calling method has made an error. This tells the caller that it should - * not have invoked the method when it did, with the arguments it did, or - * perhaps ever. Postcondition or other invariant failures should not throw - * these types of exceptions. - * - *

See the Guava User Guide on - * using {@code Preconditions}. - * - * @author Kevin Bourrillion - * @since 2.0 (imported from Google Collections Library) - */ -public final class Preconditions { - private Preconditions() {} - - /** - * Ensures the truth of an expression involving one or more parameters to the - * calling method. - * - * @param expression a boolean expression - * @throws IllegalArgumentException if {@code expression} is false - */ - public static void checkArgument(boolean expression) { - if (!expression) { - throw new IllegalArgumentException(); - } - } - - /** - * Ensures the truth of an expression involving one or more parameters to the - * calling method. - * - * @param expression a boolean expression - * @param errorMessage the exception message to use if the check fails; will - * be converted to a string using {@link String#valueOf(Object)} - * @throws IllegalArgumentException if {@code expression} is false - */ - public static void checkArgument( - boolean expression, Object errorMessage) { - if (!expression) { - throw new IllegalArgumentException(String.valueOf(errorMessage)); - } - } - - /** - * Ensures the truth of an expression involving one or more parameters to the - * calling method. - * - * @param expression a boolean expression - * @param errorMessageTemplate a template for the exception message should the - * check fail. The message is formed by replacing each {@code %s} - * placeholder in the template with an argument. These are matched by - * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc. - * Unmatched arguments will be appended to the formatted message in square - * braces. Unmatched placeholders will be left as-is. - * @param errorMessageArgs the arguments to be substituted into the message - * template. Arguments are converted to strings using - * {@link String#valueOf(Object)}. - * @throws IllegalArgumentException if {@code expression} is false - * @throws NullPointerException if the check fails and either {@code - * errorMessageTemplate} or {@code errorMessageArgs} is null (don't let - * this happen) - */ - public static void checkArgument(boolean expression, - String errorMessageTemplate, - Object... errorMessageArgs) { - if (!expression) { - throw new IllegalArgumentException( - format(errorMessageTemplate, errorMessageArgs)); - } - } - - /** - * Ensures the truth of an expression involving the state of the calling - * instance, but not involving any parameters to the calling method. - * - * @param expression a boolean expression - * @throws IllegalStateException if {@code expression} is false - */ - public static void checkState(boolean expression) { - if (!expression) { - throw new IllegalStateException(); - } - } - - /** - * Ensures the truth of an expression involving the state of the calling - * instance, but not involving any parameters to the calling method. - * - * @param expression a boolean expression - * @param errorMessage the exception message to use if the check fails; will - * be converted to a string using {@link String#valueOf(Object)} - * @throws IllegalStateException if {@code expression} is false - */ - public static void checkState( - boolean expression, Object errorMessage) { - if (!expression) { - throw new IllegalStateException(String.valueOf(errorMessage)); - } - } - - /** - * Ensures the truth of an expression involving the state of the calling - * instance, but not involving any parameters to the calling method. - * - * @param expression a boolean expression - * @param errorMessageTemplate a template for the exception message should the - * check fail. The message is formed by replacing each {@code %s} - * placeholder in the template with an argument. These are matched by - * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc. - * Unmatched arguments will be appended to the formatted message in square - * braces. Unmatched placeholders will be left as-is. - * @param errorMessageArgs the arguments to be substituted into the message - * template. Arguments are converted to strings using - * {@link String#valueOf(Object)}. - * @throws IllegalStateException if {@code expression} is false - * @throws NullPointerException if the check fails and either {@code - * errorMessageTemplate} or {@code errorMessageArgs} is null (don't let - * this happen) - */ - public static void checkState(boolean expression, - String errorMessageTemplate, - Object... errorMessageArgs) { - if (!expression) { - throw new IllegalStateException( - format(errorMessageTemplate, errorMessageArgs)); - } - } - - /** - * Ensures that an object reference passed as a parameter to the calling - * method is not null. - * - * @param reference an object reference - * @return the non-null reference that was validated - * @throws NullPointerException if {@code reference} is null - */ - public static T checkNotNull(T reference) { - if (reference == null) { - throw new NullPointerException(); - } - return reference; - } - - /** - * Ensures that an object reference passed as a parameter to the calling - * method is not null. - * - * @param reference an object reference - * @param errorMessage the exception message to use if the check fails; will - * be converted to a string using {@link String#valueOf(Object)} - * @return the non-null reference that was validated - * @throws NullPointerException if {@code reference} is null - */ - public static T checkNotNull(T reference, Object errorMessage) { - if (reference == null) { - throw new NullPointerException(String.valueOf(errorMessage)); - } - return reference; - } - - /** - * Ensures that an object reference passed as a parameter to the calling - * method is not null. - * - * @param reference an object reference - * @param errorMessageTemplate a template for the exception message should the - * check fail. The message is formed by replacing each {@code %s} - * placeholder in the template with an argument. These are matched by - * position - the first {@code %s} gets {@code errorMessageArgs[0]}, etc. - * Unmatched arguments will be appended to the formatted message in square - * braces. Unmatched placeholders will be left as-is. - * @param errorMessageArgs the arguments to be substituted into the message - * template. Arguments are converted to strings using - * {@link String#valueOf(Object)}. - * @return the non-null reference that was validated - * @throws NullPointerException if {@code reference} is null - */ - public static T checkNotNull(T reference, - String errorMessageTemplate, - Object... errorMessageArgs) { - if (reference == null) { - // If either of these parameters is null, the right thing happens anyway - throw new NullPointerException( - format(errorMessageTemplate, errorMessageArgs)); - } - return reference; - } - - /* - * All recent hotspots (as of 2009) *really* like to have the natural code - * - * if (guardExpression) { - * throw new BadException(messageExpression); - * } - * - * refactored so that messageExpression is moved to a separate - * String-returning method. - * - * if (guardExpression) { - * throw new BadException(badMsg(...)); - * } - * - * The alternative natural refactorings into void or Exception-returning - * methods are much slower. This is a big deal - we're talking factors of - * 2-8 in microbenchmarks, not just 10-20%. (This is a hotspot optimizer - * bug, which should be fixed, but that's a separate, big project). - * - * The coding pattern above is heavily used in java.util, e.g. in ArrayList. - * There is a RangeCheckMicroBenchmark in the JDK that was used to test this. - * - * But the methods in this class want to throw different exceptions, - * depending on the args, so it appears that this pattern is not directly - * applicable. But we can use the ridiculous, devious trick of throwing an - * exception in the middle of the construction of another exception. - * Hotspot is fine with that. - */ - - /** - * Ensures that {@code index} specifies a valid element in an array, - * list or string of size {@code size}. An element index may range from zero, - * inclusive, to {@code size}, exclusive. - * - * @param index a user-supplied index identifying an element of an array, list - * or string - * @param size the size of that array, list or string - * @return the value of {@code index} - * @throws IndexOutOfBoundsException if {@code index} is negative or is not - * less than {@code size} - * @throws IllegalArgumentException if {@code size} is negative - */ - public static int checkElementIndex(int index, int size) { - return checkElementIndex(index, size, "index"); - } - - /** - * Ensures that {@code index} specifies a valid element in an array, - * list or string of size {@code size}. An element index may range from zero, - * inclusive, to {@code size}, exclusive. - * - * @param index a user-supplied index identifying an element of an array, list - * or string - * @param size the size of that array, list or string - * @param desc the text to use to describe this index in an error message - * @return the value of {@code index} - * @throws IndexOutOfBoundsException if {@code index} is negative or is not - * less than {@code size} - * @throws IllegalArgumentException if {@code size} is negative - */ - public static int checkElementIndex( - int index, int size, String desc) { - // Carefully optimized for execution by hotspot (explanatory comment above) - if (index < 0 || index >= size) { - throw new IndexOutOfBoundsException(badElementIndex(index, size, desc)); - } - return index; - } - - private static String badElementIndex(int index, int size, String desc) { - if (index < 0) { - return format("%s (%s) must not be negative", desc, index); - } else if (size < 0) { - throw new IllegalArgumentException("negative size: " + size); - } else { // index >= size - return format("%s (%s) must be less than size (%s)", desc, index, size); - } - } - - /** - * Ensures that {@code index} specifies a valid position in an array, - * list or string of size {@code size}. A position index may range from zero - * to {@code size}, inclusive. - * - * @param index a user-supplied index identifying a position in an array, list - * or string - * @param size the size of that array, list or string - * @return the value of {@code index} - * @throws IndexOutOfBoundsException if {@code index} is negative or is - * greater than {@code size} - * @throws IllegalArgumentException if {@code size} is negative - */ - public static int checkPositionIndex(int index, int size) { - return checkPositionIndex(index, size, "index"); - } - - /** - * Ensures that {@code index} specifies a valid position in an array, - * list or string of size {@code size}. A position index may range from zero - * to {@code size}, inclusive. - * - * @param index a user-supplied index identifying a position in an array, list - * or string - * @param size the size of that array, list or string - * @param desc the text to use to describe this index in an error message - * @return the value of {@code index} - * @throws IndexOutOfBoundsException if {@code index} is negative or is - * greater than {@code size} - * @throws IllegalArgumentException if {@code size} is negative - */ - public static int checkPositionIndex( - int index, int size, String desc) { - // Carefully optimized for execution by hotspot (explanatory comment above) - if (index < 0 || index > size) { - throw new IndexOutOfBoundsException(badPositionIndex(index, size, desc)); - } - return index; - } - - private static String badPositionIndex(int index, int size, String desc) { - if (index < 0) { - return format("%s (%s) must not be negative", desc, index); - } else if (size < 0) { - throw new IllegalArgumentException("negative size: " + size); - } else { // index > size - return format("%s (%s) must not be greater than size (%s)", - desc, index, size); - } - } - - /** - * Ensures that {@code start} and {@code end} specify a valid positions - * in an array, list or string of size {@code size}, and are in order. A - * position index may range from zero to {@code size}, inclusive. - * - * @param start a user-supplied index identifying a starting position in an - * array, list or string - * @param end a user-supplied index identifying a ending position in an array, - * list or string - * @param size the size of that array, list or string - * @throws IndexOutOfBoundsException if either index is negative or is - * greater than {@code size}, or if {@code end} is less than {@code start} - * @throws IllegalArgumentException if {@code size} is negative - */ - public static void checkPositionIndexes(int start, int end, int size) { - // Carefully optimized for execution by hotspot (explanatory comment above) - if (start < 0 || end < start || end > size) { - throw new IndexOutOfBoundsException(badPositionIndexes(start, end, size)); - } - } - - private static String badPositionIndexes(int start, int end, int size) { - if (start < 0 || start > size) { - return badPositionIndex(start, size, "start index"); - } - if (end < 0 || end > size) { - return badPositionIndex(end, size, "end index"); - } - // end < start - return format("end index (%s) must not be less than start index (%s)", - end, start); - } - - /** - * Substitutes each {@code %s} in {@code template} with an argument. These - * are matched by position - the first {@code %s} gets {@code args[0]}, etc. - * If there are more arguments than placeholders, the unmatched arguments will - * be appended to the end of the formatted message in square braces. - * - * @param template a non-null string containing 0 or more {@code %s} - * placeholders. - * @param args the arguments to be substituted into the message - * template. Arguments are converted to strings using - * {@link String#valueOf(Object)}. Arguments can be null. - */ - static String format(String template, Object... args) { - template = String.valueOf(template); // null -> "null" - - // start substituting the arguments into the '%s' placeholders - StringBuilder builder = new StringBuilder( - template.length() + 16 * args.length); - int templateStart = 0; - int i = 0; - while (i < args.length) { - int placeholderStart = template.indexOf("%s", templateStart); - if (placeholderStart == -1) { - break; - } - builder.append(template.substring(templateStart, placeholderStart)); - builder.append(args[i++]); - templateStart = placeholderStart + 2; - } - builder.append(template.substring(templateStart)); - - // if we run out of placeholders, append the extra args in square braces - if (i < args.length) { - builder.append(" ["); - builder.append(args[i++]); - while (i < args.length) { - builder.append(", "); - builder.append(args[i++]); - } - builder.append(']'); - } - - return builder.toString(); - } -} diff --git a/src/main/java/com/kpelykh/docker/client/Config.java b/src/main/java/com/kpelykh/docker/client/Config.java deleted file mode 100644 index f6e59d76..00000000 --- a/src/main/java/com/kpelykh/docker/client/Config.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.kpelykh.docker.client; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.net.URI; -import java.util.Properties; - -class Config { - URI url; - String version, username, password, email; - - private Config() { - } - - static Config createConfig() throws DockerException { - final Properties p = new Properties(); - - try { - p.load(Config.class.getResourceAsStream("/docker.io.properties")); - } catch (IOException e) { - throw new DockerException(e); - } - - final File file = new File(System.getProperty("user.home"), ".docker.io.properties"); - - if (file.isFile()) { - try { - final FileInputStream in = new FileInputStream(file); - try { - p.load(in); - } finally { - in.close(); - } - } catch (IOException e) { - throw new DockerException(e); - } - } - - for (String s : new String[]{"url", "version", "username", "password", "email"}) { - final String key = "docker.io." + s; - if (System.getProperties().keySet().contains(key)) { - p.setProperty(key, System.getProperty(key)); - } - } - - final Config c = new Config(); - - c.url = URI.create(p.getProperty("docker.io.url")); - c.version = p.getProperty("docker.io.version"); - c.username = p.getProperty("docker.io.username"); - c.password = p.getProperty("docker.io.password"); - c.email = p.getProperty("docker.io.email"); - - return c; - } -} diff --git a/src/main/java/com/kpelykh/docker/client/DockerClient.java b/src/main/java/com/kpelykh/docker/client/DockerClient.java deleted file mode 100644 index 101d7209..00000000 --- a/src/main/java/com/kpelykh/docker/client/DockerClient.java +++ /dev/null @@ -1,954 +0,0 @@ -package com.kpelykh.docker.client; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.node.ObjectNode; -import com.google.common.base.Preconditions; -import com.kpelykh.docker.client.model.*; -import com.kpelykh.docker.client.utils.CompressArchiveUtil; -import com.kpelykh.docker.client.utils.JsonClientFilter; -import com.sun.jersey.api.client.*; -import com.sun.jersey.api.client.WebResource.Builder; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.api.client.filter.LoggingFilter; -import com.sun.jersey.client.apache4.ApacheHttpClient4; -import com.sun.jersey.client.apache4.ApacheHttpClient4Handler; -import com.sun.jersey.core.util.MultivaluedMapImpl; - -import org.apache.commons.codec.binary.Base64; -import org.apache.commons.io.FileUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.LineIterator; -import org.apache.commons.lang.StringUtils; -import org.apache.http.client.HttpClient; -import org.apache.http.conn.scheme.PlainSocketFactory; -import org.apache.http.conn.scheme.Scheme; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.conn.ssl.SSLSocketFactory; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.impl.conn.PoolingClientConnectionManager; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import static org.apache.commons.io.IOUtils.closeQuietly; - -/** - * @author Konstantin Pelykh (kpelykh@gmail.com) - */ -public class DockerClient { - - private static final Logger LOGGER = LoggerFactory.getLogger(DockerClient.class); - - private Client client; - private String restEndpointUrl; - private AuthConfig authConfig; - - public DockerClient() throws DockerException { - this(Config.createConfig()); - } - - public DockerClient(String serverUrl) throws DockerException { - this(configWithServerUrl(serverUrl)); - } - - private static Config configWithServerUrl(String serverUrl) throws DockerException { - final Config c = Config.createConfig(); - c.url = URI.create(serverUrl); - return c; - } - - private DockerClient(Config config) { - restEndpointUrl = config.url + "/v" + config.version; - ClientConfig clientConfig = new DefaultClientConfig(); - //clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); - - SchemeRegistry schemeRegistry = new SchemeRegistry(); - schemeRegistry.register(new Scheme("http", config.url.getPort(), PlainSocketFactory.getSocketFactory())); - schemeRegistry.register(new Scheme("https", 443, SSLSocketFactory.getSocketFactory())); - - PoolingClientConnectionManager cm = new PoolingClientConnectionManager(schemeRegistry); - // Increase max total connection - cm.setMaxTotal(1000); - // Increase default max connection per route - cm.setDefaultMaxPerRoute(1000); - - HttpClient httpClient = new DefaultHttpClient(cm); - client = new ApacheHttpClient4(new ApacheHttpClient4Handler(httpClient, null, false), clientConfig); - - client.setReadTimeout(10000); - //Experimental support for unix sockets: - //client = new UnixSocketClient(clientConfig); - - client.addFilter(new JsonClientFilter()); - client.addFilter(new LoggingFilter()); - } - - public void setCredentials(String username, String password, String email) { - if (username == null) { - throw new IllegalArgumentException("username is null"); - } - if (password == null) { - throw new IllegalArgumentException("password is null"); - } - if (email == null) { - throw new IllegalArgumentException("email is null"); - } - authConfig = new AuthConfig(); - authConfig.setUsername(username); - authConfig.setPassword(password); - authConfig.setEmail(email); - } - - /** - * Authenticate with the server, useful for checking authentication. - */ - public void auth() throws DockerException { - try { - client.resource(restEndpointUrl + "/auth") - .header("Content-Type", MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON) - .post(authConfig()); - } catch (UniformInterfaceException e) { - throw new DockerException(e); - } - } - - private String registryAuth() throws DockerException { - try { - return Base64.encodeBase64String(new ObjectMapper().writeValueAsString(authConfig()).getBytes()); - } catch (IOException e) { - throw new DockerException(e); - } - } - - public AuthConfig authConfig() throws DockerException { - return authConfig != null - ? authConfig - : authConfigFromProperties(); - } - - private static AuthConfig authConfigFromProperties() throws DockerException { - final AuthConfig a = new AuthConfig(); - - a.setUsername(Config.createConfig().username); - a.setPassword(Config.createConfig().password); - a.setEmail(Config.createConfig().email); - - if (a.getUsername() == null) {throw new IllegalStateException("username is null");} - if (a.getPassword() == null) {throw new IllegalStateException("password is null");} - if (a.getEmail() == null) {throw new IllegalStateException("email is null");} - - return a; - } - - - /** - * * MISC API - * * - */ - - public Info info() throws DockerException { - WebResource webResource = client.resource(restEndpointUrl + "/info"); - - try { - LOGGER.trace("GET: {}", webResource); - return webResource.accept(MediaType.APPLICATION_JSON).get(Info.class); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error.", exception); - } else { - throw new DockerException(exception); - } - } - } - - - public Version version() throws DockerException { - WebResource webResource = client.resource(restEndpointUrl + "/version"); - - try { - LOGGER.trace("GET: {}", webResource); - return webResource.accept(MediaType.APPLICATION_JSON).get(Version.class); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error.", exception); - } else { - throw new DockerException(exception); - } - } - } - - - public int ping() throws DockerException { - WebResource webResource = client.resource(restEndpointUrl + "/_ping"); - - try { - LOGGER.trace("GET: {}", webResource); - ClientResponse resp = webResource.get(ClientResponse.class); - return resp.getStatus(); - } catch (UniformInterfaceException exception) { - throw new DockerException(exception); - } - } - - - /** - * * IMAGE API - * * - */ - - public ClientResponse pull(String repository) throws DockerException { - return this.pull(repository, null, null); - } - - public ClientResponse pull(String repository, String tag) throws DockerException { - return this.pull(repository, tag, null); - } - - public ClientResponse pull(String repository, String tag, String registry) throws DockerException { - Preconditions.checkNotNull(repository, "Repository was not specified"); - - if (StringUtils.countMatches(repository, ":") == 1) { - String repositoryTag[] = StringUtils.split(repository, ':'); - repository = repositoryTag[0]; - tag = repositoryTag[1]; - - } - - MultivaluedMap params = new MultivaluedMapImpl(); - params.add("tag", tag); - params.add("fromImage", repository); - params.add("registry", registry); - - WebResource webResource = client.resource(restEndpointUrl + "/images/create").queryParams(params); - - try { - LOGGER.trace("POST: {}", webResource); - return webResource.accept(MediaType.APPLICATION_OCTET_STREAM_TYPE).post(ClientResponse.class); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error.", exception); - } else { - throw new DockerException(exception); - } - } - } - - - - - /** - * @return The output slurped into a string. - */ - public static String asString(ClientResponse response) throws IOException { - - StringWriter out = new StringWriter(); - try { - LineIterator itr = IOUtils.lineIterator( - response.getEntityInputStream(), "UTF-8"); - while (itr.hasNext()) { - String line = itr.next(); - out.write(line + (itr.hasNext() ? "\n" : "")); - } - } finally { - closeQuietly(response.getEntityInputStream()); - } - return out.toString(); - } - - /** - * Push the latest image to the repository. - * - * @param name The name, e.g. "alexec/busybox" or just "busybox" if you want to default. Not null. - */ - public ClientResponse push(final String name) throws DockerException { - if (name == null) { - throw new IllegalArgumentException("name is null"); - } - try { - final String registryAuth = registryAuth(); - return client.resource(restEndpointUrl + "/images/" + name(name) + "/push") - .header("X-Registry-Auth", registryAuth) - .accept(MediaType.APPLICATION_JSON) - .post(ClientResponse.class); - } catch (UniformInterfaceException e) { - throw new DockerException(e); - } - } - - private String name(String name) { - return name.contains("/") ? name : authConfig.getUsername(); - } - - /** - * Tag an image into a repository - * - * @param image the local image to tag (either a name or an id) - * @param repository the repository to tag in - * @param tag any tag for this image - * @param force (not documented) - * @return the HTTP status code (201 for success) - */ - public int tag(String image, String repository, String tag, boolean force) throws DockerException { - Preconditions.checkNotNull(image, "image was not specified"); - Preconditions.checkNotNull(repository, "repository was not specified"); - Preconditions.checkNotNull(tag, " tag was not provided"); - - MultivaluedMap params = new MultivaluedMapImpl(); - params.add("repo", repository); - params.add("tag", tag); - params.add("force", String.valueOf(force)); - - WebResource webResource = client.resource(restEndpointUrl + "/images/" + image + "/tag").queryParams(params); - - try { - LOGGER.trace("POST: {}", webResource); - ClientResponse resp = webResource.post(ClientResponse.class); - return resp.getStatus(); - } catch (UniformInterfaceException exception) { - throw new DockerException(exception); - } - } - - /** - * Create an image by importing the given stream of a tar file. - * - * @param repository the repository to import to - * @param tag any tag for this image - * @param imageStream the InputStream of the tar file - * @return an {@link ImageCreateResponse} containing the id of the imported image - * @throws DockerException if the import fails for some reason. - */ - public ImageCreateResponse importImage(String repository, String tag, InputStream imageStream) throws DockerException { - Preconditions.checkNotNull(repository, "Repository was not specified"); - Preconditions.checkNotNull(imageStream, "imageStream was not provided"); - - MultivaluedMap params = new MultivaluedMapImpl(); - params.add("repo", repository); - params.add("tag", tag); - params.add("fromSrc", "-"); - - WebResource webResource = client.resource(restEndpointUrl + "/images/create").queryParams(params); - - try { - LOGGER.trace("POST: {}", webResource); - return webResource.accept(MediaType.APPLICATION_OCTET_STREAM_TYPE).post(ImageCreateResponse.class, imageStream); - - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error.", exception); - } else { - throw new DockerException(exception); - } - } - } - - public List search(String search) throws DockerException { - WebResource webResource = client.resource(restEndpointUrl + "/images/search").queryParam("term", search); - try { - return webResource.accept(MediaType.APPLICATION_JSON).get(new GenericType>() { - }); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error.", exception); - } else { - throw new DockerException(exception); - } - } - - } - - /** - * Remove an image, deleting any tags it might have. - */ - public void removeImage(String imageId) throws DockerException { - Preconditions.checkState(!StringUtils.isEmpty(imageId), "Image ID can't be empty"); - - try { - WebResource webResource = client.resource(restEndpointUrl + "/images/" + imageId) - .queryParam("force", "true"); - LOGGER.trace("DELETE: {}", webResource); - webResource.delete(); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 204) { - //no error - LOGGER.trace("Successfully removed image " + imageId); - } else if (exception.getResponse().getStatus() == 404) { - LOGGER.warn("{} no such image", imageId); - } else if (exception.getResponse().getStatus() == 409) { - throw new DockerException("Conflict"); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error.", exception); - } else { - throw new DockerException(exception); - } - } - - } - - public void removeImages(List images) throws DockerException { - Preconditions.checkNotNull(images, "List of images can't be null"); - - for (String imageId : images) { - removeImage(imageId); - } - } - - public String getVizImages() throws DockerException { - WebResource webResource = client.resource(restEndpointUrl + "/images/viz"); - - try { - LOGGER.trace("GET: {}", webResource); - String response = webResource.get(String.class); - LOGGER.trace("Response: {}", response); - - return response; - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 400) { - throw new DockerException("bad parameter"); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - } - - - public List getImages() throws DockerException { - return this.getImages(null, false); - } - - public List getImages(boolean allContainers) throws DockerException { - return this.getImages(null, allContainers); - } - - public List getImages(String name) throws DockerException { - return this.getImages(name, false); - } - - public List getImages(String name, boolean allImages) throws DockerException { - - MultivaluedMap params = new MultivaluedMapImpl(); - params.add("filter", name); - params.add("all", allImages ? "1" : "0"); - - WebResource webResource = client.resource(restEndpointUrl + "/images/json").queryParams(params); - - try { - LOGGER.trace("GET: {}", webResource); - List images = webResource.accept(MediaType.APPLICATION_JSON).get(new GenericType>() { - }); - LOGGER.trace("Response: {}", images); - return images; - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 400) { - throw new DockerException("bad parameter"); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(); - } - } - - } - - public ImageInspectResponse inspectImage(String imageId) throws DockerException, NotFoundException { - - WebResource webResource = client.resource(restEndpointUrl + String.format("/images/%s/json", imageId)); - - try { - LOGGER.trace("GET: {}", webResource); - return webResource.accept(MediaType.APPLICATION_JSON).get(ImageInspectResponse.class); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 404) { - throw new NotFoundException(String.format("No such image %s", imageId)); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - } - - /** - * * CONTAINER API - * * - */ - - public List listContainers(boolean allContainers) { - return this.listContainers(allContainers, false, -1, false, null, null); - } - - public List listContainers(boolean allContainers, boolean latest) { - return this.listContainers(allContainers, latest, -1, false, null, null); - } - - public List listContainers(boolean allContainers, boolean latest, int limit) { - return this.listContainers(allContainers, latest, limit, false, null, null); - } - - public List listContainers(boolean allContainers, boolean latest, int limit, boolean showSize) { - return this.listContainers(allContainers, latest, limit, showSize, null, null); - } - - public List listContainers(boolean allContainers, boolean latest, int limit, boolean showSize, String since) { - return this.listContainers(allContainers, latest, limit, false, since, null); - } - - public List listContainers(boolean allContainers, boolean latest, int limit, boolean showSize, String since, String before) { - - MultivaluedMap params = new MultivaluedMapImpl(); - params.add("limit", latest ? "1" : String.valueOf(limit)); - params.add("all", allContainers ? "1" : "0"); - params.add("since", since); - params.add("before", before); - params.add("size", showSize ? "1" : "0"); - - WebResource webResource = client.resource(restEndpointUrl + "/containers/json").queryParams(params); - LOGGER.trace("GET: {}", webResource); - List containers = webResource.accept(MediaType.APPLICATION_JSON).get(new GenericType>() { - }); - LOGGER.trace("Response: {}", containers); - - return containers; - } - - public ContainerCreateResponse createContainer(ContainerConfig config) throws DockerException { - return createContainer(config, null); - } - - public ContainerCreateResponse createContainer(ContainerConfig config, String name) throws DockerException, NotFoundException { - - MultivaluedMap params = new MultivaluedMapImpl(); - if (name != null) { - params.add("name", name); - } - WebResource webResource = client.resource(restEndpointUrl + "/containers/create").queryParams(params); - - try { - LOGGER.trace("POST: {} ", webResource); - return webResource.accept(MediaType.APPLICATION_JSON) - .type(MediaType.APPLICATION_JSON) - .post(ContainerCreateResponse.class, config); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 404) { - throw new NotFoundException(String.format("%s is an unrecognized image. Please pull the image first.", config.getImage())); - } else if (exception.getResponse().getStatus() == 406) { - throw new DockerException("impossible to attach (container not running)"); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - - } - - public void startContainer(String containerId) throws DockerException { - this.startContainer(containerId, null); - } - - public void startContainer(String containerId, HostConfig hostConfig) throws DockerException, NotFoundException { - - WebResource webResource = client.resource(restEndpointUrl + String.format("/containers/%s/start", containerId)); - - try { - LOGGER.trace("POST: {}", webResource); - Builder builder = webResource.accept(MediaType.TEXT_PLAIN); - if (hostConfig != null) { - builder.type(MediaType.APPLICATION_JSON).post(hostConfig); - } else { - builder.post((HostConfig) null); - } - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 404) { - throw new NotFoundException(String.format("No such container %s", containerId)); - } else if (exception.getResponse().getStatus() == 204) { - //no error - LOGGER.trace("Successfully started container {}", containerId); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - } - - public ContainerInspectResponse inspectContainer(String containerId) throws DockerException, NotFoundException { - - WebResource webResource = client.resource(restEndpointUrl + String.format("/containers/%s/json", containerId)); - - try { - LOGGER.trace("GET: {}", webResource); - return webResource.accept(MediaType.APPLICATION_JSON).get(ContainerInspectResponse.class); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 404) { - throw new NotFoundException(String.format("No such container %s", containerId)); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - } - - - public void removeContainer(String container) throws DockerException { - this.removeContainer(container, false); - } - - public void removeContainer(String containerId, boolean removeVolumes) throws DockerException { - Preconditions.checkState(!StringUtils.isEmpty(containerId), "Container ID can't be empty"); - - WebResource webResource = client.resource(restEndpointUrl + "/containers/" + containerId).queryParam("v", removeVolumes ? "1" : "0"); - - try { - LOGGER.trace("DELETE: {}", webResource); - String response = webResource.accept(MediaType.APPLICATION_JSON).delete(String.class); - LOGGER.trace("Response: {}", response); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 204) { - //no error - LOGGER.trace("Successfully removed container " + containerId); - } else if (exception.getResponse().getStatus() == 400) { - throw new DockerException("bad parameter"); - } else if (exception.getResponse().getStatus() == 404) { - // should really throw a NotFoundException instead of silently ignoring the problem - LOGGER.warn(String.format("%s is an unrecognized container.", containerId)); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - } - - - public void removeContainers(List containers, boolean removeVolumes) throws DockerException { - Preconditions.checkNotNull(containers, "List of containers can't be null"); - - for (String containerId : containers) { - removeContainer(containerId, removeVolumes); - } - } - - public int waitContainer(String containerId) throws DockerException, NotFoundException { - WebResource webResource = client.resource(restEndpointUrl + String.format("/containers/%s/wait", containerId)); - - try { - LOGGER.trace("POST: {}", webResource); - ObjectNode ObjectNode = webResource.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).post(ObjectNode.class); - return ObjectNode.get("StatusCode").asInt(); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 404) { - throw new NotFoundException(String.format("No such container %s", containerId)); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } catch (Exception e) { - throw new DockerException(e); - } - } - - - public ClientResponse logContainer(String containerId) throws DockerException { - return logContainer(containerId, false); - } - - public ClientResponse logContainerStream(String containerId) throws DockerException { - return logContainer(containerId, true); - } - - private ClientResponse logContainer(String containerId, boolean stream) throws DockerException, NotFoundException { - MultivaluedMap params = new MultivaluedMapImpl(); - params.add("logs", "1"); - params.add("stdout", "1"); - params.add("stderr", "1"); - if (stream) { - params.add("stream", "1"); // this parameter keeps stream open indefinitely - } - - WebResource webResource = client.resource(restEndpointUrl + String.format("/containers/%s/attach", containerId)) - .queryParams(params); - - try { - LOGGER.trace("POST: {}", webResource); - return webResource.accept(MediaType.APPLICATION_OCTET_STREAM_TYPE).post(ClientResponse.class, params); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 400) { - throw new DockerException("bad parameter"); - } else if (exception.getResponse().getStatus() == 404) { - throw new NotFoundException(String.format("No such container %s", containerId)); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - } - - public ClientResponse copyFile(String containerId, String resource) throws DockerException { - CopyConfig copyConfig = new CopyConfig(); - copyConfig.setResource(resource); - - WebResource webResource = - client.resource(restEndpointUrl + String.format("/containers/%s/copy", containerId)); - - try { - LOGGER.trace("POST: " + webResource.toString()); - WebResource.Builder builder = - webResource.accept(MediaType.APPLICATION_OCTET_STREAM_TYPE).type("application/json"); - - return builder.post(ClientResponse.class, copyConfig.toString()); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 400) { - throw new DockerException("bad parameter"); - } else if (exception.getResponse().getStatus() == 404) { - throw new DockerException(String.format("No such container %s", containerId)); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - } - - public List containerDiff(String containerId) throws DockerException, NotFoundException { - - WebResource webResource = client.resource(restEndpointUrl + String.format("/containers/%s/changes", containerId)); - - try { - LOGGER.trace("GET: {}", webResource); - return webResource.accept(MediaType.APPLICATION_JSON).get(new GenericType>() { - }); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 404) { - throw new NotFoundException(String.format("No such container %s", containerId)); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - } - - - public void stopContainer(String containerId) throws DockerException { - this.stopContainer(containerId, 10); - } - - public void stopContainer(String containerId, int timeout) throws DockerException { - - WebResource webResource = client.resource(restEndpointUrl + String.format("/containers/%s/stop", containerId)) - .queryParam("t", String.valueOf(timeout)); - - - try { - LOGGER.trace("POST: {}", webResource); - webResource.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).post(); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 404) { - LOGGER.warn("No such container {}", containerId); - } else if (exception.getResponse().getStatus() == 204) { - //no error - LOGGER.trace("Successfully stopped container {}", containerId); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - } - - public void kill(String containerId) throws DockerException { - WebResource webResource = client.resource(restEndpointUrl + String.format("/containers/%s/kill", containerId)); - - try { - LOGGER.trace("POST: {}", webResource); - webResource.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).post(); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 404) { - LOGGER.warn("No such container {}", containerId); - } else if (exception.getResponse().getStatus() == 204) { - //no error - LOGGER.trace("Successfully killed container {}", containerId); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - } - - public void restart(String containerId, int timeout) throws DockerException, NotFoundException { - WebResource webResource = client.resource(restEndpointUrl + String.format("/containers/%s/restart", containerId)); - - try { - LOGGER.trace("POST: {}", webResource); - webResource.accept(MediaType.APPLICATION_JSON).type(MediaType.APPLICATION_JSON).post(); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 404) { - throw new NotFoundException(String.format("No such container %s", containerId)); - } else if (exception.getResponse().getStatus() == 204) { - //no error - LOGGER.trace("Successfully restarted container {}", containerId); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } - } - - public String commit(CommitConfig commitConfig) throws DockerException, NotFoundException { - Preconditions.checkNotNull(commitConfig.getContainer(), "Container ID was not specified"); - - MultivaluedMap params = new MultivaluedMapImpl(); - params.add("container", commitConfig.getContainer()); - params.add("repo", commitConfig.getRepo()); - params.add("tag", commitConfig.getTag()); - params.add("m", commitConfig.getMessage()); - params.add("author", commitConfig.getAuthor()); - params.add("run", commitConfig.getRun()); - - WebResource webResource = client.resource(restEndpointUrl + "/commit").queryParams(params); - - try { - LOGGER.trace("POST: {}", webResource); - ObjectNode ObjectNode = webResource.accept("application/vnd.docker.raw-stream").post(ObjectNode.class, params); - return ObjectNode.get("Id").asText(); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 404) { - throw new NotFoundException(String.format("No such container %s", commitConfig.getContainer())); - } else if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } catch (Exception e) { - throw new DockerException(e); - } - } - - - public ClientResponse build(File dockerFolder) throws DockerException { - return this.build(dockerFolder, null); - } - - public ClientResponse build(File dockerFolder, String tag) throws DockerException { - return this.build(dockerFolder, tag, false); - } - - private static boolean isFileResource(String resource) { - URI uri; - try { - uri = new URI(resource); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - return uri.getScheme() == null || "file".equals(uri.getScheme()); - } - - public ClientResponse build(File dockerFolder, String tag, boolean noCache) throws DockerException { - Preconditions.checkNotNull(dockerFolder, "Folder is null"); - Preconditions.checkArgument(dockerFolder.exists(), "Folder %s doesn't exist", dockerFolder); - Preconditions.checkState(new File(dockerFolder, "Dockerfile").exists(), "Dockerfile doesn't exist in " + dockerFolder); - - //We need to use Jersey HttpClient here, since ApacheHttpClient4 will not add boundary filed to - //Content-Type: multipart/form-data; boundary=Boundary_1_372491238_1372806136625 - - MultivaluedMap params = new MultivaluedMapImpl(); - params.add("t", tag); - if (noCache) { - params.add("nocache", "true"); - } - - // ARCHIVE TAR - String archiveNameWithOutExtension = UUID.randomUUID().toString(); - - File dockerFolderTar = null; - - try { - File dockerFile = new File(dockerFolder, "Dockerfile"); - List dockerFileContent = FileUtils.readLines(dockerFile); - - if (dockerFileContent.size() <= 0) { - throw new DockerException(String.format("Dockerfile %s is empty", dockerFile)); - } - - List filesToAdd = new ArrayList(); - filesToAdd.add(dockerFile); - - for (String cmd : dockerFileContent) { - if (StringUtils.startsWithIgnoreCase(cmd.trim(), "ADD")) { - String addArgs[] = StringUtils.split(cmd, " \t"); - if (addArgs.length != 3) { - throw new DockerException(String.format("Wrong format on line [%s]", cmd)); - } - - String resource = addArgs[1]; - - if(isFileResource(resource)) { - File src = new File(resource); - if (!src.isAbsolute()) { - src = new File(dockerFolder, resource).getCanonicalFile(); - } else { - throw new DockerException(String.format("Source file %s must be relative to %s", src, dockerFolder)); - } - - if (!src.exists()) { - throw new DockerException(String.format("Source file %s doesn't exist", src)); - } - if (src.isDirectory()) { - filesToAdd.addAll(FileUtils.listFiles(src, null, true)); - } else { - filesToAdd.add(src); - } - } - } - } - - dockerFolderTar = CompressArchiveUtil.archiveTARFiles(dockerFolder, filesToAdd, archiveNameWithOutExtension); - - } catch (IOException ex) { - FileUtils.deleteQuietly(dockerFolderTar); - throw new DockerException("Error occurred while preparing Docker context folder.", ex); - } - - WebResource webResource = client.resource(restEndpointUrl + "/build").queryParams(params); - - try { - LOGGER.trace("POST: {}", webResource); - return webResource - .type("application/tar") - .accept(MediaType.TEXT_PLAIN) - .post(ClientResponse.class, FileUtils.openInputStream(dockerFolderTar)); - } catch (UniformInterfaceException exception) { - if (exception.getResponse().getStatus() == 500) { - throw new DockerException("Server error", exception); - } else { - throw new DockerException(exception); - } - } catch (IOException e) { - throw new DockerException(e); - } finally { - FileUtils.deleteQuietly(dockerFolderTar); - } - } -} diff --git a/src/main/java/com/kpelykh/docker/client/DockerException.java b/src/main/java/com/kpelykh/docker/client/DockerException.java deleted file mode 100644 index aa3df660..00000000 --- a/src/main/java/com/kpelykh/docker/client/DockerException.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.kpelykh.docker.client; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ - -public class DockerException extends Exception { - - public DockerException() { - } - - public DockerException(String message) { - super(message); - } - - public DockerException(String message, Throwable cause) { - super(message, cause); - } - - public DockerException(Throwable cause) { - super(cause); - } -} diff --git a/src/main/java/com/kpelykh/docker/client/NotFoundException.java b/src/main/java/com/kpelykh/docker/client/NotFoundException.java deleted file mode 100644 index 76569f7b..00000000 --- a/src/main/java/com/kpelykh/docker/client/NotFoundException.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.kpelykh.docker.client; - -/** - * Indicates that the given entity does not exist. - * - * @author Ryan Campbell ryan.campbell@gmail.com - */ -public class NotFoundException extends DockerException { - - public NotFoundException(String message) { - super(message); - } - -} diff --git a/src/main/java/com/kpelykh/docker/client/model/BoundHostVolumes.java b/src/main/java/com/kpelykh/docker/client/model/BoundHostVolumes.java deleted file mode 100644 index 9a912439..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/BoundHostVolumes.java +++ /dev/null @@ -1,92 +0,0 @@ -/** - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.JsonSerializer; -import com.fasterxml.jackson.databind.SerializerProvider; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -/** - * @author Kevin A. Archie - * - */ -@JsonSerialize(using=BoundHostVolumes.Serializer.class) -public class BoundHostVolumes { - private static final String[] STRING_ARRAY = new String[0]; - private final String[] dests, binds; - - /** - * - * @param specs Iterable of String binding specs, each of form "{host-path}:{container-patch}:[rw|ro]" - * @throws MalformedVolumeSpecException if any specs are null or empty - */ - public BoundHostVolumes(final Iterable specs) { - final List dests = new ArrayList(), binds = new ArrayList(); - for (final String spec : specs) { - if (null == spec || "".equals(spec)) { - // skip empty spec lines - } else { - final String[] sspec = spec.split(":"); - dests.add(sspec.length > 1 ? sspec[1] : sspec[0]); - binds.add(spec); - } - } - this.dests = dests.toArray(STRING_ARRAY); - this.binds = binds.toArray(STRING_ARRAY); - } - - public String[] asBinds() { - return binds; - } - - private BoundHostVolumes writeVolumes(final JsonGenerator jg) throws IOException { - jg.writeStartObject(); - for (final String dest : dests) { - jg.writeObjectFieldStart(dest); - jg.writeEndObject(); - } - jg.writeEndObject(); - return this; - } - - /** - * This is an ugly hack. We assume that the serializer only gets called when - * a containing ContainerConfig gets serialized, when POSTing to - * /containers/create . In that context, we pass only the container-path - * part (the key in the volumes map). - * - * @author Kevin A. Archie - * - */ - public static class Serializer extends JsonSerializer { - /* (non-Javadoc) - * @see org.codehaus.jackson.map.JsonSerializer#serialize(java.lang.Object, org.codehaus.jackson.JsonGenerator, org.codehaus.jackson.map.SerializerProvider) - */ - @Override - public void serialize(final BoundHostVolumes volumes, final JsonGenerator jg, final SerializerProvider sp) - throws IOException { - volumes.writeVolumes(jg); - } - } -} diff --git a/src/main/java/com/kpelykh/docker/client/model/CommitConfig.java b/src/main/java/com/kpelykh/docker/client/model/CommitConfig.java deleted file mode 100644 index 4023deb7..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/CommitConfig.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class CommitConfig { - - @JsonProperty("container") - private String container; - - @JsonProperty("repo") - private String repo; - - @JsonProperty("tag") - private String tag; - - @JsonProperty("m") - private String message; - - //author (eg. “John Hannibal Smith ”) - @JsonProperty("author") - private String author; - - //config automatically applied when the image is run. (ex: {“Cmd”: [“cat”, “/world”], “PortSpecs”:[“22”]}) - @JsonProperty("run") - private String run; - - public String getContainer() { - return container; - } - - public String getRepo() { - return repo; - } - - public String getTag() { - return tag; - } - - public String getMessage() { - return message; - } - - public String getAuthor() { - return author; - } - - public String getRun() { - return run; - } - - public CommitConfig setRepo(String repo) { - this.repo = repo; - return this; - } - - public CommitConfig setTag(String tag) { - this.tag = tag; - return this; - } - - public CommitConfig setMessage(String message) { - this.message = message; - return this; - } - - public CommitConfig setAuthor(String author) { - this.author = author; - return this; - } - - public CommitConfig setRun(String run) { - this.run = run; - return this; - } - - public CommitConfig(String container) { - this.container = container; - } - -} diff --git a/src/main/java/com/kpelykh/docker/client/model/Container.java b/src/main/java/com/kpelykh/docker/client/model/Container.java deleted file mode 100644 index 3e6554cb..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/Container.java +++ /dev/null @@ -1,140 +0,0 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Arrays; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown=true) -public class Container { - - @JsonProperty("Id") - private String id; - - @JsonProperty("Command") - private String command; - - @JsonProperty("Image") - private String image; - - @JsonProperty("Created") - private long created; - - @JsonProperty("Status") - private String status; - - /* Example: - "Ports": { - "22/tcp": [ - { - "HostIp": "0.0.0.0", - "HostPort": "8022" - } - ] - } - */ - - @JsonProperty("Ports") - public Ports ports; - - @JsonProperty("SizeRw") - private int size; - - @JsonProperty("SizeRootFs") - private int sizeRootFs; - - @JsonProperty("Names") - private String[] names; - - public String getId() { - return id; - } - - public String getCommand() { - return command; - } - - public String getImage() { - return image; - } - - public long getCreated() { - return created; - } - - public String getStatus() { - return status; - } - - public Ports getPorts() { - return ports; - } - - public void setPorts(Ports ports) { - this.ports = ports; - } - - public int getSize() { - return size; - } - - public int getSizeRootFs() { - return sizeRootFs; - } - - public String[] getNames() { - return names; - } - - public void setId(String id) { - this.id = id; - } - - public void setCommand(String command) { - this.command = command; - } - - public void setImage(String image) { - this.image = image; - } - - public void setCreated(long created) { - this.created = created; - } - - public void setStatus(String status) { - this.status = status; - } - - public void setSize(int size) { - this.size = size; - } - - public void setSizeRootFs(int sizeRootFs) { - this.sizeRootFs = sizeRootFs; - } - - public void setNames(String[] names) { - this.names = names; - } - - @Override - public String toString() { - return "Container{" + - "id='" + id + '\'' + - ", command='" + command + '\'' + - ", image='" + image + '\'' + - ", created=" + created + - ", status='" + status + '\'' + - ", ports=" + ports + - ", size=" + size + - ", sizeRootFs=" + sizeRootFs + - ", names=" + Arrays.toString(names) + - '}'; - } -} diff --git a/src/main/java/com/kpelykh/docker/client/model/ContainerConfig.java b/src/main/java/com/kpelykh/docker/client/model/ContainerConfig.java deleted file mode 100644 index 27a1d7e3..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/ContainerConfig.java +++ /dev/null @@ -1,291 +0,0 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Arrays; -import java.util.Map; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class ContainerConfig { - - @JsonProperty("Hostname") private String hostName = ""; - @JsonProperty("PortSpecs") private String[] portSpecs; - @JsonProperty("User") private String user = ""; - @JsonProperty("Tty") private boolean tty = false; - @JsonProperty("OpenStdin") private boolean stdinOpen = false; - @JsonProperty("StdinOnce") private boolean stdInOnce = false; - @JsonProperty("Memory") private long memoryLimit = 0; - @JsonProperty("MemorySwap") private long memorySwap = 0; - @JsonProperty("CpuShares") private int cpuShares = 0; - @JsonProperty("AttachStdin") private boolean attachStdin = false; - @JsonProperty("AttachStdout") private boolean attachStdout = false; - @JsonProperty("AttachStderr") private boolean attachStderr = false; - @JsonProperty("Env") private String[] env; - @JsonProperty("Cmd") private String[] cmd; - @JsonProperty("Dns") private String[] dns; - @JsonProperty("Image") private String image; - @JsonProperty("Volumes") private BoundHostVolumes volumes; - @JsonProperty("VolumesFrom") private String volumesFrom = ""; - @JsonProperty("Entrypoint") private String[] entrypoint = new String[]{}; - @JsonProperty("NetworkDisabled") private boolean networkDisabled = false; - @JsonProperty("Privileged") private boolean privileged = false; - @JsonProperty("WorkingDir") private String workingDir = ""; - @JsonProperty("Domainname") private String domainName = ""; - // FIXME Is this the right type? -BJE - @JsonProperty("ExposedPorts") private Map exposedPorts; - - @JsonProperty("OnBuild") private int[] onBuild; - - public Map getExposedPorts() { - return exposedPorts; - } - - public boolean isNetworkDisabled() { - return networkDisabled; - } - - public String getDomainName() { - return domainName; - } - - public String getWorkingDir() { return workingDir; } - - public ContainerConfig setWorkingDir(String workingDir) { - this.workingDir = workingDir; - return this; - } - - public boolean isPrivileged() { - return privileged; - } - - public ContainerConfig setPrivileged(boolean privileged) { - this.privileged = privileged; - return this; - } - - public String getHostName() { - return hostName; - } - - public ContainerConfig setNetworkDisabled(boolean networkDisabled) { - this.networkDisabled = networkDisabled; - return this; - } - - public ContainerConfig setHostName(String hostName) { - this.hostName = hostName; - return this; - } - - public String[] getPortSpecs() { - return portSpecs; - } - - public ContainerConfig setPortSpecs(String[] portSpecs) { - this.portSpecs = portSpecs; - return this; - } - - public String getUser() { - return user; - } - - public ContainerConfig setUser(String user) { - this.user = user; - return this; - } - - public boolean isTty() { - return tty; - } - - public ContainerConfig setTty(boolean tty) { - this.tty = tty; - return this; - } - - public boolean isStdinOpen() { - return stdinOpen; - } - - public ContainerConfig setStdinOpen(boolean stdinOpen) { - this.stdinOpen = stdinOpen; - return this; - } - - public boolean isStdInOnce() { - return stdInOnce; - } - - public ContainerConfig setStdInOnce(boolean stdInOnce) { - this.stdInOnce = stdInOnce; - return this; - } - - public long getMemoryLimit() { - return memoryLimit; - } - - public ContainerConfig setMemoryLimit(long memoryLimit) { - this.memoryLimit = memoryLimit; - return this; - } - - public long getMemorySwap() { - return memorySwap; - } - - public ContainerConfig setMemorySwap(long memorySwap) { - this.memorySwap = memorySwap; - return this; - } - - public int getCpuShares() { - return cpuShares; - } - - public ContainerConfig setCpuShares(int cpuShares) { - this.cpuShares = cpuShares; - return this; - } - - public boolean isAttachStdin() { - return attachStdin; - } - - public ContainerConfig setAttachStdin(boolean attachStdin) { - this.attachStdin = attachStdin; - return this; - } - - public boolean isAttachStdout() { - return attachStdout; - } - - public ContainerConfig setAttachStdout(boolean attachStdout) { - this.attachStdout = attachStdout; - return this; - } - - public boolean isAttachStderr() { - return attachStderr; - } - - public ContainerConfig setAttachStderr(boolean attachStderr) { - this.attachStderr = attachStderr; - return this; - } - - public String[] getEnv() { - return env; - } - - public ContainerConfig setEnv(String[] env) { - this.env = env; - return this; - } - - public String[] getCmd() { - return cmd; - } - - public ContainerConfig setCmd(String[] cmd) { - this.cmd = cmd; - return this; - } - - public String[] getDns() { - return dns; - } - - public ContainerConfig setDns(String[] dns) { - this.dns = dns; - return this; - } - - public String getImage() { - return image; - } - - public ContainerConfig setImage(String image) { - this.image = image; - return this; - } - - public BoundHostVolumes getVolumes() { - return volumes; - } - - public ContainerConfig setVolumes(BoundHostVolumes volumes) { - this.volumes = volumes; - return this; - } - - public String getVolumesFrom() { - return volumesFrom; - } - - public ContainerConfig setVolumesFrom(String volumesFrom) { - this.volumesFrom = volumesFrom; - return this; - } - - public String[] getEntrypoint() { - return entrypoint; - } - - public ContainerConfig setEntrypoint(String[] entrypoint) { - this.entrypoint = entrypoint; - return this; - } - - public void setOnBuild(int[] onBuild) { - this.onBuild = onBuild; - } - - public int[] getOnBuild() { - return onBuild; - } - - public void setDomainName(String domainName) { - this.domainName = domainName; - } - - - @Override - public String toString() { - return "ContainerConfig{" + - "hostName='" + hostName + '\'' + - ", portSpecs=" + Arrays.toString(portSpecs) + - ", user='" + user + '\'' + - ", tty=" + tty + - ", stdinOpen=" + stdinOpen + - ", stdInOnce=" + stdInOnce + - ", memoryLimit=" + memoryLimit + - ", memorySwap=" + memorySwap + - ", cpuShares=" + cpuShares + - ", attachStdin=" + attachStdin + - ", attachStdout=" + attachStdout + - ", attachStderr=" + attachStderr + - ", env=" + Arrays.toString(env) + - ", cmd=" + Arrays.toString(cmd) + - ", dns=" + Arrays.toString(dns) + - ", image='" + image + '\'' + - ", volumes=" + volumes + - ", volumesFrom='" + volumesFrom + '\'' + - ", entrypoint=" + Arrays.toString(entrypoint) + - ", networkDisabled=" + networkDisabled + - ", privileged=" + privileged + - ", workingDir='" + workingDir + '\'' + - ", domainName='" + domainName + '\'' + - ", onBuild='" + Arrays.toString(onBuild) + '\'' + - '}'; - } -} diff --git a/src/main/java/com/kpelykh/docker/client/model/ContainerInspectResponse.java b/src/main/java/com/kpelykh/docker/client/model/ContainerInspectResponse.java deleted file mode 100644 index d686f9eb..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/ContainerInspectResponse.java +++ /dev/null @@ -1,270 +0,0 @@ -package com.kpelykh.docker.client.model; - - -import java.util.Map; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class ContainerInspectResponse { - - @JsonProperty("ID") - private String id; - - @JsonProperty("Created") - private String created; - - @JsonProperty("Path") - private String path; - - @JsonProperty("Args") - private String[] args; - - @JsonProperty("Config") - public ContainerConfig config; - - @JsonProperty("State") - private ContainerState state; - - @JsonProperty("Image") - private String imageId; - - @JsonProperty("NetworkSettings") - private NetworkSettings networkSettings; - - @JsonProperty("SysInitPath") - private String sysInitPath; - - @JsonProperty("ResolvConfPath") - private String resolvConfPath; - - @JsonProperty("Volumes") - private Map volumes; - - @JsonProperty("VolumesRW") - private Map volumesRW; - - @JsonProperty("HostnamePath") - private String hostnamePath; - - @JsonProperty("HostsPath") - private String hostsPath; - - @JsonProperty("Name") - private String name; - - @JsonProperty("Driver") - private String driver; - - @JsonProperty("HostConfig") - private HostConfig hostConfig; - - @JsonProperty("ExecDriver") - private String execDriver; - - @JsonProperty("MountLabel") - private String mountLabel; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getCreated() { - return created; - } - - public void setCreated(String created) { - this.created = created; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - public String[] getArgs() { - return args; - } - - public void setArgs(String[] args) { - this.args = args; - } - - public ContainerConfig getConfig() { - return config; - } - - public void setConfig(ContainerConfig config) { - this.config = config; - } - - public ContainerState getState() { - return state; - } - - public void setState(ContainerState state) { - this.state = state; - } - - public String getImageId() { - return imageId; - } - - public void setImageId(String image) { - this.imageId = image; - } - - public NetworkSettings getNetworkSettings() { - return networkSettings; - } - - public void setNetworkSettings(NetworkSettings networkSettings) { - this.networkSettings = networkSettings; - } - - public String getSysInitPath() { - return sysInitPath; - } - - public void setSysInitPath(String sysInitPath) { - this.sysInitPath = sysInitPath; - } - - public String getResolvConfPath() { - return resolvConfPath; - } - - public void setResolvConfPath(String resolvConfPath) { - this.resolvConfPath = resolvConfPath; - } - - public Map getVolumes() { - return volumes; - } - - public void setVolumes(Map volumes) { - this.volumes = volumes; - } - - public Map getVolumesRW() { - return volumesRW; - } - - public void setVolumesRW(Map volumesRW) { - this.volumesRW = volumesRW; - } - - public String getHostnamePath() { - return hostnamePath; - } - - public void setHostnamePath(String hostnamePath) { - this.hostnamePath = hostnamePath; - } - - public String getHostsPath() { - return hostsPath; - } - - public void setHostsPath(String hostsPath) { - this.hostsPath = hostsPath; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDriver() { - return driver; - } - - public void setDriver(String driver) { - this.driver = driver; - } - - public HostConfig getHostConfig() { - return hostConfig; - } - - public void setHostConfig(HostConfig hostConfig) { - this.hostConfig = hostConfig; - } - - public void setExecDriver(String execDriver) { - this.execDriver = execDriver; - } - - public String getExecDriver() { - return execDriver; - } - - public String getMountLabel() { - return mountLabel; - } - - public void setMountLabel(String mountLabel) { - this.mountLabel = mountLabel; - } - - public class NetworkSettings { - - @JsonProperty("IPAddress") public String ipAddress; - @JsonProperty("IPPrefixLen") public int ipPrefixLen; - @JsonProperty("Gateway") public String gateway; - @JsonProperty("Bridge") public String bridge; - @JsonProperty("PortMapping") public Map> portMapping; - @JsonProperty("Ports") public Ports ports; - - @Override - public String toString() { - return "NetworkSettings{" + - "ports=" + ports + - ", portMapping=" + portMapping + - ", bridge='" + bridge + '\'' + - ", gateway='" + gateway + '\'' + - ", ipPrefixLen=" + ipPrefixLen + - ", ipAddress='" + ipAddress + '\'' + - '}'; - } - } - - public class ContainerState { - - @JsonProperty("Running") public boolean running; - @JsonProperty("Pid") public int pid; - @JsonProperty("ExitCode") public int exitCode; - @JsonProperty("StartedAt") public String startedAt; - @JsonProperty("Ghost") public boolean ghost; - @JsonProperty("FinishedAt") private String finishedAt; - - @Override - public String toString() { - return "ContainerState{" + - "running=" + running + - ", pid=" + pid + - ", exitCode=" + exitCode + - ", startedAt='" + startedAt + '\'' + - ", ghost=" + ghost + - ", finishedAt='" + finishedAt + '\'' + - '}'; - } - } - -} diff --git a/src/main/java/com/kpelykh/docker/client/model/CopyConfig.java b/src/main/java/com/kpelykh/docker/client/model/CopyConfig.java deleted file mode 100755 index 696778a2..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/CopyConfig.java +++ /dev/null @@ -1,63 +0,0 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * Configuration object for copy command. - * @author Victor Lyuboslavsky - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class CopyConfig { - - @JsonProperty("HostPath") - private String hostPath; - - @JsonProperty("Resource") - private String resource; - - /** - * Constructor. - */ - public CopyConfig() { - hostPath = "."; - } - - /** - * Retrieves the 'resource' variable. - * @return the 'resource' variable value - */ - public String getResource() { - return resource; - } - - /** - * Sets the 'resource' variable. - * @param resource the new 'resource' variable value to set - */ - public void setResource(String resource) { - this.resource = resource; - } - - /** - * Retrieves the 'hostPath' variable. - * @return the 'hostPath' variable value - */ - public String getHostPath() { - return hostPath; - } - - /** - * Sets the 'hostPath' variable. - * @param hostPath the new 'hostPath' variable value to set - */ - public void setHostPath(String hostPath) { - this.hostPath = hostPath; - } - - @Override - public String toString() { - return "{\"HostPath\":\"" + hostPath + "\", \"Resource\":\"" + resource + "\"}"; - } - -} diff --git a/src/main/java/com/kpelykh/docker/client/model/HostConfig.java b/src/main/java/com/kpelykh/docker/client/model/HostConfig.java deleted file mode 100644 index dc7d4258..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/HostConfig.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Arrays; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class HostConfig { - - @JsonProperty("Binds") - private String[] binds; - - @JsonProperty("ContainerIDFile") - private String containerIDFile; - - @JsonProperty("LxcConf") - private LxcConf[] lxcConf; - - - @JsonProperty("Links") - private String[] links; - - @JsonProperty("PortBindings") - private Ports portBindings; - - @JsonProperty("Privileged") - private boolean privileged; - - @JsonProperty("PublishAllPorts") - private boolean publishAllPorts; - - @JsonProperty("Dns") - private String dns; - - @JsonProperty("DnsSearch") - private String dnsSearch; - - @JsonProperty("VolumesFrom") - private String volumesFrom; - - public HostConfig() { - this.binds = null; - } - - - public String[] getBinds() { - return binds; - } - - public void setBinds(String[] binds) { - this.binds = binds; - } - - public String getContainerIDFile() { - return containerIDFile; - } - - public void setContainerIDFile(String containerIDFile) { - this.containerIDFile = containerIDFile; - } - - public LxcConf[] getLxcConf() { - return lxcConf; - } - - public void setLxcConf(LxcConf[] lxcConf) { - this.lxcConf = lxcConf; - } - - public String[] getLinks() { - return links; - } - - public void setLinks(String[] links) { - this.links = links; - } - - public Ports getPortBindings() { - return portBindings; - } - - public void setPortBindings(Ports portBindings) { - this.portBindings = portBindings; - } - - public boolean isPrivileged() { - return privileged; - } - - public void setPrivileged(boolean privileged) { - this.privileged = privileged; - } - - public boolean isPublishAllPorts() { - return publishAllPorts; - } - - public void setPublishAllPorts(boolean publishAllPorts) { - this.publishAllPorts = publishAllPorts; - } - - public String getDns() { - return dns; - } - - public void setDns(String dns) { - this.dns = dns; - } - - public void setDnsSearch(String dnsSearch) { - this.dnsSearch = dnsSearch; - } - - public String getDnsSearch() { - return dnsSearch; - } - - public void setVolumesFrom(String volumesFrom) { - this.volumesFrom = volumesFrom; - } - - public String getVolumesFrom() { - return volumesFrom; - } - - @Override - public String toString() { - return "HostConfig{" + - "binds=" + Arrays.toString(binds) + - ", containerIDFile='" + containerIDFile + '\'' + - ", lxcConf=" + Arrays.toString(lxcConf) + - ", links=" + Arrays.toString(links) + - ", portBindings=" + portBindings + - ", privileged=" + privileged + - ", publishAllPorts=" + publishAllPorts + - ", dns='" + dns + '\'' + - '}'; - } - - public class LxcConf { - @JsonProperty("Key") - public String key; - - @JsonProperty("Value") - public String value; - - public LxcConf(String key, String value) { - this.key = key; - this.value = value; - } - - public LxcConf() { - } - - public String getKey() { - return key; - } - - public LxcConf setKey(String key) { - this.key = key; - return this; - } - - public String getValue() { - return value; - } - - public LxcConf setValue(String value) { - this.value = value; - return this; - } - - } -} diff --git a/src/main/java/com/kpelykh/docker/client/model/IBuilder.java b/src/main/java/com/kpelykh/docker/client/model/IBuilder.java deleted file mode 100644 index 7f5f1606..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/IBuilder.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.kpelykh.docker.client.model; - -/** - * Created by ben on 12/12/13. - */ -public interface IBuilder { - - T build(); -} diff --git a/src/main/java/com/kpelykh/docker/client/model/Image.java b/src/main/java/com/kpelykh/docker/client/model/Image.java deleted file mode 100644 index cfc578ce..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/Image.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Arrays; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class Image { - - @JsonProperty("Id") - private String id; - - @JsonProperty("RepoTags") - private String[] repoTags; - - @JsonProperty("Repository") - private String repository; - - @JsonProperty("Tag") - private String tag; - - - @JsonProperty("ParentId") - private String parentId; - - @JsonProperty("Created") - private long created; - - @JsonProperty("Size") - private long size; - - @JsonProperty("VirtualSize") - private long virtualSize; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String[] getRepoTags() { - return repoTags; - } - - public void setRepoTags(String[] repoTags) { - this.repoTags = repoTags; - } - - public String getRepository() { - return repository; - } - - public void setRepository(String repository) { - this.repository = repository; - } - - public String getTag() { - return tag; - } - - public void setTag(String tag) { - this.tag = tag; - } - - public String getParentId() { - return parentId; - } - - public void setParentId(String parentId) { - this.parentId = parentId; - } - - public long getCreated() { - return created; - } - - public void setCreated(long created) { - this.created = created; - } - - public long getSize() { - return size; - } - - public void setSize(long size) { - this.size = size; - } - - public long getVirtualSize() { - return virtualSize; - } - - public void setVirtualSize(long virtualSize) { - this.virtualSize = virtualSize; - } - - @Override - public String toString() { - return "Image{" + - "virtualSize=" + virtualSize + - ", id='" + id + '\'' + - ", repoTags=" + Arrays.toString(repoTags) + - ", repository='" + repository + '\'' + - ", tag='" + tag + '\'' + - ", parentId='" + parentId + '\'' + - ", created=" + created + - ", size=" + size + - '}'; - } -} diff --git a/src/main/java/com/kpelykh/docker/client/model/ImageInspectResponse.java b/src/main/java/com/kpelykh/docker/client/model/ImageInspectResponse.java deleted file mode 100644 index 3514670c..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/ImageInspectResponse.java +++ /dev/null @@ -1,152 +0,0 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class ImageInspectResponse { - - @JsonProperty("id") - private String id; - - @JsonProperty("parent") private String parent; - - @JsonProperty("created") private String created; - - @JsonProperty("container") private String container; - - @JsonProperty("container_config") private ContainerConfig containerConfig; - - @JsonProperty("Size") private long size; - - @JsonProperty("docker_version") private String dockerVersion; - - @JsonProperty("config") private ContainerConfig config; - - @JsonProperty("architecture") private String arch; - - @JsonProperty("comment") private String comment; - - @JsonProperty("author") private String author; - - @JsonProperty("os") private String os; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getParent() { - return parent; - } - - public void setParent(String parent) { - this.parent = parent; - } - - public String getCreated() { - return created; - } - - public void setCreated(String created) { - this.created = created; - } - - public String getContainer() { - return container; - } - - public void setContainer(String container) { - this.container = container; - } - - public ContainerConfig getContainerConfig() { - return containerConfig; - } - - public void setContainerConfig(ContainerConfig containerConfig) { - this.containerConfig = containerConfig; - } - - public long getSize() { - return size; - } - - public void setSize(long size) { - this.size = size; - } - - public String getDockerVersion() { - return dockerVersion; - } - - public void setDockerVersion(String dockerVersion) { - this.dockerVersion = dockerVersion; - } - - public ContainerConfig getConfig() { - return config; - } - - public void setConfig(ContainerConfig config) { - this.config = config; - } - - public String getArch() { - return arch; - } - - public void setArch(String arch) { - this.arch = arch; - } - - public String getComment() { - return comment; - } - - public void setComment(String comment) { - this.comment = comment; - } - - public String getAuthor() { - return author; - } - - public void setAuthor(String author) { - this.author = author; - } - - public String getOs() { - return os; - } - - public void setOs(String os) { - this.os = os; - } - - @Override - public String toString() { - return "ImageInspectResponse{" + - "id='" + id + '\'' + - ", parent='" + parent + '\'' + - ", created='" + created + '\'' + - ", container='" + container + '\'' + - ", containerConfig=" + containerConfig + - ", size=" + size + - ", dockerVersion='" + dockerVersion + '\'' + - ", config=" + config + - ", arch='" + arch + '\'' + - ", comment='" + comment + '\'' + - ", author='" + author + '\'' + - ", os='" + os + '\'' + - '}'; - } -} diff --git a/src/main/java/com/kpelykh/docker/client/model/Info.java b/src/main/java/com/kpelykh/docker/client/model/Info.java deleted file mode 100644 index 72f2f360..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/Info.java +++ /dev/null @@ -1,227 +0,0 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; - -import java.util.List; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -public class Info { - - @JsonProperty("Debug") - private boolean debug; - - @JsonProperty("Containers") - private int containers; - - @JsonProperty("Driver") - private String driver; - - @JsonProperty("DriverStatus") - private List driverStatuses; - - - @JsonProperty("Images") - private int images; - - @JsonProperty("IPv4Forwarding") - private String IPv4Forwarding; - - @JsonProperty("IndexServerAddress") - private String IndexServerAddress; - - - @JsonProperty("InitPath") - private String initPath; - - @JsonProperty("InitSha1") - private String initSha1; - - @JsonProperty("KernelVersion") - private String kernelVersion; - - @JsonProperty("LXCVersion") - private String lxcVersion; - - @JsonProperty("MemoryLimit") - private boolean memoryLimit; - - @JsonProperty("NEventsListener") - private long nEventListener; - - @JsonProperty("NFd") - private int NFd; - - @JsonProperty("NGoroutines") - private int NGoroutines; - - @JsonProperty("SwapLimit") - private int swapLimit; - - @JsonProperty("ExecutionDriver") - private String executionDriver; - - public boolean isDebug() { - return debug; - } - - public void setDebug(boolean debug) { - this.debug = debug; - } - - public int getContainers() { - return containers; - } - - public void setContainers(int containers) { - this.containers = containers; - } - - public String getDriver() { - return driver; - } - - public void setDriver(String driver) { - this.driver = driver; - } - - public List getDriverStatuses() { - return driverStatuses; - } - - public void setDriverStatuses(List driverStatuses) { - this.driverStatuses = driverStatuses; - } - - public int getImages() { - return images; - } - - public void setImages(int images) { - this.images = images; - } - - public String getIPv4Forwarding() { - return IPv4Forwarding; - } - - public void setIPv4Forwarding(String IPv4Forwarding) { - this.IPv4Forwarding = IPv4Forwarding; - } - - public String getIndexServerAddress() { - return IndexServerAddress; - } - - public void setIndexServerAddress(String indexServerAddress) { - IndexServerAddress = indexServerAddress; - } - - public String getInitPath() { - return initPath; - } - - public void setInitPath(String initPath) { - this.initPath = initPath; - } - - public String getInitSha1() { - return initSha1; - } - - public void setInitSha1(String initSha1) { - this.initSha1 = initSha1; - } - - public String getKernelVersion() { - return kernelVersion; - } - - public void setKernelVersion(String kernelVersion) { - this.kernelVersion = kernelVersion; - } - - public String getLxcVersion() { - return lxcVersion; - } - - public void setLxcVersion(String lxcVersion) { - this.lxcVersion = lxcVersion; - } - - public boolean isMemoryLimit() { - return memoryLimit; - } - - public void setMemoryLimit(boolean memoryLimit) { - this.memoryLimit = memoryLimit; - } - - public long getnEventListener() { - return nEventListener; - } - - public void setnEventListener(long nEventListener) { - this.nEventListener = nEventListener; - } - - public int getNFd() { - return NFd; - } - - public void setNFd(int NFd) { - this.NFd = NFd; - } - - public int getNGoroutines() { - return NGoroutines; - } - - public void setNGoroutines(int NGoroutines) { - this.NGoroutines = NGoroutines; - } - - public int getSwapLimit() { - return swapLimit; - } - - public void setSwapLimit(int swapLimit) { - this.swapLimit = swapLimit; - } - public String getExecutionDriver() { - return executionDriver; - } - - public void setExecutionDriver(String executionDriver) { - this.executionDriver=executionDriver; - } - - @Override - public String toString() { - return "Info{" + - "debug=" + debug + - ", containers=" + containers + - ", driver='" + driver + '\'' + - ", driverStatuses=" + driverStatuses + - ", images=" + images + - ", IPv4Forwarding='" + IPv4Forwarding + '\'' + - ", IndexServerAddress='" + IndexServerAddress + '\'' + - ", initPath='" + initPath + '\'' + - ", initSha1='" + initSha1 + '\'' + - ", kernelVersion='" + kernelVersion + '\'' + - ", lxcVersion='" + lxcVersion + '\'' + - ", memoryLimit=" + memoryLimit + - ", nEventListener=" + nEventListener + - ", NFd=" + NFd + - ", NGoroutines=" + NGoroutines + - ", swapLimit=" + swapLimit + - '}'; - } -} diff --git a/src/main/java/com/kpelykh/docker/client/model/Port.java b/src/main/java/com/kpelykh/docker/client/model/Port.java deleted file mode 100644 index 538213ec..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/Port.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * @author Nicolas De Loof - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class Port { - - @JsonProperty("PrivatePort") - private long privatePort; - - @JsonProperty("PublicPort") - private long publicPort; - - @JsonProperty("Type") - private String type; - - public long getPrivatePort() { - return privatePort; - } - - public void setPrivatePort(long privatePort) { - this.privatePort = privatePort; - } - - public long getPublicPort() { - return publicPort; - } - - public void setPublicPort(long publicPort) { - this.publicPort = publicPort; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - @Override - public String toString() { - return "Port{" + - "privatePort=" + privatePort + - ", publicPort=" + publicPort + - ", type='" + type + '\'' + - '}'; - } -} \ No newline at end of file diff --git a/src/main/java/com/kpelykh/docker/client/model/Ports.java b/src/main/java/com/kpelykh/docker/client/model/Ports.java deleted file mode 100644 index fc590289..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/Ports.java +++ /dev/null @@ -1,132 +0,0 @@ -package com.kpelykh.docker.client.model; - - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.ObjectCodec; -import com.fasterxml.jackson.databind.*; -import com.fasterxml.jackson.databind.annotation.JsonDeserialize; -import com.fasterxml.jackson.databind.annotation.JsonSerialize; -import com.fasterxml.jackson.databind.node.NullNode; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -/** - * Created by ben on 16/12/13. - */ -@JsonDeserialize(using=Ports.Deserializer.class) -@JsonSerialize(using=Ports.Serializer.class) -public class Ports { - - - private final Map ports = new HashMap(); - - public Ports() { } - - public void addPort(Port port) { - ports.put(port.getPort(), port); - } - - @Override - public String toString(){ - return ports.toString(); - } - - public Map getAllPorts(){ - return ports; - } - - public static class Port{ - - private final String scheme; - private final String port; - private final String hostIp; - private final String hostPort; - - public Port(String scheme_, String port_, String hostIp_, String hostPort_) { - scheme = scheme_; - port = port_; - hostIp = hostIp_; - hostPort = hostPort_; - } - - public String getScheme() { - return scheme; - } - - public String getPort() { - return port; - } - - public String getHostIp() { - return hostIp; - } - - public String getHostPort() { - return hostPort; - } - - public static Port makePort(String full, String hostIp, String hostPort) { - if (full == null) return null; - String[] pieces = full.split("/"); - return new Port(pieces[1], pieces[0], hostIp, hostPort); - } - - @Override - public String toString() { - return "Port{" + - "scheme='" + scheme + '\'' + - ", port='" + port + '\'' + - ", hostIp='" + hostIp + '\'' + - ", hostPort='" + hostPort + '\'' + - '}'; - } - } - - public static class Deserializer extends JsonDeserializer { - @Override - public Ports deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { - - Ports out = new Ports(); - ObjectCodec oc = jsonParser.getCodec(); - JsonNode node = oc.readTree(jsonParser); - for (Iterator> it = node.fields(); it.hasNext();) { - - Map.Entry field = it.next(); - if (!field.getValue().equals(NullNode.getInstance())) { - String hostIp = field.getValue().get(0).get("HostIp").textValue(); - String hostPort = field.getValue().get(0).get("HostPort").textValue(); - out.addPort(Port.makePort(field.getKey(), hostIp, hostPort)); - } - } - return out; - } - } - - public static class Serializer extends JsonSerializer { - - @Override - public void serialize(Ports ports, JsonGenerator jsonGen, - SerializerProvider serProvider) throws IOException, JsonProcessingException { - - jsonGen.writeStartObject();//{ - for(String portKey : ports.getAllPorts().keySet()){ - Port p = ports.getAllPorts().get(portKey); - jsonGen.writeFieldName(p.getPort() + "/" + p.getScheme()); - jsonGen.writeStartArray(); - jsonGen.writeStartObject(); - jsonGen.writeStringField("HostIp", p.hostIp); - jsonGen.writeStringField("HostPort", p.hostPort); - jsonGen.writeEndObject(); - jsonGen.writeEndArray(); - } - jsonGen.writeEndObject();//} - } - - } - -} \ No newline at end of file diff --git a/src/main/java/com/kpelykh/docker/client/model/Version.java b/src/main/java/com/kpelykh/docker/client/model/Version.java deleted file mode 100644 index a427aafb..00000000 --- a/src/main/java/com/kpelykh/docker/client/model/Version.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.kpelykh.docker.client.model; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class Version { - - @JsonProperty("Version") - private String version; - - @JsonProperty("GitCommit") - private String gitCommit; - - @JsonProperty("GoVersion") - private String goVersion; - - @JsonProperty("KernelVersion") - private String kernelVersion; - - @JsonProperty("Arch") - private String arch; - - @JsonProperty("Os") - private String operatingSystem; - - @JsonProperty("ApiVersion") - private String apiVersion; - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public String getGitCommit() { - return gitCommit; - } - - public void setGitCommit(String gitCommit) { - this.gitCommit = gitCommit; - } - - public String getGoVersion() { - return goVersion; - } - - public void setGoVersion(String goVersion) { - this.goVersion = goVersion; - } - - public String getKernelVersion() { - return kernelVersion; - } - - public void setKernelVersion(String kernelVersion) { - this.kernelVersion = kernelVersion; - } - - public String getArch() { - return arch; - } - - public void setArch(String arch) { - this.arch = arch; - } - - public String getOperatingSystem() { - return operatingSystem; - } - - public void setOperatingSystem(String operatingSystem) { - this.operatingSystem = operatingSystem; - } - - public void setApiVersion(String apiVersion) { - this.apiVersion = apiVersion; - } - - public String getApiVersion() { - return apiVersion; - } - - @Override - public String toString() { - return "Version{" + - "version='" + version + '\'' + - ", gitCommit='" + gitCommit + '\'' + - ", goVersion='" + goVersion + '\'' + - ", kernelVersion='" + kernelVersion + '\'' + - ", arch='" + arch + '\'' + - ", operatingSystem='" + operatingSystem + '\'' + - ", apiVersion='" + apiVersion + '\'' + - '}'; - } -} diff --git a/src/main/java/com/kpelykh/docker/client/utils/JsonClientFilter.java b/src/main/java/com/kpelykh/docker/client/utils/JsonClientFilter.java deleted file mode 100644 index 55b8b287..00000000 --- a/src/main/java/com/kpelykh/docker/client/utils/JsonClientFilter.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.kpelykh.docker.client.utils; - - -import com.sun.jersey.api.client.ClientRequest; -import com.sun.jersey.api.client.ClientResponse; -import com.sun.jersey.api.client.filter.ClientFilter; - -/** - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - * - */ -public class JsonClientFilter extends ClientFilter { - - public ClientResponse handle(ClientRequest cr) { - // Call the next filter - ClientResponse resp = getNext().handle(cr); - String respContentType = resp.getHeaders().getFirst("Content-Type"); - if (respContentType.startsWith("text/plain")) { - String newContentType = "application/json" + respContentType.substring(10); - resp.getHeaders().putSingle("Content-Type", newContentType); - } - return resp; - } - -} diff --git a/src/main/resources/META-INF/services/com.github.dockerjava.api.command.DockerCmdExecFactory b/src/main/resources/META-INF/services/com.github.dockerjava.api.command.DockerCmdExecFactory new file mode 100644 index 00000000..f0686bc9 --- /dev/null +++ b/src/main/resources/META-INF/services/com.github.dockerjava.api.command.DockerCmdExecFactory @@ -0,0 +1 @@ +com.github.dockerjava.jaxrs.DockerCmdExecFactoryImpl \ No newline at end of file diff --git a/src/main/resources/docker.io.properties b/src/main/resources/docker.io.properties index 0ce162bd..927b78b5 100644 --- a/src/main/resources/docker.io.properties +++ b/src/main/resources/docker.io.properties @@ -1,2 +1,4 @@ -docker.io.url=http://localhost:4243 -docker.io.version=1.11 \ No newline at end of file +docker.io.url=http://192.168.33.10:8080 +docker.io.version=1.15 +docker.io.enableLoggingFilter=false +docker.io.dockerCertPath=${user.home}/.docker \ No newline at end of file diff --git a/src/test/java/com/github/dockerjava/api/model/AccessModeTest.java b/src/test/java/com/github/dockerjava/api/model/AccessModeTest.java new file mode 100644 index 00000000..432f7b00 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/AccessModeTest.java @@ -0,0 +1,31 @@ +package com.github.dockerjava.api.model; + +import static com.github.dockerjava.api.model.AccessMode.rw; +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +public class AccessModeTest { + + @Test + public void defaultAccessMode() { + assertEquals(AccessMode.DEFAULT, rw); + } + + @Test + public void stringify() { + assertEquals(AccessMode.rw.toString(), "rw"); + } + + @Test + public void fromString() { + assertEquals(AccessMode.valueOf("rw"), rw); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "No enum const.*") + public void fromIllegalString() { + AccessMode.valueOf("xx"); + } + +} diff --git a/src/test/java/com/github/dockerjava/api/model/BindTest.java b/src/test/java/com/github/dockerjava/api/model/BindTest.java new file mode 100644 index 00000000..50a41fc3 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/BindTest.java @@ -0,0 +1,68 @@ +package com.github.dockerjava.api.model; + +import static com.github.dockerjava.api.model.AccessMode.ro; +import static com.github.dockerjava.api.model.AccessMode.rw; +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +public class BindTest { + + @Test + public void parseUsingDefaultAccessMode() { + Bind bind = Bind.parse("/host:/container"); + assertEquals(bind.getPath(), "/host"); + assertEquals(bind.getVolume().getPath(), "/container"); + assertEquals(bind.getAccessMode(), AccessMode.DEFAULT); + } + + @Test + public void parseReadWrite() { + Bind bind = Bind.parse("/host:/container:rw"); + assertEquals(bind.getPath(), "/host"); + assertEquals(bind.getVolume().getPath(), "/container"); + assertEquals(bind.getAccessMode(), rw); + } + + @Test + public void parseReadOnly() { + Bind bind = Bind.parse("/host:/container:ro"); + assertEquals(bind.getPath(), "/host"); + assertEquals(bind.getVolume().getPath(), "/container"); + assertEquals(bind.getAccessMode(), ro); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Error parsing Bind.*") + public void parseInvalidAccessMode() { + Bind.parse("/host:/container:xx"); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Error parsing Bind 'nonsense'") + public void parseInvalidInput() { + Bind.parse("nonsense"); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Error parsing Bind 'null'") + public void parseNull() { + Bind.parse(null); + } + + @Test + public void toStringReadOnly() { + assertEquals(Bind.parse("/host:/container:ro").toString(), "/host:/container:ro"); + } + + @Test + public void toStringReadWrite() { + assertEquals(Bind.parse("/host:/container:rw").toString(), "/host:/container:rw"); + } + + @Test + public void toStringDefaultAccessMode() { + assertEquals(Bind.parse("/host:/container").toString(), "/host:/container:rw"); + } + +} diff --git a/src/test/java/com/github/dockerjava/api/model/ExposedPortTest.java b/src/test/java/com/github/dockerjava/api/model/ExposedPortTest.java new file mode 100644 index 00000000..052e44ff --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/ExposedPortTest.java @@ -0,0 +1,32 @@ +package com.github.dockerjava.api.model; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +public class ExposedPortTest { + + @Test + public void parse() { + ExposedPort exposedPort = ExposedPort.parse("80/tcp"); + assertEquals(exposedPort.getPort(), 80); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Error parsing ExposedPort 'nonsense'") + public void parseInvalidInput() { + ExposedPort.parse("nonsense"); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Error parsing ExposedPort 'null'") + public void parseNull() { + ExposedPort.parse(null); + } + + @Test + public void stringify() { + assertEquals(ExposedPort.parse("80/tcp").toString(), "80/tcp"); + } + +} diff --git a/src/test/java/com/github/dockerjava/api/model/InternetProtocolTest.java b/src/test/java/com/github/dockerjava/api/model/InternetProtocolTest.java new file mode 100644 index 00000000..ea0b20d7 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/InternetProtocolTest.java @@ -0,0 +1,42 @@ +package com.github.dockerjava.api.model; + +import static com.github.dockerjava.api.model.InternetProtocol.*; +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +public class InternetProtocolTest { + + @Test + public void defaultProtocol() { + assertEquals(InternetProtocol.DEFAULT, TCP); + } + + @Test + public void stringify() { + assertEquals(TCP.toString(), "tcp"); + } + + @Test + public void parseUpperCase() { + assertEquals(InternetProtocol.parse("TCP"), TCP); + } + + @Test + public void parseLowerCase() { + assertEquals(InternetProtocol.parse("tcp"), TCP); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Error parsing Protocol.*") + public void parseInvalidInput() { + InternetProtocol.parse("xx"); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Error parsing Protocol 'null'") + public void parseNull() { + InternetProtocol.parse(null); + } + +} diff --git a/src/test/java/com/github/dockerjava/api/model/LinkTest.java b/src/test/java/com/github/dockerjava/api/model/LinkTest.java new file mode 100644 index 00000000..c42af9da --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/LinkTest.java @@ -0,0 +1,33 @@ +package com.github.dockerjava.api.model; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +public class LinkTest { + + @Test + public void parse() { + Link link = Link.parse("name:alias"); + assertEquals(link.getName(), "name"); + assertEquals(link.getAlias(), "alias"); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Error parsing Link 'nonsense'") + public void parseInvalidInput() { + Link.parse("nonsense"); + } + + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = "Error parsing Link 'null'") + public void parseNull() { + Link.parse(null); + } + + @Test + public void stringify() { + assertEquals(Link.parse("name:alias").toString(), "name:alias"); + } + +} diff --git a/src/test/java/com/github/dockerjava/api/model/PortsTest.java b/src/test/java/com/github/dockerjava/api/model/PortsTest.java new file mode 100644 index 00000000..f60be435 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/PortsTest.java @@ -0,0 +1,37 @@ +package com.github.dockerjava.api.model; + +import static org.testng.Assert.assertEquals; + +import java.util.Map; + +import org.testng.annotations.Test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.api.model.Ports.Binding; + +public class PortsTest { + private final ObjectMapper objectMapper = new ObjectMapper(); + private final String jsonWithDoubleBindingForOnePort = + "{\"80/tcp\":[{\"HostIp\":\"10.0.0.1\",\"HostPort\":\"80\"},{\"HostIp\":\"10.0.0.2\",\"HostPort\":\"80\"}]}"; + + @Test + public void deserializingPortWithMultipleBindings() throws Exception { + Ports ports = objectMapper.readValue(jsonWithDoubleBindingForOnePort, Ports.class); + Map map = ports.getBindings(); + assertEquals(map.size(), 1); + + Binding[] bindings = map.get(ExposedPort.tcp(80)); + assertEquals(bindings.length, 2); + assertEquals(bindings[0], new Binding("10.0.0.1", 80)); + assertEquals(bindings[1], new Binding("10.0.0.2", 80)); + } + + @Test + public void serializingPortWithMultipleBindings() throws Exception { + Ports ports = new Ports(); + ports.bind(ExposedPort.tcp(80), new Binding("10.0.0.1", 80)); + ports.bind(ExposedPort.tcp(80), new Binding("10.0.0.2", 80)); + assertEquals(objectMapper.writeValueAsString(ports), jsonWithDoubleBindingForOnePort); + } + +} diff --git a/src/test/java/com/github/dockerjava/api/model/VolumeBindsTest.java b/src/test/java/com/github/dockerjava/api/model/VolumeBindsTest.java new file mode 100644 index 00000000..e8bafc46 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/VolumeBindsTest.java @@ -0,0 +1,32 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import org.testng.annotations.Test; + +import java.io.IOException; + +import static org.testng.Assert.*; + +public class VolumeBindsTest { + @Test + public void t() throws IOException { + String s = "{\"/data\":\"/some/path\"}"; + ObjectMapper objectMapper = new ObjectMapper(); + VolumeBinds volumeBinds = objectMapper.readValue(s, VolumeBinds.class); + VolumeBind[] binds = volumeBinds.getBinds(); + assertEquals(binds.length,1); + assertEquals(binds[0].getHostPath(),"/some/path"); + assertEquals(binds[0].getContainerPath(), "/data"); + } + + @Test(expectedExceptions = JsonMappingException.class) + public void t1() throws IOException { + String s = "{\"/data\": {} }"; + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.readValue(s, VolumeBinds.class); + } + + +} \ No newline at end of file diff --git a/src/test/java/com/github/dockerjava/api/model/VolumeTest.java b/src/test/java/com/github/dockerjava/api/model/VolumeTest.java new file mode 100644 index 00000000..8fdf1997 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/VolumeTest.java @@ -0,0 +1,12 @@ +package com.github.dockerjava.api.model; + +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +public class VolumeTest { + @Test + public void stringify() { + assertEquals(Volume.parse("/path").toString(), "/path"); + } +} diff --git a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java new file mode 100644 index 00000000..385508b6 --- /dev/null +++ b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java @@ -0,0 +1,146 @@ +package com.github.dockerjava.client; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.lang.reflect.Method; +import java.net.DatagramSocket; +import java.net.ServerSocket; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.LineIterator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.Assert; +import org.testng.ITestResult; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.core.DockerClientBuilder; +import com.github.dockerjava.core.TestDockerCmdExecFactory; + +public abstract class AbstractDockerClientTest extends Assert { + + public static final Logger LOG = LoggerFactory + .getLogger(AbstractDockerClientTest.class); + + protected DockerClient dockerClient; + + protected TestDockerCmdExecFactory dockerCmdExecFactory = new TestDockerCmdExecFactory(DockerClientBuilder.getDefaultDockerCmdExecFactory()); + + public void beforeTest() { + LOG.info("======================= BEFORETEST ======================="); + LOG.info("Connecting to Docker server"); + dockerClient = DockerClientBuilder.getInstance() + .withDockerCmdExecFactory(dockerCmdExecFactory) + .build(); + + LOG.info("Pulling image 'busybox'"); + // need to block until image is pulled completely + asString(dockerClient.pullImageCmd("busybox").withTag("latest").exec()); + + + + assertNotNull(dockerClient); + LOG.info("======================= END OF BEFORETEST =======================\n\n"); + } + + public void afterTest() { + LOG.info("======================= END OF AFTERTEST ======================="); + } + + + public void beforeMethod(Method method) { + LOG.info(String + .format("################################## STARTING %s ##################################", + method.getName())); + } + + public void afterMethod(ITestResult result) { + + for (String container : dockerCmdExecFactory.getContainerNames()) { + LOG.info("Cleaning up temporary container {}", container); + + try { + dockerClient.removeContainerCmd(container).withForce().exec(); + } catch (DockerException ignore) { + ignore.printStackTrace(); + } + } + + for (String image : dockerCmdExecFactory.getImageNames()) { + LOG.info("Cleaning up temporary image with {}", image); + try { + dockerClient.removeImageCmd(image).withForce().exec(); + } catch (DockerException ignore) { + ignore.printStackTrace(); + } + } + + LOG.info( + "################################## END OF {} ##################################\n", + result.getName()); + } + + protected String asString(InputStream response) { + + StringWriter logwriter = new StringWriter(); + + try { + LineIterator itr = IOUtils.lineIterator( + response, "UTF-8"); + + while (itr.hasNext()) { + String line = itr.next(); + logwriter.write(line + (itr.hasNext() ? "\n" : "")); + //LOG.info("line: "+line); + } + + return logwriter.toString(); + } catch (IOException e) { + throw new RuntimeException(e); + } finally { + IOUtils.closeQuietly(response); + } + } + + // UTIL + + /** + * Checks to see if a specific port is available. + * + * @param port + * the port to check for availability + */ + public static boolean available(int port) { + if (port < 1100 || port > 60000) { + throw new IllegalArgumentException("Invalid start port: " + port); + } + + ServerSocket ss = null; + DatagramSocket ds = null; + try { + ss = new ServerSocket(port); + ss.setReuseAddress(true); + ds = new DatagramSocket(port); + ds.setReuseAddress(true); + return true; + } catch (IOException e) { + } finally { + if (ds != null) { + ds.close(); + } + + if (ss != null) { + try { + ss.close(); + } catch (IOException e) { + /* should not be thrown */ + } + } + } + + return false; + } + +} diff --git a/src/test/java/com/github/dockerjava/client/DockerClientTest.java b/src/test/java/com/github/dockerjava/client/DockerClientTest.java new file mode 100644 index 00000000..e5bef57d --- /dev/null +++ b/src/test/java/com/github/dockerjava/client/DockerClientTest.java @@ -0,0 +1,73 @@ +package com.github.dockerjava.client; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +import java.lang.reflect.Method; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.command.CreateContainerResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +/** + * Unit test for DockerClient. + * + * @author Konstantin Pelykh (kpelykh@gmail.com) + */ +@Test(groups = "integration") +public class DockerClientTest extends AbstractDockerClientTest { + public static final Logger LOG = LoggerFactory + .getLogger(DockerClientTest.class); + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + + @Test + public void testRunShlex() throws DockerException { + + String[] commands = new String[] { + "true", + "echo \"The Young Descendant of Tepes & Septette for the Dead Princess\"", + "echo -n 'The Young Descendant of Tepes & Septette for the Dead Princess'", + "/bin/sh -c echo Hello World", "/bin/sh -c echo 'Hello World'", + "echo 'Night of Nights'", "true && echo 'Night of Nights'" }; + + for (String command : commands) { + LOG.info("Running command: [{}]", command); + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd(commands).exec(); + dockerClient.startContainerCmd(container.getId()); + + int exitcode = dockerClient.waitContainerCmd(container.getId()).exec(); + assertThat(exitcode, equalTo(0)); + } + } + + +} diff --git a/src/test/java/com/github/dockerjava/client/EnhancedDockerClientTest.java b/src/test/java/com/github/dockerjava/client/EnhancedDockerClientTest.java new file mode 100644 index 00000000..a8eb88db --- /dev/null +++ b/src/test/java/com/github/dockerjava/client/EnhancedDockerClientTest.java @@ -0,0 +1,195 @@ +package com.github.dockerjava.client; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.Assert; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.github.dockerjava.api.EnhancedDockerClient; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.CreateExecCmd; +import com.github.dockerjava.api.command.CreateExecResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.model.ExecConfig; +import com.github.dockerjava.api.model.LimitationConfig; +import com.github.dockerjava.api.model.Subsystem; +import com.github.dockerjava.api.model.WriteSubsystem; +import com.github.dockerjava.api.model.metric.Metric; +import com.github.dockerjava.core.DockerClientBuilder; +import com.github.dockerjava.core.EnhancedDockerClientBuilder; +import com.github.dockerjava.core.TestDockerCmdExecFactory; + +public class EnhancedDockerClientTest { + + private static final String DOCKER_IMAGE = "busybox"; + + private EnhancedDockerClient docker; + private TestDockerCmdExecFactory dockerCmdExecFactory = new TestDockerCmdExecFactory(DockerClientBuilder.getDefaultDockerCmdExecFactory()); + private List tmpContainers = new ArrayList(); + + @Before + public void before() throws Exception { + docker = EnhancedDockerClientBuilder.getInstance() + .withDockerCmdExecFactory(dockerCmdExecFactory) + .build(); + } + + @After + public void after() throws Exception { + for (String id : tmpContainers) { + docker.killContainerCmd(id).exec(); + docker.removeContainerCmd(id).exec(); + } + } + + @Test + public void testChangeCgroup() throws Exception { + CreateContainerCmd cmd = docker.createContainerCmd(DOCKER_IMAGE); + buildCommonCreateContainerConfig(cmd); + cmd.withCpuset("0"); + String instanceId = cmd.exec().getId(); + tmpContainers.add(instanceId); + + docker.startContainerCmd(instanceId).exec(); + + List toRead = new ArrayList(); + toRead.add("cpu.shares"); + List toWrite = new ArrayList(); + WriteSubsystem w = new WriteSubsystem("cpuset.cpus", "1"); + toWrite.add(w); + List subsystems = docker.cgroupContainerCmd(instanceId) + .withReadSubsystem(toRead).withWriteSubsystem(toWrite).exec(); + Assert.assertEquals(2, subsystems.size()); + Assert.assertEquals(0, subsystems.get(0).getStatus()); + Assert.assertEquals(0, subsystems.get(1).getStatus()); + + } + + @Test + public void testGetMetric() throws Exception { + CreateContainerCmd cmd = docker.createContainerCmd(DOCKER_IMAGE); + buildCommonCreateContainerConfig(cmd); + String instanceId = cmd.exec().getId(); + tmpContainers.add(instanceId); + + docker.startContainerCmd(instanceId).exec(); + Thread.sleep(2000); + Metric metric = docker.metricContainerCmd(instanceId).exec(); + System.out.println(metric); + } + + @Test + public void testCreateContainerWithIp() throws Exception { + CreateContainerCmd cmd = docker.createContainerCmd(DOCKER_IMAGE); + buildCommonCreateContainerConfig(cmd); + String ip = "192.168.3.100/24@192.168.3.1"; + cmd.withIp(ip); + CreateContainerResponse ccr = cmd.exec(); + Assert.assertNotNull(ccr.getId()); + InspectContainerResponse cir = docker.inspectContainerCmd(ccr.getId()).exec(); + Assert.assertEquals(ip, cir.getConfig().getIp()); + tmpContainers.add(ccr.getId()); + } + + @Test + public void testExecCommandInContainer() throws Exception { + CreateContainerCmd cmd = docker.createContainerCmd(DOCKER_IMAGE); + buildCommonCreateContainerConfig(cmd); + CreateContainerResponse ccr = cmd.exec(); + Assert.assertNotNull(ccr.getId()); + tmpContainers.add(ccr.getId()); + + docker.startContainerCmd(ccr.getId()).exec(); + Thread.sleep(2000); + String text = "hello"; + String response = docker.execContainerCmd(ccr.getId()).withCmd("echo", "-n", text).exec(); + Assert.assertEquals(text, response); + + } + + @Test + public void testExecCommandInContainerWithRawAPI() throws Exception { + CreateContainerCmd cmd = docker.createContainerCmd(DOCKER_IMAGE); + buildCommonCreateContainerConfig(cmd); + CreateContainerResponse ccr = cmd.exec(); + Assert.assertNotNull(ccr.getId()); + tmpContainers.add(ccr.getId()); + + docker.startContainerCmd(ccr.getId()).exec(); + Thread.sleep(2000); + String text = "hello"; + CreateExecCmd createExecCmd = docker.createExecCmd(ccr.getId()).withCmd("echo", "-n", text); + ExecConfig execConfig = createExecCmd.getExecConfig(); + CreateExecResponse cer = createExecCmd.exec(); + String response = docker.startExecCmd(cer.getId()).withExecConfig(execConfig).exec(); + Assert.assertEquals("hello", response); + } + + @Test + public void testSweepContainer() throws Exception { + CreateContainerCmd cmd = docker.createContainerCmd(DOCKER_IMAGE); + buildCommonCreateContainerConfig(cmd); + String ip = "192.168.3.100/24@192.168.3.1"; + cmd.withIp(ip); + CreateContainerResponse ccr = cmd.exec(); + Assert.assertNotNull(ccr.getId()); + docker.startContainerCmd(ccr.getId()).exec(); + docker.sweepContainerCmd(ccr.getId()).exec(); + InspectContainerResponse cir = docker.inspectContainerCmd(ccr.getId()).exec(); + Assert.assertEquals("", cir.getConfig().getIp()); + Assert.assertEquals(true, cir.getConfig().isNetworkDisabled()); + Assert.assertEquals("none", cir.getHostConfig().getNetworkMode()); + tmpContainers.add(ccr.getId()); + } + + @Test + public void testRemoveContainerWithCheckDevice() throws Exception { + CreateContainerCmd cmd = docker.createContainerCmd(DOCKER_IMAGE); + buildCommonCreateContainerConfig(cmd); + CreateContainerResponse ccr = cmd.exec(); + Assert.assertNotNull(ccr.getId()); + docker.startContainerCmd(ccr.getId()).exec(); + docker.sweepContainerCmd(ccr.getId()).exec(); + docker.removeContainerCmd(ccr.getId()).withCheckDevice().exec(); + } + + @Test + public void testLimitContainerResource() throws Exception { + CreateContainerCmd cmd = docker.createContainerCmd(DOCKER_IMAGE); + buildCommonCreateContainerConfig(cmd); + cmd.withMemoryLimit(100 * 1024 * 1024); + cmd.withCpuset("0"); + cmd.withCpuShares(500); + CreateContainerResponse ccr = cmd.exec(); + Assert.assertNotNull(ccr.getId()); + tmpContainers.add(ccr.getId()); + docker.startContainerCmd(ccr.getId()).exec(); + Thread.sleep(2000); + LimitationConfig limitationConfig = new LimitationConfig(); + long newMemoryLimit = 200 * 1024 * 1024; + String newCpuset = "1"; + int newCpuShares = 1024; + limitationConfig.setMemoryLimit(newMemoryLimit); + limitationConfig.setCpuset(newCpuset); + limitationConfig.setCpuShares(newCpuShares); + limitationConfig.setSaveChanges(true); + docker.limitContainerCmd(limitationConfig, ccr.getId()).exec(); + docker.restartContainerCmd(ccr.getId()).exec(); + InspectContainerResponse cir = docker.inspectContainerCmd(ccr.getId()).exec(); + Assert.assertEquals(newMemoryLimit, cir.getConfig().getMemoryLimit()); + Assert.assertEquals(newCpuset, cir.getConfig().getCpuset()); + Assert.assertEquals(newCpuShares, cir.getConfig().getCpuShares()); + } + + private void buildCommonCreateContainerConfig(CreateContainerCmd cmd) { + cmd.withAttachStderr(false) + .withAttachStdin(false) + .withAttachStdout(false) + .withCmd(new String[]{"tail", "-f", "/dev/null"}); + } +} diff --git a/src/test/java/com/github/dockerjava/core/CompressArchiveUtilTest.java b/src/test/java/com/github/dockerjava/core/CompressArchiveUtilTest.java new file mode 100644 index 00000000..5212fe50 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/CompressArchiveUtilTest.java @@ -0,0 +1,59 @@ +package com.github.dockerjava.core; + +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.testng.annotations.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; + +import static java.util.Arrays.asList; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class CompressArchiveUtilTest { + + @Test + public void testExecutableFlagIsPreserved() throws Exception { + File executableFile = createExecutableFile(); + File archive = CompressArchiveUtil.archiveTARFiles(executableFile.getParentFile(), asList(executableFile), "archive"); + File expectedFile = extractFileByName(archive, "executableFile.sh.result"); + + assertThat("should be executable", expectedFile.canExecute()); + } + + private File createExecutableFile() throws IOException { + File baseDir = new File(FileUtils.getTempDirectoryPath()); + File executableFile = new File(baseDir, "executableFile.sh"); + executableFile.createNewFile(); + executableFile.setExecutable(true); + assertThat(executableFile.canExecute(), is(true)); + return executableFile; + } + + private File extractFileByName(File archive, String filenameToExtract) throws IOException { + File baseDir = new File(FileUtils.getTempDirectoryPath()); + File expectedFile = new File(baseDir, filenameToExtract); + expectedFile.delete(); + assertThat(expectedFile.exists(), is(false)); + + TarArchiveInputStream tarArchiveInputStream = new TarArchiveInputStream(new FileInputStream(archive)); + TarArchiveEntry entry; + while ((entry = tarArchiveInputStream.getNextTarEntry()) != null) { + String individualFiles = entry.getName(); + // there should be only one file in this archive + assertThat(individualFiles, equalTo("executableFile.sh")); + IOUtils.copy(tarArchiveInputStream, new FileOutputStream(expectedFile)); + if ((entry.getMode() & 0755) == 0755) { + expectedFile.setExecutable(true); + } + } + tarArchiveInputStream.close(); + return expectedFile; + } +} diff --git a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java new file mode 100644 index 00000000..b0747e68 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java @@ -0,0 +1,125 @@ +package com.github.dockerjava.core; + +import org.testng.annotations.Test; + +import java.net.URI; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import static org.testng.Assert.assertEquals; + +public class DockerClientConfigTest { + + public static final DockerClientConfig EXAMPLE_CONFIG = newExampleConfig(); + + private static DockerClientConfig newExampleConfig() { + return new DockerClientConfig(URI.create("http://foo"), "bar", "baz", "qux", "blam", "flim", 877, false); + } + + @Test + public void string() throws Exception { + assertEquals("DockerClientConfig{uri=http://foo, version='bar', username='baz', password='qux', email='blam', dockerCertPath='flim', readTimeout=877, loggingFilterEnabled=false}", + EXAMPLE_CONFIG.toString()); + } + + @Test + public void equals() throws Exception { + assertEquals(EXAMPLE_CONFIG, newExampleConfig()); + } + + @Test + public void environmentDockerHost() throws Exception { + + // given docker host in env + Map env = new HashMap(System.getenv()); + env.put("DOCKER_HOST", "tcp://baz:8768"); + + // when you build a config + DockerClientConfig config = buildConfig(env, new Properties()); + + // then the URL is that value with "http" instead of "tcp" + assertEquals(config.getUri(), URI.create("http://baz:8768")); + } + + @Test + public void environmentDockerHostHttpsAutoDetect() throws Exception { + + // given docker host in env + Map env = new HashMap(System.getenv()); + env.put("DOCKER_HOST", "tcp://bar:8768"); + // and it looks to be SSL enabled + env.put("DOCKER_CERT_PATH", "any value"); + + // when you build a config + DockerClientConfig config = buildConfig(env, new Properties()); + + // then the URL is that value with "tcp" changed to "https" + assertEquals(config.getUri(), URI.create("https://bar:8768")); + } + + @Test + public void environment() throws Exception { + + // given a default config in env properties + Map env = new HashMap(); + env.put("DOCKER_URL", "http://foo"); + env.put("DOCKER_VERSION", "bar"); + env.put("DOCKER_USERNAME", "baz"); + env.put("DOCKER_PASSWORD", "qux"); + env.put("DOCKER_EMAIL", "blam"); + env.put("DOCKER_CERT_PATH", "flim"); + env.put("DOCKER_READ_TIMEOUT", "877"); + env.put("DOCKER_LOGGING_FILTER_ENABLED", "false"); + + // when you build a config + DockerClientConfig config = buildConfig(env, new Properties()); + + // then we get the example object + assertEquals(config, EXAMPLE_CONFIG); + } + + private DockerClientConfig buildConfig(Map env, Properties systemProperties) { + return DockerClientConfig.createDefaultConfigBuilder(env, systemProperties).build(); + } + + @Test + public void defaults() throws Exception { + + // given default cert path + Properties systemProperties = new Properties(); + systemProperties.setProperty("user.home", "someHomeDir"); + + // when you build config + DockerClientConfig config = buildConfig(Collections.emptyMap(), systemProperties); + + // then the cert path is as expected + assertEquals(config.getUri(), URI.create("https://localhost:2376")); + assertEquals(config.getVersion(), "1.15"); + assertEquals(config.isLoggingFilterEnabled(), true); + assertEquals(config.getDockerCertPath(), "someHomeDir/.docker"); + } + + @Test + public void systemProperties() throws Exception { + + // given system properties based on the example + Properties systemProperties = new Properties(); + systemProperties.setProperty("docker.io.url", "http://foo"); + systemProperties.setProperty("docker.io.version", "bar"); + systemProperties.setProperty("docker.io.username", "baz"); + systemProperties.setProperty("docker.io.password", "qux"); + systemProperties.setProperty("docker.io.email", "blam"); + systemProperties.setProperty("docker.io.dockerCertPath", "flim"); + systemProperties.setProperty("docker.io.readTimeout", "877"); + systemProperties.setProperty("docker.io.enableLoggingFilter", "false"); + + // when you build new config + DockerClientConfig config = buildConfig(Collections.emptyMap(), systemProperties); + + // then it is the same as the example + assertEquals(config, EXAMPLE_CONFIG); + + } +} \ No newline at end of file diff --git a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java new file mode 100644 index 00000000..a07f8c2e --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java @@ -0,0 +1,322 @@ +package com.github.dockerjava.core; + +import java.io.IOException; +import java.io.InputStream; +import java.security.SecureRandom; +import java.util.ArrayList; +import java.util.List; + +import com.github.dockerjava.api.command.AttachContainerCmd; +import com.github.dockerjava.api.command.AuthCmd.Exec; +import com.github.dockerjava.api.command.BuildImageCmd; +import com.github.dockerjava.api.command.CgroupContainerCmd; +import com.github.dockerjava.api.command.CommitCmd; +import com.github.dockerjava.api.command.ContainerDiffCmd; +import com.github.dockerjava.api.command.CopyFileFromContainerCmd; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.CreateExecCmd; +import com.github.dockerjava.api.command.CreateImageCmd; +import com.github.dockerjava.api.command.CreateImageResponse; +import com.github.dockerjava.api.command.DockerCmdExecFactory; +import com.github.dockerjava.api.command.EventsCmd; +import com.github.dockerjava.api.command.ExecContainerCmd; +import com.github.dockerjava.api.command.InfoCmd; +import com.github.dockerjava.api.command.InspectContainerCmd; +import com.github.dockerjava.api.command.InspectImageCmd; +import com.github.dockerjava.api.command.KillContainerCmd; +import com.github.dockerjava.api.command.LimitContainerCmd; +import com.github.dockerjava.api.command.ListContainersCmd; +import com.github.dockerjava.api.command.ListImagesCmd; +import com.github.dockerjava.api.command.LogContainerCmd; +import com.github.dockerjava.api.command.MetricContainerCmd; +import com.github.dockerjava.api.command.PauseContainerCmd; +import com.github.dockerjava.api.command.PingCmd; +import com.github.dockerjava.api.command.PullImageCmd; +import com.github.dockerjava.api.command.PushImageCmd; +import com.github.dockerjava.api.command.RemoveContainerCmd; +import com.github.dockerjava.api.command.RemoveImageCmd; +import com.github.dockerjava.api.command.RestartContainerCmd; +import com.github.dockerjava.api.command.SearchImagesCmd; +import com.github.dockerjava.api.command.StartContainerCmd; +import com.github.dockerjava.api.command.StartExecCmd; +import com.github.dockerjava.api.command.StopContainerCmd; +import com.github.dockerjava.api.command.SweepContainerCmd; +import com.github.dockerjava.api.command.TagImageCmd; +import com.github.dockerjava.api.command.TopContainerCmd; +import com.github.dockerjava.api.command.UnpauseContainerCmd; +import com.github.dockerjava.api.command.VersionCmd; +import com.github.dockerjava.api.command.WaitContainerCmd; + +/** + * Special {@link DockerCmdExecFactory} implementation that collects container and image creations + * while test execution for the purpose of automatically cleanup. + * + * @author marcus + * + */ +public class TestDockerCmdExecFactory implements DockerCmdExecFactory { + + private List containerNames = new ArrayList(); + + private List imageNames = new ArrayList(); + + private DockerCmdExecFactory delegate; + + public TestDockerCmdExecFactory(DockerCmdExecFactory delegate) { + this.delegate = delegate; + } + + @Override + public void init(DockerClientConfig dockerClientConfig) { + delegate.init(dockerClientConfig); + } + + @Override + public void close() throws IOException { + delegate.close(); + } + + @Override + public CreateContainerCmd.Exec createCreateContainerCmdExec() { + return new CreateContainerCmd.Exec() { + @Override + public CreateContainerResponse exec(CreateContainerCmd command) { + CreateContainerResponse createContainerResponse = delegate.createCreateContainerCmdExec().exec(command); + containerNames.add(createContainerResponse.getId()); + return createContainerResponse; + } + }; + } + + @Override + public RemoveContainerCmd.Exec createRemoveContainerCmdExec() { + return new RemoveContainerCmd.Exec() { + @Override + public Void exec(RemoveContainerCmd command) { + delegate.createRemoveContainerCmdExec().exec(command); + containerNames.remove(command.getContainerId()); + return null; + } + }; + } + + @Override + public CreateImageCmd.Exec createCreateImageCmdExec() { + return new CreateImageCmd.Exec() { + @Override + public CreateImageResponse exec(CreateImageCmd command) { + CreateImageResponse createImageResponse = delegate.createCreateImageCmdExec().exec(command); + imageNames.add(createImageResponse.getId()); + return createImageResponse; + } + }; + } + + + + @Override + public RemoveImageCmd.Exec createRemoveImageCmdExec() { + return new RemoveImageCmd.Exec() { + @Override + public Void exec(RemoveImageCmd command) { + delegate.createRemoveImageCmdExec().exec(command); + imageNames.remove(command.getImageId()); + return null; + } + }; + } + + @Override + public BuildImageCmd.Exec createBuildImageCmdExec() { + return new BuildImageCmd.Exec() { + @Override + public InputStream exec(BuildImageCmd command) { + // can't detect image id here so tagging it + String tag = command.getTag(); + if(tag == null || "".equals(tag.trim())) { + tag = "" + new SecureRandom().nextInt(Integer.MAX_VALUE); + command.withTag(tag); + } + InputStream inputStream = delegate.createBuildImageCmdExec().exec(command); + imageNames.add(tag); + return inputStream; + } + }; + } + + @Override + public Exec createAuthCmdExec() { + return delegate.createAuthCmdExec(); + } + + @Override + public InfoCmd.Exec createInfoCmdExec() { + return delegate.createInfoCmdExec(); + } + + @Override + public PingCmd.Exec createPingCmdExec() { + return delegate.createPingCmdExec(); + } + + @Override + public VersionCmd.Exec createVersionCmdExec() { + return delegate.createVersionCmdExec(); + } + + @Override + public PullImageCmd.Exec createPullImageCmdExec() { + return delegate.createPullImageCmdExec(); + } + + @Override + public PushImageCmd.Exec createPushImageCmdExec() { + return delegate.createPushImageCmdExec(); + } + + @Override + public SearchImagesCmd.Exec createSearchImagesCmdExec() { + return delegate.createSearchImagesCmdExec(); + } + + @Override + public ListImagesCmd.Exec createListImagesCmdExec() { + return delegate.createListImagesCmdExec(); + } + + @Override + public InspectImageCmd.Exec createInspectImageCmdExec() { + return delegate.createInspectImageCmdExec(); + } + + @Override + public ListContainersCmd.Exec createListContainersCmdExec() { + return delegate.createListContainersCmdExec(); + } + + @Override + public StartContainerCmd.Exec createStartContainerCmdExec() { + return delegate.createStartContainerCmdExec(); + } + + @Override + public InspectContainerCmd.Exec createInspectContainerCmdExec() { + return delegate.createInspectContainerCmdExec(); + } + + @Override + public WaitContainerCmd.Exec createWaitContainerCmdExec() { + return delegate.createWaitContainerCmdExec(); + } + + @Override + public AttachContainerCmd.Exec createAttachContainerCmdExec() { + return delegate.createAttachContainerCmdExec(); + } + + @Override + public LogContainerCmd.Exec createLogContainerCmdExec() { + return delegate.createLogContainerCmdExec(); + } + + @Override + public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec() { + return delegate.createCopyFileFromContainerCmdExec(); + } + + @Override + public StopContainerCmd.Exec createStopContainerCmdExec() { + return delegate.createStopContainerCmdExec(); + } + + @Override + public ContainerDiffCmd.Exec createContainerDiffCmdExec() { + return delegate.createContainerDiffCmdExec(); + } + + @Override + public KillContainerCmd.Exec createKillContainerCmdExec() { + return delegate.createKillContainerCmdExec(); + } + + @Override + public RestartContainerCmd.Exec createRestartContainerCmdExec() { + return delegate.createRestartContainerCmdExec(); + } + + @Override + public CommitCmd.Exec createCommitCmdExec() { + return delegate.createCommitCmdExec(); + } + + @Override + public TopContainerCmd.Exec createTopContainerCmdExec() { + return delegate.createTopContainerCmdExec(); + } + + @Override + public TagImageCmd.Exec createTagImageCmdExec() { + return delegate.createTagImageCmdExec(); + } + + @Override + public PauseContainerCmd.Exec createPauseContainerCmdExec() { + return delegate.createPauseContainerCmdExec(); + } + + @Override + public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec() { + return delegate.createUnpauseContainerCmdExec(); + } + + @Override + public EventsCmd.Exec createEventsCmdExec() { + return delegate.createEventsCmdExec(); + } + + @Override + public CgroupContainerCmd.Exec createCgroupContainerCmdExec() { + return delegate.createCgroupContainerCmdExec(); + } + + @Override + public SweepContainerCmd.Exec createSweepContainerCmdExec() { + return delegate.createSweepContainerCmdExec(); + } + + @Override + public MetricContainerCmd.Exec createMetricContainerCmdExec() { + return delegate.createMetricContainerCmdExec(); + } + + @Override + public CreateExecCmd.Exec createCreateExecCmdExec() { + return delegate.createCreateExecCmdExec(); + } + + @Override + public StartExecCmd.Exec createStartExecCmdExec() { + return delegate.createStartExecCmdExec(); + } + + @Override + public ExecContainerCmd.Exec createExecContainerCmdExec( + CreateExecCmd createExecCmd, StartExecCmd startExecCmd) { + return delegate.createExecContainerCmdExec(createExecCmd, startExecCmd); + } + + @Override + public LimitContainerCmd.Exec createLimitContainerCmdExec() { + return delegate.createLimitContainerCmdExec(); + } + + public List getContainerNames() { + return new ArrayList(containerNames); + } + + public List getImageNames() { + return new ArrayList(imageNames); + } + +} diff --git a/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java new file mode 100644 index 00000000..3c03b1b4 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java @@ -0,0 +1,59 @@ +package com.github.dockerjava.core.command; + +import java.lang.reflect.Method; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.UnauthorizedException; +import com.github.dockerjava.client.AbstractDockerClientTest; +import com.github.dockerjava.core.DockerClientBuilder; +import com.github.dockerjava.core.DockerClientConfig; + +@Test(groups = "integration") +public class AuthCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void testAuth() throws Exception { + dockerClient.authCmd().exec(); + } + + @Test + public void testAuthInvalid() throws Exception { + DockerClientConfig config = DockerClientConfig.createDefaultConfigBuilder().withPassword("garbage").build(); + DockerClient client = DockerClientBuilder.getInstance(config).withDockerCmdExecFactory(dockerCmdExecFactory).build(); + + try { + client.authCmd().exec(); + fail("Expected a UnauthorizedException caused by a bad password."); + } catch (UnauthorizedException e) { + + } + } +} diff --git a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java new file mode 100644 index 00000000..62603706 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java @@ -0,0 +1,184 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; + +import org.apache.commons.lang.StringUtils; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.command.InspectImageResponse; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class BuildImageCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void testNginxDockerfileBuilder() { + File baseDir = new File(Thread.currentThread().getContextClassLoader() + .getResource("nginx").getFile()); + + InputStream response = dockerClient.buildImageCmd(baseDir).withNoCache().exec(); + + String fullLog = asString(response); + assertThat(fullLog, containsString("Successfully built")); + + String imageId = StringUtils.substringBetween(fullLog, + "Successfully built ", "\\n\"}").trim(); + + InspectImageResponse inspectImageResponse = dockerClient + .inspectImageCmd(imageId).exec(); + assertThat(inspectImageResponse, not(nullValue())); + LOG.info("Image Inspect: {}", inspectImageResponse.toString()); + + assertThat(inspectImageResponse.getAuthor(), + equalTo("Guillaume J. Charmes \"guillaume@dotcloud.com\"")); + } + + @Test + public void testDockerBuilderAddUrl() { + File baseDir = new File(Thread.currentThread().getContextClassLoader() + .getResource("testAddUrl").getFile()); + dockerfileBuild(baseDir, "Docker"); + } + + @Test + public void testDockerBuilderAddFileInSubfolder() throws DockerException, + IOException { + File baseDir = new File(Thread.currentThread().getContextClassLoader() + .getResource("testAddFileInSubfolder").getFile()); + dockerfileBuild(baseDir, "Successfully executed testrun.sh"); + } + + @Test + public void testDockerBuilderAddFolder() throws DockerException, + IOException { + File baseDir = new File(Thread.currentThread().getContextClassLoader() + .getResource("testAddFolder").getFile()); + dockerfileBuild(baseDir, "Successfully executed testAddFolder.sh"); + } + + + private String dockerfileBuild(File baseDir, String expectedText) { + + // Build image + InputStream response = dockerClient.buildImageCmd(baseDir).withNoCache().exec(); + + String fullLog = asString(response); + assertThat(fullLog, containsString("Successfully built")); + + String imageId = StringUtils.substringBetween(fullLog, + "Successfully built ", "\\n\"}").trim(); + + // Create container based on image + CreateContainerResponse container = dockerClient.createContainerCmd( + imageId).exec(); + + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + dockerClient.waitContainerCmd(container.getId()).exec(); + + // Log container + InputStream logResponse = logContainer(container + .getId()); + + assertThat(asString(logResponse), containsString(expectedText)); + + return container.getId(); + } + + + private InputStream logContainer(String containerId) { + return dockerClient.logContainerCmd(containerId).withStdErr().withStdOut().exec(); + } + + @Test + public void testNetCatDockerfileBuilder() throws InterruptedException { + File baseDir = new File(Thread.currentThread().getContextClassLoader() + .getResource("netcat").getFile()); + + InputStream response = dockerClient.buildImageCmd(baseDir).withNoCache().exec(); + + String fullLog = asString(response); + + assertThat(fullLog, containsString("Successfully built")); + + String imageId = StringUtils.substringBetween(fullLog, + "Successfully built ", "\\n\"}").trim(); + + InspectImageResponse inspectImageResponse = dockerClient + .inspectImageCmd(imageId).exec(); + assertThat(inspectImageResponse, not(nullValue())); + assertThat(inspectImageResponse.getId(), not(nullValue())); + LOG.info("Image Inspect: {}", inspectImageResponse.toString()); + + CreateContainerResponse container = dockerClient.createContainerCmd( + inspectImageResponse.getId()).exec(); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + + assertThat(inspectContainerResponse.getId(), notNullValue()); + assertThat(inspectContainerResponse.getNetworkSettings().getPorts(), + notNullValue()); + + // No use as such if not running on the server +// for (Ports.Port p : inspectContainerResponse.getNetworkSettings().getPorts().getAllPorts()) { +// int port = Integer.valueOf(p.getHostPort()); +// LOG.info("Checking port {} is open", port); +// assertThat(available(port), is(false)); +// } + dockerClient.stopContainerCmd(container.getId()).withTimeout(0).exec(); + + } + + @Test + public void testAddAndCopySubstitution () throws DockerException, IOException { + File baseDir = new File(Thread.currentThread().getContextClassLoader() + .getResource("testENVSubstitution").getFile()); + dockerfileBuild(baseDir, "testENVSubstitution successfully completed"); + + } +} diff --git a/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java new file mode 100644 index 00000000..ea5f6128 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java @@ -0,0 +1,87 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.startsWith; +import static org.testinfected.hamcrest.jpa.HasFieldWithValue.hasField; + +import java.lang.reflect.Method; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectImageResponse; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class CommitCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void commit() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("touch", "/test").exec(); + + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + LOG.info("Commiting container: {}", container.toString()); + String imageId = dockerClient + .commitCmd(container.getId()).exec(); + + InspectImageResponse inspectImageResponse = dockerClient + .inspectImageCmd(imageId).exec(); + LOG.info("Image Inspect: {}", inspectImageResponse.toString()); + + assertThat(inspectImageResponse, + hasField("container", startsWith(container.getId()))); + assertThat(inspectImageResponse.getContainerConfig().getImage(), + equalTo("busybox")); + + InspectImageResponse busyboxImg = dockerClient.inspectImageCmd("busybox").exec(); + + assertThat(inspectImageResponse.getParent(), + equalTo(busyboxImg.getId())); + } + + + @Test + public void commitNonExistingContainer() throws DockerException { + try { + dockerClient.commitCmd("non-existent").exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + } + } + +} diff --git a/src/test/java/com/github/dockerjava/core/command/ContainerDiffCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ContainerDiffCmdImplTest.java new file mode 100644 index 00000000..8d6f9254 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/ContainerDiffCmdImplTest.java @@ -0,0 +1,81 @@ +package com.github.dockerjava.core.command; + +import static ch.lambdaj.Lambda.selectUnique; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; +import static org.testinfected.hamcrest.jpa.HasFieldWithValue.hasField; + +import java.lang.reflect.Method; +import java.util.List; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.model.ChangeLog; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class ContainerDiffCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void testContainerDiff() throws DockerException { + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("touch", "/test" ).exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(); + assertThat(exitCode, equalTo(0)); + + List filesystemDiff = dockerClient.containerDiffCmd(container.getId()).exec(); + LOG.info("Container DIFF: {}", filesystemDiff.toString()); + + assertThat(filesystemDiff.size(), equalTo(1)); + ChangeLog testChangeLog = selectUnique(filesystemDiff, + hasField("path", equalTo("/test"))); + + assertThat(testChangeLog, hasField("path", equalTo("/test"))); + assertThat(testChangeLog, hasField("kind", equalTo(1))); + } + + @Test + public void testContainerDiffWithNonExistingContainer() throws DockerException { + try { + dockerClient.containerDiffCmd("non-existing").exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + } + } + + +} diff --git a/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java new file mode 100644 index 00000000..945b6198 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java @@ -0,0 +1,64 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.client.AbstractDockerClientTest; + +import org.testng.ITestResult; +import org.testng.annotations.*; + +import java.io.InputStream; +import java.lang.reflect.Method; + +import static org.hamcrest.Matchers.*; +import static org.hamcrest.MatcherAssert.assertThat; + +@Test(groups = "integration") +public class CopyFileFromContainerCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void copyFromContainer() throws Exception { + // TODO extract this into a shared method + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withName("docker-java-itest-copyFromContainer") + .withCmd("touch", "/test") + .exec(); + + LOG.info("Created container: {}", container); + assertThat(container.getId(), not(isEmptyOrNullString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + + InputStream response = dockerClient.copyFileFromContainerCmd(container.getId(), "/test").exec(); + assertTrue(response.available() > 0, "The file was not copied from the container."); + } + + @Test + public void copyFromNonExistingContainer() throws Exception { + try { + dockerClient.copyFileFromContainerCmd("non-existing", "/test").exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + } + } +} diff --git a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java new file mode 100644 index 00000000..284fd772 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -0,0 +1,162 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +import java.lang.reflect.Method; +import java.security.SecureRandom; +import java.util.Arrays; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.ConflictException; +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.model.Volume; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class CreateContainerCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void createContainerWithExistingName() throws DockerException { + + String containerName = "generated_" + new SecureRandom().nextInt(); + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("env") + .withName(containerName).exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + try { + dockerClient.createContainerCmd("busybox").withCmd("env") + .withName(containerName).exec(); + fail("expected ConflictException"); + } catch (ConflictException e) { + } + } + + @Test + public void createContainerWithVolume() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox") + .withVolumes(new Volume("/var/log")).withCmd("true").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + + LOG.info("Inspect container {}", inspectContainerResponse.getConfig() + .getVolumes()); + + assertThat(inspectContainerResponse.getConfig().getVolumes().keySet(), + contains("/var/log")); + } + + @Test + public void createContainerWithEnv() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withEnv("VARIABLE=success") + .withCmd("env").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + + assertThat( + Arrays.asList(inspectContainerResponse.getConfig().getEnv()), + containsInAnyOrder("VARIABLE=success", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin")); + + dockerClient.startContainerCmd(container.getId()).exec(); + + assertThat(asString(dockerClient.logContainerCmd(container.getId()) + .withStdOut().exec()), containsString("VARIABLE=success")); + } + + @Test + public void createContainerWithHostname() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withHostName("docker-java") + .withCmd("env").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + + assertThat(inspectContainerResponse.getConfig().getHostName(), + equalTo("docker-java")); + + dockerClient.startContainerCmd(container.getId()).exec(); + + assertThat(asString(dockerClient.logContainerCmd(container.getId()) + .withStdOut().exec()), containsString("HOSTNAME=docker-java")); + } + + @Test + public void createContainerWithName() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withName("container") + .withCmd("env").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + + assertThat(inspectContainerResponse.getName(), equalTo("/container")); + + try { + dockerClient.createContainerCmd("busybox").withName("container") + .withCmd("env").exec(); + fail("Expected ConflictException"); + } catch (ConflictException e) { + } + + } + +} diff --git a/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java new file mode 100644 index 00000000..6935227b --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java @@ -0,0 +1,129 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.EventCallback; +import com.github.dockerjava.api.command.EventsCmd; +import com.github.dockerjava.api.model.Event; +import com.github.dockerjava.client.AbstractDockerClientTest; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.TimeUnit; + +@Test(groups = "integration") +public class EventsCmdImplTest extends AbstractDockerClientTest { + + private static int KNOWN_NUM_EVENTS = 4; + + private static String getEpochTime() { + return String.valueOf(System.currentTimeMillis() / 1000); + } + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void testEventStreamTimeBound() throws InterruptedException, IOException { + // Don't include other tests events + TimeUnit.SECONDS.sleep(1); + + String startTime = getEpochTime(); + int expectedEvents = generateEvents(); + String endTime = getEpochTime(); + + CountDownLatch countDownLatch = new CountDownLatch(expectedEvents); + EventCallback eventCallback = new EventCallbackTest(countDownLatch); + + EventsCmd eventsCmd = dockerClient.eventsCmd(eventCallback).withSince(startTime).withUntil(endTime); + ExecutorService executorService = eventsCmd.exec(); + + boolean zeroCount = countDownLatch.await(5, TimeUnit.SECONDS); + + executorService.shutdown(); + + + assertTrue(zeroCount, "Expected 4 events, [create, start, die, stop]"); + } + + @Test + public void testEventStreaming() throws InterruptedException, IOException { + // Don't include other tests events + TimeUnit.SECONDS.sleep(1); + + CountDownLatch countDownLatch = new CountDownLatch(KNOWN_NUM_EVENTS); + EventCallback eventCallback = new EventCallbackTest(countDownLatch); + + EventsCmd eventsCmd = dockerClient.eventsCmd(eventCallback).withSince(getEpochTime()); + ExecutorService executorService = eventsCmd.exec(); + + generateEvents(); + + boolean zeroCount = countDownLatch.await(5, TimeUnit.SECONDS); + executorService.shutdown(); + assertTrue(zeroCount, "Expected 4 events, [create, start, die, stop]"); + } + + /** + * This method generates {#link KNOWN_NUM_EVENTS} events + */ + private int generateEvents() { + String testImage = "busybox"; + asString(dockerClient.pullImageCmd(testImage).exec()); + CreateContainerResponse container = dockerClient + .createContainerCmd(testImage).withCmd("echo").exec(); + dockerClient.startContainerCmd(container.getId()).exec(); + dockerClient.stopContainerCmd(container.getId()).exec(); + return KNOWN_NUM_EVENTS; + } + + private class EventCallbackTest implements EventCallback { + private final CountDownLatch countDownLatch; + + public EventCallbackTest(CountDownLatch countDownLatch) { + this.countDownLatch = countDownLatch; + } + + @Override + public void onEvent(Event event) { + LOG.info("Received event #{}: {}", countDownLatch.getCount(), event); + countDownLatch.countDown(); + } + + @Override + public void onException(Throwable throwable) { + LOG.error("Error occurred: {}", throwable.getMessage()); + } + + @Override + public void onCompletion(int numEvents) { + LOG.info("Number of events received: {}", numEvents); + } + } +} diff --git a/src/test/java/com/github/dockerjava/core/command/InfoCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/InfoCmdImplTest.java new file mode 100644 index 00000000..37214418 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/InfoCmdImplTest.java @@ -0,0 +1,73 @@ +package com.github.dockerjava.core.command; + +import java.lang.reflect.Method; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.model.Info; +import com.github.dockerjava.client.AbstractDockerClientTest; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.isEmptyOrNullString; +import static org.hamcrest.Matchers.not; + +@Test(groups = "integration") +public class InfoCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void info() throws DockerException { + // Make sure that there is at least one container for the assertion + // TODO extract this into a shared method + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withName("docker-java-itest-info") + .withCmd("touch", "/test") + .exec(); + + LOG.info("Created container: {}", container); + assertThat(container.getId(), not(isEmptyOrNullString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + + Info dockerInfo = dockerClient.infoCmd().exec(); + LOG.info(dockerInfo.toString()); + + assertTrue(dockerInfo.toString().contains("containers")); + assertTrue(dockerInfo.toString().contains("images")); + assertTrue(dockerInfo.toString().contains("debug")); + + assertTrue(dockerInfo.getContainers() > 0); + assertTrue(dockerInfo.getImages() > 0); + assertTrue(dockerInfo.getNFd() > 0); + assertTrue(dockerInfo.getNGoroutines() > 0); + assertTrue(dockerInfo.isMemoryLimit()); + } + + +} diff --git a/src/test/java/com/github/dockerjava/core/command/KillContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/KillContainerCmdImplTest.java new file mode 100644 index 00000000..419d6e02 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/KillContainerCmdImplTest.java @@ -0,0 +1,85 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; + +import java.lang.reflect.Method; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class KillContainerCmdImplTest extends AbstractDockerClientTest { + + public static final Logger LOG = LoggerFactory + .getLogger(KillContainerCmdImplTest.class); + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void killContainer() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + LOG.info("Killing container: {}", container.getId()); + dockerClient.killContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); + + assertThat(inspectContainerResponse.getState().isRunning(), + is(equalTo(false))); + assertThat(inspectContainerResponse.getState().getExitCode(), + not(equalTo(0))); + + } + + @Test + public void killNonExistingContainer() throws DockerException { + + try { + dockerClient.killContainerCmd("non-existing").exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + } + } + +} diff --git a/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java new file mode 100644 index 00000000..f73ac5e4 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java @@ -0,0 +1,106 @@ +package com.github.dockerjava.core.command; + +import static ch.lambdaj.Lambda.filter; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; +import static org.testinfected.hamcrest.jpa.HasFieldWithValue.hasField; + +import java.lang.reflect.Method; +import java.util.List; + +import org.hamcrest.Matcher; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.model.Container; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class ListContainersCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void testListContainers() throws DockerException { + + String testImage = "busybox"; + + // need to block until image is pulled completely + asString(dockerClient.pullImageCmd(testImage).exec()); + + List containers = dockerClient.listContainersCmd().withShowAll(true).exec(); + assertThat(containers, notNullValue()); + LOG.info("Container List: {}", containers); + + int size = containers.size(); + + CreateContainerResponse container1 = dockerClient + .createContainerCmd(testImage).withCmd("echo").exec(); + + assertThat(container1.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container1.getId()).exec(); + + assertThat(inspectContainerResponse.getConfig().getImage(), is(equalTo(testImage))); + + dockerClient.startContainerCmd(container1.getId()).exec(); + + LOG.info("container id: " + container1.getId()); + + List containers2 = dockerClient.listContainersCmd().withShowAll(true).exec(); + + for(Container container: containers2) { + LOG.info("listContainer: id=" + container.getId() +" image=" + container.getImage()); + } + + assertThat(size + 1, is(equalTo(containers2.size()))); + Matcher matcher = hasItem(hasField("id", startsWith(container1.getId()))); + assertThat(containers2, matcher); + + List filteredContainers = filter( + hasField("id", startsWith(container1.getId())), containers2); + assertThat(filteredContainers.size(), is(equalTo(1))); + + for(Container container: filteredContainers) { + LOG.info("filteredContainer: " + container); + } + + Container container2 = filteredContainers.get(0); + assertThat(container2.getCommand(), not(isEmptyString())); + assertThat(container2.getImage(), startsWith(testImage + ":")); + } + + + +} diff --git a/src/test/java/com/github/dockerjava/core/command/ListImagesCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ListImagesCmdImplTest.java new file mode 100644 index 00000000..b2f3b88e --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/ListImagesCmdImplTest.java @@ -0,0 +1,61 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +import java.lang.reflect.Method; +import java.util.List; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.model.Image; +import com.github.dockerjava.api.model.Info; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class ListImagesCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void listImages() throws DockerException { + List images = dockerClient.listImagesCmd().withShowAll(true).exec(); + assertThat(images, notNullValue()); + LOG.info("Images List: {}", images); + Info info = dockerClient.infoCmd().exec(); + + assertThat(images.size(), equalTo(info.getImages())); + + Image img = images.get(0); + assertThat(img.getCreated(), is(greaterThan(0L))); + assertThat(img.getVirtualSize(), is(greaterThan(0L))); + assertThat(img.getId(), not(isEmptyString())); + assertThat(img.getRepoTags(), not(emptyArray())); + } + + +} diff --git a/src/test/java/com/github/dockerjava/core/command/LogContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/LogContainerCmdImplTest.java new file mode 100644 index 00000000..84299219 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/LogContainerCmdImplTest.java @@ -0,0 +1,84 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; + +import java.io.InputStream; +import java.lang.reflect.Method; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class LogContainerCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void logContainer() throws Exception { + + String snippet = "hello world"; + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("/bin/echo", snippet).exec(); + + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + + int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(); + + assertThat(exitCode, equalTo(0)); + + InputStream response = dockerClient.logContainerCmd(container.getId()).withStdErr().withStdOut().exec(); + + String log = asString(response); + + //LOG.info("resonse: " + log); + + assertThat(log, endsWith(snippet)); + } + + @Test + public void logNonExistingContainer() throws Exception { + + try { + dockerClient.logContainerCmd("non-existing").withStdErr().withStdOut().exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + } + } + + +} diff --git a/src/test/java/com/github/dockerjava/core/command/PullImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/PullImageCmdImplTest.java new file mode 100644 index 00000000..84af9e72 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/PullImageCmdImplTest.java @@ -0,0 +1,110 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.lessThanOrEqualTo; +import static org.hamcrest.Matchers.notNullValue; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Method; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.InternalServerErrorException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.InspectImageResponse; +import com.github.dockerjava.api.model.Info; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class PullImageCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void testPullImage() throws DockerException, IOException { + Info info = dockerClient.infoCmd().exec(); + LOG.info("Client info: {}", info.toString()); + + int imgCount = info.getImages(); + LOG.info("imgCount1: {}", imgCount); + + // This should be an image that is not used by other repositories + // already + // pulled down, preferably small in size. If tag is not used pull will + // download all images in that repository but tmpImgs will only + // deleted 'latest' image but not images with other tags + String testImage = "hackmann/empty"; + + LOG.info("Removing image: {}", testImage); + + try { + dockerClient.removeImageCmd(testImage).exec(); + } catch (NotFoundException e) { + // just ignore if not exist + } + + + info = dockerClient.infoCmd().exec(); + LOG.info("Client info: {}", info.toString()); + + imgCount = info.getImages(); + LOG.info("imgCount2: {}", imgCount); + + LOG.info("Pulling image: {}", testImage); + + InputStream response = dockerClient.pullImageCmd(testImage).exec(); + + assertThat(asString(response), containsString("Download complete")); + + info = dockerClient.infoCmd().exec(); + LOG.info("Client info after pull, {}", info.toString()); + + assertThat(imgCount, lessThanOrEqualTo(info.getImages())); + + InspectImageResponse inspectImageResponse = dockerClient + .inspectImageCmd(testImage).exec(); + LOG.info("Image Inspect: {}", inspectImageResponse.toString()); + assertThat(inspectImageResponse, notNullValue()); + } + + @Test + public void testPullNonExistingImage() throws DockerException, IOException { + + // does not throw an exception + dockerClient.pullImageCmd("nonexisting/foo").exec(); + + try { + dockerClient.pullImageCmd("non-existing/foo").exec(); + fail("expected InternalServerErrorException"); + } catch (InternalServerErrorException e) { + } + + } + +} diff --git a/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java new file mode 100644 index 00000000..b12ac4ec --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java @@ -0,0 +1,82 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; + +import java.lang.reflect.Method; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class PushImageCmdImplTest extends AbstractDockerClientTest { + + public static final Logger LOG = LoggerFactory + .getLogger(PushImageCmdImplTest.class); + + String username; + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + username = dockerClient.authConfig().getUsername(); + } + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void pushLatest() throws Exception { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("true").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + LOG.info("Commiting container: {}", container.toString()); + String imageId = dockerClient.commitCmd(container.getId()).withRepository(username + "/busybox").exec(); + + // we have to block until image is pushed + asString(dockerClient.pushImageCmd(username + "/busybox").exec()); + + dockerClient.removeImageCmd(imageId).exec(); + + String response = asString(dockerClient.pullImageCmd(username + "/busybox").exec()); + + assertThat(response, not(containsString("HTTP code: 404"))); + } + + @Test + public void pushExistentImage() throws Exception { + + assertThat(asString(dockerClient.pushImageCmd(username + "/xxx").exec()), containsString("error")); + } + + +} + diff --git a/src/test/java/com/github/dockerjava/core/command/RemoveContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RemoveContainerCmdImplTest.java new file mode 100644 index 00000000..9c23d70e --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/RemoveContainerCmdImplTest.java @@ -0,0 +1,84 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.startsWith; +import static org.testinfected.hamcrest.jpa.HasFieldWithValue.hasField; + +import java.lang.reflect.Method; +import java.util.List; + +import org.hamcrest.Matcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.model.Container; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class RemoveContainerCmdImplTest extends AbstractDockerClientTest { + + public static final Logger LOG = LoggerFactory + .getLogger(RemoveContainerCmdImplTest.class); + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void removeContainer() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("true").exec(); + + dockerClient.startContainerCmd(container.getId()).exec(); + dockerClient.waitContainerCmd(container.getId()).exec(); + + LOG.info("Removing container: {}", container.getId()); + dockerClient.removeContainerCmd(container.getId()).exec(); + + List containers2 = dockerClient.listContainersCmd().withShowAll(true).exec(); + + Matcher matcher = not(hasItem(hasField("id", + startsWith(container.getId())))); + assertThat(containers2, matcher); + + } + + @Test + public void removeNonExistingContainer() throws DockerException { + try { + dockerClient.removeContainerCmd("non-existing").exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + } + } + + +} + diff --git a/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java new file mode 100644 index 00000000..ec6b6ec3 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java @@ -0,0 +1,92 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.startsWith; +import static org.testinfected.hamcrest.jpa.HasFieldWithValue.hasField; + +import java.lang.reflect.Method; +import java.util.List; + +import org.hamcrest.Matcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.model.Container; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class RemoveImageCmdImplTest extends AbstractDockerClientTest { + + public static final Logger LOG = LoggerFactory + .getLogger(RemoveImageCmdImplTest.class); + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void removeImage() throws DockerException, InterruptedException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + LOG.info("Commiting container {}", container.toString()); + String imageId = dockerClient + .commitCmd(container.getId()).exec(); + + dockerClient.stopContainerCmd(container.getId()).exec(); + dockerClient.killContainerCmd(container.getId()).exec(); + dockerClient.removeContainerCmd(container.getId()).exec(); + + LOG.info("Removing image: {}", imageId); + dockerClient.removeImageCmd(imageId).exec(); + + List containers = dockerClient.listContainersCmd().withShowAll(true).exec(); + + Matcher matcher = not(hasItem(hasField("id", startsWith(imageId)))); + assertThat(containers, matcher); + } + + @Test + public void removeNonExistingImage() throws DockerException, InterruptedException { + try { + dockerClient.removeImageCmd("non-existing").exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + } + + } + + +} + diff --git a/src/test/java/com/github/dockerjava/core/command/RestartContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RestartContainerCmdImplTest.java new file mode 100644 index 00000000..b6040a0f --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/RestartContainerCmdImplTest.java @@ -0,0 +1,90 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; + +import java.lang.reflect.Method; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class RestartContainerCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void restartContainer() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); + + String startTime = inspectContainerResponse.getState().getStartedAt(); + + dockerClient.restartContainerCmd(container.getId()).withtTimeout(2).exec(); + + InspectContainerResponse inspectContainerResponse2 = dockerClient + .inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect After Restart: {}", + inspectContainerResponse2.toString()); + + String startTime2 = inspectContainerResponse2.getState().getStartedAt(); + + assertThat(startTime, not(equalTo(startTime2))); + + assertThat(inspectContainerResponse.getState().isRunning(), + is(equalTo(true))); + + dockerClient.killContainerCmd(container.getId()).exec(); + } + + @Test + public void restartNonExistingContainer() throws DockerException, InterruptedException { + try { + dockerClient.restartContainerCmd("non-existing").exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + } + + } + + +} diff --git a/src/test/java/com/github/dockerjava/core/command/SearchImagesCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/SearchImagesCmdImplTest.java new file mode 100644 index 00000000..5c239353 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/SearchImagesCmdImplTest.java @@ -0,0 +1,62 @@ +package com.github.dockerjava.core.command; + +import static ch.lambdaj.Lambda.filter; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.is; +import static org.testinfected.hamcrest.jpa.HasFieldWithValue.hasField; + +import java.lang.reflect.Method; +import java.util.List; + +import org.hamcrest.Matcher; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.model.SearchItem; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class SearchImagesCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void searchImages() throws DockerException { + List dockerSearch = dockerClient.searchImagesCmd("busybox").exec(); + LOG.info("Search returned {}", dockerSearch.toString()); + + Matcher matcher = hasItem(hasField("name", equalTo("busybox"))); + assertThat(dockerSearch, matcher); + + assertThat( + filter(hasField("name", is("busybox")), dockerSearch).size(), + equalTo(1)); + } + + +} diff --git a/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java new file mode 100644 index 00000000..469259ee --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java @@ -0,0 +1,391 @@ +package com.github.dockerjava.core.command; + +import static com.github.dockerjava.api.model.AccessMode.ro; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; + +import java.lang.reflect.Method; +import java.util.*; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.model.*; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class StartContainerCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void startContainerWithVolumes() throws DockerException { + + // see http://docs.docker.io/use/working_with_volumes/ + Volume volume1 = new Volume("/opt/webapp1"); + + Volume volume2 = new Volume("/opt/webapp2"); + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withVolumes(volume1, volume2) + .withCmd("true").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + + assertThat(inspectContainerResponse.getConfig().getVolumes().keySet(), + contains("/opt/webapp1", "/opt/webapp2")); + + dockerClient.startContainerCmd(container.getId()).withBinds(new Bind("/src/webapp1", volume1, ro), new Bind("/src/webapp2", volume2)).exec(); + + dockerClient.waitContainerCmd(container.getId()).exec(); + + inspectContainerResponse = dockerClient.inspectContainerCmd(container + .getId()).exec(); + + VolumeBind[] volumeBinds = inspectContainerResponse.getVolumes(); + List volumes = new ArrayList(); + for(VolumeBind bind :volumeBinds){ + volumes.add(bind.getContainerPath()); + } + assertThat(volumes, contains(volume1.getPath(), volume2.getPath())); + + assertThat(Arrays.asList(inspectContainerResponse.getVolumesRW()), + contains(volume1, volume2)); + + } + + @Test + public void startContainerWithDns() throws DockerException { + + String aDnsServer = "8.8.8.8"; + String anotherDnsServer = "8.8.4.4"; + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox") + .withCmd("true").withDns(aDnsServer, anotherDnsServer).exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + + dockerClient.startContainerCmd(container.getId()).withDns(aDnsServer, anotherDnsServer).exec(); + + inspectContainerResponse = dockerClient.inspectContainerCmd(container + .getId()).exec(); + + assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getDns()), + contains(aDnsServer, anotherDnsServer)); + } + + @Test + public void startContainerWithDnsSearch() throws DockerException { + + String dnsSearch = "example.com"; + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox") + .withCmd("true").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + + dockerClient.startContainerCmd(container.getId()).withDnsSearch(dnsSearch).exec(); + + inspectContainerResponse = dockerClient.inspectContainerCmd(container + .getId()).exec(); + + assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getDnsSearch()), + contains(dnsSearch)); + } + + @Test + public void startContainerWithPortBindings() throws DockerException { + + ExposedPort tcp22 = ExposedPort.tcp(22); + ExposedPort tcp23 = ExposedPort.tcp(23); + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox") + .withCmd("true").withExposedPorts(tcp22, tcp23).exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + + Ports portBindings = new Ports(); + portBindings.bind(tcp22, Ports.Binding(11022)); + portBindings.bind(tcp23, Ports.Binding(11023)); + portBindings.bind(tcp23, Ports.Binding(11024)); + + dockerClient.startContainerCmd(container.getId()).withPortBindings(portBindings).exec(); + + inspectContainerResponse = dockerClient.inspectContainerCmd(container + .getId()).exec(); + + assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), + contains(tcp22, tcp23)); + + assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp22)[0], + is(equalTo(Ports.Binding(11022)))); + + assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[0], + is(equalTo(Ports.Binding(11023)))); + + assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[1], + is(equalTo(Ports.Binding(11024)))); + + } + + @Test + public void startContainerWithLinking() throws DockerException { + + CreateContainerResponse container1 = dockerClient + .createContainerCmd("busybox").withCmd("sleep", "9999").withName("container1").exec(); + + LOG.info("Created container1 {}", container1.toString()); + assertThat(container1.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container1.getId()).exec(); + + InspectContainerResponse inspectContainerResponse1 = dockerClient + .inspectContainerCmd(container1.getId()).exec(); + LOG.info("Container1 Inspect: {}", inspectContainerResponse1.toString()); + + assertThat(inspectContainerResponse1.getConfig(), is(notNullValue())); + assertThat(inspectContainerResponse1.getId(), not(isEmptyString())); + assertThat(inspectContainerResponse1.getId(), startsWith(container1.getId())); + assertThat(inspectContainerResponse1.getName(), equalTo("/container1")); + assertThat(inspectContainerResponse1.getImageId(), not(isEmptyString())); + assertThat(inspectContainerResponse1.getState(), is(notNullValue())); + assertThat(inspectContainerResponse1.getState().isRunning(), is(true)); + + if (!inspectContainerResponse1.getState().isRunning()) { + assertThat(inspectContainerResponse1.getState().getExitCode(), + is(equalTo(0))); + } + + CreateContainerResponse container2 = dockerClient + .createContainerCmd("busybox").withCmd("true").withName("container2").exec(); + + LOG.info("Created container2 {}", container2.toString()); + assertThat(container2.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container2.getId()).withLinks(new Link("container1", "container1Link")).exec(); + + InspectContainerResponse inspectContainerResponse2 = dockerClient + .inspectContainerCmd(container2.getId()).exec(); + LOG.info("Container2 Inspect: {}", inspectContainerResponse2.toString()); + + assertThat(inspectContainerResponse2.getConfig(), is(notNullValue())); + assertThat(inspectContainerResponse2.getId(), not(isEmptyString())); + assertThat(inspectContainerResponse2.getHostConfig(), is(notNullValue())); + assertThat(inspectContainerResponse2.getHostConfig().getLinks(), is(notNullValue())); + assertThat(inspectContainerResponse2.getHostConfig().getLinks(), equalTo(new String[] {"/container1:/container2/container1Link"})); + assertThat(inspectContainerResponse2.getId(), startsWith(container2.getId())); + assertThat(inspectContainerResponse2.getName(), equalTo("/container2")); + assertThat(inspectContainerResponse2.getImageId(), not(isEmptyString())); + assertThat(inspectContainerResponse2.getState(), is(notNullValue())); + assertThat(inspectContainerResponse2.getState().isRunning(), is(true)); + + } + + + @Test + public void startContainer() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd(new String[] { "top" }).exec(); + + LOG.info("Created container {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); + + assertThat(inspectContainerResponse.getConfig(), is(notNullValue())); + assertThat(inspectContainerResponse.getId(), not(isEmptyString())); + + assertThat(inspectContainerResponse.getId(), + startsWith(container.getId())); + + assertThat(inspectContainerResponse.getImageId(), not(isEmptyString())); + assertThat(inspectContainerResponse.getState(), is(notNullValue())); + + assertThat(inspectContainerResponse.getState().isRunning(), is(true)); + + if (!inspectContainerResponse.getState().isRunning()) { + assertThat(inspectContainerResponse.getState().getExitCode(), + is(equalTo(0))); + } + } + + @Test + public void testStartNonExistingContainer() throws DockerException { + try { + dockerClient.startContainerCmd("non-existing").exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + } + } + + /** + * This tests support for --net option for the docker run command: + * --net="bridge" Set the Network mode for the container + * 'bridge': creates a new network stack for the container on the docker bridge + * 'none': no networking for this container + * 'container:': reuses another container network stack + * 'host': use the host network stack inside the container. + * Note: the host mode gives the container full access to local system services such as D-bus and is therefore considered insecure. + */ + @Test + public void startContainerWithNetworkMode() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox") + .withCmd("true").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + + dockerClient.startContainerCmd(container.getId()).withNetworkMode("host").exec(); + + inspectContainerResponse = dockerClient.inspectContainerCmd(container + .getId()).exec(); + + assertThat(inspectContainerResponse.getHostConfig().getNetworkMode(), + is(equalTo("host"))); + } + + @Test + public void startContainerWithCapAddAndCapDrop() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox") + .withCmd("sleep", "9999").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()) + .withCapAdd("NET_ADMIN") + .withCapDrop("MKNOD").exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container + .getId()).exec(); + + assertThat(inspectContainerResponse.getState().isRunning(), is(true)); + + assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getCapAdd()), + contains("NET_ADMIN")); + + assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getCapDrop()), + contains("MKNOD")); + } + + @Test + public void startContainerWithDevices() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox") + .withCmd("sleep", "9999").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()) + .withDevices(new Device("rwm", "/dev/nulo", "/dev/zero")) + .exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container + .getId()).exec(); + + assertThat(inspectContainerResponse.getState().isRunning(), is(true)); + + assertThat(Arrays.asList(inspectContainerResponse.getHostConfig().getDevices()), + contains(new Device("rwm", "/dev/nulo", "/dev/zero"))); + } + + @Test + public void startContainerWithRestartPolicy() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox") + .withCmd("sleep", "9999").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + RestartPolicy restartPolicy = RestartPolicy.onFailureRestart(5); + + dockerClient.startContainerCmd(container.getId()) + .withRestartPolicy(restartPolicy) + .exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container + .getId()).exec(); + + assertThat(inspectContainerResponse.getState().isRunning(), is(true)); + + assertThat(inspectContainerResponse.getHostConfig().getRestartPolicy(), + is(equalTo(restartPolicy))); + } + +} diff --git a/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java new file mode 100644 index 00000000..d4681428 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java @@ -0,0 +1,82 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; + +import java.lang.reflect.Method; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class StopContainerCmdImplTest extends AbstractDockerClientTest { + + public static final Logger LOG = LoggerFactory + .getLogger(StopContainerCmdImplTest.class); + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void testStopContainer() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + LOG.info("Stopping container: {}", container.getId()); + dockerClient.stopContainerCmd(container.getId()).withTimeout(2).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); + + assertThat(inspectContainerResponse.getState().isRunning(), is(equalTo(false))); + assertThat(inspectContainerResponse.getState().getExitCode(), not(equalTo(0))); + } + + @Test + public void testStopNonExistingContainer() throws DockerException { + try { + dockerClient.stopContainerCmd("non-existing").withTimeout(2).exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + + } + } + +} diff --git a/src/test/java/com/github/dockerjava/core/command/TagImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/TagImageCmdImplTest.java new file mode 100644 index 00000000..97f422f2 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/TagImageCmdImplTest.java @@ -0,0 +1,65 @@ +package com.github.dockerjava.core.command; + +import java.lang.reflect.Method; + +import org.apache.commons.lang.math.RandomUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class TagImageCmdImplTest extends AbstractDockerClientTest { + + public static final Logger LOG = LoggerFactory + .getLogger(TagImageCmdImplTest.class); + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void tagImage() throws Exception { + String tag = "" + RandomUtils.nextInt(Integer.MAX_VALUE); + + dockerClient.tagImageCmd("busybox:latest", "docker-java/busybox", tag).exec(); + + dockerClient.removeImageCmd("docker-java/busybox:" + tag).exec(); + } + + @Test + public void tagNonExistingImage() throws Exception { + String tag = "" + RandomUtils.nextInt(Integer.MAX_VALUE); + + try { + dockerClient.tagImageCmd("non-existing", "docker-java/busybox", tag).exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + } + } + +} + diff --git a/src/test/java/com/github/dockerjava/core/command/VersionCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/VersionCmdImplTest.java new file mode 100644 index 00000000..8c906434 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/VersionCmdImplTest.java @@ -0,0 +1,53 @@ +package com.github.dockerjava.core.command; + +import java.lang.reflect.Method; + +import org.apache.commons.lang.StringUtils; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.model.Version; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class VersionCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void version() throws DockerException { + Version version = dockerClient.versionCmd().exec(); + LOG.info(version.toString()); + + assertTrue(version.getGoVersion().length() > 0); + assertTrue(version.getVersion().length() > 0); + + assertEquals(StringUtils.split(version.getVersion(), ".").length, 3); + + } + + +} diff --git a/src/test/java/com/github/dockerjava/core/command/WaitContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/WaitContainerCmdImplTest.java new file mode 100644 index 00000000..32434eea --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/WaitContainerCmdImplTest.java @@ -0,0 +1,80 @@ +package com.github.dockerjava.core.command; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; + +import java.lang.reflect.Method; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerException; +import com.github.dockerjava.api.InternalServerErrorException; +import com.github.dockerjava.api.NotFoundException; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.client.AbstractDockerClientTest; + +@Test(groups = "integration") +public class WaitContainerCmdImplTest extends AbstractDockerClientTest { + + @BeforeTest + public void beforeTest() throws DockerException { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void testWaitContainer() throws DockerException { + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox").withCmd("true").exec(); + + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + + int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(); + LOG.info("Container exit code: {}", exitCode); + + assertThat(exitCode, equalTo(0)); + + InspectContainerResponse inspectContainerResponse = dockerClient + .inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); + + assertThat(inspectContainerResponse.getState().isRunning(), is(equalTo(false))); + assertThat(inspectContainerResponse.getState().getExitCode(), is(equalTo(exitCode))); + } + + @Test + public void testWaitNonExistingContainer() throws DockerException { + try { + dockerClient.waitContainerCmd("non-existing").exec(); + fail("expected NotFoundException"); + } catch (NotFoundException e) { + } + } +} diff --git a/src/test/java/com/kpelykh/docker/client/test/AbstractDockerClientTest.java b/src/test/java/com/kpelykh/docker/client/test/AbstractDockerClientTest.java deleted file mode 100644 index d8313ca4..00000000 --- a/src/test/java/com/kpelykh/docker/client/test/AbstractDockerClientTest.java +++ /dev/null @@ -1,92 +0,0 @@ -package com.kpelykh.docker.client.test; - -import com.kpelykh.docker.client.DockerClient; -import com.kpelykh.docker.client.DockerException; -import com.sun.jersey.api.client.ClientResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.Assert; -import org.testng.ITestResult; - -import java.io.IOException; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; - -public abstract class AbstractDockerClientTest extends Assert { - - public static final Logger LOG = LoggerFactory - .getLogger(AbstractDockerClientTest.class); - - protected DockerClient dockerClient; - - protected List tmpImgs; - protected List tmpContainers; - - - public void beforeTest() throws DockerException { - LOG.info("======================= BEFORETEST ======================="); - String url = System.getProperty("docker.url", "http://localhost:4243"); - LOG.info("Connecting to Docker server at " + url); - dockerClient = new DockerClient(url); - - LOG.info("Pulling image 'busybox'"); - // need to block until image is pulled completely - logResponseStream(dockerClient.pull("busybox")); - - - - assertNotNull(dockerClient); - LOG.info("======================= END OF BEFORETEST =======================\n\n"); - } - - public void afterTest() { - LOG.info("======================= END OF AFTERTEST ======================="); - } - - - public void beforeMethod(Method method) { - tmpContainers = new ArrayList(); - tmpImgs = new ArrayList(); - LOG.info(String - .format("################################## STARTING %s ##################################", - method.getName())); - } - - public void afterMethod(ITestResult result) { - - for (String container : tmpContainers) { - LOG.info("Cleaning up temporary container {}", container); - try { - dockerClient.stopContainer(container); - dockerClient.kill(container); - dockerClient.removeContainer(container); - } catch (DockerException ignore) { - } - } - - for (String image : tmpImgs) { - LOG.info("Cleaning up temporary image {}", image); - try { - dockerClient.removeImage(image); - } catch (DockerException ignore) { - } - } - - LOG.info( - "################################## END OF {} ##################################\n", - result.getName()); - } - - protected String logResponseStream(ClientResponse response) { - String responseString; - try { - responseString = DockerClient.asString(response); - } catch (IOException e) { - throw new RuntimeException(e); - } - LOG.info("Container log: {}", responseString); - return responseString; - } - -} diff --git a/src/test/java/com/kpelykh/docker/client/test/DockerClientAuthTest.java b/src/test/java/com/kpelykh/docker/client/test/DockerClientAuthTest.java deleted file mode 100644 index 8c7fc4fa..00000000 --- a/src/test/java/com/kpelykh/docker/client/test/DockerClientAuthTest.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.kpelykh.docker.client.test; - -import com.kpelykh.docker.client.DockerException; -import com.sun.jersey.api.client.UniformInterfaceException; - -import org.hamcrest.Matchers; -import org.testng.ITestResult; -import org.testng.annotations.*; - -import java.lang.reflect.Method; - -import static org.hamcrest.MatcherAssert.assertThat; - -public class DockerClientAuthTest extends AbstractDockerClientTest { - - @BeforeTest - public void beforeTest() throws DockerException { - super.beforeTest(); - } - @AfterTest - public void afterTest() { - super.afterTest(); - } - - @BeforeMethod - public void beforeMethod(Method method) { - super.beforeMethod(method); - } - - @AfterMethod - public void afterMethod(ITestResult result) { - super.afterMethod(result); - } - - @Test - public void testAuth() throws Exception { - dockerClient.auth(); - } - - @Test - public void testAuthInvalid() throws Exception { - System.setProperty("docker.io.password", "garbage"); - try { - dockerClient.auth(); - fail(); - } catch (DockerException e) { - assertThat(e.getCause(), Matchers.instanceOf(UniformInterfaceException.class)); - assertEquals(((UniformInterfaceException) e.getCause()).getResponse().getStatus(), 401); - } - } -} diff --git a/src/test/java/com/kpelykh/docker/client/test/DockerClientTest.java b/src/test/java/com/kpelykh/docker/client/test/DockerClientTest.java deleted file mode 100644 index f6af3823..00000000 --- a/src/test/java/com/kpelykh/docker/client/test/DockerClientTest.java +++ /dev/null @@ -1,824 +0,0 @@ -package com.kpelykh.docker.client.test; - -import static ch.lambdaj.Lambda.filter; -import static ch.lambdaj.Lambda.selectUnique; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.endsWith; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.greaterThan; -import static org.hamcrest.Matchers.hasItem; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.isEmptyString; -import static org.hamcrest.Matchers.lessThan; -import static org.hamcrest.Matchers.lessThanOrEqualTo; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.nullValue; -import static org.hamcrest.Matchers.startsWith; -import static org.testinfected.hamcrest.jpa.HasFieldWithValue.hasField; - -import java.io.File; -import java.io.IOException; -import java.io.StringWriter; -import java.lang.reflect.Method; -import java.net.DatagramSocket; -import java.net.ServerSocket; -import java.util.List; -import java.util.Random; - -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.LineIterator; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.math.RandomUtils; -import org.hamcrest.Matcher; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - -import com.kpelykh.docker.client.DockerException; -import com.kpelykh.docker.client.model.ChangeLog; -import com.kpelykh.docker.client.model.CommitConfig; -import com.kpelykh.docker.client.model.Container; -import com.kpelykh.docker.client.model.ContainerConfig; -import com.kpelykh.docker.client.model.ContainerCreateResponse; -import com.kpelykh.docker.client.model.ContainerInspectResponse; -import com.kpelykh.docker.client.model.Image; -import com.kpelykh.docker.client.model.ImageInspectResponse; -import com.kpelykh.docker.client.model.Info; -import com.kpelykh.docker.client.model.Ports; -import com.kpelykh.docker.client.model.SearchItem; -import com.kpelykh.docker.client.model.Version; -import com.sun.jersey.api.client.ClientResponse; - -/** - * Unit test for DockerClient. - * - * @author Konstantin Pelykh (kpelykh@gmail.com) - */ -public class DockerClientTest extends AbstractDockerClientTest { - public static final Logger LOG = LoggerFactory - .getLogger(DockerClientTest.class); - - @BeforeTest - public void beforeTest() throws DockerException { - super.beforeTest(); - } - @AfterTest - public void afterTest() { - super.afterTest(); - } - - @BeforeMethod - public void beforeMethod(Method method) { - super.beforeMethod(method); - } - - @AfterMethod - public void afterMethod(ITestResult result) { - super.afterMethod(result); - } - - /* - * ######################### ## INFORMATION TESTS ## - * ######################### - */ - - @Test - public void testDockerVersion() throws DockerException { - Version version = dockerClient.version(); - LOG.info(version.toString()); - - assertTrue(version.getGoVersion().length() > 0); - assertTrue(version.getVersion().length() > 0); - - assertEquals(StringUtils.split(version.getVersion(), ".").length, 3); - - } - - @Test - public void testDockerInfo() throws DockerException { - Info dockerInfo = dockerClient.info(); - LOG.info(dockerInfo.toString()); - - assertTrue(dockerInfo.toString().contains("containers")); - assertTrue(dockerInfo.toString().contains("images")); - assertTrue(dockerInfo.toString().contains("debug")); - - assertTrue(dockerInfo.getContainers() > 0); - assertTrue(dockerInfo.getImages() > 0); - assertTrue(dockerInfo.getNFd() > 0); - assertTrue(dockerInfo.getNGoroutines() > 0); - assertTrue(dockerInfo.isMemoryLimit()); - } - - @Test - public void testDockerSearch() throws DockerException { - List dockerSearch = dockerClient.search("busybox"); - LOG.info("Search returned {}", dockerSearch.toString()); - - Matcher matcher = hasItem(hasField("name", equalTo("busybox"))); - assertThat(dockerSearch, matcher); - - assertThat( - filter(hasField("name", is("busybox")), dockerSearch).size(), - equalTo(1)); - } - - /* - * ################### ## LISTING TESTS ## ################### - */ - - @Test - public void testImages() throws DockerException { - List images = dockerClient.getImages(true); - assertThat(images, notNullValue()); - LOG.info("Images List: {}", images); - Info info = dockerClient.info(); - - assertThat(images.size(), equalTo(info.getImages())); - - Image img = images.get(0); - assertThat(img.getCreated(), is(greaterThan(0L))); - assertThat(img.getVirtualSize(), is(greaterThan(0L))); - assertThat(img.getId(), not(isEmptyString())); - assertThat(img.getTag(), not(isEmptyString())); - assertThat(img.getRepository(), not(isEmptyString())); - } - - @Test - public void testListContainers() throws DockerException { - - String testImage = "hackmann/empty"; - - LOG.info("Pulling image 'hackmann/empty'"); - // need to block until image is pulled completely - logResponseStream(dockerClient.pull(testImage)); - tmpImgs.add(testImage); - - List containers = dockerClient.listContainers(true); - assertThat(containers, notNullValue()); - LOG.info("Container List: {}", containers); - - int size = containers.size(); - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage(testImage); - containerConfig.setCmd(new String[] { "echo" }); - - ContainerCreateResponse container1 = dockerClient - .createContainer(containerConfig); - - assertThat(container1.getId(), not(isEmptyString())); - - ContainerInspectResponse containerInspectResponse = dockerClient.inspectContainer(container1.getId()); - - assertThat(containerInspectResponse.getConfig().getImage(), is(equalTo(testImage))); - - - dockerClient.startContainer(container1.getId()); - tmpContainers.add(container1.getId()); - - LOG.info("container id: " + container1.getId()); - - List containers2 = dockerClient.listContainers(true); - - for(Container container: containers2) { - LOG.info("listContainer: id=" + container.getId() +" image=" + container.getImage()); - } - - assertThat(size + 1, is(equalTo(containers2.size()))); - Matcher matcher = hasItem(hasField("id", startsWith(container1.getId()))); - assertThat(containers2, matcher); - - List filteredContainers = filter( - hasField("id", startsWith(container1.getId())), containers2); - assertThat(filteredContainers.size(), is(equalTo(1))); - - for(Container container: filteredContainers) { - LOG.info("filteredContainer: " + container.getImage()); - } - - Container container2 = filteredContainers.get(0); - assertThat(container2.getCommand(), not(isEmptyString())); - assertThat(container2.getImage(), equalTo(testImage + ":latest")); - } - - /* - * ##################### ## CONTAINER TESTS ## ##################### - */ - - @Test - public void testCreateContainer() throws DockerException { - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "true" }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - - LOG.info("Created container {}", container.toString()); - - assertThat(container.getId(), not(isEmptyString())); - - tmpContainers.add(container.getId()); - } - - @Test - public void testStartContainer() throws DockerException { - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "true" }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - LOG.info("Created container {}", container.toString()); - assertThat(container.getId(), not(isEmptyString())); - boolean add = tmpContainers.add(container.getId()); - - dockerClient.startContainer(container.getId()); - - ContainerInspectResponse containerInspectResponse = dockerClient - .inspectContainer(container.getId()); - LOG.info("Container Inspect: {}", containerInspectResponse.toString()); - - assertThat(containerInspectResponse.config, is(notNullValue())); - assertThat(containerInspectResponse.getId(), not(isEmptyString())); - - assertThat(containerInspectResponse.getId(), - startsWith(container.getId())); - - assertThat(containerInspectResponse.getImageId(), not(isEmptyString())); - assertThat(containerInspectResponse.getState(), is(notNullValue())); - - assertThat(containerInspectResponse.getState().running, is(true)); - - if (!containerInspectResponse.getState().running) { - assertThat(containerInspectResponse.getState().exitCode, - is(equalTo(0))); - } - - } - - @Test - public void testWaitContainer() throws DockerException { - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "true" }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - LOG.info("Created container: {}", container.toString()); - assertThat(container.getId(), not(isEmptyString())); - tmpContainers.add(container.getId()); - - dockerClient.startContainer(container.getId()); - - int exitCode = dockerClient.waitContainer(container.getId()); - LOG.info("Container exit code: {}", exitCode); - - assertThat(exitCode, equalTo(0)); - - ContainerInspectResponse containerInspectResponse = dockerClient - .inspectContainer(container.getId()); - LOG.info("Container Inspect: {}", containerInspectResponse.toString()); - - assertThat(containerInspectResponse.getState().running, - is(equalTo(false))); - assertThat(containerInspectResponse.getState().exitCode, - is(equalTo(exitCode))); - - } - - @Test - public void testLogs() throws DockerException, IOException { - - String snippet = "hello world"; - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "/bin/echo", snippet }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - LOG.info("Created container: {}", container.toString()); - assertThat(container.getId(), not(isEmptyString())); - - dockerClient.startContainer(container.getId()); - tmpContainers.add(container.getId()); - - int exitCode = dockerClient.waitContainer(container.getId()); - - assertThat(exitCode, equalTo(0)); - - ClientResponse response = dockerClient.logContainer(container.getId()); - - assertThat(logResponseStream(response), endsWith(snippet)); - } - - @Test - public void testDiff() throws DockerException { - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "touch", "/test" }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - LOG.info("Created container: {}", container.toString()); - assertThat(container.getId(), not(isEmptyString())); - dockerClient.startContainer(container.getId()); - boolean add = tmpContainers.add(container.getId()); - int exitCode = dockerClient.waitContainer(container.getId()); - assertThat(exitCode, equalTo(0)); - - List filesystemDiff = dockerClient.containerDiff(container.getId()); - LOG.info("Container DIFF: {}", filesystemDiff.toString()); - - assertThat(filesystemDiff.size(), equalTo(1)); - ChangeLog testChangeLog = selectUnique(filesystemDiff, - hasField("path", equalTo("/test"))); - - assertThat(testChangeLog, hasField("path", equalTo("/test"))); - assertThat(testChangeLog, hasField("kind", equalTo(1))); - } - - @Test - public void testStopContainer() throws DockerException { - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "sleep", "9999" }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - LOG.info("Created container: {}", container.toString()); - assertThat(container.getId(), not(isEmptyString())); - dockerClient.startContainer(container.getId()); - tmpContainers.add(container.getId()); - - LOG.info("Stopping container: {}", container.getId()); - dockerClient.stopContainer(container.getId(), 2); - - ContainerInspectResponse containerInspectResponse = dockerClient - .inspectContainer(container.getId()); - LOG.info("Container Inspect: {}", containerInspectResponse.toString()); - - assertThat(containerInspectResponse.getState().running, - is(equalTo(false))); - assertThat(containerInspectResponse.getState().exitCode, - not(equalTo(0))); - } - - @Test - public void testKillContainer() throws DockerException { - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "sleep", "9999" }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - LOG.info("Created container: {}", container.toString()); - assertThat(container.getId(), not(isEmptyString())); - dockerClient.startContainer(container.getId()); - tmpContainers.add(container.getId()); - - LOG.info("Killing container: {}", container.getId()); - dockerClient.kill(container.getId()); - - ContainerInspectResponse containerInspectResponse = dockerClient - .inspectContainer(container.getId()); - LOG.info("Container Inspect: {}", containerInspectResponse.toString()); - - assertThat(containerInspectResponse.getState().running, - is(equalTo(false))); - assertThat(containerInspectResponse.getState().exitCode, - not(equalTo(0))); - - } - - @Test - public void restartContainer() throws DockerException { - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "sleep", "9999" }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - LOG.info("Created container: {}", container.toString()); - assertThat(container.getId(), not(isEmptyString())); - dockerClient.startContainer(container.getId()); - tmpContainers.add(container.getId()); - - ContainerInspectResponse containerInspectResponse = dockerClient - .inspectContainer(container.getId()); - LOG.info("Container Inspect: {}", containerInspectResponse.toString()); - - String startTime = containerInspectResponse.getState().startedAt; - - dockerClient.restart(container.getId(), 2); - - ContainerInspectResponse containerInspectResponse2 = dockerClient - .inspectContainer(container.getId()); - LOG.info("Container Inspect After Restart: {}", - containerInspectResponse2.toString()); - - String startTime2 = containerInspectResponse2.getState().startedAt; - - assertThat(startTime, not(equalTo(startTime2))); - - assertThat(containerInspectResponse.getState().running, - is(equalTo(true))); - - dockerClient.kill(container.getId()); - } - - @Test - public void removeContainer() throws DockerException { - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "true" }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - - dockerClient.startContainer(container.getId()); - dockerClient.waitContainer(container.getId()); - tmpContainers.add(container.getId()); - - LOG.info("Removing container: {}", container.getId()); - dockerClient.removeContainer(container.getId()); - - List containers2 = dockerClient.listContainers(true); - Matcher matcher = not(hasItem(hasField("id", - startsWith(container.getId())))); - assertThat(containers2, matcher); - - } - - /* - * ################## ## IMAGES TESTS ## ################## - */ - - @Test - public void testPullImage() throws DockerException, IOException { - - // This should be an image that is not used by other repositories already - // pulled down, preferably small in size. If tag is not used pull will - // download all images in that repository but tmpImgs will only - // deleted 'latest' image but not images with other tags - String testImage = "hackmann/empty"; - - LOG.info("Removing image: {}", testImage); - dockerClient.removeImage(testImage); - - Info info = dockerClient.info(); - LOG.info("Client info: {}", info.toString()); - - int imgCount = info.getImages(); - - LOG.info("Pulling image: {}", testImage); - - tmpImgs.add(testImage); - ClientResponse response = dockerClient.pull(testImage); - - assertThat(logResponseStream(response), containsString("Download complete")); - - info = dockerClient.info(); - LOG.info("Client info after pull, {}", info.toString()); - - // TODO: imgCount should differ (maybe a docker bug?) - assertThat(imgCount, lessThanOrEqualTo(info.getImages())); - - ImageInspectResponse imageInspectResponse = dockerClient - .inspectImage(testImage); - LOG.info("Image Inspect: {}", imageInspectResponse.toString()); - assertThat(imageInspectResponse, notNullValue()); - } - - @Test - public void commitImage() throws DockerException { - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "touch", "/test" }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - LOG.info("Created container: {}", container.toString()); - assertThat(container.getId(), not(isEmptyString())); - dockerClient.startContainer(container.getId()); - tmpContainers.add(container.getId()); - - LOG.info("Commiting container: {}", container.toString()); - String imageId = dockerClient - .commit(new CommitConfig(container.getId())); - tmpImgs.add(imageId); - - ImageInspectResponse imageInspectResponse = dockerClient - .inspectImage(imageId); - LOG.info("Image Inspect: {}", imageInspectResponse.toString()); - - assertThat(imageInspectResponse, - hasField("container", startsWith(container.getId()))); - assertThat(imageInspectResponse.getContainerConfig().getImage(), - equalTo("busybox")); - - ImageInspectResponse busyboxImg = dockerClient.inspectImage("busybox"); - - assertThat(imageInspectResponse.getParent(), - equalTo(busyboxImg.getId())); - } - - @Test - public void testRemoveImage() throws DockerException, InterruptedException { - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "touch", "/test" }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - LOG.info("Created container: {}", container.toString()); - assertThat(container.getId(), not(isEmptyString())); - dockerClient.startContainer(container.getId()); - tmpContainers.add(container.getId()); - - LOG.info("Commiting container {}", container.toString()); - String imageId = dockerClient - .commit(new CommitConfig(container.getId())); - tmpImgs.add(imageId); - - dockerClient.stopContainer(container.getId()); - dockerClient.kill(container.getId()); - dockerClient.removeContainer(container.getId()); - - tmpContainers.remove(container.getId()); - LOG.info("Removing image: {}", imageId); - dockerClient.removeImage(imageId); - - List containers = dockerClient.listContainers(true); - Matcher matcher = not(hasItem(hasField("id", startsWith(imageId)))); - assertThat(containers, matcher); - } - - @Test - public void testTagImage() throws DockerException, InterruptedException { - String tag = String.valueOf(RandomUtils.nextInt(Integer.MAX_VALUE)); - - Integer result = dockerClient.tag("busybox:latest", "docker-java/busybox", tag, false); - assertThat(result, equalTo(Integer.valueOf(201))); - - dockerClient.removeImage("docker-java/busybox:" + tag); - } - - /* - * - * ################ ## MISC TESTS ## ################ - */ - - @Test - public void testRunShlex() throws DockerException { - - String[] commands = new String[] { - "true", - "echo \"The Young Descendant of Tepes & Septette for the Dead Princess\"", - "echo -n 'The Young Descendant of Tepes & Septette for the Dead Princess'", - "/bin/sh -c echo Hello World", "/bin/sh -c echo 'Hello World'", - "echo 'Night of Nights'", "true && echo 'Night of Nights'" }; - - for (String command : commands) { - LOG.info("Running command: [{}]", command); - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(commands); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - dockerClient.startContainer(container.getId()); - tmpContainers.add(container.getId()); - int exitcode = dockerClient.waitContainer(container.getId()); - assertThat(exitcode, equalTo(0)); - } - } - - @Test - public void testNginxDockerfileBuilder() throws DockerException, - IOException { - File baseDir = new File(Thread.currentThread().getContextClassLoader() - .getResource("nginx").getFile()); - - ClientResponse response = dockerClient.build(baseDir); - - StringWriter logwriter = new StringWriter(); - - try { - LineIterator itr = IOUtils.lineIterator( - response.getEntityInputStream(), "UTF-8"); - while (itr.hasNext()) { - String line = itr.next(); - logwriter.write(line + "\n"); - LOG.info(line); - } - } finally { - IOUtils.closeQuietly(response.getEntityInputStream()); - } - - String fullLog = logwriter.toString(); - assertThat(fullLog, containsString("Successfully built")); - - String imageId = StringUtils.substringBetween(fullLog, - "Successfully built ", "\\n\"}").trim(); - - ImageInspectResponse imageInspectResponse = dockerClient - .inspectImage(imageId); - assertThat(imageInspectResponse, not(nullValue())); - LOG.info("Image Inspect: {}", imageInspectResponse.toString()); - tmpImgs.add(imageInspectResponse.getId()); - - assertThat(imageInspectResponse.getAuthor(), - equalTo("Guillaume J. Charmes \"guillaume@dotcloud.com\"")); - } - - @Test - public void testDockerBuilderAddUrl() throws DockerException, IOException { - File baseDir = new File(Thread.currentThread().getContextClassLoader() - .getResource("testAddUrl").getFile()); - dockerfileBuild(baseDir, "docker.io"); - } - - @Test - public void testDockerBuilderAddFileInSubfolder() throws DockerException, IOException { - File baseDir = new File(Thread.currentThread().getContextClassLoader() - .getResource("testAddFileInSubfolder").getFile()); - dockerfileBuild(baseDir, "Successfully executed testrun.sh"); - } - - @Test - public void testDockerBuilderAddFolder() throws DockerException, - IOException { - File baseDir = new File(Thread.currentThread().getContextClassLoader() - .getResource("testAddFolder").getFile()); - dockerfileBuild(baseDir, "Successfully executed testAddFolder.sh"); - } - - @Test - public void testNetCatDockerfileBuilder() throws DockerException, - IOException, InterruptedException { - File baseDir = new File(Thread.currentThread().getContextClassLoader() - .getResource("netcat").getFile()); - - ClientResponse response = dockerClient.build(baseDir); - - StringWriter logwriter = new StringWriter(); - - try { - LineIterator itr = IOUtils.lineIterator( - response.getEntityInputStream(), "UTF-8"); - while (itr.hasNext()) { - String line = itr.next(); - logwriter.write(line + "\n"); - LOG.info(line); - } - } finally { - IOUtils.closeQuietly(response.getEntityInputStream()); - } - - String fullLog = logwriter.toString(); - assertThat(fullLog, containsString("Successfully built")); - - String imageId = StringUtils.substringBetween(fullLog, - "Successfully built ", "\\n\"}").trim(); - - ImageInspectResponse imageInspectResponse = dockerClient - .inspectImage(imageId); - assertThat(imageInspectResponse, not(nullValue())); - LOG.info("Image Inspect: {}", imageInspectResponse.toString()); - tmpImgs.add(imageInspectResponse.getId()); - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage(imageInspectResponse.getId()); - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - assertThat(container.getId(), not(isEmptyString())); - dockerClient.startContainer(container.getId()); - tmpContainers.add(container.getId()); - - ContainerInspectResponse containerInspectResponse = dockerClient - .inspectContainer(container.getId()); - - assertThat(containerInspectResponse.getId(), notNullValue()); - assertThat(containerInspectResponse.getNetworkSettings().ports, - notNullValue()); - - // No use as such if not running on the server - for (String portstr : containerInspectResponse.getNetworkSettings().ports - .getAllPorts().keySet()) { - - Ports.Port p = containerInspectResponse.getNetworkSettings().ports - .getAllPorts().get(portstr); - int port = Integer.valueOf(p.getHostPort()); - LOG.info("Checking port {} is open", port); - assertThat(available(port), is(false)); - } - dockerClient.stopContainer(container.getId(), 0); - - } - - // UTIL - - /** - * Checks to see if a specific port is available. - * - * @param port - * the port to check for availability - */ - public static boolean available(int port) { - if (port < 1100 || port > 60000) { - throw new IllegalArgumentException("Invalid start port: " + port); - } - - ServerSocket ss = null; - DatagramSocket ds = null; - try { - ss = new ServerSocket(port); - ss.setReuseAddress(true); - ds = new DatagramSocket(port); - ds.setReuseAddress(true); - return true; - } catch (IOException e) { - } finally { - if (ds != null) { - ds.close(); - } - - if (ss != null) { - try { - ss.close(); - } catch (IOException e) { - /* should not be thrown */ - } - } - } - - return false; - } - - private String dockerfileBuild(File baseDir, String expectedText) - throws DockerException, IOException { - - // Build image - ClientResponse response = dockerClient.build(baseDir); - - StringWriter logwriter = new StringWriter(); - - try { - LineIterator itr = IOUtils.lineIterator( - response.getEntityInputStream(), "UTF-8"); - while (itr.hasNext()) { - String line = itr.next(); - logwriter.write(line + "\n"); - LOG.info(line); - } - } finally { - IOUtils.closeQuietly(response.getEntityInputStream()); - } - - String fullLog = logwriter.toString(); - assertThat(fullLog, containsString("Successfully built")); - - String imageId = StringUtils.substringBetween(fullLog, - "Successfully built ", "\\n\"}").trim(); - - // Create container based on image - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage(imageId); - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - LOG.info("Created container: {}", container.toString()); - assertThat(container.getId(), not(isEmptyString())); - - dockerClient.startContainer(container.getId()); - dockerClient.waitContainer(container.getId()); - - tmpContainers.add(container.getId()); - - // Log container - ClientResponse logResponse = dockerClient.logContainer(container - .getId()); - - assertThat(logResponseStream(logResponse), containsString(expectedText)); - - return container.getId(); - } -} \ No newline at end of file diff --git a/src/test/java/com/kpelykh/docker/client/test/DockerPushTest.java b/src/test/java/com/kpelykh/docker/client/test/DockerPushTest.java deleted file mode 100644 index 7e6d88a9..00000000 --- a/src/test/java/com/kpelykh/docker/client/test/DockerPushTest.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.kpelykh.docker.client.test; - - -import com.kpelykh.docker.client.DockerException; -import com.kpelykh.docker.client.model.CommitConfig; -import com.kpelykh.docker.client.model.ContainerConfig; -import com.kpelykh.docker.client.model.ContainerCreateResponse; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.ITestResult; -import org.testng.annotations.*; - -import java.lang.reflect.Method; - -import static com.kpelykh.docker.client.DockerClient.asString; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; - -// delete here : https://index.docker.io/u/alexec/busybox/delete/ -public class DockerPushTest extends AbstractDockerClientTest { - - public static final Logger LOG = LoggerFactory - .getLogger(DockerPushTest.class); - - String username; - - @BeforeTest - public void beforeTest() throws DockerException { - super.beforeTest(); - username = dockerClient.authConfig().getUsername(); - } - @AfterTest - public void afterTest() { - super.afterTest(); - } - - @BeforeMethod - public void beforeMethod(Method method) { - super.beforeMethod(method); - } - - @AfterMethod - public void afterMethod(ITestResult result) { - super.afterMethod(result); - } - - @Test - public void testPushLatest() throws Exception { - - - ContainerConfig containerConfig = new ContainerConfig(); - containerConfig.setImage("busybox"); - containerConfig.setCmd(new String[] { "true" }); - - ContainerCreateResponse container = dockerClient - .createContainer(containerConfig); - - LOG.info("Created container {}", container.toString()); - - assertThat(container.getId(), not(isEmptyString())); - - tmpContainers.add(container.getId()); - - LOG.info("Commiting container: {}", container.toString()); - CommitConfig commitConfig = new CommitConfig(container.getId()); - - commitConfig.setRepo(username + "/busybox"); - - String imageId = dockerClient.commit(commitConfig); - - logResponseStream(dockerClient.push(username + "/busybox")); - - dockerClient.removeImage(imageId); - - assertThat(asString(dockerClient.pull(username + "/busybox")), not(containsString("404"))); - } - - @Test - public void testNotExistentImage() throws Exception { - - assertThat(logResponseStream(dockerClient.push(username + "/xxx")), containsString("error")); - } - - -} - diff --git a/src/test/resources/logback.xml b/src/test/resources/logback.xml index 99f8b3d9..318af286 100644 --- a/src/test/resources/logback.xml +++ b/src/test/resources/logback.xml @@ -6,8 +6,8 @@ - - + + diff --git a/src/test/resources/netcat/Dockerfile b/src/test/resources/netcat/Dockerfile index 1ea35547..1974f106 100644 --- a/src/test/resources/netcat/Dockerfile +++ b/src/test/resources/netcat/Dockerfile @@ -2,7 +2,7 @@ # # VERSION 0.3 -FROM ubuntu +FROM ubuntu:latest #install netcat RUN apt-get install -y netcat diff --git a/src/test/resources/nginx/Dockerfile b/src/test/resources/nginx/Dockerfile index b0abcd67..2d0fa24c 100644 --- a/src/test/resources/nginx/Dockerfile +++ b/src/test/resources/nginx/Dockerfile @@ -2,7 +2,7 @@ # # VERSION 0.0.1 -FROM ubuntu +FROM ubuntu:latest MAINTAINER Guillaume J. Charmes "guillaume@dotcloud.com" # make sure the package repository is up to date diff --git a/src/test/resources/testAddFile/Dockerfile b/src/test/resources/testAddFile/Dockerfile index 2900a5e7..8a4a6776 100644 --- a/src/test/resources/testAddFile/Dockerfile +++ b/src/test/resources/testAddFile/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu +FROM ubuntu:latest # Copy testrun.sh files into the container diff --git a/src/test/resources/testAddFileInSubfolder/Dockerfile b/src/test/resources/testAddFileInSubfolder/Dockerfile index 41d8f437..eac6b0e9 100644 --- a/src/test/resources/testAddFileInSubfolder/Dockerfile +++ b/src/test/resources/testAddFileInSubfolder/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu +FROM ubuntu:latest # Copy testrun.sh files into the container diff --git a/src/test/resources/testAddFolder/Dockerfile b/src/test/resources/testAddFolder/Dockerfile index b2a8e2a1..183e831c 100644 --- a/src/test/resources/testAddFolder/Dockerfile +++ b/src/test/resources/testAddFolder/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu +FROM ubuntu:latest # Copy testrun.sh files into the container diff --git a/src/test/resources/testAddUrl/Dockerfile b/src/test/resources/testAddUrl/Dockerfile index 1d76926c..ba0b91a0 100644 --- a/src/test/resources/testAddUrl/Dockerfile +++ b/src/test/resources/testAddUrl/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu +FROM ubuntu:latest # Copy testrun.sh files into the container diff --git a/src/test/resources/testENVSubstitution/Dockerfile b/src/test/resources/testENVSubstitution/Dockerfile new file mode 100644 index 00000000..134f7a60 --- /dev/null +++ b/src/test/resources/testENVSubstitution/Dockerfile @@ -0,0 +1,11 @@ +FROM ubuntu:latest + +# Copy testrun.sh files into the container + +ENV variable abc123 +ADD ./testrun.sh /tmp/ +ADD ./subst-file-$variable.txt /tmp/ +COPY ./subst-file-2-${variable}.txt /tmp/ +RUN cp /tmp/testrun.sh /usr/local/bin/ && chmod +x /usr/local/bin/testrun.sh + +CMD ["testrun.sh"] diff --git a/src/test/resources/testENVSubstitution/subst-file-2-abc123.txt b/src/test/resources/testENVSubstitution/subst-file-2-abc123.txt new file mode 100644 index 00000000..ac1acee1 --- /dev/null +++ b/src/test/resources/testENVSubstitution/subst-file-2-abc123.txt @@ -0,0 +1 @@ +Old File \ No newline at end of file diff --git a/src/test/resources/testENVSubstitution/subst-file-abc123.txt b/src/test/resources/testENVSubstitution/subst-file-abc123.txt new file mode 100644 index 00000000..ac1acee1 --- /dev/null +++ b/src/test/resources/testENVSubstitution/subst-file-abc123.txt @@ -0,0 +1 @@ +Old File \ No newline at end of file diff --git a/src/test/resources/testENVSubstitution/testrun.sh b/src/test/resources/testENVSubstitution/testrun.sh new file mode 100644 index 00000000..e79c944f --- /dev/null +++ b/src/test/resources/testENVSubstitution/testrun.sh @@ -0,0 +1,27 @@ +#!/bin/sh + +echo "Hello Word" > hello.txt +echo "hello.txt Created" + +TEST_FILE=/tmp/subst-file-abc123.txt +TEST_FILE_2=/tmp/subst-file-2-abc123.txt + +if test -f $TEST_FILE +then + + if test -f $TEST_FILE_2 + then + echo "testENVSubstitution successfully completed" + exit 0 + else + echo "$TEST_FILE_2 does not exist" + exit 1 + fi + +else + + echo "$TEST_FILE does not exist" + exit 1 + +fi + diff --git a/src/test/resources/testReadFile/Dockerfile b/src/test/resources/testReadFile/Dockerfile index 3dfe89f9..0f73b8ea 100644 --- a/src/test/resources/testReadFile/Dockerfile +++ b/src/test/resources/testReadFile/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu +FROM ubuntu:latest # Copy testrun.sh files into the container