From 6c748c61330cc996c78d5c294e40d98c8294e37e Mon Sep 17 00:00:00 2001 From: valerijf Date: Tue, 11 Oct 2016 13:23:26 +0200 Subject: [PATCH 001/565] 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 cf8c1b77e..6827be4e8 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/565] 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 6827be4e8..9307da6b3 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 49b94f6fd6fd6f59c45138698051047e82719dd8 Mon Sep 17 00:00:00 2001 From: ooxi Date: Fri, 25 Nov 2016 08:32:41 +0100 Subject: [PATCH 003/565] 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 832890e87..8f35fac12 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 80ba61f434a9a67fd0428f8c5e606be7d4485f07 Mon Sep 17 00:00:00 2001 From: Valerij Date: Wed, 15 Feb 2017 18:35:32 +0100 Subject: [PATCH 004/565] 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 9307da6b3..6bb1930e1 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 a3be9a5c32fd90c6c5d2f19e8c903b5df67fed2f Mon Sep 17 00:00:00 2001 From: "Lubos.Palisek" Date: Thu, 15 Dec 2016 13:30:57 +0100 Subject: [PATCH 005/565] 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 000000000..6f5418713 --- /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 000000000..e7f4c15a9 --- /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 c8027b0ed..497aaad2b 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 191126798..6d3265afa 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 000000000..514bf4f41 --- /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 cd4562b4a..51e8bd1dc 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 000000000..54d23923f --- /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 006/565] Update CHANGELOG.md --- CHANGELOG.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ca927c2c3..114c66147 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 007/565] [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 726afefa4..a6f046ba4 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 008/565] [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 a6f046ba4..bc1970e66 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 009/565] 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 c91d4af21..2c8a83b0e 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 000000000..54184f674 --- /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 010/565] 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 54184f674..d0ddccca8 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 011/565] 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 cd6908185..590fb7fb3 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 012/565] 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 bc1970e66..acc3a160c 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 013/565] 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 acc3a160c..154153fe5 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 000000000..35d278889 --- /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 014/565] 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 1f77b8b9d..98e181a1b 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 3bc22c00e..85740be61 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 74c97fcf6..06debb34f 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 69e1e88a2..611343736 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 015/565] 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 590fb7fb3..821d4c4ac 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 016/565] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 114c66147..b0c7f2237 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 017/565] 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 d0ddccca8..e36ee6b8b 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 018/565] [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 154153fe5..fd58ad39c 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 019/565] [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 fd58ad39c..8933bad62 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 020/565] 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 1ca276434..e622c4725 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 021/565] 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 ac98db2f9..0c9b7f5a4 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 f567dcfc8..63fcf7ea1 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 022/565] 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 a705c1129..5399371c4 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 000000000..6f3c789b4 --- /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 000000000..c0bce7084 --- /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 023/565] 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 e2a066101..2a3301287 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 024/565] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0c7f2237..84f2b27d9 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 025/565] 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 ac98db2f9..a36b1b17e 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 c34b05155..97629568c 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 2a7aea40e..ae2302b0d 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 ef1510f5c..96fb42bec 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 43152570e..bbca686e0 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 cb4c1b2a8..9ba283732 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 f567dcfc8..55dcf353b 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 026/565] 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 2a08f4cf5..59a0d2077 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 f40b5b4d5..44c4f0237 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 fedd8bf98..cb9e81a39 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 ae2302b0d..7ce132963 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 bbca686e0..321ae63c1 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 a655af126..20ac2b62d 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 b5df27d37..54ede31dd 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 027/565] 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 321ae63c1..a99dac833 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 028/565] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 84f2b27d9..d2da1378a 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 029/565] [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 8933bad62..0ba096dc5 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 030/565] [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 0ba096dc5..10fad3860 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 031/565] 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 2251d8fad..36256fca0 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 032/565] 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 4b7f2f67e..1d9d65f0a 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 033/565] 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 39989bd13..298e05aca 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 c0f9f36eb..2a532f88c 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 834aa6905..e6cff4c09 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 7c625ea94..53c9d9ad0 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 cc70331f2..7dae2e1d6 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 034/565] 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 6f3c789b4..9e5672189 100644 --- a/.idea/codeStyleSettings.xml +++ b/.idea/codeStyleSettings.xml @@ -5,6 +5,7 @@