From 6c748c61330cc996c78d5c294e40d98c8294e37e Mon Sep 17 00:00:00 2001 From: valerijf Date: Tue, 11 Oct 2016 13:23:26 +0200 Subject: [PATCH 001/599] Added getter for previous cpu stats --- .../github/dockerjava/api/model/Statistics.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/com/github/dockerjava/api/model/Statistics.java b/src/main/java/com/github/dockerjava/api/model/Statistics.java index cf8c1b77ee..6827be4e84 100644 --- a/src/main/java/com/github/dockerjava/api/model/Statistics.java +++ b/src/main/java/com/github/dockerjava/api/model/Statistics.java @@ -46,6 +46,12 @@ public class Statistics implements Serializable { @JsonProperty("cpu_stats") private Map cpuStats; + /** + * @since Docker Remote API 1.19 + */ + @JsonProperty("precpu_stats") + private Map precpuStats; + /** * @since Docker Remote API 1.21 */ @@ -66,6 +72,14 @@ public Map getCpuStats() { return cpuStats; } + /** + * The cpu statistic of last read, which is used for calculating the cpu usage percent. + * It is not the exact copy of the {@link #getCpuStats()}. + */ + public Map getPreviousCpuStats() { + return precpuStats; + } + public Map getMemoryStats() { return memoryStats; } From 9d2c93e5eacf4807f5368d28c3277d85aa6bd546 Mon Sep 17 00:00:00 2001 From: valerijf Date: Fri, 14 Oct 2016 09:49:01 +0200 Subject: [PATCH 002/599] Renamed getter as field --- src/main/java/com/github/dockerjava/api/model/Statistics.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/api/model/Statistics.java b/src/main/java/com/github/dockerjava/api/model/Statistics.java index 6827be4e84..9307da6b3d 100644 --- a/src/main/java/com/github/dockerjava/api/model/Statistics.java +++ b/src/main/java/com/github/dockerjava/api/model/Statistics.java @@ -76,7 +76,7 @@ public Map getCpuStats() { * The cpu statistic of last read, which is used for calculating the cpu usage percent. * It is not the exact copy of the {@link #getCpuStats()}. */ - public Map getPreviousCpuStats() { + public Map getPrecpuStats() { return precpuStats; } From 75e9a2cd3d1bf1489f7a94fd9dc8d624359fa430 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Thu, 27 Oct 2016 20:09:07 +0200 Subject: [PATCH 003/599] Expose netty connect timeout (#725) --- .../netty/NettyDockerCmdExecFactory.java | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java index cead92e92d..c91d4af21b 100644 --- a/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java @@ -108,6 +108,9 @@ import com.github.dockerjava.netty.exec.RenameContainerCmdExec; import io.netty.bootstrap.Bootstrap; +import io.netty.channel.Channel; +import io.netty.channel.ChannelConfig; +import io.netty.channel.ChannelFactory; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.epoll.EpollDomainSocketChannel; @@ -178,6 +181,8 @@ public DuplexChannel getChannel() { } }; + private Integer connectTimeout = null; + @Override public void init(DockerClientConfig dockerClientConfig) { checkNotNull(dockerClientConfig, "config was not specified"); @@ -218,7 +223,15 @@ private class UnixDomainSocketInitializer implements NettyInitializer { @Override public EventLoopGroup init(Bootstrap bootstrap, DockerClientConfig dockerClientConfig) { EventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup(0, new DefaultThreadFactory(threadPrefix)); - bootstrap.group(epollEventLoopGroup).channel(EpollDomainSocketChannel.class) + + ChannelFactory factory = new ChannelFactory() { + @Override + public EpollDomainSocketChannel newChannel() { + return configure(new EpollDomainSocketChannel()); + } + }; + + bootstrap.group(epollEventLoopGroup).channelFactory(factory) .handler(new ChannelInitializer() { @Override protected void initChannel(final UnixChannel channel) throws Exception { @@ -245,7 +258,14 @@ public EventLoopGroup init(Bootstrap bootstrap, final DockerClientConfig dockerC Security.addProvider(new BouncyCastleProvider()); - bootstrap.group(nioEventLoopGroup).channel(NioSocketChannel.class) + ChannelFactory factory = new ChannelFactory() { + @Override + public NioSocketChannel newChannel() { + return configure(new NioSocketChannel()); + } + }; + + bootstrap.group(nioEventLoopGroup).channelFactory(factory) .handler(new ChannelInitializer() { @Override protected void initChannel(final SocketChannel channel) throws Exception { @@ -580,6 +600,24 @@ public void close() throws IOException { eventLoopGroup.shutdownGracefully(); } + /** + * Configure connection timeout in milliseconds + */ + public NettyDockerCmdExecFactory withConnectTimeout(Integer connectTimeout) { + this.connectTimeout = connectTimeout; + return this; + } + + private T configure(T channel) { + ChannelConfig channelConfig = channel.config(); + + if (connectTimeout != null) { + channelConfig.setConnectTimeoutMillis(connectTimeout); + } + + return channel; + } + private WebTarget getBaseResource() { return new WebTarget(channelProvider); } From 39ef5d14bb7a6b217bba97525585fac08be39d00 Mon Sep 17 00:00:00 2001 From: Matt Fulgo Date: Wed, 2 Nov 2016 09:55:49 -0400 Subject: [PATCH 004/599] Fixes broken Docker documentation link The official Docker documentation has moved around a bit and the link for how to configure the Docker Engine needed to be updated. The previous link pointed to a page that no longer exists. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0396578079..c2fa5d854d 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ client also uses UNIX domain sockets to connect to the docker daemon by default. DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock" -More details about setting up Docker server can be found in official documentation: http://docs.docker.io/en/latest/use/basics/ +More details about setting up Docker Engine can be found in the official documentation: https://docs.docker.com/engine/admin/ To force docker-java to use TCP (http) configure the following (see [Configuration](https://github.com/docker-java/docker-java#configuration) for details): From 49b94f6fd6fd6f59c45138698051047e82719dd8 Mon Sep 17 00:00:00 2001 From: ooxi Date: Fri, 25 Nov 2016 08:32:41 +0100 Subject: [PATCH 005/599] Add javadoc for `saveImageCmd' Maybe we can automatically copy the documentation from `SaveImageCmd.withName`, but I don't know how. --- src/main/java/com/github/dockerjava/api/DockerClient.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java index 832890e87a..8f35fac124 100644 --- a/src/main/java/com/github/dockerjava/api/DockerClient.java +++ b/src/main/java/com/github/dockerjava/api/DockerClient.java @@ -111,6 +111,10 @@ public interface DockerClient extends Closeable { InspectImageCmd inspectImageCmd(@Nonnull String imageId); + /** + * @param name + * The name, e.g. "alexec/busybox" or just "busybox" if you want to default. Not null. + */ SaveImageCmd saveImageCmd(@Nonnull String name); /** From 3c04924a2deb4419bf6d987ed615bec88e7ed4f4 Mon Sep 17 00:00:00 2001 From: ooxi Date: Fri, 25 Nov 2016 08:36:37 +0100 Subject: [PATCH 006/599] Fixed Docker Remote API link (#747) File was moved in docker repository. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0396578079..79bad7fa95 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ For secure tls (https) communication: DOCKER_CERT_PATH=/Users/marcus/.docker/machine/machines/docker-1.11.2 ### Latest release version -Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.23.md), Docker Server version 1.11.x +Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/docker/blob/master/docs/api/v1.23.md), Docker Server version 1.11.x com.github.docker-java @@ -60,7 +60,7 @@ Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/doc ### Latest development version -Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.23.md), Docker Server version 1.11.x +Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/docker/blob/master/docs/api/v1.23.md), Docker Server version 1.11.x You can find the latest development version including javadoc and source files on [Sonatypes OSS repository](https://oss.sonatype.org/content/groups/public/com/github/docker-java/docker-java/). From 15aa30eaa6ed5c40dbbe1ef4dc3e4a4caeb867ec Mon Sep 17 00:00:00 2001 From: ooxi Date: Fri, 25 Nov 2016 08:37:28 +0100 Subject: [PATCH 007/599] Fix Maven package version (#748) Version `3.0.6` was released, current snapshot is `3.0.7-SNAPSHOT` --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 79bad7fa95..d5052e6b9f 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Supports a subset of the Docker Remote API [v1.23](https://github.com/docker/doc com.github.docker-java docker-java - 3.0.3 + 3.0.6 ### Latest development version @@ -67,7 +67,7 @@ You can find the latest development version including javadoc and source files o com.github.docker-java docker-java - 3.0.4-SNAPSHOT + 3.0.7-SNAPSHOT From 259b7d638e20781c3085e679176f34b1c5d92c89 Mon Sep 17 00:00:00 2001 From: Raffael Stein Date: Wed, 4 Jan 2017 10:22:03 +0100 Subject: [PATCH 008/599] Clone system properties on access in default config --- .../com/github/dockerjava/core/DefaultDockerClientConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java index a9a15bb365..9d13ec71e6 100644 --- a/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -188,7 +188,7 @@ private static Properties overrideDockerPropertiesWithSystemProperties(Propertie } public static Builder createDefaultConfigBuilder() { - return createDefaultConfigBuilder(System.getenv(), System.getProperties()); + return createDefaultConfigBuilder(System.getenv(), (Properties) System.getProperties().clone()); } /** From 5ba770cf010271632980029f73856081f45b7ef0 Mon Sep 17 00:00:00 2001 From: Aboubacar Toure Date: Thu, 12 Jan 2017 02:15:33 -0500 Subject: [PATCH 009/599] Add support for private docker registry version 2 (#756) Private docker registry version 1 expects the authentication credentials in $DOCKER_HOME/.dockercfg while version 2 expects them in $DOCKER_HOME/config.json. Support for both paths should be added to make docker-java more portable. This pull request has the following modifications: * When resolving the path of the authentication configuration file, $DOCKER_HOME/config.json (v2) is tried before $DOCKER_HOME/.dockercfg (v1) * When parsing the content of the authentication configuration file, the format of config.json (v2) is tried before .dockercfg (v1) * Test for both config.json (v2) and dockercfg (v1) have been added --- .../dockerjava/core/AuthConfigFile.java | 30 ++++++++++++--- .../core/DefaultDockerClientConfig.java | 30 ++++++++++++--- .../core/DefaultDockerClientConfigTest.java | 37 +++++++++++++++++++ .../registry.v1/.dockercfg | 5 +++ .../registry.v2/config.json | 7 ++++ 5 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 src/test/resources/com.github.dockerjava.core/registry.v1/.dockercfg create mode 100644 src/test/resources/com.github.dockerjava.core/registry.v2/config.json diff --git a/src/main/java/com/github/dockerjava/core/AuthConfigFile.java b/src/main/java/com/github/dockerjava/core/AuthConfigFile.java index f796fd7c9e..539ac7f75e 100644 --- a/src/main/java/com/github/dockerjava/core/AuthConfigFile.java +++ b/src/main/java/com/github/dockerjava/core/AuthConfigFile.java @@ -19,8 +19,13 @@ public class AuthConfigFile { private static final ObjectMapper MAPPER = new ObjectMapper(); - private static final TypeReference> CONFIG_MAP_TYPE = new TypeReference>() { - }; + private static final TypeReference> CONFIG_CFG_MAP_TYPE = + new TypeReference>() { + }; + + private static final TypeReference>> CONFIG_JSON_MAP_TYPE = + new TypeReference>>() { + }; private final Map authConfigMap; @@ -101,12 +106,27 @@ public static AuthConfigFile loadConfig(File confFile) throws IOException { if (!confFile.exists()) { return new AuthConfigFile(); } + Map configMap = null; + /* + Registry v2 expects config expects config.json while v2 expects .dockercfg + The only difference between them is that config.json wraps "auths" around the AuthConfig + */ try { - configMap = MAPPER.readValue(confFile, CONFIG_MAP_TYPE); - } catch (IOException e) { - // pass + // try registry version 2 + Map> configJson = MAPPER.readValue(confFile, CONFIG_JSON_MAP_TYPE); + if (configJson != null) { + configMap = configJson.get("auths"); + } + } catch (IOException e1) { + try { + // try registry version 1 + configMap = MAPPER.readValue(confFile, CONFIG_CFG_MAP_TYPE); + } catch (IOException e2) { + // pass + } } + if (configMap != null) { for (Map.Entry entry : configMap.entrySet()) { AuthConfig authConfig = entry.getValue(); diff --git a/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java index 9d13ec71e6..5857227aeb 100644 --- a/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -9,6 +9,9 @@ import java.io.InputStream; import java.io.Serializable; import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.HashSet; import java.util.Map; import java.util.Properties; @@ -55,6 +58,8 @@ public class DefaultDockerClientConfig implements Serializable, DockerClientConf private static final String DOCKER_CFG = ".dockercfg"; + private static final String CONFIG_JSON = "config.json"; + private static final Set CONFIG_KEYS = new HashSet(); static { @@ -253,9 +258,9 @@ && getRegistryUrl() != null) { public AuthConfig effectiveAuthConfig(String imageName) { AuthConfig authConfig = null; - File dockerCfgFile = new File(getDockerConfig() + File.separator + DOCKER_CFG); + File dockerCfgFile = getDockerConfigFile(); - if (dockerCfgFile.exists() && dockerCfgFile.isFile() && imageName != null) { + if (dockerCfgFile != null) { AuthConfigFile authConfigFile; try { authConfigFile = AuthConfigFile.loadConfig(dockerCfgFile); @@ -279,13 +284,15 @@ public AuthConfig effectiveAuthConfig(String imageName) { @Override public AuthConfigurations getAuthConfigurations() { - File dockerCfgFile = new File(getDockerConfig() + File.separator + DOCKER_CFG); - if (dockerCfgFile.exists() && dockerCfgFile.isFile()) { + File dockerCfgFile = getDockerConfigFile(); + + if (dockerCfgFile != null) { AuthConfigFile authConfigFile; try { authConfigFile = AuthConfigFile.loadConfig(dockerCfgFile); } catch (IOException e) { - throw new DockerClientException("Failed to parse dockerCfgFile", e); + throw new DockerClientException("Failed to parse dockerCfgFile: " + + dockerCfgFile.getAbsolutePath(), e); } return authConfigFile.getAuthConfigurations(); @@ -294,6 +301,19 @@ public AuthConfigurations getAuthConfigurations() { return new AuthConfigurations(); } + private File getDockerConfigFile() { + final Path configJson = Paths.get(getDockerConfig(), CONFIG_JSON); + final Path dockerCfg = Paths.get(getDockerConfig(), DOCKER_CFG); + + if (Files.exists(configJson)) { + return configJson.toFile(); + } else if (Files.exists(dockerCfg)) { + return dockerCfg.toFile(); + } else { + return null; + } + } + @Override public SSLConfig getSSLConfig() { return sslConfig; diff --git a/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java b/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java index 54e70c5119..3a4238b227 100644 --- a/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java +++ b/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java @@ -2,12 +2,15 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.core.Is.is; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; +import java.io.File; import java.lang.reflect.Field; import java.net.URI; +import java.net.URISyntaxException; import java.util.Collections; import java.util.HashMap; import java.util.Map; @@ -18,6 +21,8 @@ import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.api.model.AuthConfig; +import com.github.dockerjava.api.model.AuthConfigurations; +import com.google.common.io.Resources; public class DefaultDockerClientConfigTest { @@ -201,4 +206,36 @@ public void withDockerTlsVerify() throws Exception { assertThat((Boolean) field.get(builder), is(true)); } + @Test + public void testGetAuthConfigurationsFromDockerCfg() throws URISyntaxException { + File cfgFile = new File(Resources.getResource("com.github.dockerjava.core/registry.v1").toURI()); + DefaultDockerClientConfig clientConfig = new DefaultDockerClientConfig(URI.create( + "unix://foo"), cfgFile.getAbsolutePath(), "apiVersion", "registryUrl", "registryUsername", "registryPassword", + "registryEmail", null); + + AuthConfigurations authConfigurations = clientConfig.getAuthConfigurations(); + assertThat(authConfigurations, notNullValue()); + assertThat(authConfigurations.getConfigs().get("https://test.docker.io/v1/"), notNullValue()); + + AuthConfig authConfig = authConfigurations.getConfigs().get("https://test.docker.io/v1/"); + assertThat(authConfig.getUsername(), equalTo("user")); + assertThat(authConfig.getPassword(), equalTo("password")); + } + + @Test + public void testGetAuthConfigurationsFromConfigJson() throws URISyntaxException { + File cfgFile = new File(Resources.getResource("com.github.dockerjava.core/registry.v2").toURI()); + DefaultDockerClientConfig clientConfig = new DefaultDockerClientConfig(URI.create( + "unix://foo"), cfgFile.getAbsolutePath(), "apiVersion", "registryUrl", "registryUsername", "registryPassword", + "registryEmail", null); + + AuthConfigurations authConfigurations = clientConfig.getAuthConfigurations(); + assertThat(authConfigurations, notNullValue()); + assertThat(authConfigurations.getConfigs().get("https://test.docker.io/v2/"), notNullValue()); + + AuthConfig authConfig = authConfigurations.getConfigs().get("https://test.docker.io/v2/"); + assertThat(authConfig.getUsername(), equalTo("user")); + assertThat(authConfig.getPassword(), equalTo("password")); + } + } diff --git a/src/test/resources/com.github.dockerjava.core/registry.v1/.dockercfg b/src/test/resources/com.github.dockerjava.core/registry.v1/.dockercfg new file mode 100644 index 0000000000..3ab173fbaa --- /dev/null +++ b/src/test/resources/com.github.dockerjava.core/registry.v1/.dockercfg @@ -0,0 +1,5 @@ +{ + "https://test.docker.io/v1/": { + "auth": "dXNlcjpwYXNzd29yZA==" + } +} diff --git a/src/test/resources/com.github.dockerjava.core/registry.v2/config.json b/src/test/resources/com.github.dockerjava.core/registry.v2/config.json new file mode 100644 index 0000000000..73ab82acad --- /dev/null +++ b/src/test/resources/com.github.dockerjava.core/registry.v2/config.json @@ -0,0 +1,7 @@ +{ + "auths": { + "https://test.docker.io/v2/": { + "auth": "dXNlcjpwYXNzd29yZA==" + } + } +} From 5b8ed07cfbbd409cad344ffc7d21c905cd2d4886 Mon Sep 17 00:00:00 2001 From: Logan O'Sullivan Bruns Date: Fri, 13 Jan 2017 14:09:13 -0800 Subject: [PATCH 010/599] Issue 674: 3.0.x switch from docker host using https|http scheme to tcp breaks proxy configure (#675) https://github.com/docker-java/docker-java/issues/674 With the 3.0.x release, the code has been changed to use docker hosts of the format: tcp://host:port Instead of: https://host:port This breaks some of the logic in JerseyDockerCmdExecFactory that configures the proxy setting. --- .../github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java index 73bab979e6..4b7f2f67eb 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java @@ -190,7 +190,7 @@ public void init(DockerClientConfig dockerClientConfig) { throw new RuntimeException(e); } - configureProxy(clientConfig, protocol); + configureProxy(clientConfig, originalUri, protocol); } connManager = new PoolingHttpClientConnectionManager(getSchemeRegistry( @@ -241,9 +241,9 @@ private URI sanitizeUrl(URI originalUri) { return originalUri; } - private void configureProxy(ClientConfig clientConfig, String protocol) { + private void configureProxy(ClientConfig clientConfig, URI originalUri, String protocol) { - List proxies = ProxySelector.getDefault().select(dockerClientConfig.getDockerHost()); + List proxies = ProxySelector.getDefault().select(originalUri); for (Proxy proxy : proxies) { InetSocketAddress address = (InetSocketAddress) proxy.address(); From 3ad75e0870a35ac166a0e1cb33a636e152cc0dbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sekunda?= Date: Tue, 17 Jan 2017 19:43:50 +0100 Subject: [PATCH 011/599] add support for PidsLimit #734 (#764) * add support for PidsLimit #734 * add support for PidsLimit #734 - using hamcrest in assertions * add support for PidsLimit #734 - remove proxing * add support for PidsLimit #734 - remove proxing * add support for PidsLimit #734 - formatting fixed --- .../dockerjava/api/model/HostConfig.java | 22 +++++++++++++++ .../command/CreateContainerCmdImplTest.java | 28 +++++++++++++++++-- .../exec/CreateContainerCmdExecTest.java | 25 +++++++++++++++-- 3 files changed, 71 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/HostConfig.java b/src/main/java/com/github/dockerjava/api/model/HostConfig.java index 062082a037..d808ef245d 100644 --- a/src/main/java/com/github/dockerjava/api/model/HostConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/HostConfig.java @@ -194,6 +194,12 @@ public class HostConfig implements Serializable { @JsonProperty("ShmSize") private Long shmSize; + /** + * @since ~{@link RemoteApiVersion#VERSION_1_23} + */ + @JsonProperty("PidsLimit") + private Long pidsLimit; + @JsonIgnore public Bind[] getBinds() { @@ -415,6 +421,14 @@ public String getVolumeDriver() { return volumeDriver; } + /** + * @see #pidsLimit + */ + @CheckForNull + public Long getPidsLimit() { + return pidsLimit; + } + /** * Parse the network mode as specified at * {@see https://github.com/docker/engine-api/blob/master/types/container/hostconfig_unix.go} @@ -794,6 +808,14 @@ public HostConfig withVolumesFrom(VolumesFrom[] volumesFrom) { this.volumesFrom = volumesFrom; return this; } + + /** + * @see #pidsLimit + */ + public HostConfig withPidsLimit(Long pidsLimit) { + this.pidsLimit = pidsLimit; + return this; + } // end of auto-generated @Override diff --git a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java index 1f62527e9b..7c625ea949 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -22,8 +22,10 @@ import com.github.dockerjava.api.model.Ports.Binding; import com.github.dockerjava.client.AbstractDockerClientTest; +import com.github.dockerjava.core.RemoteApiVersion; import org.apache.commons.io.FileUtils; import org.testng.ITestResult; +import org.testng.SkipException; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeMethod; @@ -34,7 +36,6 @@ import java.lang.reflect.Method; import java.security.SecureRandom; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -42,6 +43,7 @@ import static com.github.dockerjava.api.model.Capability.MKNOD; import static com.github.dockerjava.api.model.Capability.NET_ADMIN; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; @@ -751,6 +753,28 @@ public void createContainerWithShmSize() throws DockerException { InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); - assertEquals(inspectContainerResponse.getHostConfig().getShmSize(), hostConfig.getShmSize()); + assertThat(inspectContainerResponse.getHostConfig().getShmSize(), is(hostConfig.getShmSize())); + } + + @SuppressWarnings("Duplicates") + @Test + public void createContainerWithShmPidsLimit() throws DockerException { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + + if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_23)) { + throw new SkipException("API version should be >= 1.23"); + } + + HostConfig hostConfig = new HostConfig().withPidsLimit(2L); + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE) + .withHostConfig(hostConfig).withCmd("true").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + + assertThat(inspectContainerResponse.getHostConfig().getPidsLimit(), is(hostConfig.getPidsLimit())); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java index aa97b88399..ab2bd36a04 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java @@ -36,7 +36,6 @@ import java.lang.reflect.Method; import java.security.SecureRandom; import java.util.Arrays; -import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -729,6 +728,28 @@ public void createContainerWithShmSize() throws DockerException { InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); - assertEquals(inspectContainerResponse.getHostConfig().getShmSize(), hostConfig.getShmSize()); + assertThat(inspectContainerResponse.getHostConfig().getShmSize(), is(hostConfig.getShmSize())); + } + + @SuppressWarnings("Duplicates") + @Test + public void createContainerWithShmPidsLimit() throws DockerException { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + + if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_23)) { + throw new SkipException("API version should be >= 1.23"); + } + + HostConfig hostConfig = new HostConfig().withPidsLimit(2L); + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE) + .withHostConfig(hostConfig).withCmd("true").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + + assertThat(inspectContainerResponse.getHostConfig().getPidsLimit(), is(hostConfig.getPidsLimit())); } } From cccc1b6da7af0ba3fe470389478ccee7339ba4b3 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 18 Jan 2017 03:29:07 +0300 Subject: [PATCH 012/599] [maven-release-plugin] prepare release 3.0.7 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 216c486318..609059f0b0 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.7-SNAPSHOT + 3.0.7 docker-java https://github.com/docker-java/docker-java @@ -28,7 +28,7 @@ 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 + 3.0.7 From 15c61b33a3dd4b197fd8b1afe7fcb077b2a08b50 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 18 Jan 2017 03:29:17 +0300 Subject: [PATCH 013/599] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 609059f0b0..852ad82838 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.7 + 3.0.8-SNAPSHOT docker-java https://github.com/docker-java/docker-java @@ -28,7 +28,7 @@ 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 - 3.0.7 + HEAD From b465546f7300819103b6c614b6680e5ecf0d1fff Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 18 Jan 2017 03:45:30 +0300 Subject: [PATCH 014/599] 3.0.7 release link to milestone --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f41b2938a..ca927c2c31 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Change Log === -## Next 3.0.7 +## (dev) 3.1.0 (reserverd for swarm features) + +## next... + +## 3.0.7 + * https://github.com/docker-java/docker-java/milestone/17?closed=1 + * HostConfig pidLimits * Label image during build * Expose 'User' property on ExecCreateCmd #707 #708 From c49f598fb0ee79a4a3b463312da4aab1b55d3050 Mon Sep 17 00:00:00 2001 From: Sukhanov Stas Date: Wed, 25 Jan 2017 22:33:49 +0500 Subject: [PATCH 015/599] Add support for multiple certificates in ca.pem file A single PEM file can contain a number of certificates. Usually keys and certificates are split into different files, but ca.pem still can contain several certificates in some cases. --- .../core/util/CertificateUtils.java | 21 +++++--- .../core/util/CertificateUtilsTest.java | 40 +++++++++++++++ .../caTest/multiple_ca.pem | 50 +++++++++++++++++++ .../CertificateUtilsTest/caTest/single_ca.pem | 25 ++++++++++ 4 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caTest/multiple_ca.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caTest/single_ca.pem diff --git a/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java b/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java index b5a5dcae60..63e66952d1 100644 --- a/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java +++ b/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java @@ -18,11 +18,11 @@ import java.util.List; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; - import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter; +import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; import org.slf4j.Logger; @@ -88,7 +88,8 @@ public static List loadCertificates(final Reader reader) throws IOE try (PEMParser pemParser = new PEMParser(reader)) { List certificates = new ArrayList<>(); - JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter().setProvider("BC"); + JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter() + .setProvider(BouncyCastleProvider.PROVIDER_NAME); Object certObj = pemParser.readObject(); if (certObj instanceof X509CertificateHolder) { @@ -181,14 +182,20 @@ public static KeyStore createTrustStore(String capem) throws IOException, Certif public static KeyStore createTrustStore(final Reader certReader) throws IOException, CertificateException, KeyStoreException, NoSuchAlgorithmException { try (PEMParser pemParser = new PEMParser(certReader)) { - 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); + + int index = 1; + Object pemCert; + + while ((pemCert = pemParser.readObject()) != null) { + Certificate caCertificate = new JcaX509CertificateConverter() + .setProvider(BouncyCastleProvider.PROVIDER_NAME) + .getCertificate((X509CertificateHolder) pemCert); + trustStore.setCertificateEntry("ca-" + index, caCertificate); + index++; + } return trustStore; } diff --git a/src/test/java/com/github/dockerjava/core/util/CertificateUtilsTest.java b/src/test/java/com/github/dockerjava/core/util/CertificateUtilsTest.java index 36c00c0767..9c7120d1f8 100644 --- a/src/test/java/com/github/dockerjava/core/util/CertificateUtilsTest.java +++ b/src/test/java/com/github/dockerjava/core/util/CertificateUtilsTest.java @@ -1,5 +1,14 @@ package com.github.dockerjava.core.util; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.security.KeyStore; +import java.security.Security; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; import static org.hamcrest.MatcherAssert.assertThat; @@ -9,6 +18,16 @@ public class CertificateUtilsTest { private static final String baseDir = CertificateUtilsTest.class.getResource( CertificateUtilsTest.class.getSimpleName() + "/").getFile(); + @BeforeClass + public static void init() { + Security.addProvider(new BouncyCastleProvider()); + } + + @AfterClass + public static void tearDown() { + Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME); + } + @Test public void allFilesExist() { assertThat(CertificateUtils.verifyCertificatesExist(baseDir + "allFilesExist"), is(true)); @@ -48,4 +67,25 @@ public void certMissing() { public void keyMissing() { assertThat(CertificateUtils.verifyCertificatesExist(baseDir + "keyMissing"), is(false)); } + + @Test + public void readCaCert() throws Exception { + String capem = readFileAsString("caTest/single_ca.pem"); + KeyStore keyStore = CertificateUtils.createTrustStore(capem); + assertThat(keyStore.size(), is(1)); + assertThat(keyStore.isCertificateEntry("ca-1"), is(true)); + } + + @Test + public void readMultipleCaCerts() throws Exception { + String capem = readFileAsString("caTest/multiple_ca.pem"); + KeyStore keyStore = CertificateUtils.createTrustStore(capem); + assertThat(keyStore.size(), is(2)); + assertThat(keyStore.isCertificateEntry("ca-1"), is(true)); + assertThat(keyStore.isCertificateEntry("ca-2"), is(true)); + } + + private String readFileAsString(String path) throws IOException { + return new String(Files.readAllBytes(Paths.get(baseDir + path))); + } } diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caTest/multiple_ca.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caTest/multiple_ca.pem new file mode 100644 index 0000000000..53b5712694 --- /dev/null +++ b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caTest/multiple_ca.pem @@ -0,0 +1,50 @@ +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIJALOOFdRswGmDMA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV +BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDDAKBgNVBAMTA0NBMTEaMBgGCSqGSIb3DQEJARYLY2FA +dGVzdC5jb20wHhcNMTcwMTI1MTc0ODE5WhcNMjcwMTIzMTc0ODE5WjBvMQswCQYD +VQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQg +V2lkZ2l0cyBQdHkgTHRkMQwwCgYDVQQDEwNDQTExGjAYBgkqhkiG9w0BCQEWC2Nh +QHRlc3QuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA346h3pA5 +5Uu6t7I8oNsiwF9PNgY7FKL/fXAiGAi1GMcPvil5Sf+GOYenQNsh4unfMRu8C+Xn +0NSnQNRkgJ2eIR5w3qDDK+UFj34rLdBK+wNze3gMGOaTFiSZLeoxrXs6fGbJ7Jmd +GaW7u8+P1+1Iej2k7lz61SXRL7+fn5lo3Lpfi+7s44zzOHoPkbHYNyl3md5Wgsoc +U+VGcABl1cq956ycQU1/jWZgclaTL3sQjNvLJ+dnN4+IwbFiPE9tY+cJtdNn2YXd +jLqxkfr/MZXoxArASanzPa4S7sKl8nnGrYM8cnppMeFk2a/p1YT+507V6VEmLM1A +IlqtzOAWpZ4vSQIDAQABo4HUMIHRMB0GA1UdDgQWBBRTvtGtQ298/2Ukc6ncXNUI +plkkxjCBoQYDVR0jBIGZMIGWgBRTvtGtQ298/2Ukc6ncXNUIplkkxqFzpHEwbzEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVy +bmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAxMDQ0ExMRowGAYJKoZIhvcNAQkB +FgtjYUB0ZXN0LmNvbYIJALOOFdRswGmDMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN +AQEFBQADggEBAIs8PjXPWvTWVDQ8xsZHLosD5BzCqM6ac+W7pjKEVNaiIo+UT3st +bl1rZS2U924M9xtOkmAOPCQx1ozMxqKk2SVYztll3/Nw7p3qbP2/7L1tOTjoNZqT +o2dd4Jf8txj9AaDus9FW8gmR6TLSgm7xeNb/kEa1b5ZW6l0zYRSBNT4I38d9wCa4 +QeohD8t1T1QOSc82dTHqccSiCSRiOX883I/fK+cTo8o1gdyUjYoCQlsJESr1rUun +C3zMTZ4Lkt72vM88Hf0OyK/+sw7sqVEf+95VMx+a/UaYYkJY3Bg6JTJb9vukbtAl +5GrDZOGM1AgW8iZyG/jSJlwkjiB9vy8RRnI= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIJAL4WwpOexcT8MA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV +BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDDAKBgNVBAMTA0NBMjEaMBgGCSqGSIb3DQEJARYLY2FA +dGVzdC5jb20wHhcNMTcwMTI1MTc0ODQ4WhcNMjcwMTIzMTc0ODQ4WjBvMQswCQYD +VQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQg +V2lkZ2l0cyBQdHkgTHRkMQwwCgYDVQQDEwNDQTIxGjAYBgkqhkiG9w0BCQEWC2Nh +QHRlc3QuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA346h3pA5 +5Uu6t7I8oNsiwF9PNgY7FKL/fXAiGAi1GMcPvil5Sf+GOYenQNsh4unfMRu8C+Xn +0NSnQNRkgJ2eIR5w3qDDK+UFj34rLdBK+wNze3gMGOaTFiSZLeoxrXs6fGbJ7Jmd +GaW7u8+P1+1Iej2k7lz61SXRL7+fn5lo3Lpfi+7s44zzOHoPkbHYNyl3md5Wgsoc +U+VGcABl1cq956ycQU1/jWZgclaTL3sQjNvLJ+dnN4+IwbFiPE9tY+cJtdNn2YXd +jLqxkfr/MZXoxArASanzPa4S7sKl8nnGrYM8cnppMeFk2a/p1YT+507V6VEmLM1A +IlqtzOAWpZ4vSQIDAQABo4HUMIHRMB0GA1UdDgQWBBRTvtGtQ298/2Ukc6ncXNUI +plkkxjCBoQYDVR0jBIGZMIGWgBRTvtGtQ298/2Ukc6ncXNUIplkkxqFzpHEwbzEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVy +bmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAxMDQ0EyMRowGAYJKoZIhvcNAQkB +FgtjYUB0ZXN0LmNvbYIJAL4WwpOexcT8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN +AQEFBQADggEBAKVIxgBQ76JQYfejcaK946J6VglSKaHuPZ8bDVM9e2KB1HFwTzAA +oRtMBIJaSO1+CSopTnzvzv/j8XeXbAUt6UHWiejGcIke1wW1CSVHeDQM7KUzXYtu +2jWzlGHXtnni4EeSwdE628Kfk82r/NU3+3+zo/3ASkYcSGBEYgIdvLBmbvQ8sviJ +rQZ1HCDP/TgP/ExBDi2QWBHe3XSTD0pBK153FC2YT1Q0AG5mxsIeq7C85m22aNX9 +fUmG5ORnVMkT/ktY+jg5aP+50o58MX24ZG1mh59vZtuBbvD74qZ2eNauStt1ji34 +V43XhW5Bigsp/z7GyFb2VzejH9n+VvPmTnU= +-----END CERTIFICATE----- diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caTest/single_ca.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caTest/single_ca.pem new file mode 100644 index 0000000000..8e67cb783d --- /dev/null +++ b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caTest/single_ca.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIENjCCAx6gAwIBAgIJAL4WwpOexcT8MA0GCSqGSIb3DQEBBQUAMG8xCzAJBgNV +BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDDAKBgNVBAMTA0NBMjEaMBgGCSqGSIb3DQEJARYLY2FA +dGVzdC5jb20wHhcNMTcwMTI1MTc0ODQ4WhcNMjcwMTIzMTc0ODQ4WjBvMQswCQYD +VQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQg +V2lkZ2l0cyBQdHkgTHRkMQwwCgYDVQQDEwNDQTIxGjAYBgkqhkiG9w0BCQEWC2Nh +QHRlc3QuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA346h3pA5 +5Uu6t7I8oNsiwF9PNgY7FKL/fXAiGAi1GMcPvil5Sf+GOYenQNsh4unfMRu8C+Xn +0NSnQNRkgJ2eIR5w3qDDK+UFj34rLdBK+wNze3gMGOaTFiSZLeoxrXs6fGbJ7Jmd +GaW7u8+P1+1Iej2k7lz61SXRL7+fn5lo3Lpfi+7s44zzOHoPkbHYNyl3md5Wgsoc +U+VGcABl1cq956ycQU1/jWZgclaTL3sQjNvLJ+dnN4+IwbFiPE9tY+cJtdNn2YXd +jLqxkfr/MZXoxArASanzPa4S7sKl8nnGrYM8cnppMeFk2a/p1YT+507V6VEmLM1A +IlqtzOAWpZ4vSQIDAQABo4HUMIHRMB0GA1UdDgQWBBRTvtGtQ298/2Ukc6ncXNUI +plkkxjCBoQYDVR0jBIGZMIGWgBRTvtGtQ298/2Ukc6ncXNUIplkkxqFzpHEwbzEL +MAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVy +bmV0IFdpZGdpdHMgUHR5IEx0ZDEMMAoGA1UEAxMDQ0EyMRowGAYJKoZIhvcNAQkB +FgtjYUB0ZXN0LmNvbYIJAL4WwpOexcT8MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcN +AQEFBQADggEBAKVIxgBQ76JQYfejcaK946J6VglSKaHuPZ8bDVM9e2KB1HFwTzAA +oRtMBIJaSO1+CSopTnzvzv/j8XeXbAUt6UHWiejGcIke1wW1CSVHeDQM7KUzXYtu +2jWzlGHXtnni4EeSwdE628Kfk82r/NU3+3+zo/3ASkYcSGBEYgIdvLBmbvQ8sviJ +rQZ1HCDP/TgP/ExBDi2QWBHe3XSTD0pBK153FC2YT1Q0AG5mxsIeq7C85m22aNX9 +fUmG5ORnVMkT/ktY+jg5aP+50o58MX24ZG1mh59vZtuBbvD74qZ2eNauStt1ji34 +V43XhW5Bigsp/z7GyFb2VzejH9n+VvPmTnU= +-----END CERTIFICATE----- From 5d00d5e75c4e2a79b5f5ca2bfaccfbde39b8a15d Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 14 Feb 2017 00:08:26 +0300 Subject: [PATCH 016/599] Disable failing tests. --- .../dockerjava/core/command/AuthCmdImplTest.java | 10 ++++++++++ .../dockerjava/netty/exec/AuthCmdExecTest.java | 14 ++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java index 887c99130d..2a9ce0fbf7 100644 --- a/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java @@ -2,7 +2,9 @@ import java.lang.reflect.Method; +import com.github.dockerjava.core.RemoteApiVersion; import org.testng.ITestResult; +import org.testng.SkipException; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeMethod; @@ -14,6 +16,8 @@ import com.github.dockerjava.client.AbstractDockerClientTest; import com.github.dockerjava.core.DockerClientBuilder; +import static com.github.dockerjava.utils.TestUtils.getVersion; + @Test(groups = "integration") public class AuthCmdImplTest extends AbstractDockerClientTest { @@ -39,6 +43,12 @@ public void afterMethod(ITestResult result) { @Test public void testAuth() throws Exception { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + + if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_23)) { + throw new SkipException("Fails on 1.22. Temporary disabled."); + } + AuthResponse response = dockerClient.authCmd().exec(); assertEquals(response.getStatus(), "Login Succeeded"); diff --git a/src/test/java/com/github/dockerjava/netty/exec/AuthCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/AuthCmdExecTest.java index 690d478f46..d753fca2bc 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/AuthCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/AuthCmdExecTest.java @@ -2,7 +2,9 @@ import java.lang.reflect.Method; +import com.github.dockerjava.core.RemoteApiVersion; import org.testng.ITestResult; +import org.testng.SkipException; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeMethod; @@ -14,6 +16,8 @@ import com.github.dockerjava.core.DockerClientBuilder; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; +import static com.github.dockerjava.utils.TestUtils.getVersion; + @Test(groups = "integration") public class AuthCmdExecTest extends AbstractNettyDockerClientTest { @@ -39,6 +43,11 @@ public void afterMethod(ITestResult result) { @Test public void testAuth() throws Exception { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_23)) { + throw new SkipException("Fails on 1.22. Temporary disabled."); + } + AuthResponse response = dockerClient.authCmd().exec(); assertEquals(response.getStatus(), "Login Succeeded"); @@ -46,6 +55,11 @@ public void testAuth() throws Exception { @Test(expectedExceptions = UnauthorizedException.class) public void testAuthInvalid() throws Exception { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_23)) { + throw new SkipException("Fails on 1.22. Temporary disabled."); + } + DockerClientBuilder.getInstance(config("garbage")).build().authCmd().exec(); } } From acb7ee41d8d67610b882b1ac59790b1784aebfb0 Mon Sep 17 00:00:00 2001 From: John Gallagher Date: Sun, 5 Feb 2017 14:10:23 -0500 Subject: [PATCH 017/599] Add ability to add labels when running commit --- .../dockerjava/api/command/CommitCmd.java | 10 ++++++++ .../core/command/CommitCmdImpl.java | 19 +++++++++++++++ .../core/command/CommitCmdImplTest.java | 24 ++++++++++++++++++- .../netty/exec/CommitCmdExecTest.java | 24 ++++++++++++++++++- 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/CommitCmd.java b/src/main/java/com/github/dockerjava/api/command/CommitCmd.java index c5da5bab63..a182751b82 100644 --- a/src/main/java/com/github/dockerjava/api/command/CommitCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CommitCmd.java @@ -3,6 +3,8 @@ import javax.annotation.CheckForNull; import javax.annotation.Nonnull; +import java.util.Map; + import com.github.dockerjava.api.exception.NotFoundException; import com.github.dockerjava.api.model.ExposedPorts; import com.github.dockerjava.api.model.Volumes; @@ -29,6 +31,9 @@ public interface CommitCmd extends SyncDockerCmd { @CheckForNull String getHostname(); + @CheckForNull + Map getLabels(); + @CheckForNull Integer getMemory(); @@ -88,6 +93,11 @@ public interface CommitCmd extends SyncDockerCmd { CommitCmd withHostname(String hostname); + /** + * @since 1.19 + */ + CommitCmd withLabels(Map labels); + CommitCmd withMemory(Integer memory); CommitCmd withMemorySwap(Integer memorySwap); diff --git a/src/main/java/com/github/dockerjava/core/command/CommitCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CommitCmdImpl.java index 534cce52cb..1c8ad26a46 100644 --- a/src/main/java/com/github/dockerjava/core/command/CommitCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CommitCmdImpl.java @@ -2,6 +2,8 @@ import static com.google.common.base.Preconditions.checkNotNull; +import java.util.Map; + import com.fasterxml.jackson.annotation.JsonProperty; import com.github.dockerjava.api.command.CommitCmd; import com.github.dockerjava.api.exception.NotFoundException; @@ -43,6 +45,12 @@ public class CommitCmdImpl extends AbstrDockerCmd implements @JsonProperty("Hostname") private String hostname; + /** + * @since 1.19 + */ + @JsonProperty("Labels") + private Map labels; + @JsonProperty("Memory") private Integer memory; @@ -189,6 +197,17 @@ public CommitCmdImpl withEnv(String... env) { return this; } + @Override + public Map getLabels() { + return labels; + } + + @Override + public CommitCmdImpl withLabels(Map labels) { + this.labels = labels; + return this; + } + @Override public ExposedPorts getExposedPorts() { return exposedPorts; diff --git a/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java index 64e1d7ddf6..a6195ed4de 100644 --- a/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java @@ -8,7 +8,9 @@ import static org.testinfected.hamcrest.jpa.HasFieldWithValue.hasField; import java.lang.reflect.Method; +import java.util.Map; +import com.google.common.collect.ImmutableMap; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -54,7 +56,7 @@ public void commit() throws DockerException { assertThat(container.getId(), not(isEmptyString())); dockerClient.startContainerCmd(container.getId()).exec(); - LOG.info("Commiting container: {}", container.toString()); + LOG.info("Committing container: {}", container.toString()); String imageId = dockerClient.commitCmd(container.getId()).exec(); InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); @@ -68,6 +70,26 @@ public void commit() throws DockerException { assertThat(inspectImageResponse.getParent(), equalTo(busyboxImg.getId())); } + @Test + public void commitWithLabels() 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("Committing container: {}", container.toString()); + Map labels = ImmutableMap.of("label1", "abc", "label2", "123"); + String imageId = dockerClient.commitCmd(container.getId()).withLabels(labels).exec(); + + InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); + LOG.info("Image Inspect: {}", inspectImageResponse.toString()); + Map responseLabels = inspectImageResponse.getContainerConfig().getLabels(); + assertThat(responseLabels.get("label1"), equalTo("abc")); + assertThat(responseLabels.get("label2"), equalTo("123")); + } + @Test(expectedExceptions = NotFoundException.class) public void commitNonExistingContainer() throws DockerException { diff --git a/src/test/java/com/github/dockerjava/netty/exec/CommitCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CommitCmdExecTest.java index 3d1a66333a..8d8f6e6bbb 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CommitCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CommitCmdExecTest.java @@ -8,7 +8,9 @@ import static org.testinfected.hamcrest.jpa.HasFieldWithValue.hasField; import java.lang.reflect.Method; +import java.util.Map; +import com.google.common.collect.ImmutableMap; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -54,7 +56,7 @@ public void commit() throws DockerException { assertThat(container.getId(), not(isEmptyString())); dockerClient.startContainerCmd(container.getId()).exec(); - LOG.info("Commiting container: {}", container.toString()); + LOG.info("Committing container: {}", container.toString()); String imageId = dockerClient.commitCmd(container.getId()).exec(); InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); @@ -68,6 +70,26 @@ public void commit() throws DockerException { assertThat(inspectImageResponse.getParent(), equalTo(busyboxImg.getId())); } + @Test + public void commitWithLabels() 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("Committing container: {}", container.toString()); + Map labels = ImmutableMap.of("label1", "abc", "label2", "123"); + String imageId = dockerClient.commitCmd(container.getId()).withLabels(labels).exec(); + + InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); + LOG.info("Image Inspect: {}", inspectImageResponse.toString()); + Map responseLabels = inspectImageResponse.getContainerConfig().getLabels(); + assertThat(responseLabels.get("label1"), equalTo("abc")); + assertThat(responseLabels.get("label2"), equalTo("123")); + } + @Test(expectedExceptions = NotFoundException.class) public void commitNonExistingContainer() throws DockerException { From aa75982f3e43cb212cad80524fa8441617038562 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 14 Feb 2017 00:36:04 +0300 Subject: [PATCH 018/599] Test all latest --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d055f76e05..69aa647809 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,10 @@ env: - COVERITY_SCAN_NOTIFICATION_EMAIL="kanstantsin.sha@gmail.com" matrix: - - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.12.1-0~trusty" CODECOV=true - - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.12.1-0~trusty" CODECOV=true + - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.13.1-0~ubuntu-trusty" CODECOV=true + - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.13.1-0~ubuntu-trusty" CODECOV=true + - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.12.6-0~ubuntu-trusty" CODECOV=true + - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.12.6-0~ubuntu-trusty" CODECOV=true - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" DEPLOY=true COVERITY=true CODECOV=true - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.11.2-0~trusty" CODECOV=true - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.10.3-0~trusty" CODECOV=true From 1fbe1c401a6fc97d55a80cc93b00826d51206c0a Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 14 Feb 2017 01:12:23 +0300 Subject: [PATCH 019/599] Disable 1.13.1 Some tests failing. --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 69aa647809..eaf11b5142 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,11 +21,11 @@ env: - COVERITY_SCAN_NOTIFICATION_EMAIL="kanstantsin.sha@gmail.com" matrix: - - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.13.1-0~ubuntu-trusty" CODECOV=true - - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.13.1-0~ubuntu-trusty" CODECOV=true - - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.12.6-0~ubuntu-trusty" CODECOV=true +# - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.13.1-0~ubuntu-trusty" CODECOV=true +# - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.13.1-0~ubuntu-trusty" CODECOV=true + - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.12.6-0~ubuntu-trusty" DEPLOY=true COVERITY=true CODECOV=true - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.12.6-0~ubuntu-trusty" CODECOV=true - - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" DEPLOY=true COVERITY=true CODECOV=true + - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" CODECOV=true - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.11.2-0~trusty" CODECOV=true - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.10.3-0~trusty" CODECOV=true - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.10.3-0~trusty" CODECOV=true From 17d04f6d9565696c7d527da622ddc99e6e6f46c2 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 14 Feb 2017 02:22:33 +0300 Subject: [PATCH 020/599] rerun failing tests count to 3 --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 852ad82838..726afefa45 100644 --- a/pom.xml +++ b/pom.xml @@ -397,6 +397,7 @@ maven-surefire-plugin ${maven-surefire-plugin.version} + 3 integration,integration-auth @@ -412,6 +413,7 @@ verify + 3 true true 1 From 80ba61f434a9a67fd0428f8c5e606be7d4485f07 Mon Sep 17 00:00:00 2001 From: Valerij Date: Wed, 15 Feb 2017 18:35:32 +0100 Subject: [PATCH 021/599] Capitalize variable name --- .../java/com/github/dockerjava/api/model/Statistics.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/Statistics.java b/src/main/java/com/github/dockerjava/api/model/Statistics.java index 9307da6b3d..6bb1930e1a 100644 --- a/src/main/java/com/github/dockerjava/api/model/Statistics.java +++ b/src/main/java/com/github/dockerjava/api/model/Statistics.java @@ -50,7 +50,7 @@ public class Statistics implements Serializable { * @since Docker Remote API 1.19 */ @JsonProperty("precpu_stats") - private Map precpuStats; + private Map preCpuStats; /** * @since Docker Remote API 1.21 @@ -76,8 +76,8 @@ public Map getCpuStats() { * The cpu statistic of last read, which is used for calculating the cpu usage percent. * It is not the exact copy of the {@link #getCpuStats()}. */ - public Map getPrecpuStats() { - return precpuStats; + public Map getPreCpuStats() { + return preCpuStats; } public Map getMemoryStats() { From 1c1833709beaa1d103cc9e02827347c0c696d263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Warcha=C5=82?= Date: Thu, 16 Feb 2017 10:35:13 +0100 Subject: [PATCH 022/599] Use TLSv2 by default --- .../dockerjava/core/LocalDirectorySSLConfig.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/LocalDirectorySSLConfig.java b/src/main/java/com/github/dockerjava/core/LocalDirectorySSLConfig.java index 961c282dea..5e4a7fa57f 100644 --- a/src/main/java/com/github/dockerjava/core/LocalDirectorySSLConfig.java +++ b/src/main/java/com/github/dockerjava/core/LocalDirectorySSLConfig.java @@ -45,14 +45,6 @@ public SSLContext getSSLContext() { Security.addProvider(new BouncyCastleProvider()); - // 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); - } - String caPemPath = dockerCertPath + File.separator + "ca.pem"; String keyPemPath = dockerCertPath + File.separator + "key.pem"; String certPemPath = dockerCertPath + File.separator + "cert.pem"; @@ -61,6 +53,8 @@ public SSLContext getSSLContext() { String certpem = new String(Files.readAllBytes(Paths.get(certPemPath))); String capem = new String(Files.readAllBytes(Paths.get(caPemPath))); + SslConfigurator sslConfig = SslConfigurator.newInstance(true); + sslConfig.securityProtocol("TLSv1.2"); sslConfig.keyStore(CertificateUtils.createKeyStore(keypem, certpem)); sslConfig.keyStorePassword("docker"); sslConfig.trustStore(CertificateUtils.createTrustStore(capem)); From a3be9a5c32fd90c6c5d2f19e8c903b5df67fed2f Mon Sep 17 00:00:00 2001 From: "Lubos.Palisek" Date: Thu, 15 Dec 2016 13:30:57 +0100 Subject: [PATCH 023/599] Added healthcheck support in container inspect JSON result --- .../dockerjava/api/command/HealthState.java | 30 ++++ .../api/command/HealthStateLog.java | 36 ++++ .../api/command/InspectContainerResponse.java | 13 +- .../dockerjava/api/model/ContainerConfig.java | 11 ++ .../dockerjava/api/model/HealthCheck.java | 45 +++++ .../command/InspectContainerResponseTest.java | 27 ++- .../samples/1.24/containers/inspect/1.json | 167 ++++++++++++++++++ 7 files changed, 326 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/github/dockerjava/api/command/HealthState.java create mode 100644 src/main/java/com/github/dockerjava/api/command/HealthStateLog.java create mode 100644 src/main/java/com/github/dockerjava/api/model/HealthCheck.java create mode 100644 src/test/resources/samples/1.24/containers/inspect/1.json diff --git a/src/main/java/com/github/dockerjava/api/command/HealthState.java b/src/main/java/com/github/dockerjava/api/command/HealthState.java new file mode 100644 index 0000000000..6f5418713c --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/HealthState.java @@ -0,0 +1,30 @@ +package com.github.dockerjava.api.command; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class HealthState { + + @JsonProperty("Status") + private String status; + + @JsonProperty("FailingStreak") + private Integer failingStreak; + + @JsonProperty("Log") + private List log; + + public String getStatus() { + return status; + } + + public Integer getFailingStreak() { + return failingStreak; + } + + public List getLog() { + return log; + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/HealthStateLog.java b/src/main/java/com/github/dockerjava/api/command/HealthStateLog.java new file mode 100644 index 0000000000..e7f4c15a9b --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/HealthStateLog.java @@ -0,0 +1,36 @@ +package com.github.dockerjava.api.command; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class HealthStateLog { + + @JsonProperty("Start") + private String start; + + @JsonProperty("End") + private String end; + + @JsonProperty("ExitCode") + private Integer exitCode; + + @JsonProperty("Output") + private String output; + + public String getStart() { + return start; + } + + public String getEnd() { + return end; + } + + public Integer getExitCode() { + return exitCode; + } + + public String getOutput() { + return output; + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java b/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java index c8027b0ede..497aaad2b5 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java @@ -112,7 +112,7 @@ public String getId() { } public Integer getSizeRootFs() { - return sizeRootFs; + return sizeRootFs; } public String getCreated() { @@ -302,6 +302,13 @@ public class ContainerState { @JsonProperty("FinishedAt") private String finishedAt; + + /** + * @since Docker version 1.12 + */ + @JsonProperty("Health") + private HealthState health; + /** * See {@link #status} */ @@ -390,6 +397,10 @@ public String getFinishedAt() { return finishedAt; } + public HealthState getHealth() { + return health; + } + @Override public boolean equals(Object o) { return EqualsBuilder.reflectionEquals(this, o); diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java index 1911267983..6d3265afa3 100644 --- a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java @@ -86,6 +86,9 @@ public class ContainerConfig implements Serializable { @JsonProperty("WorkingDir") private String workingDir; + @JsonProperty("Healthcheck") + private HealthCheck healthCheck; + @JsonIgnore public ExposedPort[] getExposedPorts() { return exposedPorts != null ? exposedPorts.getExposedPorts() : null; @@ -411,6 +414,14 @@ public String getWorkingDir() { return workingDir; } + /** + * @see #healthCheck + */ + @CheckForNull + public HealthCheck getHealthcheck() { + return healthCheck; + } + /** * @see #workingDir */ diff --git a/src/main/java/com/github/dockerjava/api/model/HealthCheck.java b/src/main/java/com/github/dockerjava/api/model/HealthCheck.java new file mode 100644 index 0000000000..514bf4f417 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/HealthCheck.java @@ -0,0 +1,45 @@ +/* + * Copyright 2017 cdancy. + * + * 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.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + +/** + * + * @author cdancy + */ +@JsonIgnoreProperties(ignoreUnknown = true) +@JsonInclude(JsonInclude.Include.NON_NULL) +public class HealthCheck implements Serializable { + private static final long serialVersionUID = 1L; + + @JsonProperty("Interval") + private Long interval; + + @JsonProperty("Timeout") + private Long timeout; + + public Long getInterval() { + return interval; + } + + public Long getTimeout() { + return timeout; + } +} diff --git a/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java b/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java index cd4562b4af..51e8bd1dc9 100644 --- a/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java +++ b/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java @@ -15,10 +15,15 @@ */ package com.github.dockerjava.api.command; -import org.testng.annotations.Test; - +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.api.model.Event; +import com.github.dockerjava.core.RemoteApiVersion; +import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; import java.io.IOException; +import org.testng.annotations.Test; + import static com.github.dockerjava.test.serdes.JSONTestHelper.testRoundTrip; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; @@ -55,6 +60,24 @@ public void roundTrip_full() throws IOException { assertThat(response.getLogPath(), is("/mnt/sda1/var/lib/docker/containers/469e5edd8d5b33e3c905a7ffc97360ec6ee211d6782815fbcd144568045819e1/469e5edd8d5b33e3c905a7ffc97360ec6ee211d6782815fbcd144568045819e1-json.log")); } + @Test + public void roundTrip_full_healthcheck() throws IOException { + + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().uncheckedSimpleType(InspectContainerResponse.class); + + final InspectContainerResponse response = testRoundTrip(RemoteApiVersion.VERSION_1_24, + "/containers/inspect/1.json", + type + ); + + assertEquals(response.getState().getHealth().getStatus(), "healthy"); + assertEquals(response.getState().getHealth().getFailingStreak(), new Integer(0)); + assertEquals(response.getState().getHealth().getLog().size(), 2); + assertEquals(response.getState().getHealth().getLog().get(0).getOutput(), "Hello"); + assertEquals(response.getState().getHealth().getLog().get(1).getOutput(), "World"); + } + @Test public void roundTrip_1_21_full() throws IOException { InspectContainerResponse[] responses = testRoundTrip(CommandJSONSamples.inspectContainerResponse_full_1_21, diff --git a/src/test/resources/samples/1.24/containers/inspect/1.json b/src/test/resources/samples/1.24/containers/inspect/1.json new file mode 100644 index 0000000000..54d23923f0 --- /dev/null +++ b/src/test/resources/samples/1.24/containers/inspect/1.json @@ -0,0 +1,167 @@ +{ + "Id": "fc1243c01bbb791d9eca64204d76f72fc47fbebbca892d7dd0a5cd0e4e346045", + "Created": "2015-11-20T21:10:34.775649753Z", + "Path": "cat", + "Args": [], + "State": { + "Status": "running", + "Running": true, + "Paused": false, + "Restarting": false, + "OOMKilled": false, + "Dead": false, + "Pid": 10912, + "ExitCode": 0, + "Error": "", + "StartedAt": "2015-11-20T21:10:34.845546358Z", + "FinishedAt": "0001-01-01T00:00:00Z", + "Health": { + "Status": "healthy", + "FailingStreak": 0, + "Log": [ + { + "Start": "2016-11-12T03:23:03.351561Z", + "End": "2016-11-12T03:23:03.422176171Z", + "ExitCode": 0, + "Output" : "Hello" + }, + { + "Start": "2016-11-12T03:23:08.423558928Z", + "End": "2016-11-12T03:23:08.510122392Z", + "ExitCode": 0, + "Output" : "World" + } + ] + } + }, + "Image": "c51f86c283408d1749d066333f7acd5d33b053b003a61ff6a7b36819ddcbc7b7", + "ResolvConfPath": "/mnt/sda1/var/lib/docker/containers/fc1243c01bbb791d9eca64204d76f72fc47fbebbca892d7dd0a5cd0e4e346045/resolv.conf", + "HostnamePath": "/mnt/sda1/var/lib/docker/containers/fc1243c01bbb791d9eca64204d76f72fc47fbebbca892d7dd0a5cd0e4e346045/hostname", + "HostsPath": "/mnt/sda1/var/lib/docker/containers/fc1243c01bbb791d9eca64204d76f72fc47fbebbca892d7dd0a5cd0e4e346045/hosts", + "LogPath": "/mnt/sda1/var/lib/docker/containers/fc1243c01bbb791d9eca64204d76f72fc47fbebbca892d7dd0a5cd0e4e346045/fc1243c01bbb791d9eca64204d76f72fc47fbebbca892d7dd0a5cd0e4e346045-json.log", + "Name": "/small_hodgkin", + "RestartCount": 0, + "Driver": "aufs", + "ExecDriver": "native-0.2", + "MountLabel": "", + "ProcessLabel": "", + "AppArmorProfile": "", + "ExecIDs": null, + "HostConfig": { + "Binds": null, + "ContainerIDFile": "", + "LxcConf": [], + "Memory": 0, + "MemoryReservation": 0, + "MemorySwap": 0, + "KernelMemory": 0, + "CpuShares": 0, + "CpuPeriod": 0, + "CpusetCpus": "", + "CpusetMems": "", + "CpuQuota": 0, + "BlkioWeight": 0, + "OomKillDisable": false, + "MemorySwappiness": -1, + "Privileged": false, + "PortBindings": {}, + "Links": null, + "PublishAllPorts": false, + "Dns": null, + "DnsOptions": null, + "DnsSearch": null, + "ExtraHosts": null, + "VolumesFrom": null, + "Devices": [], + "NetworkMode": "default", + "IpcMode": "", + "PidMode": "", + "UTSMode": "", + "CapAdd": null, + "CapDrop": null, + "GroupAdd": null, + "RestartPolicy": { + "Name": "no", + "MaximumRetryCount": 0 + }, + "SecurityOpt": null, + "ReadonlyRootfs": false, + "Ulimits": null, + "LogConfig": { + "Type": "json-file", + "Config": {} + }, + "CgroupParent": "", + "ConsoleSize": [ + 0, + 0 + ], + "VolumeDriver": "" + }, + "GraphDriver": { + "Name": "aufs", + "Data": null + }, + "Mounts": [], + "Config": { + "Hostname": "fc1243c01bbb", + "Domainname": "", + "User": "", + "AttachStdin": false, + "AttachStdout": false, + "AttachStderr": false, + "Tty": false, + "OpenStdin": true, + "StdinOnce": false, + "Env": null, + "Cmd": [ + "cat" + ], + "Healthcheck": { + "Test": [ + "CMD-SHELL", + "mysqladmin ping --silent" + ], + "Interval": 2000000000, + "Timeout": 3000000000 + }, + "Image": "busybox", + "Volumes": null, + "WorkingDir": "", + "Entrypoint": null, + "OnBuild": null, + "Labels": {}, + "StopSignal": "SIGTERM" + }, + "NetworkSettings": { + "Bridge": "", + "SandboxID": "5a6ded01bf23cc180e8ba6a059449ac832f28fa1d8367127e316607f92d3228c", + "HairpinMode": false, + "LinkLocalIPv6Address": "", + "LinkLocalIPv6PrefixLen": 0, + "Ports": {}, + "SandboxKey": "/var/run/docker/netns/5a6ded01bf23", + "SecondaryIPAddresses": null, + "SecondaryIPv6Addresses": null, + "EndpointID": "6b4bb2aff9981d6e132cf37ebbfd370069061fab848ae56247b154717a99aba7", + "Gateway": "172.17.0.1", + "GlobalIPv6Address": "", + "GlobalIPv6PrefixLen": 0, + "IPAddress": "172.17.0.2", + "IPPrefixLen": 16, + "IPv6Gateway": "", + "MacAddress": "02:42:ac:11:00:02", + "Networks": { + "bridge": { + "EndpointID": "6b4bb2aff9981d6e132cf37ebbfd370069061fab848ae56247b154717a99aba7", + "Gateway": "172.17.0.1", + "IPAddress": "172.17.0.2", + "IPPrefixLen": 16, + "IPv6Gateway": "", + "GlobalIPv6Address": "", + "GlobalIPv6PrefixLen": 0, + "MacAddress": "02:42:ac:11:00:02" + } + } + } +} From 7427db3f5d8cd03f294f1c5b0929b2fcda7122fa Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 3 Mar 2017 22:22:24 +0300 Subject: [PATCH 024/599] Update CHANGELOG.md --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca927c2c31..114c661478 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,11 @@ Change Log === ## (dev) 3.1.0 (reserverd for swarm features) -## next... +## 3.0.8 + - Use TLSv1.2 by default + - Health api + - Labels + - Support for multiple certificates ## 3.0.7 * https://github.com/docker-java/docker-java/milestone/17?closed=1 From c57c6b184ac3fb8a347463f07bd140054d903908 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 3 Mar 2017 22:32:03 +0300 Subject: [PATCH 025/599] [maven-release-plugin] prepare release 3.0.8 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 726afefa45..a6f046ba43 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.8-SNAPSHOT + 3.0.8 docker-java https://github.com/docker-java/docker-java @@ -28,7 +28,7 @@ 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 + 3.0.8 From 0a3ac8d071b297d681d37080649a90a64ef59417 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 3 Mar 2017 22:32:16 +0300 Subject: [PATCH 026/599] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a6f046ba43..bc1970e660 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.8 + 3.0.9-SNAPSHOT docker-java https://github.com/docker-java/docker-java @@ -28,7 +28,7 @@ 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 - 3.0.8 + HEAD From 32e1116d0f869597967682de18678260b4cd9e6a Mon Sep 17 00:00:00 2001 From: James Netherton Date: Sat, 4 Mar 2017 14:35:16 +0000 Subject: [PATCH 027/599] Fixes #807. NettyDockerCmdExecFactory ignores API version configuration --- .../netty/NettyDockerCmdExecFactory.java | 7 +- .../NettyDockerCmdExecFactoryConfigTest.java | 142 ++++++++++++++++++ 2 files changed, 148 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java diff --git a/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java index c91d4af21b..2c8a83b0ea 100644 --- a/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java @@ -172,6 +172,8 @@ public class NettyDockerCmdExecFactory implements DockerCmdExecFactory { private NettyInitializer nettyInitializer; + private WebTarget baseResource; + private ChannelProvider channelProvider = new ChannelProvider() { @Override public DuplexChannel getChannel() { @@ -199,6 +201,8 @@ public void init(DockerClientConfig dockerClientConfig) { } eventLoopGroup = nettyInitializer.init(bootstrap, dockerClientConfig); + + baseResource = new WebTarget(channelProvider).path(dockerClientConfig.getApiVersion().asWebPathPart()); } private DuplexChannel connect() { @@ -619,6 +623,7 @@ private T configure(T channel) { } private WebTarget getBaseResource() { - return new WebTarget(channelProvider); + checkNotNull(baseResource, "Factory not initialized, baseResource not set. You probably forgot to call init()!"); + return baseResource; } } diff --git a/src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java b/src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java new file mode 100644 index 0000000000..54184f6742 --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java @@ -0,0 +1,142 @@ +package com.github.dockerjava.netty; + +import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_LENGTH; +import static io.netty.handler.codec.http.HttpHeaderNames.CONTENT_TYPE; +import static io.netty.handler.codec.http.HttpResponseStatus.OK; +import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1; +import static org.testng.Assert.assertEquals; + +import io.netty.bootstrap.ServerBootstrap; +import io.netty.buffer.Unpooled; +import io.netty.channel.Channel; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.channel.SimpleChannelInboundHandler; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioServerSocketChannel; +import io.netty.handler.codec.http.DefaultFullHttpResponse; +import io.netty.handler.codec.http.FullHttpResponse; +import io.netty.handler.codec.http.HttpContent; +import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpServerCodec; +import io.netty.util.CharsetUtil; + +import java.util.ArrayList; +import java.util.List; + +import org.testng.annotations.Test; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.core.DefaultDockerClientConfig; +import com.github.dockerjava.core.DefaultDockerClientConfig.Builder; +import com.github.dockerjava.core.DockerClientBuilder; + +public class NettyDockerCmdExecFactoryConfigTest { + + @Test + public void testNettyDockerCmdExecFactoryConfigWithApiVersion() throws Exception { + NettyDockerCmdExecFactory factory = new NettyDockerCmdExecFactory(); + Builder configBuilder = DefaultDockerClientConfig.createDefaultConfigBuilder() + .withDockerHost("tcp://localhost:2378") + .withApiVersion("1.23"); + + DockerClient client = DockerClientBuilder.getInstance(configBuilder) + .withDockerCmdExecFactory(factory) + .build(); + + FakeDockerServer server = new FakeDockerServer(2378); + server.start(); + try { + client.versionCmd().exec(); + + List requests = server.getRequests(); + + assertEquals(requests.size(), 1); + assertEquals(requests.get(0).uri(), "/v1.23/version"); + } finally { + server.stop(); + } + } + + @Test + public void testNettyDockerCmdExecFactoryConfigWithoutApiVersion() throws Exception { + NettyDockerCmdExecFactory factory = new NettyDockerCmdExecFactory(); + Builder configBuilder = DefaultDockerClientConfig.createDefaultConfigBuilder().withDockerHost("tcp://localhost:2378"); + + DockerClient client = DockerClientBuilder.getInstance(configBuilder) + .withDockerCmdExecFactory(factory) + .build(); + + FakeDockerServer server = new FakeDockerServer(2378); + server.start(); + try { + client.versionCmd().exec(); + + List requests = server.getRequests(); + + assertEquals(requests.size(), 1); + assertEquals(requests.get(0).uri(), "/version"); + } finally { + server.stop(); + } + } + + private class FakeDockerServer { + private final int port; + private final NioEventLoopGroup parent; + private final NioEventLoopGroup child; + private final List requests = new ArrayList<>(); + private Channel channel; + + private FakeDockerServer(int port) { + this.port = port; + this.parent = new NioEventLoopGroup(); + this.child = new NioEventLoopGroup(); + } + + private void start() throws Exception { + ServerBootstrap bootstrap = new ServerBootstrap(); + bootstrap.group(parent, child) + .channel(NioServerSocketChannel.class) + .childHandler(new ChannelInitializer() { + @Override + protected void initChannel(SocketChannel socketChannel) throws Exception { + ChannelPipeline pipeline = socketChannel.pipeline(); + pipeline.addLast("codec", new HttpServerCodec()); + pipeline.addLast("httpHandler", new SimpleChannelInboundHandler() { + @Override + protected void channelRead0(ChannelHandlerContext context, Object message) throws Exception { + if (message instanceof HttpRequest) { + // Keep track of processed requests + HttpRequest request = (HttpRequest) message; + requests.add(request); + } + + if (message instanceof HttpContent) { + // Write an empty JSON response back to the client + FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.copiedBuffer("{}", CharsetUtil.UTF_8)); + response.headers().set(CONTENT_TYPE, "application/json; charset=UTF-8"); + response.headers().set(CONTENT_LENGTH, response.content().readableBytes()); + context.writeAndFlush(response); + } + } + }); + } + }); + + channel = bootstrap.bind(port).syncUninterruptibly().channel(); + } + + private void stop() throws Exception { + parent.shutdownGracefully(); + child.shutdownGracefully(); + channel.closeFuture().sync(); + } + + private List getRequests() { + return requests; + } + } +} From 221fff63fba1a82296198d67679f3eb7590d15ef Mon Sep 17 00:00:00 2001 From: James Netherton Date: Mon, 6 Mar 2017 20:46:56 +0000 Subject: [PATCH 028/599] Ensure FakeDockerServer is started on a random free port --- .../NettyDockerCmdExecFactoryConfigTest.java | 21 +++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java b/src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java index 54184f6742..d0ddccca88 100644 --- a/src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java +++ b/src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java @@ -23,6 +23,8 @@ import io.netty.handler.codec.http.HttpServerCodec; import io.netty.util.CharsetUtil; +import java.io.IOException; +import java.net.ServerSocket; import java.util.ArrayList; import java.util.List; @@ -37,16 +39,18 @@ public class NettyDockerCmdExecFactoryConfigTest { @Test public void testNettyDockerCmdExecFactoryConfigWithApiVersion() throws Exception { + int dockerPort = getFreePort(); + NettyDockerCmdExecFactory factory = new NettyDockerCmdExecFactory(); Builder configBuilder = DefaultDockerClientConfig.createDefaultConfigBuilder() - .withDockerHost("tcp://localhost:2378") + .withDockerHost("tcp://localhost:" + dockerPort) .withApiVersion("1.23"); DockerClient client = DockerClientBuilder.getInstance(configBuilder) .withDockerCmdExecFactory(factory) .build(); - FakeDockerServer server = new FakeDockerServer(2378); + FakeDockerServer server = new FakeDockerServer(dockerPort); server.start(); try { client.versionCmd().exec(); @@ -62,14 +66,16 @@ public void testNettyDockerCmdExecFactoryConfigWithApiVersion() throws Exception @Test public void testNettyDockerCmdExecFactoryConfigWithoutApiVersion() throws Exception { + int dockerPort = getFreePort(); + NettyDockerCmdExecFactory factory = new NettyDockerCmdExecFactory(); - Builder configBuilder = DefaultDockerClientConfig.createDefaultConfigBuilder().withDockerHost("tcp://localhost:2378"); + Builder configBuilder = DefaultDockerClientConfig.createDefaultConfigBuilder().withDockerHost("tcp://localhost:" + dockerPort); DockerClient client = DockerClientBuilder.getInstance(configBuilder) .withDockerCmdExecFactory(factory) .build(); - FakeDockerServer server = new FakeDockerServer(2378); + FakeDockerServer server = new FakeDockerServer(dockerPort); server.start(); try { client.versionCmd().exec(); @@ -83,6 +89,13 @@ public void testNettyDockerCmdExecFactoryConfigWithoutApiVersion() throws Except } } + private int getFreePort() throws IOException { + ServerSocket socket = new ServerSocket(0); + int freePort = socket.getLocalPort(); + socket.close(); + return freePort; + } + private class FakeDockerServer { private final int port; private final NioEventLoopGroup parent; From d9ca42c5a2f8d54f26f29ef5c2f06637254d9021 Mon Sep 17 00:00:00 2001 From: Maxim Chireychik Date: Tue, 14 Mar 2017 10:43:25 +0200 Subject: [PATCH 029/599] Unable to deserialize status response from amazon ECR login --- src/main/java/com/github/dockerjava/api/model/AuthResponse.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/github/dockerjava/api/model/AuthResponse.java b/src/main/java/com/github/dockerjava/api/model/AuthResponse.java index cd69081850..590fb7fb3a 100644 --- a/src/main/java/com/github/dockerjava/api/model/AuthResponse.java +++ b/src/main/java/com/github/dockerjava/api/model/AuthResponse.java @@ -1,9 +1,11 @@ package com.github.dockerjava.api.model; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import java.io.Serializable; +@JsonIgnoreProperties(ignoreUnknown = true) public class AuthResponse implements Serializable { private static final long serialVersionUID = 1L; From 0b2abbc3a8bedeee1c5ab67eee65badfcd1f5d6e Mon Sep 17 00:00:00 2001 From: David Byron Date: Wed, 15 Mar 2017 09:13:23 -0700 Subject: [PATCH 030/599] exclude commons-logging since docker-java uses slf4j/logback --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index bc1970e660..acc3a160cd 100644 --- a/pom.xml +++ b/pom.xml @@ -108,6 +108,12 @@ org.apache.httpcomponents httpclient ${httpclient.version} + + + commons-logging + commons-logging + + org.glassfish.jersey.core From f9fdc392bc676fa667f34e4e94b851919040ff7d Mon Sep 17 00:00:00 2001 From: orzeh Date: Tue, 28 Mar 2017 23:53:12 +0200 Subject: [PATCH 031/599] Generate OSGi compliant manifest (#797) * Generate OSGi compliant manifest Manifest is generated by the Bundlor plugin according to the template defined in template.mf file. Import package versions are mainly derived from properties defined in pom.xml. Imports of Netty packages are marked as optional. * Export com.github.dockerjava.core package and subpackages --- pom.xml | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ template.mf | 31 +++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 template.mf diff --git a/pom.xml b/pom.xml index acc3a160cd..154153fe52 100644 --- a/pom.xml +++ b/pom.xml @@ -86,6 +86,8 @@ 2.19.1 2.19.1 1.8 + 1.1.2.RELEASE + 3.0.0 @@ -275,6 +277,19 @@ + + + eclipse.virgo.build.bundles.release + Eclipse Virgo Build + http://build.eclipse.org/rt/virgo/maven/bundles/release + + + com.springsource.repository.bundles.external + SpringSource Enterprise Bundle Repository - External Bundle Releases + http://repository.springsource.com/maven/bundles/external + + + @@ -301,6 +316,11 @@ org.apache.maven.plugins maven-jar-plugin ${maven-jar-plugin.version} + + + target/classes/META-INF/MANIFEST.MF + + @@ -436,6 +456,37 @@ org.apache.maven.plugins maven-source-plugin + + + org.eclipse.virgo.bundlor + org.eclipse.virgo.bundlor.maven + ${maven-bundlor-plugin.version} + + + bundlor + + bundlor + + + true + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + ${maven-build-helper-plugin.version} + + + parse-version + + parse-version + + + + diff --git a/template.mf b/template.mf new file mode 100644 index 0000000000..35d278889e --- /dev/null +++ b/template.mf @@ -0,0 +1,31 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-SymbolicName: com.github.docker-java +Bundle-Version: ${parsedVersion.osgiVersion} +Bundle-Name: ${project.name} +Version-Patterns: + default;pattern="[=.=.=, =.+1.0)", + short;pattern="[=.=,+1.0)" +Import-Template: + com.fasterxml.jackson.*;version="${jackson-jaxrs.version}", + com.google.common.*;version="${guava.version:short}", + io.netty.*;version="${netty.version:default}";resolution:=optional, + javax.ws.rs.*;version="[2.0.0, 2.1.0)", + org.apache.commons.codec.*;version="${commons-codec.version:short}", + org.apache.commons.compress.*;version="${commons-compress.version:short}", + org.apache.commons.io.*;version="${commons-io.version:short}", + org.apache.commons.lang.*;version="${commons-lang.version:short}", + org.apache.http.*;version="[4.4.0, 4.6.0)", + org.bouncycastle.*;version="${bouncycastle.version:short}", + org.glassfish.jersey.*;version="${jersey.version:default}", + org.slf4j.*;version="[1.7.0, 1.8.0)", + org.newsclub.net.unix;version="${junixsocket.version:default}";resolution:=optional +Excluded-Exports: + org.apache.http.impl.io, + org.newsclub.net.unix, + com.github.dockerjava.jaxrs.*, + com.github.dockerjava.netty.* +Excluded-Imports: + javax.annotation, + javax.net.ssl, + edu.umd.cs.findbugs.annotations From 7016a6364e6638b126baa684209246068d57c773 Mon Sep 17 00:00:00 2001 From: nimantha siriwardana Date: Wed, 29 Mar 2017 09:40:50 +0100 Subject: [PATCH 032/599] adding support for unless-stopped restart policy --- .../github/dockerjava/api/model/RestartPolicy.java | 11 +++++++++++ .../api/model/RestartPolicy_ParsingTest.java | 5 +++++ .../api/model/RestartPolicy_SerializingTest.java | 7 +++++++ .../api/model/RestartPolicy_toStringTest.java | 2 +- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java b/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java index 1f77b8b9db..98e181a1bf 100644 --- a/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java +++ b/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java @@ -70,6 +70,13 @@ public static RestartPolicy onFailureRestart(int maximumRetryCount) { return new RestartPolicy(maximumRetryCount, "on-failure"); } + /** + * Restart the container unless it has been stopped + */ + public static RestartPolicy unlessStoppedRestart() { + return new RestartPolicy(0, "unless-stopped"); + } + public Integer getMaximumRetryCount() { return maximumRetryCount; } @@ -99,6 +106,10 @@ public static RestartPolicy parse(String serialized) throws IllegalArgumentExcep return alwaysRestart(); } + if ("unless-stopped".equals(name)) { + return unlessStoppedRestart(); + } + if ("on-failure".equals(name)) { int count = 0; if (parts.length == 2) { diff --git a/src/test/java/com/github/dockerjava/api/model/RestartPolicy_ParsingTest.java b/src/test/java/com/github/dockerjava/api/model/RestartPolicy_ParsingTest.java index 3bc22c00ee..85740be616 100644 --- a/src/test/java/com/github/dockerjava/api/model/RestartPolicy_ParsingTest.java +++ b/src/test/java/com/github/dockerjava/api/model/RestartPolicy_ParsingTest.java @@ -16,6 +16,11 @@ public void alwaysRestart() throws Exception { assertEquals(RestartPolicy.parse("always"), RestartPolicy.alwaysRestart()); } + @Test + public void unlessStoppedRestart() throws Exception { + assertEquals(RestartPolicy.parse("unless-stopped"), RestartPolicy.unlessStoppedRestart()); + } + @Test public void onFailureRestart() throws Exception { assertEquals(RestartPolicy.parse("on-failure"), RestartPolicy.onFailureRestart(0)); diff --git a/src/test/java/com/github/dockerjava/api/model/RestartPolicy_SerializingTest.java b/src/test/java/com/github/dockerjava/api/model/RestartPolicy_SerializingTest.java index 74c97fcf6f..06debb34fa 100644 --- a/src/test/java/com/github/dockerjava/api/model/RestartPolicy_SerializingTest.java +++ b/src/test/java/com/github/dockerjava/api/model/RestartPolicy_SerializingTest.java @@ -27,6 +27,13 @@ public void alwaysRestart() throws Exception { assertEquals(json, "{\"MaximumRetryCount\":0,\"Name\":\"always\"}"); } + @Test + // --restart unless-stopped + public void unlessStoppedRestart() throws Exception { + String json = objectMapper.writeValueAsString(RestartPolicy.unlessStoppedRestart()); + assertEquals(json, "{\"MaximumRetryCount\":0,\"Name\":\"unless-stopped\"}"); + } + @Test // --restart on-failure public void onFailureRestart() throws Exception { diff --git a/src/test/java/com/github/dockerjava/api/model/RestartPolicy_toStringTest.java b/src/test/java/com/github/dockerjava/api/model/RestartPolicy_toStringTest.java index 69e1e88a20..611343736a 100644 --- a/src/test/java/com/github/dockerjava/api/model/RestartPolicy_toStringTest.java +++ b/src/test/java/com/github/dockerjava/api/model/RestartPolicy_toStringTest.java @@ -9,7 +9,7 @@ public class RestartPolicy_toStringTest { @DataProvider(name = "input") public Object[][] restartPolicies() { - return new Object[][] { {"no"}, {"always"}, {"on-failure"}, {"on-failure:2"}}; + return new Object[][] { {"no"}, {"always"}, {"unless-stopped"}, {"on-failure"}, {"on-failure:2"}}; } @Test(dataProvider = "input") From 2d053870d546b43b8f5d18f53e5085702ace097d Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 13 Apr 2017 22:59:40 +0300 Subject: [PATCH 033/599] Responce may contains token. --- .../dockerjava/api/model/AuthResponse.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/main/java/com/github/dockerjava/api/model/AuthResponse.java b/src/main/java/com/github/dockerjava/api/model/AuthResponse.java index 590fb7fb3a..821d4c4ac0 100644 --- a/src/main/java/com/github/dockerjava/api/model/AuthResponse.java +++ b/src/main/java/com/github/dockerjava/api/model/AuthResponse.java @@ -3,16 +3,39 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; import java.io.Serializable; @JsonIgnoreProperties(ignoreUnknown = true) public class AuthResponse implements Serializable { private static final long serialVersionUID = 1L; + /** + * @since 1.23 + */ @JsonProperty("Status") private String status; + /** + * @since 1.23 + */ + @JsonProperty("IdentityToken") + private String identityToken; + + /** + * @see #status + */ + @Nonnull public String getStatus() { return status; } + + /** + * @see #identityToken + */ + @CheckForNull + public String getIdentityToken() { + return identityToken; + } } From f01072d81b5d06b79ad4425a568e19c89c06a1cf Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 13 Apr 2017 23:03:33 +0300 Subject: [PATCH 034/599] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 114c661478..b0c7f22375 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ Change Log === ## (dev) 3.1.0 (reserverd for swarm features) +## 3.0.9 +- NettyDockerCmdExecFactory ignores API version +- exclude commons-logging from httpclient since docker-java uses slf4j/logback +- Generate OSGi compliant manifest +- AuthResponse may contains token. + ## 3.0.8 - Use TLSv1.2 by default - Health api From 250a02baa7ae3549f4d4ebc9cd6efdd88d14bfab Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 13 Apr 2017 23:14:27 +0300 Subject: [PATCH 035/599] Fix test. --- .../netty/NettyDockerCmdExecFactoryConfigTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java b/src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java index d0ddccca88..e36ee6b8bc 100644 --- a/src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java +++ b/src/test/java/com/github/dockerjava/netty/NettyDockerCmdExecFactoryConfigTest.java @@ -42,7 +42,8 @@ public void testNettyDockerCmdExecFactoryConfigWithApiVersion() throws Exception int dockerPort = getFreePort(); NettyDockerCmdExecFactory factory = new NettyDockerCmdExecFactory(); - Builder configBuilder = DefaultDockerClientConfig.createDefaultConfigBuilder() + Builder configBuilder = new DefaultDockerClientConfig.Builder() + .withDockerTlsVerify(false) .withDockerHost("tcp://localhost:" + dockerPort) .withApiVersion("1.23"); @@ -69,7 +70,9 @@ public void testNettyDockerCmdExecFactoryConfigWithoutApiVersion() throws Except int dockerPort = getFreePort(); NettyDockerCmdExecFactory factory = new NettyDockerCmdExecFactory(); - Builder configBuilder = DefaultDockerClientConfig.createDefaultConfigBuilder().withDockerHost("tcp://localhost:" + dockerPort); + Builder configBuilder = new DefaultDockerClientConfig.Builder() + .withDockerTlsVerify(false) + .withDockerHost("tcp://localhost:" + dockerPort); DockerClient client = DockerClientBuilder.getInstance(configBuilder) .withDockerCmdExecFactory(factory) From d705bfba9aea65b3556fe057e1f7fedf8622da90 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 13 Apr 2017 23:18:52 +0300 Subject: [PATCH 036/599] [maven-release-plugin] prepare release 3.0.9 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 154153fe52..fd58ad39c9 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.9-SNAPSHOT + 3.0.9 docker-java https://github.com/docker-java/docker-java @@ -28,7 +28,7 @@ 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 + 3.0.9 From 53ee7e172f85ee994bc70ab5af3719cf1ab992d8 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 13 Apr 2017 23:19:03 +0300 Subject: [PATCH 037/599] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index fd58ad39c9..8933bad62f 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.9 + 3.0.10-SNAPSHOT docker-java https://github.com/docker-java/docker-java @@ -28,7 +28,7 @@ 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 - 3.0.9 + HEAD From dc87e0c592c133acc8ccac87a4cb0941eccdbb0e Mon Sep 17 00:00:00 2001 From: Dmitry Gusev Date: Mon, 24 Apr 2017 01:01:36 +0300 Subject: [PATCH 038/599] Proposed fix for #830 (#832) * Proposed fix for #830 * Simplify the fix for #830 --- .../command/BuildImageResultCallback.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/command/BuildImageResultCallback.java b/src/main/java/com/github/dockerjava/core/command/BuildImageResultCallback.java index 1ca2764343..e622c47257 100644 --- a/src/main/java/com/github/dockerjava/core/command/BuildImageResultCallback.java +++ b/src/main/java/com/github/dockerjava/core/command/BuildImageResultCallback.java @@ -5,8 +5,6 @@ import java.util.concurrent.TimeUnit; -import javax.annotation.CheckForNull; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -23,12 +21,17 @@ public class BuildImageResultCallback extends ResultCallbackTemplate Date: Sun, 23 Apr 2017 23:03:39 +0100 Subject: [PATCH 039/599] Allow an explicit Dockerfile location string to be specified to the build command (#825) * When supplying a TAR stream to the build command, API consumers just want to pass a String location of the Dockerfile within the TAR stream they are supplying * Add netty test for building with an explicitly specified Dockerfile location within a tar --- .../dockerjava/api/command/BuildImageCmd.java | 2 ++ .../dockerjava/core/command/BuildImageCmdImpl.java | 13 ++++++++++++- .../core/command/BuildImageCmdImplTest.java | 14 ++++++++++++++ .../netty/exec/BuildImageCmdExecTest.java | 14 ++++++++++++++ 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java index ac98db2f9f..0c9b7f5a4e 100644 --- a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java @@ -117,6 +117,8 @@ public interface BuildImageCmd extends AsyncDockerCmd files = FileUtils.listFiles(baseDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE); + File tarFile = CompressArchiveUtil.archiveTARFiles(baseDir, files, UUID.randomUUID().toString()); + String response = dockerfileBuild(new FileInputStream(tarFile), "dockerfileFolder/Dockerfile"); + assertThat(response, containsString("Successfully executed testrun.sh")); + } + @Test public void onBuild() throws Exception { File baseDir = fileFromBuildTestResource("ONBUILD/parent"); @@ -123,6 +132,11 @@ public void addFolder() throws Exception { assertThat(response, containsString("Successfully executed testAddFolder.sh")); } + private String dockerfileBuild(InputStream tarInputStream, String dockerFilePath) throws Exception { + + return execBuild(dockerClient.buildImageCmd().withTarInputStream(tarInputStream).withDockerfilePath(dockerFilePath)); + } + private String dockerfileBuild(InputStream tarInputStream) throws Exception { return execBuild(dockerClient.buildImageCmd().withTarInputStream(tarInputStream)); diff --git a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java index f567dcfc82..63fcf7ea15 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java @@ -88,6 +88,15 @@ public void buildImageFromTar() throws Exception { assertThat(response, containsString("Successfully executed testrun.sh")); } + @Test + public void buildImageFromTarWithDockerfileNotInBaseDirectory() throws Exception { + File baseDir = fileFromBuildTestResource("dockerfileNotInBaseDirectory"); + Collection files = FileUtils.listFiles(baseDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE); + File tarFile = CompressArchiveUtil.archiveTARFiles(baseDir, files, UUID.randomUUID().toString()); + String response = dockerfileBuild(new FileInputStream(tarFile), "dockerfileFolder/Dockerfile"); + assertThat(response, containsString("Successfully executed testrun.sh")); + } + @Test public void onBuild() throws Exception { File baseDir = fileFromBuildTestResource("ONBUILD/parent"); @@ -128,6 +137,11 @@ public void addFolder() throws Exception { assertThat(response, containsString("Successfully executed testAddFolder.sh")); } + private String dockerfileBuild(InputStream tarInputStream, String dockerFilePath) throws Exception { + + return execBuild(dockerClient.buildImageCmd().withTarInputStream(tarInputStream).withDockerfilePath(dockerFilePath)); + } + private String dockerfileBuild(InputStream tarInputStream) throws Exception { return execBuild(dockerClient.buildImageCmd().withTarInputStream(tarInputStream)); From e81067367657c6dac686cd0e613f849685a5c3c3 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 24 Apr 2017 01:51:56 +0300 Subject: [PATCH 040/599] Add some coding styles. TODO sync and share eclipse files? --- .gitignore | 3 ++- .idea/codeStyleSettings.xml | 12 ++++++++++++ .idea/encodings.xml | 7 +++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 .idea/codeStyleSettings.xml create mode 100644 .idea/encodings.xml diff --git a/.gitignore b/.gitignore index a705c11293..5399371c40 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,8 @@ target # Ignore InteliJ Idea project files .idea -.idea/* +!.idea/codeStyleSettings.xml +!.idea/encodings.xml *.iml *.iws *.ipr diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml new file mode 100644 index 0000000000..6f3c789b4d --- /dev/null +++ b/.idea/codeStyleSettings.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000000..c0bce70846 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file From 3ad99322f80ecd502cbe2fc68f7185c9d2807a3e Mon Sep 17 00:00:00 2001 From: Jonas Trollvik Date: Thu, 27 Apr 2017 17:22:24 +0200 Subject: [PATCH 041/599] Add db LoggingType Synology uses it's own logging type called db --- src/main/java/com/github/dockerjava/api/model/LogConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/github/dockerjava/api/model/LogConfig.java b/src/main/java/com/github/dockerjava/api/model/LogConfig.java index e2a0661010..2a33012876 100644 --- a/src/main/java/com/github/dockerjava/api/model/LogConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/LogConfig.java @@ -79,6 +79,7 @@ public enum LoggingType { GELF("gelf"), FLUENTD("fluentd"), AWSLOGS("awslogs"), + DB("db"), // Synology specific driver SPLUNK("splunk"); private String type; From 460406705daf705ae46467f2ffa6f371aafeed12 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 5 May 2017 05:12:40 +0300 Subject: [PATCH 042/599] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0c7f22375..84f2b27d9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ Change Log === ## (dev) 3.1.0 (reserverd for swarm features) + +## 3.0.10 +- Custom `db` logging type +- Allow an explicit Dockerfile location string to be specified to theuild command +- Fix image build for docker 17 with 'tagged' word. + ## 3.0.9 - NettyDockerCmdExecFactory ignores API version - exclude commons-logging from httpclient since docker-java uses slf4j/logback From c82b92d38374e242e8130af7282f8cf59c91297d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Warcha=C5=82?= Date: Tue, 15 Nov 2016 13:48:57 +0100 Subject: [PATCH 043/599] Allow multiple tags in build image command Several tags for image can be defined by calling multiple time withTag() method of BuildImageCmd. In Netty implementation, the WebTarget class is modified to support several query parameteres with the same name. Fix #720 --- .../dockerjava/api/command/BuildImageCmd.java | 19 +++++ .../core/command/BuildImageCmdImpl.java | 24 +++++- .../dockerjava/jaxrs/BuildImageCmdExec.java | 9 +- .../github/dockerjava/netty/WebTarget.java | 85 +++++++++++++++++-- .../netty/exec/BuildImageCmdExec.java | 34 +++----- .../core/command/BuildImageCmdImplTest.java | 25 ++++++ .../netty/exec/BuildImageCmdExecTest.java | 25 ++++++ 7 files changed, 189 insertions(+), 32 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java index ac98db2f9f..a36b1b17ec 100644 --- a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java @@ -4,6 +4,7 @@ import java.io.InputStream; import java.net.URI; import java.util.Map; +import java.util.Set; import javax.annotation.CheckForNull; import javax.annotation.Nonnull; @@ -34,10 +35,21 @@ public interface BuildImageCmd extends AsyncDockerCmd getTags(); + /** * "remote" in API */ @@ -109,8 +121,15 @@ public interface BuildImageCmd extends AsyncDockerCmd)} + */ + @Deprecated BuildImageCmd withTag(String tag); + BuildImageCmd withTags(Set tags); + BuildImageCmd withRemote(URI remote); BuildImageCmd withBaseDirectory(File baseDirectory); diff --git a/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java index c34b051559..97629568c4 100644 --- a/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java @@ -8,6 +8,7 @@ import java.net.URI; import java.util.HashMap; import java.util.Map; +import java.util.Set; import com.github.dockerjava.api.command.BuildImageCmd; import com.github.dockerjava.api.model.AuthConfigurations; @@ -15,17 +16,20 @@ import com.github.dockerjava.core.dockerfile.Dockerfile; import com.github.dockerjava.core.util.FilePathUtil; +import javax.annotation.CheckForNull; + /** - * * Build an image from Dockerfile. - * */ public class BuildImageCmdImpl extends AbstrAsyncDockerCmd implements BuildImageCmd { private InputStream tarInputStream; + @Deprecated private String tag; + private Set tags; + private Boolean noCache; private Boolean remove = true; @@ -82,11 +86,17 @@ public BuildImageCmdImpl(BuildImageCmd.Exec exec, InputStream tarInputStream) { // getters API + @Deprecated @Override public String getTag() { return tag; } + @CheckForNull + public Set getTags() { + return tags; + } + @Override public URI getRemote() { return remote; @@ -178,6 +188,10 @@ public Long getShmsize() { // setters + /** + * @deprecated use #withTags() + */ + @Deprecated @Override public BuildImageCmdImpl withTag(String tag) { checkNotNull(tag, "Tag is null"); @@ -185,6 +199,12 @@ public BuildImageCmdImpl withTag(String tag) { return this; } + @Override + public BuildImageCmd withTags(Set tags) { + this.tags = tags; + return this; + } + @Override public BuildImageCmd withRemote(URI remote) { this.remote = remote; diff --git a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java index 2a7aea40e1..ae2302b0da 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java @@ -1,6 +1,7 @@ package com.github.dockerjava.jaxrs; import static javax.ws.rs.client.Entity.entity; +import static org.apache.commons.lang.StringUtils.isNotBlank; import javax.ws.rs.client.Invocation; import javax.ws.rs.client.WebTarget; @@ -65,9 +66,15 @@ protected AbstractCallbackNotifier callbackNotifier(BuildImag if (dockerFilePath != null && command.getRemote() == null && !"Dockerfile".equals(dockerFilePath)) { webTarget = webTarget.queryParam("dockerfile", dockerFilePath); } - if (command.getTag() != null) { + + if (command.getTags() != null && !command.getTags().isEmpty()) { + for (String t : command.getTags()) { + webTarget = webTarget.queryParam("t", t); + } + } else if (isNotBlank(command.getTag())) { webTarget = webTarget.queryParam("t", command.getTag()); } + if (command.getRemote() != null) { webTarget = webTarget.queryParam("remote", command.getRemote().toString()); } diff --git a/src/main/java/com/github/dockerjava/netty/WebTarget.java b/src/main/java/com/github/dockerjava/netty/WebTarget.java index ef1510f5c0..96fb42beca 100644 --- a/src/main/java/com/github/dockerjava/netty/WebTarget.java +++ b/src/main/java/com/github/dockerjava/netty/WebTarget.java @@ -1,22 +1,32 @@ package com.github.dockerjava.netty; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.Set; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.collect.ImmutableSet; +import io.netty.handler.codec.http.HttpConstants; import org.apache.commons.lang.StringUtils; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; /** - * This class is basically a replacement of javax.ws.rs.client.WebTarget to allow simpler migration of JAX-RS code to a netty based + * This class is basically a replacement of {@link javax.ws.rs.client.WebTarget} to allow simpler migration of JAX-RS code to a netty based * implementation. * * @author Marcus Linke */ public class WebTarget { + private static final ObjectMapper MAPPER = new ObjectMapper(); private final ChannelProvider channelProvider; @@ -24,18 +34,26 @@ public class WebTarget { private final ImmutableMap queryParams; + /** + * Multiple values for the same name param. + */ + private final ImmutableMap> queryParamsSet; + private static final String PATH_SEPARATOR = "/"; public WebTarget(ChannelProvider channelProvider) { - this(channelProvider, ImmutableList.of(), ImmutableMap.of()); + this(channelProvider, ImmutableList.of(), ImmutableMap.of(), + ImmutableMap.>of()); } private WebTarget(ChannelProvider channelProvider, ImmutableList path, - ImmutableMap queryParams) { + ImmutableMap queryParams, + ImmutableMap> queryParamsSet) { this.channelProvider = channelProvider; this.path = path; this.queryParams = queryParams; + this.queryParamsSet = queryParamsSet; } public WebTarget path(String... components) { @@ -45,7 +63,7 @@ public WebTarget path(String... components) { newPath.addAll(Arrays.asList(StringUtils.split(component, PATH_SEPARATOR))); } - return new WebTarget(channelProvider, newPath.build(), queryParams); + return new WebTarget(channelProvider, newPath.build(), queryParams, queryParamsSet); } public InvocationBuilder request() { @@ -53,7 +71,13 @@ public InvocationBuilder request() { List params = new ArrayList<>(); for (Map.Entry entry : queryParams.entrySet()) { - params.add(entry.getKey() + "=" + entry.getValue()); + params.add(entry.getKey() + "=" + encodeComponent(entry.getValue(), HttpConstants.DEFAULT_CHARSET)); + } + + for (Map.Entry> entry : queryParamsSet.entrySet()) { + for (String entryValueValue : entry.getValue()) { + params.add(entry.getKey() + "=" + encodeComponent(entryValueValue, HttpConstants.DEFAULT_CHARSET)); + } } if (!params.isEmpty()) { @@ -63,13 +87,25 @@ public InvocationBuilder request() { return new InvocationBuilder(channelProvider, resource); } + /** + * @see io.netty.handler.codec.http.QueryStringEncoder + */ + private static String encodeComponent(String s, Charset charset) { + // TODO: Optimize me. + try { + return URLEncoder.encode(s, charset.name()).replace("+", "%20"); + } catch (UnsupportedEncodingException ignored) { + throw new UnsupportedCharsetException(charset.name()); + } + } + public WebTarget resolveTemplate(String name, Object value) { ImmutableList.Builder newPath = ImmutableList.builder(); for (String component : path) { component = component.replaceAll("\\{" + name + "\\}", value.toString()); newPath.add(component); } - return new WebTarget(channelProvider, newPath.build(), queryParams); + return new WebTarget(channelProvider, newPath.build(), queryParams, queryParamsSet); } public WebTarget queryParam(String name, Object value) { @@ -77,7 +113,32 @@ public WebTarget queryParam(String name, Object value) { if (value != null) { builder.put(name, value.toString()); } - return new WebTarget(channelProvider, path, builder.build()); + return new WebTarget(channelProvider, path, builder.build(), queryParamsSet); + } + + public WebTarget queryParamsSet(String name, Set values) { + ImmutableMap.Builder> builder = ImmutableMap.>builder().putAll(queryParamsSet); + if (values != null) { + ImmutableSet.Builder valueBuilder = ImmutableSet.builder(); + for (Object value : values) { + valueBuilder.add(value.toString()); + } + builder.put(name, valueBuilder.build()); + } + return new WebTarget(channelProvider, path, queryParams, builder.build()); + } + + public WebTarget queryParamsJsonMap(String name, Map values) { + if (values != null && !values.isEmpty()) { + try { + // when param value is JSON string + return queryParam(name, MAPPER.writeValueAsString(values)); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + return this; + } } @Override @@ -97,7 +158,14 @@ public boolean equals(Object o) { if (path != null ? !path.equals(webTarget.path) : webTarget.path != null) { return false; } - return queryParams != null ? queryParams.equals(webTarget.queryParams) : webTarget.queryParams == null; + if (queryParams != null ? !queryParams.equals(webTarget.queryParams) : webTarget.queryParams != null) { + return false; + } + if (queryParamsSet != null ? !queryParamsSet.equals(webTarget.queryParamsSet) : webTarget.queryParamsSet != null) { + return false; + } + + return true; } @Override @@ -105,6 +173,7 @@ public int hashCode() { int result = channelProvider != null ? channelProvider.hashCode() : 0; result = 31 * result + (path != null ? path.hashCode() : 0); result = 31 * result + (queryParams != null ? queryParams.hashCode() : 0); + result = 31 * result + (queryParamsSet != null ? queryParamsSet.hashCode() : 0); return result; } } diff --git a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java index 43152570e7..bbca686e01 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java @@ -1,6 +1,5 @@ package com.github.dockerjava.netty.exec; -import com.fasterxml.jackson.databind.ObjectMapper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,15 +13,12 @@ import com.github.dockerjava.netty.MediaType; import com.github.dockerjava.netty.WebTarget; -import java.io.IOException; -import java.util.Map; +import static org.apache.commons.lang.StringUtils.isNotBlank; public class BuildImageCmdExec extends AbstrAsyncDockerCmdExec implements BuildImageCmd.Exec { private static final Logger LOGGER = LoggerFactory.getLogger(BuildImageCmdExec.class); - private static final ObjectMapper MAPPER = new ObjectMapper(); - public BuildImageCmdExec(WebTarget baseResource, DockerClientConfig dockerClientConfig) { super(baseResource, dockerClientConfig); } @@ -55,9 +51,13 @@ protected Void execute0(BuildImageCmd command, ResultCallback if (dockerFilePath != null && command.getRemote() == null && !"Dockerfile".equals(dockerFilePath)) { webTarget = webTarget.queryParam("dockerfile", dockerFilePath); } - if (command.getTag() != null) { - webTarget = webTarget.queryParam("t", command.getTag()); + + if (command.getTags() != null && !command.getTags().isEmpty()) { + webTarget = webTarget.queryParamsSet("t", command.getTags()); + } else if (isNotBlank(command.getTag())) { + webTarget = webTarget.queryParam("t", command.getTags()); } + if (command.getRemote() != null) { webTarget = webTarget.queryParam("remote", command.getRemote().toString()); } @@ -86,13 +86,17 @@ protected Void execute0(BuildImageCmd command, ResultCallback webTarget = webTarget.queryParam("cpusetcpus", command.getCpusetcpus()); } - webTarget = writeMap(webTarget, "buildargs", command.getBuildArgs()); + if (command.getBuildArgs() != null) { + webTarget = webTarget.queryParamsJsonMap("buildargs", command.getBuildArgs()); + } if (command.getShmsize() != null) { webTarget = webTarget.queryParam("shmsize", command.getShmsize()); } - webTarget = writeMap(webTarget, "labels", command.getLabels()); + if (command.getLabels() != null) { + webTarget = webTarget.queryParamsJsonMap("labels", command.getLabels()); + } LOGGER.trace("POST: {}", webTarget); @@ -106,16 +110,4 @@ protected Void execute0(BuildImageCmd command, ResultCallback return null; } - - private WebTarget writeMap(WebTarget webTarget, String name, Map value) { - if (value != null && !value.isEmpty()) { - try { - return webTarget.queryParam(name, MAPPER.writeValueAsString(value)); - } catch (IOException e) { - throw new RuntimeException(e); - } - } else { - return webTarget; - } - } } diff --git a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java index cb4c1b2a8e..9ba2837320 100644 --- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java @@ -7,13 +7,16 @@ import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.containsInAnyOrder; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.UUID; import org.apache.commons.io.FileUtils; @@ -274,6 +277,28 @@ public void labels() throws Exception { assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc")); } + @Test + public void multipleTags() throws Exception { + if (!getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_21)) { + throw new SkipException("API version should be >= 1.21"); + } + + File baseDir = fileFromBuildTestResource("labels"); + + String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true) + .withTag("fallback-when-withTags-not-called") + .withTags(new HashSet<>(Arrays.asList("docker-java-test:tag1", "docker-java-test:tag2"))) + .exec(new BuildImageResultCallback()) + .awaitImageId(); + + InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); + assertThat(inspectImageResponse, not(nullValue())); + LOG.info("Image Inspect: {}", inspectImageResponse.toString()); + + assertThat(inspectImageResponse.getRepoTags().size(), equalTo(2)); + assertThat(inspectImageResponse.getRepoTags(), containsInAnyOrder("docker-java-test:tag1", "docker-java-test:tag2")); + } + public void dockerfileNotInBaseDirectory() throws Exception { File baseDirectory = fileFromBuildTestResource("dockerfileNotInBaseDirectory"); File dockerfile = fileFromBuildTestResource("dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile"); diff --git a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java index f567dcfc82..55dcf353b5 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java @@ -7,13 +7,16 @@ import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.containsInAnyOrder; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.UUID; import org.apache.commons.io.FileUtils; @@ -279,6 +282,28 @@ public void labels() throws Exception { assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc")); } + @Test + public void multipleTags() throws Exception { + if (!getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_21)) { + throw new SkipException("API version should be >= 1.21"); + } + + File baseDir = fileFromBuildTestResource("labels"); + + String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true) + .withTag("fallback-when-withTags-not-called") + .withTags(new HashSet<>(Arrays.asList("docker-java-test:tag1", "docker-java-test:tag2"))) + .exec(new BuildImageResultCallback()) + .awaitImageId(); + + InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); + assertThat(inspectImageResponse, not(nullValue())); + LOG.info("Image Inspect: {}", inspectImageResponse.toString()); + + assertThat(inspectImageResponse.getRepoTags().size(), equalTo(2)); + assertThat(inspectImageResponse.getRepoTags(), containsInAnyOrder("docker-java-test:tag1", "docker-java-test:tag2")); + } + public void dockerfileNotInBaseDirectory() throws Exception { File baseDirectory = fileFromBuildTestResource("dockerfileNotInBaseDirectory"); File dockerfile = fileFromBuildTestResource("dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile"); From e5e674a73199633ed05817d4283ec9e160c8ec0d Mon Sep 17 00:00:00 2001 From: kannan-ca Date: Thu, 11 May 2017 17:05:01 -0400 Subject: [PATCH 044/599] Docker API update to 1.25 and support for cache-from command as part of the docker build --- .../dockerjava/api/command/BuildImageCmd.java | 11 +++++++++ .../dockerjava/core/RemoteApiVersion.java | 6 +++++ .../core/command/BuildImageCmdImpl.java | 13 ++++++++++ .../dockerjava/jaxrs/BuildImageCmdExec.java | 6 +++++ .../netty/exec/BuildImageCmdExec.java | 8 ++++++- .../core/command/BuildImageCmdImplTest.java | 24 +++++++++++++++++++ .../netty/exec/BuildImageCmdExecTest.java | 23 ++++++++++++++++++ 7 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java index 2a08f4cf59..59a0d20773 100644 --- a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java @@ -50,6 +50,12 @@ public interface BuildImageCmd extends AsyncDockerCmd getTags(); + /** + * "Cache-from" in API + */ + @CheckForNull + Set getCacheFrom(); + /** * "remote" in API */ @@ -130,6 +136,11 @@ public interface BuildImageCmd extends AsyncDockerCmd tags); + /* + * @since {@link RemoteApiVersion#VERSION_1_25} + */ + BuildImageCmd withCacheFrom(Set cacheFrom); + BuildImageCmd withRemote(URI remote); BuildImageCmd withBaseDirectory(File baseDirectory); diff --git a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java index f40b5b4d58..44c4f0237a 100644 --- a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java +++ b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java @@ -72,6 +72,12 @@ public class RemoteApiVersion implements Serializable { */ public static final RemoteApiVersion VERSION_1_24 = RemoteApiVersion.create(1, 24); + /* + * @see Docker API 1.25 + */ + public static final RemoteApiVersion VERSION_1_25 = RemoteApiVersion.create(1, 25); + + /** * Unknown, docker doesn't reflect reality. I.e. we implemented method, but for javadoc it not clear when it was added. */ diff --git a/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java index fedd8bf98f..cb9e81a395 100644 --- a/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java @@ -30,6 +30,8 @@ public class BuildImageCmdImpl extends AbstrAsyncDockerCmd tags; + private Set cacheFrom; + private Boolean noCache; private Boolean remove = true; @@ -99,6 +101,11 @@ public Set getTags() { return tags; } + @CheckForNull + public Set getCacheFrom() { + return cacheFrom; + } + @Override public URI getRemote() { return remote; @@ -209,6 +216,12 @@ public BuildImageCmd withTags(Set tags) { return this; } + @Override + public BuildImageCmd withCacheFrom(Set cacheFrom) { + this.cacheFrom = cacheFrom; + return this; + } + @Override public BuildImageCmd withRemote(URI remote) { this.remote = remote; diff --git a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java index ae2302b0da..7ce132963f 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java @@ -75,6 +75,12 @@ protected AbstractCallbackNotifier callbackNotifier(BuildImag webTarget = webTarget.queryParam("t", command.getTag()); } + if (command.getCacheFrom() != null) { + for (String c: command.getCacheFrom()) { + webTarget = webTarget.queryParam("cachefrom", c); + } + } + if (command.getRemote() != null) { webTarget = webTarget.queryParam("remote", command.getRemote().toString()); } diff --git a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java index bbca686e01..321ae63c1e 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java @@ -55,7 +55,13 @@ protected Void execute0(BuildImageCmd command, ResultCallback if (command.getTags() != null && !command.getTags().isEmpty()) { webTarget = webTarget.queryParamsSet("t", command.getTags()); } else if (isNotBlank(command.getTag())) { - webTarget = webTarget.queryParam("t", command.getTags()); + webTarget = webTarget.queryParam("t", command.getTag()); + } + + if (command.getCacheFrom() != null) { + for (String c: command.getCacheFrom()) { + webTarget = webTarget.queryParam("cachefrom", c); + } } if (command.getRemote() != null) { diff --git a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java index a655af1262..20ac2b62d9 100644 --- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java @@ -312,6 +312,30 @@ public void multipleTags() throws Exception { assertThat(inspectImageResponse.getRepoTags().size(), equalTo(2)); assertThat(inspectImageResponse.getRepoTags(), containsInAnyOrder("docker-java-test:tag1", "docker-java-test:tag2")); } + + @Test + public void cacheFrom() throws Exception { + if (!getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_25)) { + throw new SkipException("API version should be >= 1.25"); + } + File baseDir1 = fileFromBuildTestResource("CacheFrom/test1"); + String imageId1 = dockerClient.buildImageCmd(baseDir1) + .exec(new BuildImageResultCallback()) + .awaitImageId(); + InspectImageResponse inspectImageResponse1 = dockerClient.inspectImageCmd(imageId1).exec(); + assertThat(inspectImageResponse1, not(nullValue())); + + File baseDir2 = fileFromBuildTestResource("CacheFrom/test2"); + String imageId2 = dockerClient.buildImageCmd(baseDir2).withCacheFrom(new HashSet<>(Arrays.asList(imageId1))) + .exec(new BuildImageResultCallback()) + .awaitImageId(); + InspectImageResponse inspectImageResponse2 = dockerClient.inspectImageCmd(imageId2).exec(); + assertThat(inspectImageResponse2, not(nullValue())); + + // Compare whether the image2's parent layer is from image1 so that cache is used + assertThat(inspectImageResponse2.getParent(), equalTo(inspectImageResponse1.getId())); + + } public void dockerfileNotInBaseDirectory() throws Exception { File baseDirectory = fileFromBuildTestResource("dockerfileNotInBaseDirectory"); diff --git a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java index b5df27d37b..54ede31dd3 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java @@ -318,6 +318,29 @@ public void multipleTags() throws Exception { assertThat(inspectImageResponse.getRepoTags(), containsInAnyOrder("docker-java-test:tag1", "docker-java-test:tag2")); } + @Test + public void cacheFrom() throws Exception { + if (!getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_25)) { + throw new SkipException("API version should be >= 1.25"); + } + File baseDir1 = fileFromBuildTestResource("CacheFrom/test1"); + String imageId1 = dockerClient.buildImageCmd(baseDir1) + .exec(new BuildImageResultCallback()) + .awaitImageId(); + InspectImageResponse inspectImageResponse1 = dockerClient.inspectImageCmd(imageId1).exec(); + assertThat(inspectImageResponse1, not(nullValue())); + + File baseDir2 = fileFromBuildTestResource("CacheFrom/test2"); + String imageId2 = dockerClient.buildImageCmd(baseDir2).withCacheFrom(new HashSet<>(Arrays.asList(imageId1))) + .exec(new BuildImageResultCallback()) + .awaitImageId(); + InspectImageResponse inspectImageResponse2 = dockerClient.inspectImageCmd(imageId2).exec(); + assertThat(inspectImageResponse2, not(nullValue())); + + // Compare whether the image2's parent layer is from image1 so that cache is used + assertThat(inspectImageResponse2.getParent(), equalTo(inspectImageResponse1.getId())); + } + public void dockerfileNotInBaseDirectory() throws Exception { File baseDirectory = fileFromBuildTestResource("dockerfileNotInBaseDirectory"); File dockerfile = fileFromBuildTestResource("dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile"); From 05a9a74d55fd321ac2285170a56e330306c3c207 Mon Sep 17 00:00:00 2001 From: kannan-ca Date: Wed, 17 May 2017 10:05:05 -0400 Subject: [PATCH 045/599] Used existing queryParamSet method --- .../com/github/dockerjava/netty/exec/BuildImageCmdExec.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java index 321ae63c1e..a99dac8338 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java @@ -58,10 +58,8 @@ protected Void execute0(BuildImageCmd command, ResultCallback webTarget = webTarget.queryParam("t", command.getTag()); } - if (command.getCacheFrom() != null) { - for (String c: command.getCacheFrom()) { - webTarget = webTarget.queryParam("cachefrom", c); - } + if (command.getCacheFrom() != null && !command.getCacheFrom().isEmpty()) { + webTarget = webTarget.queryParamsSet("cachefrom", command.getCacheFrom()); } if (command.getRemote() != null) { From 5444f05f88b97c4a2963964eb400678910e92e89 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 May 2017 19:30:07 +0300 Subject: [PATCH 046/599] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84f2b27d9d..d2da1378ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ Change Log ## 3.0.10 +- Support for cache-from in build image command +- Allow multiple tags in build image command - Custom `db` logging type - Allow an explicit Dockerfile location string to be specified to theuild command - Fix image build for docker 17 with 'tagged' word. From b014f26dce76e67e6c133c36079154a710e3c838 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 May 2017 20:01:38 +0300 Subject: [PATCH 047/599] [maven-release-plugin] prepare release 3.0.10 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 8933bad62f..0ba096dc54 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.10-SNAPSHOT + 3.0.10 docker-java https://github.com/docker-java/docker-java @@ -28,7 +28,7 @@ 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 + 3.0.10 From a14ace4f972a3de4cac3ddc3cb0f7006f629cfdf Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 May 2017 20:01:49 +0300 Subject: [PATCH 048/599] [maven-release-plugin] prepare for next development iteration --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 0ba096dc54..10fad38607 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.10 + 3.0.11-SNAPSHOT docker-java https://github.com/docker-java/docker-java @@ -28,7 +28,7 @@ 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 - 3.0.10 + HEAD From 342feb6f9cd2d3a7d17cf56b36aff6ad6fa02ad3 Mon Sep 17 00:00:00 2001 From: Ted Xiao Date: Tue, 23 May 2017 14:51:22 +0800 Subject: [PATCH 049/599] ignore application/x-tar --- .../github/dockerjava/jaxrs/filter/SelectiveLoggingFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/github/dockerjava/jaxrs/filter/SelectiveLoggingFilter.java b/src/main/java/com/github/dockerjava/jaxrs/filter/SelectiveLoggingFilter.java index 2251d8fadf..36256fca02 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/filter/SelectiveLoggingFilter.java +++ b/src/main/java/com/github/dockerjava/jaxrs/filter/SelectiveLoggingFilter.java @@ -24,6 +24,7 @@ public class SelectiveLoggingFilter extends LoggingFilter { Set s = new HashSet(); s.add(MediaType.APPLICATION_OCTET_STREAM); s.add("application/tar"); + s.add("application/x-tar"); SKIPPED_CONTENT = Collections.unmodifiableSet(s); } From c44eba80e7742195e78351ed1bf35452066ff4f1 Mon Sep 17 00:00:00 2001 From: Ted Xiao Date: Tue, 23 May 2017 21:40:06 +0800 Subject: [PATCH 050/599] allow user to call connectionManager's closeIdleConnections --- .../jaxrs/JerseyDockerCmdExecFactory.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java index 4b7f2f67eb..1d9d65f0a4 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java @@ -9,6 +9,7 @@ import java.net.URI; import java.net.URISyntaxException; import java.util.List; +import java.util.concurrent.TimeUnit; import javax.net.ssl.SSLContext; import javax.ws.rs.client.Client; @@ -266,7 +267,7 @@ private void configureProxy(ClientConfig clientConfig, URI originalUri, String p } private org.apache.http.config.Registry getSchemeRegistry(final URI originalUri, - SSLContext sslContext) { + SSLContext sslContext) { RegistryBuilder registryBuilder = RegistryBuilder.create(); registryBuilder.register("http", PlainConnectionSocketFactory.getSocketFactory()); if (sslContext != null) { @@ -589,4 +590,14 @@ public JerseyDockerCmdExecFactory withClientRequestFilters(ClientRequestFilter.. return this; } + + /** + * release connections from the pool + * + * @param idleSeconds idle seconds, longer than the configured value will be evicted + */ + public void releaseConnection(long idleSeconds) { + this.connManager.closeExpiredConnections(); + this.connManager.closeIdleConnections(idleSeconds, TimeUnit.SECONDS); + } } From d700d721c13de2fd5b60c4e8db107652aa614843 Mon Sep 17 00:00:00 2001 From: Ted Xiao Date: Thu, 18 May 2017 19:16:16 +0800 Subject: [PATCH 051/599] add labels and attachable properties to network --- .../api/command/CreateNetworkCmd.java | 20 ++++++++++ .../github/dockerjava/api/model/Network.java | 25 +++++++++++++ .../core/command/CreateNetworkCmdImpl.java | 37 +++++++++++++++++++ .../command/CreateContainerCmdImplTest.java | 24 ++++++++++++ .../command/CreateNetworkCmdImplTest.java | 34 +++++++++++++++++ 5 files changed, 140 insertions(+) diff --git a/src/main/java/com/github/dockerjava/api/command/CreateNetworkCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateNetworkCmd.java index 39989bd130..298e05aca2 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateNetworkCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateNetworkCmd.java @@ -36,6 +36,12 @@ public interface CreateNetworkCmd extends SyncDockerCmd { @CheckForNull Boolean getEnableIPv6(); + @CheckForNull + Boolean getAttachable(); + + @CheckForNull + Map getLabels(); + /** The new network's name. Required. */ CreateNetworkCmd withName(@Nonnull String name); @@ -54,6 +60,20 @@ public interface CreateNetworkCmd extends SyncDockerCmd { CreateNetworkCmd withEnableIpv6(boolean enableIpv6); + /** + * If enabled, and the network is in the global scope, non-service containers on worker nodes will be able to connect to the network. + * + * @since {@link RemoteApiVersion#VERSION_1_21} + */ + CreateNetworkCmd withAttachable(Boolean attachable); + + /** + * Add label for network + * + * @since {@link RemoteApiVersion#VERSION_1_24} + */ + CreateNetworkCmd withLabels(Map labels); + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/model/Network.java b/src/main/java/com/github/dockerjava/api/model/Network.java index c0f9f36ebb..2a532f88c6 100644 --- a/src/main/java/com/github/dockerjava/api/model/Network.java +++ b/src/main/java/com/github/dockerjava/api/model/Network.java @@ -37,6 +37,12 @@ public class Network implements Serializable { @JsonProperty("Options") private Map options; + @JsonProperty("Attachable") + private Boolean attachable; + + @JsonProperty("Labels") + public Map labels; + public String getId() { return id; } @@ -65,6 +71,14 @@ public Map getOptions() { return options; } + public Boolean isAttachable() { + return attachable; + } + + public Map getLabels() { + return labels; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this); @@ -158,6 +172,9 @@ public static class Config { @JsonProperty("Gateway") private String gateway; + @JsonProperty("NetworkID") + private String networkID; + public String getSubnet() { return subnet; } @@ -184,6 +201,14 @@ public Config withGateway(String gateway) { this.gateway = gateway; return this; } + + public String getNetworkID() { + return networkID; + } + + public void setNetworkID(String networkID) { + this.networkID = networkID; + } } } } diff --git a/src/main/java/com/github/dockerjava/core/command/CreateNetworkCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateNetworkCmdImpl.java index 834aa6905e..e6cff4c094 100644 --- a/src/main/java/com/github/dockerjava/core/command/CreateNetworkCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CreateNetworkCmdImpl.java @@ -10,6 +10,8 @@ import com.github.dockerjava.api.model.Network; import com.github.dockerjava.api.model.Network.Ipam; +import static com.google.common.base.Preconditions.checkNotNull; + public class CreateNetworkCmdImpl extends AbstrDockerCmd implements CreateNetworkCmd { @@ -34,6 +36,12 @@ public class CreateNetworkCmdImpl extends AbstrDockerCmd labels; + public CreateNetworkCmdImpl(DockerCmdSyncExec execution) { super(execution); } @@ -114,4 +122,33 @@ public CreateNetworkCmd withEnableIpv6(boolean enableIpv6) { this.enableIpv6 = enableIpv6; return this; } + + @Override + public Boolean getAttachable() { + return this.attachable; + } + + /** + * {@inheritDoc} + */ + @Override + public CreateNetworkCmd withAttachable(Boolean attachable) { + this.attachable = attachable; + return this; + } + + @Override + public Map getLabels() { + return labels; + } + + /** + * {@inheritDoc} + */ + @Override + public CreateNetworkCmd withLabels(Map labels) { + checkNotNull(labels, "labels was not specified"); + this.labels = labels; + return this; + } } diff --git a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java index 7c625ea949..53c9d9ad02 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -777,4 +777,28 @@ public void createContainerWithShmPidsLimit() throws DockerException { assertThat(inspectContainerResponse.getHostConfig().getPidsLimit(), is(hostConfig.getPidsLimit())); } + + @Test + public void createContainerWithNetworkID() { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_24)) { + throw new SkipException("API version should be >= 1.24"); + } + String networkName = "net-" + UUID.randomUUID().toString(); + Map labels=new HashMap<>(); + labels.put("com.example.label","test"); + CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd().withName(networkName) + .withLabels(labels).withAttachable(true).exec(); + String networkId = createNetworkResponse.getId(); + CreateContainerResponse createContainerResponse = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withLabels(labels).withCmd("true").exec(); + String containerId = createContainerResponse.getId(); + dockerClient.connectToNetworkCmd().withContainerId(containerId).withNetworkId(networkId).exec(); + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(containerId).exec(); + ContainerNetwork containerNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get(networkName); + if(containerNetwork==null){ + // swarm node used network id + containerNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get(networkId); + } + assertThat(containerNetwork, notNullValue()); + } } diff --git a/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java index cc70331f22..7dae2e1d64 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java @@ -4,7 +4,9 @@ import com.github.dockerjava.api.exception.DockerException; import com.github.dockerjava.api.model.Network; import com.github.dockerjava.client.AbstractDockerClientTest; +import com.github.dockerjava.core.RemoteApiVersion; import org.testng.ITestResult; +import org.testng.SkipException; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeMethod; @@ -12,6 +14,10 @@ import org.testng.annotations.Test; import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import static com.github.dockerjava.utils.TestUtils.getVersion; @Test(groups = "integration") public class CreateNetworkCmdImplTest extends AbstractDockerClientTest { @@ -64,4 +70,32 @@ public void createNetworkWithIpamConfig() throws DockerException { assertEquals(network.getDriver(), "bridge"); assertEquals("10.67.79.0/24", network.getIpam().getConfig().iterator().next().getSubnet()); } + + @Test + public void createAttachableNetwork() throws DockerException { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_24)) { + throw new SkipException("API version should be >= 1.24"); + } + String networkName = "createAttachableNetwork"; + CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd().withName(networkName).withAttachable(true).exec(); + assertNotNull(createNetworkResponse.getId()); + Network network = dockerClient.inspectNetworkCmd().withNetworkId(createNetworkResponse.getId()).exec(); + assertTrue(network.isAttachable()); + } + + @Test + public void createNetworkWithLabel() throws DockerException { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_21)) { + throw new SkipException("API version should be >= 1.21"); + } + String networkName = "createNetworkWithLabel"; + Map labels=new HashMap<>(); + labels.put("com.example.usage","test"); + CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd().withName(networkName).withLabels(labels).exec(); + assertNotNull(createNetworkResponse.getId()); + Network network = dockerClient.inspectNetworkCmd().withNetworkId(createNetworkResponse.getId()).exec(); + assertEquals(network.getLabels(), labels); + } } From a9b78cc4f5ec45c0bdeec2e68136f8a59b96b1c3 Mon Sep 17 00:00:00 2001 From: Ted Xiao Date: Tue, 23 May 2017 18:14:36 +0800 Subject: [PATCH 052/599] clean tmp file after upload --- .idea/codeStyleSettings.xml | 1 + .../CopyArchiveToContainerCmdImpl.java | 30 ++++++++++++------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml index 6f3c789b4d..9e5672189a 100644 --- a/.idea/codeStyleSettings.xml +++ b/.idea/codeStyleSettings.xml @@ -5,6 +5,7 @@