From 43feaf1fb17165b81cc39e39759024c93ab37f63 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 8 Feb 2016 01:58:36 +0300 Subject: [PATCH 001/855] Make AuthConfig fluent setters. Resolves #453 --- .../dockerjava/api/model/AuthConfig.java | 19 ++++++----- .../dockerjava/core/AuthConfigFile.java | 10 +++--- .../dockerjava/core/DockerClientConfig.java | 10 +++--- .../dockerjava/core/DockerClientImpl.java | 12 +++---- .../dockerjava/core/GoLangFileMatch.java | 2 +- .../dockerjava/api/model/AuthConfigTest.java | 10 +++--- .../dockerjava/core/AuthConfigFileTest.java | 32 +++++++++---------- .../core/command/BuildImageCmdImplTest.java | 11 +++---- .../netty/exec/BuildImageCmdExecTest.java | 11 +++---- 9 files changed, 58 insertions(+), 59 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/AuthConfig.java b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java index 3dc3ef348..5c99942fc 100644 --- a/src/main/java/com/github/dockerjava/api/model/AuthConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java @@ -3,7 +3,6 @@ import org.apache.commons.lang.builder.ReflectionToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; -import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; @@ -30,48 +29,52 @@ public class AuthConfig { @JsonProperty("serveraddress") private String serverAddress = DEFAULT_SERVER_ADDRESS; + @JsonProperty("auth") private String auth; public String getUsername() { return username; } - public void setUsername(String username) { + public AuthConfig withUsername(String username) { this.username = username; + return this; } public String getPassword() { return password; } - public void setPassword(String password) { + public AuthConfig withPassword(String password) { this.password = password; + return this; } public String getEmail() { return email; } - public void setEmail(String email) { + public AuthConfig withEmail(String email) { this.email = email; + return this; } public String getServerAddress() { return serverAddress; } - public void setServerAddress(String serverAddress) { + public AuthConfig withServerAddress(String serverAddress) { this.serverAddress = serverAddress; + return this; } - @JsonIgnore public String getAuth() { return auth; } - @JsonProperty("auth") - public void setAuth(String auth) { + public AuthConfig withAuth(String auth) { this.auth = auth; + return this; } @Override diff --git a/src/main/java/com/github/dockerjava/core/AuthConfigFile.java b/src/main/java/com/github/dockerjava/core/AuthConfigFile.java index 1a4ef5a47..ed96a7c44 100644 --- a/src/main/java/com/github/dockerjava/core/AuthConfigFile.java +++ b/src/main/java/com/github/dockerjava/core/AuthConfigFile.java @@ -111,8 +111,8 @@ public static AuthConfigFile loadConfig(File confFile) throws IOException { for (Map.Entry entry : configMap.entrySet()) { AuthConfig authConfig = entry.getValue(); decodeAuth(authConfig.getAuth(), authConfig); - authConfig.setAuth(null); - authConfig.setServerAddress(entry.getKey()); + authConfig.withAuth(null); + authConfig.withServerAddress(entry.getKey()); configFile.addConfig(authConfig); } } else { @@ -131,7 +131,7 @@ public static AuthConfigFile loadConfig(File confFile) throws IOException { if (origEmail.length != 2) { throw new IOException("Invalid Auth config file"); } - config.setEmail(origEmail[1]); + config.withEmail(origEmail[1]); configFile.addConfig(config); } return configFile; @@ -144,8 +144,8 @@ static void decodeAuth(String auth, AuthConfig config) throws IOException { if (parts.length != 2) { throw new IOException("Invalid auth configuration file"); } - config.setUsername(parts[0]); - config.setPassword(parts[1]); + config.withUsername(parts[0]); + config.withPassword(parts[1]); } static String convertToHostname(String server) { diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java index 5ebd9aa72..1472be028 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java @@ -278,11 +278,11 @@ private AuthConfig getAuthConfig() { AuthConfig authConfig = null; if (getRegistryUsername() != null && getRegistryPassword() != null && getRegistryEmail() != null && getRegistryUrl() != null) { - authConfig = new AuthConfig(); - authConfig.setUsername(getRegistryUsername()); - authConfig.setPassword(getRegistryPassword()); - authConfig.setEmail(getRegistryEmail()); - authConfig.setServerAddress(getRegistryUrl()); + authConfig = new AuthConfig() + .withUsername(getRegistryUsername()) + .withPassword(getRegistryPassword()) + .withEmail(getRegistryEmail()) + .withServerAddress(getRegistryUrl()); } return authConfig; } diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java index bbf667a89..317bb051e 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -164,13 +164,11 @@ public AuthConfig authConfig() { checkNotNull(dockerClientConfig.getRegistryUsername(), "Configured username is null."); checkNotNull(dockerClientConfig.getRegistryUrl(), "Configured serverAddress is null."); - AuthConfig authConfig = new AuthConfig(); - authConfig.setUsername(dockerClientConfig.getRegistryUsername()); - authConfig.setPassword(dockerClientConfig.getRegistryPassword()); - authConfig.setEmail(dockerClientConfig.getRegistryEmail()); - authConfig.setServerAddress(dockerClientConfig.getRegistryUrl()); - - return authConfig; + return new AuthConfig() + .withUsername(dockerClientConfig.getRegistryUsername()) + .withPassword(dockerClientConfig.getRegistryPassword()) + .withEmail(dockerClientConfig.getRegistryEmail()) + .withServerAddress(dockerClientConfig.getRegistryUrl()); } /** diff --git a/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java b/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java index 5dabdf404..62dce2adc 100644 --- a/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java +++ b/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java @@ -37,7 +37,7 @@ * is malformed. * * On Windows, escaping is disabled. Instead, '\\' is treated as - * path separator. + AuthConfigTest * path separator. * * * @author tedo diff --git a/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java b/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java index 33066a84f..252e7a11e 100644 --- a/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java +++ b/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java @@ -11,11 +11,11 @@ public class AuthConfigTest { @BeforeMethod public void setUp() throws Exception { - authConfig = new AuthConfig(); - authConfig.setEmail("foo"); - authConfig.setPassword("bar"); - authConfig.setServerAddress("baz"); - authConfig.setUsername("qux"); + authConfig = new AuthConfig() + .withEmail("foo") + .withPassword("bar") + .withServerAddress("baz") + .withUsername("qux"); } @Test diff --git a/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java b/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java index e1c1b6f8d..c9d0ea36a 100644 --- a/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java +++ b/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java @@ -48,17 +48,17 @@ public void invalidLegacyEmailLine() throws IOException { @Test public void validJson() throws IOException { - AuthConfig authConfig1 = new AuthConfig(); - authConfig1.setEmail("foo@example.com"); - authConfig1.setUsername("foo"); - authConfig1.setPassword("bar"); - authConfig1.setServerAddress("quay.io"); - - AuthConfig authConfig2 = new AuthConfig(); - authConfig2.setEmail("moo@example.com"); - authConfig2.setUsername("foo1"); - authConfig2.setPassword("bar1"); - authConfig2.setServerAddress(AuthConfig.DEFAULT_SERVER_ADDRESS); + AuthConfig authConfig1 = new AuthConfig() + .withEmail("foo@example.com") + .withUsername("foo") + .withPassword("bar") + .withServerAddress("quay.io"); + + AuthConfig authConfig2 = new AuthConfig() + .withEmail("moo@example.com") + .withUsername("foo1") + .withPassword("bar1") + .withServerAddress(AuthConfig.DEFAULT_SERVER_ADDRESS); AuthConfigFile expected = new AuthConfigFile(); expected.addConfig(authConfig1); @@ -70,11 +70,11 @@ public void validJson() throws IOException { @Test public void validLegacy() throws IOException { - AuthConfig authConfig = new AuthConfig(); - authConfig.setEmail("foo@example.com"); - authConfig.setUsername("foo"); - authConfig.setPassword("bar"); - authConfig.setServerAddress(AuthConfig.DEFAULT_SERVER_ADDRESS); + AuthConfig authConfig = new AuthConfig() + .withEmail("foo@example.com") + .withUsername("foo") + .withPassword("bar") + .withServerAddress(AuthConfig.DEFAULT_SERVER_ADDRESS); AuthConfigFile expected = new AuthConfigFile(); expected.addConfig(authConfig); 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 775b12b16..aac25d218 100644 --- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java @@ -274,13 +274,12 @@ public void testBuildFromPrivateRegistry() throws Exception { // wait for registry to boot Thread.sleep(3000); - AuthConfig authConfig = new AuthConfig(); - // credentials as configured in /auth/htpasswd - authConfig.setUsername("testuser"); - authConfig.setPassword("testpassword"); - authConfig.setEmail("foo@bar.de"); - authConfig.setServerAddress("localhost:5000"); + AuthConfig authConfig = new AuthConfig() + .withUsername("testuser") + .withPassword("testpassword") + .withEmail("foo@bar.de") + .withServerAddress("localhost:5000"); dockerClient.authCmd().withAuthConfig(authConfig).exec(); dockerClient.tagImageCmd("busybox:latest", "localhost:5000/testuser/busybox", "latest").withForce().exec(); 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 fad4ef7b1..c5b2c3aa9 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java @@ -266,13 +266,12 @@ public void testBuildFromPrivateRegistry() throws Exception { // wait for registry to boot Thread.sleep(3000); - AuthConfig authConfig = new AuthConfig(); - // credentials as configured in /auth/htpasswd - authConfig.setUsername("testuser"); - authConfig.setPassword("testpassword"); - authConfig.setEmail("foo@bar.de"); - authConfig.setServerAddress("localhost:5000"); + AuthConfig authConfig = new AuthConfig() + .withUsername("testuser") + .withPassword("testpassword") + .withEmail("foo@bar.de") + .withServerAddress("localhost:5000"); dockerClient.authCmd().withAuthConfig(authConfig).exec(); dockerClient.tagImageCmd("busybox:latest", "localhost:5000/testuser/busybox", "latest").withForce().exec(); From bd11042d0fa41d0e2dc44fc139502c45def8f873 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 8 Feb 2016 21:25:49 +0300 Subject: [PATCH 002/855] Rename withServerAddress to withRegistryAddress. This is more correct as auth used only for pull/push operations. --- .../dockerjava/api/model/AuthConfig.java | 18 +++++++++--------- .../api/model/AuthConfigurations.java | 2 +- .../github/dockerjava/core/AuthConfigFile.java | 4 ++-- .../dockerjava/core/DockerClientConfig.java | 2 +- .../dockerjava/core/DockerClientImpl.java | 2 +- .../dockerjava/api/model/AuthConfigTest.java | 4 ++-- .../dockerjava/core/AuthConfigFileTest.java | 6 +++--- .../core/command/BuildImageCmdImplTest.java | 2 +- .../netty/exec/BuildImageCmdExecTest.java | 2 +- 9 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/AuthConfig.java b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java index 5c99942fc..ae7ebdda2 100644 --- a/src/main/java/com/github/dockerjava/api/model/AuthConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java @@ -27,7 +27,7 @@ public class AuthConfig { private String email; @JsonProperty("serveraddress") - private String serverAddress = DEFAULT_SERVER_ADDRESS; + private String registryAddress = DEFAULT_SERVER_ADDRESS; @JsonProperty("auth") private String auth; @@ -59,12 +59,12 @@ public AuthConfig withEmail(String email) { return this; } - public String getServerAddress() { - return serverAddress; + public String getRegistryAddress() { + return registryAddress; } - public AuthConfig withServerAddress(String serverAddress) { - this.serverAddress = serverAddress; + public AuthConfig withRegistryAddress(String registryAddress) { + this.registryAddress = registryAddress; return this; } @@ -90,7 +90,7 @@ public int hashCode() { result = prime * result + ((auth == null) ? 0 : auth.hashCode()); result = prime * result + ((email == null) ? 0 : email.hashCode()); result = prime * result + ((password == null) ? 0 : password.hashCode()); - result = prime * result + ((serverAddress == null) ? 0 : serverAddress.hashCode()); + result = prime * result + ((registryAddress == null) ? 0 : registryAddress.hashCode()); result = prime * result + ((username == null) ? 0 : username.hashCode()); return result; } @@ -119,10 +119,10 @@ public boolean equals(Object obj) { return false; } else if (!password.equals(other.password)) return false; - if (serverAddress == null) { - if (other.serverAddress != null) + if (registryAddress == null) { + if (other.registryAddress != null) return false; - } else if (!serverAddress.equals(other.serverAddress)) + } else if (!registryAddress.equals(other.registryAddress)) return false; if (username == null) { if (other.username != null) diff --git a/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java b/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java index 21451e64b..e8edbc950 100644 --- a/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java +++ b/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java @@ -11,7 +11,7 @@ public class AuthConfigurations { private Map configs = new TreeMap<>(); public void addConfig(AuthConfig authConfig) { - configs.put(authConfig.getServerAddress(), authConfig); + configs.put(authConfig.getRegistryAddress(), authConfig); } public Map getConfigs() { diff --git a/src/main/java/com/github/dockerjava/core/AuthConfigFile.java b/src/main/java/com/github/dockerjava/core/AuthConfigFile.java index ed96a7c44..f796fd7c9 100644 --- a/src/main/java/com/github/dockerjava/core/AuthConfigFile.java +++ b/src/main/java/com/github/dockerjava/core/AuthConfigFile.java @@ -29,7 +29,7 @@ public AuthConfigFile() { } void addConfig(AuthConfig config) { - authConfigMap.put(config.getServerAddress(), config); + authConfigMap.put(config.getRegistryAddress(), config); } public AuthConfig resolveAuthConfig(String hostname) { @@ -112,7 +112,7 @@ public static AuthConfigFile loadConfig(File confFile) throws IOException { AuthConfig authConfig = entry.getValue(); decodeAuth(authConfig.getAuth(), authConfig); authConfig.withAuth(null); - authConfig.withServerAddress(entry.getKey()); + authConfig.withRegistryAddress(entry.getKey()); configFile.addConfig(authConfig); } } else { diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java index 1472be028..d3897199c 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java @@ -282,7 +282,7 @@ && getRegistryUrl() != null) { .withUsername(getRegistryUsername()) .withPassword(getRegistryPassword()) .withEmail(getRegistryEmail()) - .withServerAddress(getRegistryUrl()); + .withRegistryAddress(getRegistryUrl()); } return authConfig; } diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java index 317bb051e..59e18bc85 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -168,7 +168,7 @@ public AuthConfig authConfig() { .withUsername(dockerClientConfig.getRegistryUsername()) .withPassword(dockerClientConfig.getRegistryPassword()) .withEmail(dockerClientConfig.getRegistryEmail()) - .withServerAddress(dockerClientConfig.getRegistryUrl()); + .withRegistryAddress(dockerClientConfig.getRegistryUrl()); } /** diff --git a/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java b/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java index 252e7a11e..8f5bd64f3 100644 --- a/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java +++ b/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java @@ -14,12 +14,12 @@ public void setUp() throws Exception { authConfig = new AuthConfig() .withEmail("foo") .withPassword("bar") - .withServerAddress("baz") + .withRegistryAddress("baz") .withUsername("qux"); } @Test public void defaultServerAddress() throws Exception { - assertEquals(new AuthConfig().getServerAddress(), "https://index.docker.io/v1/"); + assertEquals(new AuthConfig().getRegistryAddress(), "https://index.docker.io/v1/"); } } diff --git a/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java b/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java index c9d0ea36a..221a926b5 100644 --- a/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java +++ b/src/test/java/com/github/dockerjava/core/AuthConfigFileTest.java @@ -52,13 +52,13 @@ public void validJson() throws IOException { .withEmail("foo@example.com") .withUsername("foo") .withPassword("bar") - .withServerAddress("quay.io"); + .withRegistryAddress("quay.io"); AuthConfig authConfig2 = new AuthConfig() .withEmail("moo@example.com") .withUsername("foo1") .withPassword("bar1") - .withServerAddress(AuthConfig.DEFAULT_SERVER_ADDRESS); + .withRegistryAddress(AuthConfig.DEFAULT_SERVER_ADDRESS); AuthConfigFile expected = new AuthConfigFile(); expected.addConfig(authConfig1); @@ -74,7 +74,7 @@ public void validLegacy() throws IOException { .withEmail("foo@example.com") .withUsername("foo") .withPassword("bar") - .withServerAddress(AuthConfig.DEFAULT_SERVER_ADDRESS); + .withRegistryAddress(AuthConfig.DEFAULT_SERVER_ADDRESS); AuthConfigFile expected = new AuthConfigFile(); expected.addConfig(authConfig); 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 aac25d218..99eefb4de 100644 --- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java @@ -279,7 +279,7 @@ public void testBuildFromPrivateRegistry() throws Exception { .withUsername("testuser") .withPassword("testpassword") .withEmail("foo@bar.de") - .withServerAddress("localhost:5000"); + .withRegistryAddress("localhost:5000"); dockerClient.authCmd().withAuthConfig(authConfig).exec(); dockerClient.tagImageCmd("busybox:latest", "localhost:5000/testuser/busybox", "latest").withForce().exec(); 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 c5b2c3aa9..8a19c7eb9 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java @@ -271,7 +271,7 @@ public void testBuildFromPrivateRegistry() throws Exception { .withUsername("testuser") .withPassword("testpassword") .withEmail("foo@bar.de") - .withServerAddress("localhost:5000"); + .withRegistryAddress("localhost:5000"); dockerClient.authCmd().withAuthConfig(authConfig).exec(); dockerClient.tagImageCmd("busybox:latest", "localhost:5000/testuser/busybox", "latest").withForce().exec(); From 2281246d41628d747a28020fedc78d4575e69256 Mon Sep 17 00:00:00 2001 From: Christopher Dancy Date: Sat, 13 Feb 2016 11:26:52 -0500 Subject: [PATCH 003/855] ADDED: gelf, fluentd, awslogs, and splunk drivers --- .../com/github/dockerjava/api/model/LogConfig.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) 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 cf9cdc1ee..8c1bbdb86 100644 --- a/src/main/java/com/github/dockerjava/api/model/LogConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/LogConfig.java @@ -69,7 +69,15 @@ public LogConfig setConfig(Map config) { @JsonDeserialize(using = LoggingType.Deserializer.class) @JsonSerialize(using = LoggingType.Serializer.class) public static enum LoggingType { - DEFAULT("json-file"), JSON_FILE("json-file"), NONE("none"), SYSLOG("syslog"), JOURNALD("journald"); + DEFAULT("json-file"), + JSON_FILE("json-file"), + NONE("none"), + SYSLOG("syslog"), + JOURNALD("journald"), + GELF("gelf"), + FLUENTD("fluentd"), + AWSLOGS("awslogs"), + SPLUNK("splunk"); private String type; From 810174a438d506c4dc601acf302bfcd08e367bfc Mon Sep 17 00:00:00 2001 From: Matthieu Baechler Date: Thu, 11 Feb 2016 16:58:41 +0100 Subject: [PATCH 004/855] Issue-456 input configuration should not be altered as it breaks unix socket support --- .../dockerjava/core/DockerClientConfig.java | 8 ++------ .../jaxrs/DockerCmdExecFactoryImpl.java | 15 +++++++++++---- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java index d3897199c..fbd285867 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java @@ -69,11 +69,11 @@ public class DockerClientConfig implements Serializable { CONFIG_KEYS.add(REGISTRY_URL); } - private URI dockerHost; + private final URI dockerHost; private final String registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig, dockerCertPath; - private boolean dockerTlsVerify; + private final boolean dockerTlsVerify; private final RemoteApiVersion apiVersion; @@ -238,10 +238,6 @@ public URI getDockerHost() { return dockerHost; } - public void setDockerHost(URI dockerHost) { - this.dockerHost = dockerHost; - } - public RemoteApiVersion getApiVersion() { return apiVersion; } diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index ec0a3b0a3..2c5b2b077 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -174,14 +174,14 @@ public void init(DockerClientConfig dockerClientConfig) { protocol = "http"; } - if (originalUri.getScheme().equals("unix")) { - dockerClientConfig.setDockerHost(UnixConnectionSocketFactory.sanitizeUri(originalUri)); - } else { + if (!originalUri.getScheme().equals("unix")) { + try { originalUri = new URI(originalUri.toString().replaceFirst("tcp", protocol)); } catch (URISyntaxException e) { throw new RuntimeException(e); } + configureProxy(clientConfig, protocol); } @@ -209,7 +209,14 @@ public void init(DockerClientConfig dockerClientConfig) { client = clientBuilder.build(); - baseResource = client.target(originalUri.toString()).path(dockerClientConfig.getApiVersion().asWebPathPart()); + baseResource = client.target(sanitizeUrl(originalUri).toString()).path(dockerClientConfig.getApiVersion().asWebPathPart()); + } + + private URI sanitizeUrl(URI originalUri) { + if (originalUri.getScheme().equals("unix")) { + return UnixConnectionSocketFactory.sanitizeUri(originalUri); + } + return originalUri; } private void configureProxy(ClientConfig clientConfig, String protocol) { From a1aaabc080b7279add661845ebca8bbe3f671a14 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 14 Feb 2016 02:05:23 +0300 Subject: [PATCH 005/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f33c3a30f..52e8c1856 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Notes * The configuration has been changed to better match the docker CLI configuration options. The properties file was renamed from `docker.io.properties` to `docker-java.properties`. See README.md for details. All changes +* [#463] (https://github.com/docker-java/docker-java/pull/463) More logging drivers * [#447] (https://github.com/docker-java/docker-java/pull/447) Refactoring of DockerClientConfig * [#430] (https://github.com/docker-java/docker-java/pull/430) Fix ExecStartCmd failure * [#426] (https://github.com/docker-java/docker-java/pull/426) Refactored filters API From dbc5fa6a76720e38bceac38bd3c05b9b57ab0059 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Mon, 15 Feb 2016 20:20:46 +0100 Subject: [PATCH 006/855] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0b519d0f3..1a99670c8 100644 --- a/README.md +++ b/README.md @@ -64,13 +64,12 @@ Run build without integration tests: com.github.docker-java docker-java - 2.1.2 + 2.2.0 - + ### Latest SNAPSHOT version You can find the latest SNAPSHOT version including javadoc and source files on [Sonatypes OSS repository](https://oss.sonatype.org/content/groups/public/com/github/docker-java/docker-java/). - com.github.docker-java docker-java From cafb8646fc5988264c40dd31234ef7c51c992282 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Mon, 15 Feb 2016 20:26:05 +0100 Subject: [PATCH 007/855] [maven-release-plugin] prepare release docker-java-3.0.0-RC1 --- pom.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 60e8fcad5..ed0a1b54f 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,4 @@ - + 4.0.0 @@ -11,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-SNAPSHOT + 3.0.0-RC1 docker-java https://github.com/docker-java/docker-java @@ -29,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 + docker-java-3.0.0-RC1 From 24802bc006a013e20c30e63b69b86affd78b9cf5 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Mon, 15 Feb 2016 20:26:09 +0100 Subject: [PATCH 008/855] [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 ed0a1b54f..a945e41e7 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-RC1 + 3.0.0-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 - docker-java-3.0.0-RC1 + HEAD From ff4055c237204ef1c43e32b6ebcf13edbbe3282f Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Mon, 15 Feb 2016 20:35:25 +0100 Subject: [PATCH 009/855] Update README.md --- README.md | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1a99670c8..144143b4b 100644 --- a/README.md +++ b/README.md @@ -67,14 +67,23 @@ Run build without integration tests: 2.2.0 -### Latest SNAPSHOT version -You can find the latest SNAPSHOT version including javadoc and source files on [Sonatypes OSS repository](https://oss.sonatype.org/content/groups/public/com/github/docker-java/docker-java/). +### Latest release candidate + + + com.github.docker-java + docker-java + 3.0.0-RC1 + + +### Latest development version +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/). com.github.docker-java docker-java 3.0.0-SNAPSHOT + ## Documentation From 39fd1f73db2bc79f1e583bd8aa02c520096bbbf1 Mon Sep 17 00:00:00 2001 From: Roman Timushev Date: Tue, 16 Feb 2016 18:19:52 +0300 Subject: [PATCH 010/855] Better unit test for ExecStart with stdin --- .../github/dockerjava/netty/exec/ExecStartCmdExecTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java index e4ceedac7..6436cd5da 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java @@ -109,16 +109,16 @@ public void execStartAttachStdin() throws Exception { dockerClient.startContainerCmd(container.getId()).exec(); - InputStream stdin = new ByteArrayInputStream("echo STDIN\n".getBytes()); + InputStream stdin = new ByteArrayInputStream("STDIN\n".getBytes("UTF-8")); ByteArrayOutputStream stdout = new ByteArrayOutputStream(); ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId()) - .withAttachStdout(true).withAttachStdin(true).withCmd("/bin/sh").exec(); + .withAttachStdout(true).withAttachStdin(true).withCmd("cat").exec(); dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withTty(true).withStdIn(stdin) .exec(new ExecStartResultCallback(stdout, System.err)).awaitCompletion(5, TimeUnit.SECONDS); - assertEquals(stdout.toString(), "STDIN\n"); + assertEquals(stdout.toString("UTF-8"), "STDIN\n"); } @Test(groups = "ignoreInCircleCi") From 875444329e0fa09e4eeef9fe825be952d1aaaac0 Mon Sep 17 00:00:00 2001 From: Roman Timushev Date: Tue, 16 Feb 2016 18:21:02 +0300 Subject: [PATCH 011/855] Fix stdin encoding --- .../dockerjava/netty/InvocationBuilder.java | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java index 83ce63979..70737eeac 100644 --- a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java +++ b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java @@ -22,13 +22,8 @@ import io.netty.util.concurrent.GenericFutureListener; import java.io.BufferedInputStream; -import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.UnsupportedEncodingException; -import java.nio.ByteBuffer; -import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; @@ -249,9 +244,9 @@ public void operationComplete(Future future) throws Exception { // now we can start a new thread that reads from stdin and writes to the channel new Thread(new Runnable() { - private int read(BufferedReader reader) { + private int read(InputStream is, byte[] buf) { try { - return reader.read(); + return is.read(buf); } catch (IOException e) { throw new RuntimeException(e); } @@ -260,19 +255,13 @@ private int read(BufferedReader reader) { @Override public void run() { - BufferedReader reader = new BufferedReader(new InputStreamReader(stdin, Charset.forName("UTF-8"))); + byte[] buffer = new byte[1024]; - int read = -1; - while ((read = read(reader)) != -1) { - byte[] bytes = ByteBuffer.allocate(4).putInt(read).array(); - try { - bytes = new String(bytes).getBytes("US-ASCII"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - - channel.writeAndFlush(Unpooled.copiedBuffer(bytes)); + int read; + while ((read = read(stdin, buffer)) != -1) { + channel.writeAndFlush(Unpooled.copiedBuffer(buffer, 0, read)); } + } }).start(); } From 91729b271d442cc9aab9016e078a8822843bff60 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Tue, 16 Feb 2016 22:43:00 +0100 Subject: [PATCH 012/855] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52e8c1856..30f109b37 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ Notes * The configuration has been changed to better match the docker CLI configuration options. The properties file was renamed from `docker.io.properties` to `docker-java.properties`. See README.md for details. All changes +* [#466] (https://github.com/docker-java/docker-java/pull/466) Fix exec start stdin encoding + +Included in 3.0.0-RC1 * [#463] (https://github.com/docker-java/docker-java/pull/463) More logging drivers * [#447] (https://github.com/docker-java/docker-java/pull/447) Refactoring of DockerClientConfig * [#430] (https://github.com/docker-java/docker-java/pull/430) Fix ExecStartCmd failure From 15400193ae77b45e9c8b88d5c5f8b0a38cf5a396 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Tue, 16 Feb 2016 23:28:02 +0100 Subject: [PATCH 013/855] Fix issue #461 --- .../core/async/JsonStreamProcessor.java | 9 ++- .../core/async/JsonStreamProcessorTest.java | 65 +++++++++++++++++++ 2 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/github/dockerjava/core/async/JsonStreamProcessorTest.java diff --git a/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java b/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java index 7e6c497e6..b17f4b220 100644 --- a/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java +++ b/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; import com.github.dockerjava.api.async.ResultCallback; /** @@ -41,8 +42,12 @@ public void processResponseStream(InputStream response, ResultCallback result JsonToken nextToken = jp.nextToken(); while (!closed && nextToken != null && nextToken != JsonToken.END_OBJECT) { try { - T next = OBJECT_MAPPER.readValue(jp, clazz); - resultCallback.onNext(next); + ObjectNode objectNode = OBJECT_MAPPER.readTree(jp); + + if (!objectNode.isEmpty(null)) { + T next = OBJECT_MAPPER.treeToValue(objectNode, clazz); + resultCallback.onNext(next); + } } catch (Exception e) { resultCallback.onError(e); } diff --git a/src/test/java/com/github/dockerjava/core/async/JsonStreamProcessorTest.java b/src/test/java/com/github/dockerjava/core/async/JsonStreamProcessorTest.java new file mode 100644 index 000000000..6c9ee8a15 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/async/JsonStreamProcessorTest.java @@ -0,0 +1,65 @@ +/* + * Created on 16.02.2016 + */ +package com.github.dockerjava.core.async; + +import static org.testng.Assert.assertFalse; + +import java.io.ByteArrayInputStream; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.testng.annotations.Test; + +import com.github.dockerjava.api.async.ResultCallback; +import com.github.dockerjava.api.model.PullResponseItem; + + +/** + * + * @author Marcus Linke + * + */ +public class JsonStreamProcessorTest { + + @Test + public void processEmptyJson() throws Exception { + + InputStream response = new ByteArrayInputStream("{}".getBytes()); + + JsonStreamProcessor jsonStreamProcessor = new JsonStreamProcessor(PullResponseItem.class); + + final List completed = new ArrayList(); + + jsonStreamProcessor.processResponseStream(response, new ResultCallback() { + + @Override + public void close() throws IOException { + } + + @Override + public void onStart(Closeable closeable) { + } + + @Override + public void onNext(PullResponseItem object) { + assertFalse(true, "onNext called for empty json"); + } + + @Override + public void onError(Throwable throwable) { + } + + @Override + public void onComplete() { + completed.add(true); + } + }); + + assertFalse(completed.isEmpty(), "Stream processing not completed"); + } + +} From 7666d875a686861c6896f0d6a357b81d0b7b6c6a Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 Feb 2016 04:56:57 +0300 Subject: [PATCH 014/855] Fix javadocs --- .../github/dockerjava/api/command/ListContainersCmd.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java b/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java index 4ae506a42..f55089393 100644 --- a/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java @@ -32,7 +32,7 @@ public interface ListContainersCmd extends SyncDockerCmd> { public Boolean hasShowSizeEnabled(); /** - * @param beforeId + * @param before * - Show only containers created before Id, include non-running ones. */ public ListContainersCmd withBefore(String before); @@ -44,7 +44,7 @@ public interface ListContainersCmd extends SyncDockerCmd> { public ListContainersCmd withExitcodeFilter(Integer exitcode); /** - * @param exitcode + * @param status * - Show only containers with the passed status (created|restarting|running|paused|exited). */ public ListContainersCmd withStatusFilter(String status); @@ -80,7 +80,7 @@ public interface ListContainersCmd extends SyncDockerCmd> { public ListContainersCmd withShowSize(Boolean showSize); /** - * @param sinceId + * @param since * - Show only containers created since Id, include non-running ones. */ public ListContainersCmd withSince(String since); From 06170d83552333c04f2e1de70c4ff18b6c6955a5 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 Feb 2016 04:57:51 +0300 Subject: [PATCH 015/855] Try with resources. API object setter. --- .../dockerjava/core/DockerClientConfig.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java index fbd285867..038c43cae 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java @@ -164,16 +164,11 @@ private static Properties overrideDockerPropertiesWithSettingsFromUserHome(Prope Properties overriddenProperties = new Properties(); overriddenProperties.putAll(p); - final File usersDockerPropertiesFile = new File(systemProperties.getProperty("user.home"), "." - + DOCKER_JAVA_PROPERTIES); + final File usersDockerPropertiesFile = new File(systemProperties.getProperty("user.home"), + "." + DOCKER_JAVA_PROPERTIES); if (usersDockerPropertiesFile.isFile()) { - try { - final FileInputStream in = new FileInputStream(usersDockerPropertiesFile); - try { - overriddenProperties.load(in); - } finally { - in.close(); - } + try (FileInputStream in = new FileInputStream(usersDockerPropertiesFile)) { + overriddenProperties.load(in); } catch (IOException e) { throw new RuntimeException(e); } @@ -381,6 +376,12 @@ public final DockerClientConfigBuilder withDockerHost(String dockerHost) { return this; } + + public final DockerClientConfigBuilder withApiVersion(RemoteApiVersion apiVersion) { + this.apiVersion = apiVersion.getVersion(); + return this; + } + public final DockerClientConfigBuilder withApiVersion(String apiVersion) { this.apiVersion = apiVersion; return this; From 373be76501c151fea5997a361d08ba4d879f4d0a Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 Feb 2016 04:58:18 +0300 Subject: [PATCH 016/855] Enable lost tests. --- .../github/dockerjava/core/RemoteApiVersion.java | 15 +++++++++++---- .../core/command/ListContainersCmdImplTest.java | 1 + .../netty/exec/ListContainersCmdExecTest.java | 1 + 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java index 4a264ab17..1dd93f466 100644 --- a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java +++ b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java @@ -1,14 +1,14 @@ package com.github.dockerjava.core; -import java.io.Serializable; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - import com.google.common.base.MoreObjects; import com.google.common.base.Objects; import com.google.common.base.Preconditions; import com.google.common.base.Strings; +import java.io.Serializable; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * Bean to encapsulate the version of the Docker Remote (REST) * API @@ -125,6 +125,13 @@ public boolean isGreaterOrEqual(final RemoteApiVersion other) { return false; } + /** + * @return String representation of version. i.e. "1.22" + */ + public String getVersion() { + return major + "." + minor; + } + // CHECKSTYLE:OFF @Override public boolean equals(final Object o) { diff --git a/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java index 529c2f89b..7bbfb3945 100644 --- a/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/ListContainersCmdImplTest.java @@ -52,6 +52,7 @@ public void afterMethod(ITestResult result) { super.afterMethod(result); } + @Test public void testListContainers() throws Exception { String testImage = "busybox"; diff --git a/src/test/java/com/github/dockerjava/netty/exec/ListContainersCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ListContainersCmdExecTest.java index 673784281..40464c6f7 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/ListContainersCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/ListContainersCmdExecTest.java @@ -54,6 +54,7 @@ public void afterMethod(ITestResult result) { super.afterMethod(result); } + @Test public void testListContainers() throws Exception { String testImage = "busybox"; From 14bf660387421f823f44d9d4e2cfeb12ad2d0e31 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Wed, 17 Feb 2016 20:39:17 +0100 Subject: [PATCH 017/855] Add comment --- .../com/github/dockerjava/core/async/JsonStreamProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java b/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java index b17f4b220..8d9a64303 100644 --- a/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java +++ b/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java @@ -43,7 +43,7 @@ public void processResponseStream(InputStream response, ResultCallback result while (!closed && nextToken != null && nextToken != JsonToken.END_OBJECT) { try { ObjectNode objectNode = OBJECT_MAPPER.readTree(jp); - + // exclude empty item serialization into class #461 if (!objectNode.isEmpty(null)) { T next = OBJECT_MAPPER.treeToValue(objectNode, clazz); resultCallback.onNext(next); From 1398d6dfccdafbc0c17e497b1fc5f50f41a83144 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 21 Feb 2016 03:26:11 +0300 Subject: [PATCH 018/855] Add jacoco and codecov.io --- .travis.yml | 3 +++ pom.xml | 26 +++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 985c35690..8f8ad52d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,9 @@ language: java jdk: - oraclejdk7 +before_install: + - pip install --user codecov after_success: + - codecov - echo "ossrh\${env.OSSRH_USER}\${env.OSSRH_PASS}" > ~/settings.xml - mvn deploy -DskipITs --settings ~/settings.xml diff --git a/pom.xml b/pom.xml index a945e41e7..d4a5b6947 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,6 @@ 2.3.1 2.17 2.17 - 2.5.1 1.7 @@ -279,12 +278,6 @@ - - org.codehaus.mojo - cobertura-maven-plugin - ${cobertura-maven-plugin.version} - - org.apache.maven.plugins maven-antrun-plugin @@ -480,6 +473,25 @@ + + org.jacoco + jacoco-maven-plugin + 0.7.6.201602180812 + + + + prepare-agent + + + + report + test + + report + + + + From f26105d14cbfb017c1fa554b710e407e0d06e5ae Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 22 Feb 2016 23:38:05 +0300 Subject: [PATCH 019/855] Fix travis. Don't push non master branches. --- .travis.yml | 4 +--- travis-after-success.sh | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100755 travis-after-success.sh diff --git a/.travis.yml b/.travis.yml index 8f8ad52d3..1d78b3bb9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,4 @@ jdk: before_install: - pip install --user codecov after_success: - - codecov - - echo "ossrh\${env.OSSRH_USER}\${env.OSSRH_PASS}" > ~/settings.xml - - mvn deploy -DskipITs --settings ~/settings.xml + - ./travis-after-success.sh diff --git a/travis-after-success.sh b/travis-after-success.sh new file mode 100755 index 000000000..aeb3c12c7 --- /dev/null +++ b/travis-after-success.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +codecov +if [[ $TRAVIS_BRANCH == "master" ]] && [[ $TRAVIS_PULL_REQUEST == "false" ]]; +then + cat << EOF >> ~/settings.xml + + + + ossrh + \${env.OSSRH_USER} + \${env.OSSRH_PASS} + + + +EOF + mvn deploy -DskipITs --settings ~/settings.xml + fi From f54a0178f7c7469347e79866d7b4a1f4911f85e6 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Tue, 23 Feb 2016 20:13:19 +0100 Subject: [PATCH 020/855] Update CHANGELOG.md --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30f109b37..222b73812 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,15 @@ Included in 3.0.0-RC1 * [#347] (https://github.com/docker-java/docker-java/pull/347) Implementation of copy archive to/from container commands * [#313] (https://github.com/docker-java/docker-java/pull/313) Refactor primitive type fields to be of object type in JSON objects +v2.2.1 +--- +* [#474] (https://github.com/docker-java/docker-java/pull/474) Fix periodic pull failure (2.x) + +v2.2.0 +--- +* [#457] (https://github.com/docker-java/docker-java/pull/457) Input configuration should not be altered as it breaks unix socket support +* [#430] (https://github.com/docker-java/docker-java/pull/430) Fix ExecStartCmd failure (backported from 3.0.0) + v2.1.4 --- From dc95e25219c26a93847c751862e996a32e02d0bb Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Tue, 23 Feb 2016 20:14:10 +0100 Subject: [PATCH 021/855] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 144143b4b..ad1f2c157 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Run build without integration tests: com.github.docker-java docker-java - 2.2.0 + 2.2.1 ### Latest release candidate From 2bff259fbc1fd656da5769cd41df0ab95ec17432 Mon Sep 17 00:00:00 2001 From: Roman Timushev Date: Wed, 24 Feb 2016 14:58:47 +0300 Subject: [PATCH 022/855] Updated to netty 4.1.0.CR3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d4a5b6947..c33a1de3a 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ 1.1.0 6.1.1 - 4.1.0.CR2 + 4.1.0.CR3 1.3 1.6 2.3.3 From 4fd5657bad7aabb6a3f6fedb236143ab988c0575 Mon Sep 17 00:00:00 2001 From: Roman Timushev Date: Thu, 18 Feb 2016 01:44:09 +0300 Subject: [PATCH 023/855] Send end of stream properly --- .../java/com/github/dockerjava/netty/InvocationBuilder.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java index 70737eeac..fc0c72846 100644 --- a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java +++ b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java @@ -4,6 +4,7 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFutureListener; +import io.netty.channel.socket.DuplexChannel; import io.netty.handler.codec.http.DefaultFullHttpRequest; import io.netty.handler.codec.http.DefaultHttpRequest; import io.netty.handler.codec.http.FullHttpRequest; @@ -262,6 +263,11 @@ public void run() { channel.writeAndFlush(Unpooled.copiedBuffer(buffer, 0, read)); } + // we close the writing side of the socket, but keep the read side open to transfer stdout/stderr + if (channel instanceof DuplexChannel) { + ((DuplexChannel) channel).shutdownOutput(); + } + } }).start(); } From fb2467a297413da3bc44ca921f703f79eb14b91f Mon Sep 17 00:00:00 2001 From: Roman Timushev Date: Thu, 18 Feb 2016 11:07:50 +0300 Subject: [PATCH 024/855] Test that exec finishes --- .../core/async/ResultCallbackTemplate.java | 16 ++++++++-------- .../core/command/AttachContainerCmdImplTest.java | 9 ++++++--- .../netty/exec/AttachContainerCmdExecTest.java | 9 ++++++--- .../netty/exec/ExecStartCmdExecTest.java | 6 ++++-- 4 files changed, 24 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java b/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java index edbf49827..f120012af 100644 --- a/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java +++ b/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java @@ -95,11 +95,11 @@ public RC_T awaitCompletion() throws InterruptedException { /** * Blocks until {@link ResultCallback#onComplete()} was called or the given timeout occurs + * @return {@code true} if completed and {@code false} if the waiting time elapsed + * before {@link ResultCallback#onComplete()} was called. */ - @SuppressWarnings("unchecked") - public RC_T awaitCompletion(long timeout, TimeUnit timeUnit) throws InterruptedException { - completed.await(timeout, timeUnit); - return (RC_T) this; + public boolean awaitCompletion(long timeout, TimeUnit timeUnit) throws InterruptedException { + return completed.await(timeout, timeUnit); } /** @@ -115,11 +115,11 @@ public RC_T awaitStarted() throws InterruptedException { /** * Blocks until {@link ResultCallback#onStart()} was called or the given timeout occurs. {@link ResultCallback#onStart()} is called when * the request was processed on the server side and the response is incoming. + * @return {@code true} if started and {@code false} if the waiting time elapsed + * before {@link ResultCallback#onStart()} was called. */ - @SuppressWarnings("unchecked") - public RC_T awaitStarted(long timeout, TimeUnit timeUnit) throws InterruptedException { - started.await(timeout, timeUnit); - return (RC_T) this; + public boolean awaitStarted(long timeout, TimeUnit timeUnit) throws InterruptedException { + return started.await(timeout, timeUnit); } @CheckForNull diff --git a/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java index be2d5fdd0..21507e44e 100644 --- a/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java @@ -68,7 +68,8 @@ public void onNext(Frame frame) { }; dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true) - .withLogs(true).exec(callback).awaitCompletion(30, TimeUnit.SECONDS).close(); + .withLogs(true).exec(callback).awaitCompletion(30, TimeUnit.SECONDS); + callback.close(); assertThat(callback.toString(), containsString(snippet)); } @@ -97,7 +98,8 @@ public void onNext(Frame frame) { }; dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true) - .exec(callback).awaitCompletion(15, TimeUnit.SECONDS).close(); + .exec(callback).awaitCompletion(15, TimeUnit.SECONDS); + callback.close(); System.out.println("log: " + callback.toString()); @@ -130,7 +132,8 @@ public void onNext(Frame frame) { InputStream stdin = new ByteArrayInputStream("".getBytes()); dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true) - .withLogs(true).withStdIn(stdin).exec(callback).awaitCompletion(30, TimeUnit.SECONDS).close(); + .withLogs(true).withStdIn(stdin).exec(callback).awaitCompletion(30, TimeUnit.SECONDS); + callback.close(); } public static class AttachContainerTestCallback extends AttachContainerResultCallback { diff --git a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java index fe34aa537..7f8e66609 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java @@ -70,7 +70,8 @@ public void onNext(Frame frame) { }; dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true) - .withLogs(true).exec(callback).awaitCompletion(10, TimeUnit.SECONDS).close(); + .withLogs(true).exec(callback).awaitCompletion(10, TimeUnit.SECONDS); + callback.close(); assertThat(callback.toString(), containsString(snippet)); } @@ -104,7 +105,8 @@ public void onNext(Frame frame) { InputStream stdin = new ByteArrayInputStream((snippet + "\n").getBytes()); dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true) - .withStdIn(stdin).exec(callback).awaitCompletion(2, TimeUnit.SECONDS).close(); + .withStdIn(stdin).exec(callback).awaitCompletion(2, TimeUnit.SECONDS); + callback.close(); assertThat(callback.toString(), containsString(snippet)); } @@ -133,7 +135,8 @@ public void onNext(Frame frame) { }; dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true) - .exec(callback).awaitCompletion(10, TimeUnit.SECONDS).close(); + .exec(callback).awaitCompletion(10, TimeUnit.SECONDS); + callback.close(); // HexDump.dump(collectFramesCallback.toString().getBytes(), 0, System.out, 0); diff --git a/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java index 6436cd5da..137c7c579 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java @@ -115,9 +115,10 @@ public void execStartAttachStdin() throws Exception { ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId()) .withAttachStdout(true).withAttachStdin(true).withCmd("cat").exec(); - dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withTty(true).withStdIn(stdin) + boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withTty(true).withStdIn(stdin) .exec(new ExecStartResultCallback(stdout, System.err)).awaitCompletion(5, TimeUnit.SECONDS); + assertTrue(completed, "The process was not finished."); assertEquals(stdout.toString("UTF-8"), "STDIN\n"); } @@ -138,9 +139,10 @@ public void execStartNotAttachedStdin() throws Exception { ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId()) .withAttachStdout(true).withAttachStdin(false).withCmd("/bin/sh").exec(); - dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withStdIn(stdin) + boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withStdIn(stdin) .exec(new ExecStartResultCallback(stdout, System.err)).awaitCompletion(5, TimeUnit.SECONDS); + assertTrue(completed, "The process was not finished."); assertEquals(stdout.toString(), ""); } } From 26af2d946a1f8e1a5a289374b899037b6b07e47e Mon Sep 17 00:00:00 2001 From: Roman Timushev Date: Wed, 24 Feb 2016 15:54:49 +0300 Subject: [PATCH 025/855] Use DuplexChannel everywhere --- .../dockerjava/netty/ChannelProvider.java | 4 ++-- .../netty/DockerCmdExecFactoryImpl.java | 20 +++++++++---------- .../dockerjava/netty/InvocationBuilder.java | 8 +++----- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/github/dockerjava/netty/ChannelProvider.java b/src/main/java/com/github/dockerjava/netty/ChannelProvider.java index c742015fc..26ceea4b4 100644 --- a/src/main/java/com/github/dockerjava/netty/ChannelProvider.java +++ b/src/main/java/com/github/dockerjava/netty/ChannelProvider.java @@ -1,7 +1,7 @@ package com.github.dockerjava.netty; -import io.netty.channel.Channel; +import io.netty.channel.socket.DuplexChannel; public interface ChannelProvider { - Channel getChannel(); + DuplexChannel getChannel(); } diff --git a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java index c714f5cc6..1eca3a9df 100644 --- a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java @@ -102,12 +102,12 @@ import com.github.dockerjava.netty.exec.WaitContainerCmdExec; import io.netty.bootstrap.Bootstrap; -import io.netty.channel.Channel; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.epoll.EpollDomainSocketChannel; import io.netty.channel.epoll.EpollEventLoopGroup; import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.DuplexChannel; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioSocketChannel; import io.netty.channel.unix.DomainSocketAddress; @@ -165,8 +165,8 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { private ChannelProvider channelProvider = new ChannelProvider() { @Override - public Channel getChannel() { - Channel channel = connect(); + public DuplexChannel getChannel() { + DuplexChannel channel = connect(); channel.pipeline().addLast(new LoggingHandler(getClass())); return channel; } @@ -190,7 +190,7 @@ public void init(DockerClientConfig dockerClientConfig) { eventLoopGroup = nettyInitializer.init(bootstrap, dockerClientConfig); } - private Channel connect() { + private DuplexChannel connect() { try { return connect(bootstrap); } catch (InterruptedException e) { @@ -198,14 +198,14 @@ private Channel connect() { } } - private Channel connect(final Bootstrap bootstrap) throws InterruptedException { + private DuplexChannel connect(final Bootstrap bootstrap) throws InterruptedException { return nettyInitializer.connect(bootstrap); } private interface NettyInitializer { EventLoopGroup init(final Bootstrap bootstrap, DockerClientConfig dockerClientConfig); - Channel connect(final Bootstrap bootstrap) throws InterruptedException; + DuplexChannel connect(final Bootstrap bootstrap) throws InterruptedException; } private class UnixDomainSocketInitializer implements NettyInitializer { @@ -223,8 +223,8 @@ protected void initChannel(final UnixChannel channel) throws Exception { } @Override - public Channel connect(Bootstrap bootstrap) throws InterruptedException { - return bootstrap.connect(new DomainSocketAddress("/var/run/docker.sock")).sync().channel(); + public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException { + return (DuplexChannel) bootstrap.connect(new DomainSocketAddress("/var/run/docker.sock")).sync().channel(); } } @@ -253,7 +253,7 @@ protected void initChannel(final SocketChannel channel) throws Exception { } @Override - public Channel connect(Bootstrap bootstrap) throws InterruptedException { + public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException { String host = dockerClientConfig.getDockerHost().getHost(); int port = dockerClientConfig.getDockerHost().getPort(); @@ -261,7 +261,7 @@ public Channel connect(Bootstrap bootstrap) throws InterruptedException { throw new RuntimeException("no port configured for " + host); } - Channel channel = bootstrap.connect(host, port).sync().channel(); + DuplexChannel channel = (DuplexChannel) bootstrap.connect(host, port).sync().channel(); if (dockerClientConfig.getDockerTlsVerify()) { final SslHandler ssl = initSsl(dockerClientConfig); diff --git a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java index fc0c72846..9669d6818 100644 --- a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java +++ b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java @@ -151,7 +151,7 @@ public void get(TypeReference typeReference, ResultCallback resultCall return; } - private Channel getChannel() { + private DuplexChannel getChannel() { return channelProvider.getChannel(); } @@ -216,7 +216,7 @@ public void post(final Object entity, final InputStream stdin, final ResultCallb FramedResponseStreamHandler streamHandler = new FramedResponseStreamHandler(resultCallback); - final Channel channel = getChannel(); + final DuplexChannel channel = getChannel(); // result callback's close() method must be called when the servers closes the connection channel.closeFuture().addListener(new GenericFutureListener>() { @@ -264,9 +264,7 @@ public void run() { } // we close the writing side of the socket, but keep the read side open to transfer stdout/stderr - if (channel instanceof DuplexChannel) { - ((DuplexChannel) channel).shutdownOutput(); - } + channel.shutdownOutput(); } }).start(); From 4ac0894f846925bbe9c15ca8e6b0dd4dbfaaa1ff Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Wed, 24 Feb 2016 21:09:57 +0100 Subject: [PATCH 026/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 222b73812..8c79ccddb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Notes * The configuration has been changed to better match the docker CLI configuration options. The properties file was renamed from `docker.io.properties` to `docker-java.properties`. See README.md for details. All changes +* [#472] (https://github.com/docker-java/docker-java/pull/472) Exec start command: detect end of STDIN stream * [#466] (https://github.com/docker-java/docker-java/pull/466) Fix exec start stdin encoding Included in 3.0.0-RC1 From c28e8d564f24150a5c3ea4d1400b70fd9b882822 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Fri, 26 Feb 2016 20:17:55 +0100 Subject: [PATCH 027/855] Test exec start with tty disabled --- .../netty/exec/ExecStartCmdExecTest.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java index 137c7c579..2938ac8c0 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java @@ -3,6 +3,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.containsString; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -122,6 +123,39 @@ public void execStartAttachStdin() throws Exception { assertEquals(stdout.toString("UTF-8"), "STDIN\n"); } + public void execStartAttachStdinToShell() throws Exception { + String containerName = "generated_" + new SecureRandom().nextInt(); + + CreateContainerResponse container = dockerClient + .createContainerCmd("busybox") + .withCmd("sleep", "9999") + .withName(containerName) + .exec(); + + LOG.info("Created container {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + + InputStream stdin = new ByteArrayInputStream("ls\n".getBytes()); + + ByteArrayOutputStream stdout = new ByteArrayOutputStream(); + + ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId()) + .withAttachStdout(true) + .withAttachStdin(true) + .withTty(false) + .withCmd("/bin/sh").exec(); + + dockerClient.execStartCmd(execCreateCmdResponse.getId()) + .withDetach(false) + .withStdIn(stdin) + .exec(new ExecStartResultCallback(stdout, System.err)) + .awaitCompletion(); + + assertThat(stdout.toString(), containsString("etc\n")); + } + @Test(groups = "ignoreInCircleCi") public void execStartNotAttachedStdin() throws Exception { String containerName = "generated_" + new SecureRandom().nextInt(); From 423998b8c937f5f0fd8165ea3b95eb0ed2baf82c Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Sat, 27 Feb 2016 17:07:21 +0100 Subject: [PATCH 028/855] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c79ccddb..5852e3338 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,10 @@ Included in 3.0.0-RC1 * [#347] (https://github.com/docker-java/docker-java/pull/347) Implementation of copy archive to/from container commands * [#313] (https://github.com/docker-java/docker-java/pull/313) Refactor primitive type fields to be of object type in JSON objects +v2.2.2 +--- +* [#478] (https://github.com/docker-java/docker-java/pull/478) Remove debug println + v2.2.1 --- * [#474] (https://github.com/docker-java/docker-java/pull/474) Fix periodic pull failure (2.x) From b2e852c42311847040e38da1df8e12b016a02f8c Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 1 Mar 2016 01:24:08 +0300 Subject: [PATCH 029/855] Fix NegativeArraySizeException in awaitCompletion() Signed-off-by: Kanstantsin Shautsou --- .../com/github/dockerjava/core/command/FrameReader.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/command/FrameReader.java b/src/main/java/com/github/dockerjava/core/command/FrameReader.java index 1e8ac0930..9c9c31e74 100644 --- a/src/main/java/com/github/dockerjava/core/command/FrameReader.java +++ b/src/main/java/com/github/dockerjava/core/command/FrameReader.java @@ -7,6 +7,8 @@ import com.github.dockerjava.api.model.Frame; import com.github.dockerjava.api.model.StreamType; +import javax.annotation.CheckForNull; + /** * Breaks the input into frame. Similar to how a buffered reader would readLies. *

@@ -42,14 +44,16 @@ private static StreamType streamType(byte streamType) { /** * @return A frame, or null if no more frames. */ + @CheckForNull public Frame readFrame() throws IOException { if (rawStreamDetected) { - int read = inputStream.read(rawBuffer); + if (read == -1) { + return null; + } return new Frame(StreamType.RAW, Arrays.copyOf(rawBuffer, read)); - } else { byte[] header = new byte[HEADER_SIZE]; From 4e4896ec9c344ca5a9ee80d072d4efa1d9e5b7ce Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Wed, 2 Mar 2016 19:39:41 +0100 Subject: [PATCH 030/855] Update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5852e3338..4ad984e21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Notes * The configuration has been changed to better match the docker CLI configuration options. The properties file was renamed from `docker.io.properties` to `docker-java.properties`. See README.md for details. All changes +* [#486] (https://github.com/docker-java/docker-java/pull/486) Fix NegativeArraySizeException in awaitCompletion() * [#472] (https://github.com/docker-java/docker-java/pull/472) Exec start command: detect end of STDIN stream * [#466] (https://github.com/docker-java/docker-java/pull/466) Fix exec start stdin encoding @@ -32,6 +33,10 @@ Included in 3.0.0-RC1 * [#347] (https://github.com/docker-java/docker-java/pull/347) Implementation of copy archive to/from container commands * [#313] (https://github.com/docker-java/docker-java/pull/313) Refactor primitive type fields to be of object type in JSON objects +v2.2.3 +--- +* [#487] (https://github.com/docker-java/docker-java/pull/487) Fix NegativeArraySizeException in awaitCompletion() + v2.2.2 --- * [#478] (https://github.com/docker-java/docker-java/pull/478) Remove debug println From 29f1a2e069f6f4afa3126d5c9203c5118043f996 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Wed, 2 Mar 2016 19:42:39 +0100 Subject: [PATCH 031/855] [maven-release-plugin] prepare release docker-java-3.0.0-RC2 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c33a1de3a..d4a3d3a4f 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-SNAPSHOT + 3.0.0-RC2 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 + docker-java-3.0.0-RC2 From 56885b5618eb05cc900c3f8a8fc9226c2a577769 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Wed, 2 Mar 2016 19:42:45 +0100 Subject: [PATCH 032/855] [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 d4a3d3a4f..c33a1de3a 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-RC2 + 3.0.0-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 - docker-java-3.0.0-RC2 + HEAD From 7ed0508d6912018da3e59d83d06600bc6df3a7e3 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Wed, 2 Mar 2016 19:47:07 +0100 Subject: [PATCH 033/855] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ad984e21..c1fd6b848 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,8 @@ Notes * The configuration has been changed to better match the docker CLI configuration options. The properties file was renamed from `docker.io.properties` to `docker-java.properties`. See README.md for details. All changes + +Included in 3.0.0-RC2 * [#486] (https://github.com/docker-java/docker-java/pull/486) Fix NegativeArraySizeException in awaitCompletion() * [#472] (https://github.com/docker-java/docker-java/pull/472) Exec start command: detect end of STDIN stream * [#466] (https://github.com/docker-java/docker-java/pull/466) Fix exec start stdin encoding From b5c7f44f365f80073c1db80cef0378d99b1cfbfa Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Wed, 2 Mar 2016 19:47:28 +0100 Subject: [PATCH 034/855] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ad1f2c157..4205fa95e 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Run build without integration tests: com.github.docker-java docker-java - 3.0.0-RC1 + 3.0.0-RC2 ### Latest development version From 6761841debc2805a8362b0cb31d8c24b232e5083 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sat, 27 Feb 2016 01:28:58 +0300 Subject: [PATCH 035/855] Add helper for api version extraction --- .../com/github/dockerjava/utils/TestUtils.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 src/test/java/com/github/dockerjava/utils/TestUtils.java diff --git a/src/test/java/com/github/dockerjava/utils/TestUtils.java b/src/test/java/com/github/dockerjava/utils/TestUtils.java new file mode 100644 index 000000000..b40273ecb --- /dev/null +++ b/src/test/java/com/github/dockerjava/utils/TestUtils.java @@ -0,0 +1,17 @@ +package com.github.dockerjava.utils; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.core.RemoteApiVersion; + +/** + * @author Kanstantsin Shautsou + */ +public class TestUtils { + private TestUtils() { + } + + public static RemoteApiVersion getVersion(DockerClient client) { + final String serverVersion = client.versionCmd().exec().getApiVersion(); + return RemoteApiVersion.parseConfig(serverVersion); + } +} From 32c65f0a46ae7337e1744bd5ec940c6445eade8c Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 21 Feb 2016 02:15:48 +0300 Subject: [PATCH 036/855] Remove package prefix for already imported class. --- .../com/github/dockerjava/core/async/JsonStreamProcessor.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java b/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java index 8d9a64303..9da43b62b 100644 --- a/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java +++ b/src/main/java/com/github/dockerjava/core/async/JsonStreamProcessor.java @@ -34,7 +34,7 @@ public JsonStreamProcessor(Class clazz) { public void processResponseStream(InputStream response, ResultCallback resultCallback) { resultCallback.onStart(response); - OBJECT_MAPPER.configure(com.fasterxml.jackson.core.JsonParser.Feature.AUTO_CLOSE_SOURCE, true); + OBJECT_MAPPER.configure(JsonParser.Feature.AUTO_CLOSE_SOURCE, true); try { JsonParser jp = JSON_FACTORY.createParser(response); From ddba77f84e22a77b1ab7c553da7b41d07d89fa86 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 19 Feb 2016 23:17:49 +0300 Subject: [PATCH 037/855] Document code rules. --- docs/devel.adoc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 docs/devel.adoc diff --git a/docs/devel.adoc b/docs/devel.adoc new file mode 100644 index 000000000..50c6a7279 --- /dev/null +++ b/docs/devel.adoc @@ -0,0 +1,25 @@ +### Code Design + * Model is based on Objects and not primitives that allows nullify requests and have null values for data + that wasn't provided by docker daemon. + * For null safeness findbugs annotations are used. + ** Every method that may return `null` (and we are unsure in any fields as docker daemon may change something) + should be annotated with `@CheckForNull` return qualifier from `javax.annotation` package. + ** Methods that can't return `null` must be annotated with `@Nonnull`. + ** The same for Arguments. + ** `@Nullable` must be used only for changing inherited (other typed) qualifier. + * Setters in builder style must be prefixed with `withXX`. + * All classes should provide `toString()` `equals()` and `hashCode()` defined methods. + * Javadocs + ** Provide full information on field: + *** For models define API version with `@since {@link RemoteApiVersion#VERSION_1_X}`. + ** getters/setters should refernce to field `@see #$field`. + +### Coding style + * TBD, some initial styling already enforced with checkstyle. + IDEA/checkstyle file analogues will be provided soon. + +### Testing + * Unit tests for serder (serialization-deserialization). + * Integration tests for commands. + * If model object has builders, then fill it with data and compare by `equals()` with expected response + from docker daemon. If failed, then some fields mappings are wrong. From 60c9efb942ac040839b5bc4194a14676b7470971 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 26 Feb 2016 20:36:16 +0300 Subject: [PATCH 038/855] Update maven surefire --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index c33a1de3a..2b5fe2119 100644 --- a/pom.xml +++ b/pom.xml @@ -72,8 +72,8 @@ 2.2 2.3.1 2.3.1 - 2.17 - 2.17 + 2.19.1 + 2.19.1 1.7 From e944b49ee09b08f92689ae1315fe18ee29a6c734 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sat, 27 Feb 2016 02:11:40 +0300 Subject: [PATCH 039/855] Fix sync test to be async. --- .../core/command/FrameReaderITest.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/github/dockerjava/core/command/FrameReaderITest.java b/src/test/java/com/github/dockerjava/core/command/FrameReaderITest.java index df616ddba..06d07667c 100644 --- a/src/test/java/com/github/dockerjava/core/command/FrameReaderITest.java +++ b/src/test/java/com/github/dockerjava/core/command/FrameReaderITest.java @@ -1,10 +1,18 @@ package com.github.dockerjava.core.command; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import java.util.ArrayList; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import org.testng.annotations.AfterTest; @@ -39,18 +47,17 @@ public void deleteDockerContainerImage() throws Exception { @Test public void canCloseFrameReaderAndReadExpectedLines() throws Exception { - // wait for the container to be successfully executed int exitCode = dockerClient.waitContainerCmd(dockerfileFixture.getContainerId()) .exec(new WaitContainerResultCallback()).awaitStatusCode(); assertEquals(0, exitCode); - Iterator response = getLoggingFrames().iterator(); - - assertEquals(response.next(), new Frame(StreamType.STDOUT, "to stdout\n".getBytes())); - assertEquals(response.next(), new Frame(StreamType.STDERR, "to stderr\n".getBytes())); - assertFalse(response.hasNext()); - + final List loggingFrames = getLoggingFrames(); + final Frame outFrame = new Frame(StreamType.STDOUT, "to stdout\n".getBytes()); + final Frame errFrame = new Frame(StreamType.STDERR, "to stderr\n".getBytes()); + + assertThat(loggingFrames, containsInAnyOrder(outFrame, errFrame)); + assertThat(loggingFrames, hasSize(2)); } private List getLoggingFrames() throws Exception { From bbab47eeaffac40342739adb600966816cbdc2af Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 Feb 2016 04:58:37 +0300 Subject: [PATCH 040/855] Sync up to 1.22 API part 1 Squashed: - HostConfig.class: setXX() -> withXX() - Info.class - remove isXX that doesn't match primitives - added builder setters - Extract nested class from Info.class - Restore getter name. - IDEA generated it as javabean getter but docker-java uses other style? - Test case Info and fix. - Switch to reflection methods. - Easier fields detection. - Version.class to use reflection. - Clean-up imports. - Version.class serder test - AuthConfig.class add serder tests. - ContainerPort.class to reflection. - HostConfig.class to refleciton. - Test for CreateContainer with stopSignal - Implement UpdateContainerCmd with tests - Fix junit errors? - Fix and update test. - Deprecate container field - Do test conditional. - Value set according to response. - Cleanup test code after fix. - Clarify usage --- .../github/dockerjava/api/DockerClient.java | 10 + .../api/command/CreateContainerCmd.java | 5 + .../api/command/DockerCmdExecFactory.java | 2 + .../api/command/InspectExecResponse.java | 52 + .../api/command/UpdateContainerCmd.java | 68 ++ .../dockerjava/api/model/AuthConfig.java | 24 + .../dockerjava/api/model/Container.java | 129 ++- .../api/model/ContainerHostConfig.java | 46 + .../api/model/ContainerNetwork.java | 273 ++++++ .../api/model/ContainerNetworkSettings.java | 55 ++ .../dockerjava/api/model/ContainerPort.java | 108 +++ .../dockerjava/api/model/HostConfig.java | 536 ++++++++++- .../com/github/dockerjava/api/model/Info.java | 890 +++++++++++++++++- .../api/model/InfoRegistryConfig.java | 189 ++++ .../dockerjava/api/model/NetworkSettings.java | 16 + .../api/model/UpdateContainerResponse.java | 28 + .../github/dockerjava/api/model/Version.java | 49 +- .../dockerjava/core/DockerClientImpl.java | 9 + .../dockerjava/core/RemoteApiVersion.java | 2 +- .../core/command/CreateContainerCmdImpl.java | 79 +- .../core/command/UpdateContainerCmdImpl.java | 264 ++++++ .../jaxrs/DockerCmdExecFactoryImpl.java | 7 + .../jaxrs/UpdateContainerCmdExec.java | 36 + .../netty/DockerCmdExecFactoryImpl.java | 7 + .../netty/exec/UpdateContainerCmdExec.java | 34 + .../api/command/InspectExecResponseTest.java | 56 ++ .../dockerjava/api/model/AuthConfigTest.java | 65 +- .../dockerjava/api/model/ContainerTest.java | 44 + .../dockerjava/api/model/IdentifierTest.java | 9 +- .../github/dockerjava/api/model/InfoTest.java | 172 ++++ .../dockerjava/api/model/VersionTest.java | 40 + .../client/AbstractDockerClientTest.java | 7 +- .../core/TestDockerCmdExecFactory.java | 5 + .../command/CreateContainerCmdImplTest.java | 170 ++-- .../core/command/InspectExecCmdImplTest.java | 24 +- .../command/StopContainerCmdImplTest.java | 12 +- .../command/UpdateContainerCmdImplTest.java | 114 +++ .../DockerfileStatementAddTest.java | 5 +- .../netty/exec/InspectExecCmdExecTest.java | 23 +- .../netty/exec/StopContainerCmdExecTest.java | 12 +- .../exec/UpdateContainerCmdExecTest.java | 98 ++ .../dockerjava/test/serdes/JSONSamples.java | 66 ++ .../test/serdes/JSONTestHelper.java | 4 - .../1.22/containers/container/json/1.json | 151 +++ .../containers/container/update/docs.json | 12 + .../samples/1.22/containers/create/docs.json | 131 +++ .../samples/1.22/containers/json/filter1.json | 37 + .../resources/samples/1.22/exec/ID/1.json | 18 + src/test/resources/samples/1.22/info/1.json | 91 ++ .../resources/samples/1.22/info/docs.json | 76 ++ .../samples/1.22/other/AuthConfig/docs1.json | 5 + .../samples/1.22/other/AuthConfig/docs2.json | 3 + .../resources/samples/1.22/version/1.json | 10 + 53 files changed, 4153 insertions(+), 225 deletions(-) create mode 100644 src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java create mode 100644 src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java create mode 100644 src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java create mode 100644 src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java create mode 100644 src/main/java/com/github/dockerjava/api/model/ContainerPort.java create mode 100644 src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java create mode 100644 src/main/java/com/github/dockerjava/api/model/UpdateContainerResponse.java create mode 100644 src/main/java/com/github/dockerjava/core/command/UpdateContainerCmdImpl.java create mode 100644 src/main/java/com/github/dockerjava/jaxrs/UpdateContainerCmdExec.java create mode 100644 src/main/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExec.java create mode 100644 src/test/java/com/github/dockerjava/api/command/InspectExecResponseTest.java create mode 100644 src/test/java/com/github/dockerjava/api/model/ContainerTest.java create mode 100644 src/test/java/com/github/dockerjava/api/model/InfoTest.java create mode 100644 src/test/java/com/github/dockerjava/api/model/VersionTest.java create mode 100644 src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java create mode 100644 src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java create mode 100644 src/test/java/com/github/dockerjava/test/serdes/JSONSamples.java create mode 100644 src/test/resources/samples/1.22/containers/container/json/1.json create mode 100644 src/test/resources/samples/1.22/containers/container/update/docs.json create mode 100644 src/test/resources/samples/1.22/containers/create/docs.json create mode 100644 src/test/resources/samples/1.22/containers/json/filter1.json create mode 100644 src/test/resources/samples/1.22/exec/ID/1.json create mode 100644 src/test/resources/samples/1.22/info/1.json create mode 100644 src/test/resources/samples/1.22/info/docs.json create mode 100644 src/test/resources/samples/1.22/other/AuthConfig/docs1.json create mode 100644 src/test/resources/samples/1.22/other/AuthConfig/docs2.json create mode 100644 src/test/resources/samples/1.22/version/1.json diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java index aaa3c5fcf..4ae45ec89 100644 --- a/src/main/java/com/github/dockerjava/api/DockerClient.java +++ b/src/main/java/com/github/dockerjava/api/DockerClient.java @@ -53,6 +53,7 @@ import com.github.dockerjava.api.command.TagImageCmd; import com.github.dockerjava.api.command.TopContainerCmd; import com.github.dockerjava.api.command.UnpauseContainerCmd; +import com.github.dockerjava.api.command.UpdateContainerCmd; import com.github.dockerjava.api.command.VersionCmd; import com.github.dockerjava.api.command.WaitContainerCmd; import com.github.dockerjava.api.exception.DockerException; @@ -175,6 +176,15 @@ public interface DockerClient extends Closeable { public KillContainerCmd killContainerCmd(@Nonnull String containerId); + /** + * Update container settings + * + * @param containerId id of the container + * @return command + * @since {@link RemoteApiVersion#VERSION_1_22} + */ + public UpdateContainerCmd updateContainerCmd(@Nonnull String containerId); + public RestartContainerCmd restartContainerCmd(@Nonnull String containerId); public CommitCmd commitCmd(@Nonnull String containerId); diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java index 6b004c826..972739898 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java @@ -80,6 +80,9 @@ public interface CreateContainerCmd extends SyncDockerCmd exposedPorts); /** diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java index fc793558f..fcaad81fc 100644 --- a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java @@ -69,6 +69,8 @@ public interface DockerCmdExecFactory extends Closeable { public KillContainerCmd.Exec createKillContainerCmdExec(); + UpdateContainerCmd.Exec createUpdateContainerCmdExec(); + public RestartContainerCmd.Exec createRestartContainerCmdExec(); public CommitCmd.Exec createCommitCmdExec(); diff --git a/src/main/java/com/github/dockerjava/api/command/InspectExecResponse.java b/src/main/java/com/github/dockerjava/api/command/InspectExecResponse.java index 63f111dce..2833a5ade 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectExecResponse.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectExecResponse.java @@ -9,6 +9,8 @@ import com.github.dockerjava.api.model.NetworkSettings; import com.github.dockerjava.core.RemoteApiVersion; +import javax.annotation.CheckForNull; + @JsonIgnoreProperties(ignoreUnknown = true) public class InspectExecResponse { @JsonProperty("ID") @@ -26,15 +28,37 @@ public class InspectExecResponse { @JsonProperty("Running") private Boolean running; + /** + * @since {@link RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("CanRemove") + private Boolean canRemove; + @JsonProperty("ExitCode") private Integer exitCode; @JsonProperty("ProcessConfig") private ProcessConfig processConfig; + /** + * @deprecated @since {@link RemoteApiVersion#VERSION_1_22} + */ + @Deprecated @JsonProperty("Container") private Container container; + /** + * @since {@link RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("ContainerID") + private String containerID; + + /** + * @since {@link RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("DetachKeys") + private String detachKeys; + public String getId() { return id; } @@ -63,10 +87,38 @@ public ProcessConfig getProcessConfig() { return processConfig; } + /** + * @see #container + */ + @Deprecated public Container getContainer() { return container; } + /** + * @see #canRemove + */ + @CheckForNull + public Boolean getCanRemove() { + return canRemove; + } + + /** + * @see #containerID + */ + @CheckForNull + public String getContainerID() { + return containerID; + } + + /** + * @see #detachKeys + */ + @CheckForNull + public String getDetachKeys() { + return detachKeys; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this); diff --git a/src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java new file mode 100644 index 000000000..3dc7a0773 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java @@ -0,0 +1,68 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.model.UpdateContainerResponse; + +import javax.annotation.CheckForNull; + +/** + * @author Kanstantsin Shautsou + */ +public interface UpdateContainerCmd extends SyncDockerCmd { + @CheckForNull + String getContainerId(); + + @CheckForNull + public Integer getBlkioWeight(); + + public UpdateContainerCmd withBlkioWeight(Integer blkioWeight); + + public UpdateContainerCmd withContainerId(String containerId); + + @CheckForNull + public Integer getCpuPeriod(); + + public UpdateContainerCmd withCpuPeriod(Integer cpuPeriod); + + @CheckForNull + public Integer getCpuQuota(); + + public UpdateContainerCmd withCpuQuota(Integer cpuQuota); + + @CheckForNull + public String getCpusetCpus(); + + public UpdateContainerCmd withCpusetCpus(String cpusetCpus); + + @CheckForNull + public String getCpusetMems(); + + public UpdateContainerCmd withCpusetMems(String cpusetMems); + + @CheckForNull + public Integer getCpuShares(); + + public UpdateContainerCmd withCpuShares(Integer cpuShares); + + @CheckForNull + public Long getKernelMemory(); + + public UpdateContainerCmd withKernelMemory(Long kernelMemory); + + @CheckForNull + public Long getMemory(); + + public UpdateContainerCmd withMemory(Long memory); + + @CheckForNull + public Long getMemoryReservation(); + + public UpdateContainerCmd withMemoryReservation(Long memoryReservation); + + @CheckForNull + Long getMemorySwap(); + + UpdateContainerCmd withMemorySwap(Long memorySwap); + + interface Exec extends DockerCmdSyncExec { + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/AuthConfig.java b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java index ae7ebdda2..849f26a21 100644 --- a/src/main/java/com/github/dockerjava/api/model/AuthConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java @@ -7,6 +7,8 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.CheckForNull; + @JsonInclude(Include.NON_NULL) public class AuthConfig { @@ -32,6 +34,12 @@ public class AuthConfig { @JsonProperty("auth") private String auth; + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("registrytoken") + private String registrytoken; + public String getUsername() { return username; } @@ -77,6 +85,22 @@ public AuthConfig withAuth(String auth) { return this; } + /** + * @see #registrytoken + */ + @CheckForNull + public String getRegistrytoken() { + return registrytoken; + } + + /** + * @see #registrytoken + */ + public AuthConfig withRegistrytoken(String registrytoken) { + this.registrytoken = registrytoken; + return this; + } + @Override public String toString() { return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); diff --git a/src/main/java/com/github/dockerjava/api/model/Container.java b/src/main/java/com/github/dockerjava/api/model/Container.java index dcdf1699d..47492920d 100644 --- a/src/main/java/com/github/dockerjava/api/model/Container.java +++ b/src/main/java/com/github/dockerjava/api/model/Container.java @@ -1,18 +1,22 @@ package com.github.dockerjava.api.model; -import java.util.Map; - -import org.apache.commons.lang.builder.ToStringBuilder; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.dockerjava.api.command.ListContainersCmd; +import com.github.dockerjava.core.RemoteApiVersion; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; +import java.util.Map; /** + * Used for Listing containers. * * @author Konstantin Pelykh (kpelykh@gmail.com) - * */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) @@ -30,11 +34,17 @@ public class Container { @JsonProperty("Image") private String image; + /** + * @since since {@link RemoteApiVersion#VERSION_1_21} + */ + @JsonProperty("ImageID") + private String imageId; + @JsonProperty("Names") private String[] names; @JsonProperty("Ports") - public Port[] ports; + public ContainerPort[] ports; @JsonProperty("Labels") public Map labels; @@ -42,6 +52,35 @@ public class Container { @JsonProperty("Status") private String status; + /** + * @since ~{@link RemoteApiVersion#VERSION_1_19} + */ + @JsonProperty("SizeRw") + private Long sizeRw; + + /** + * Returns only when {@link ListContainersCmd#withShowSize(java.lang.Boolean)} set + * + * @since ~{@link RemoteApiVersion#VERSION_1_19} + */ + @JsonProperty("SizeRootFs") + private Long sizeRootFs; + + /** + * @since ~{@link RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("HostConfig") + private ContainerHostConfig hostConfig; + + /** + * Docker API docs says "list of networks", but json names `networkSettings`. + * So, reusing existed NetworkSettings model object. + * + * @since ~{@link RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("NetworkSettings") + private ContainerNetworkSettings networkSettings; + public String getId() { return id; } @@ -54,6 +93,11 @@ public String getImage() { return image; } + @CheckForNull + public String getImageId() { + return imageId; + } + public Long getCreated() { return created; } @@ -62,7 +106,7 @@ public String getStatus() { return status; } - public Port[] getPorts() { + public ContainerPort[] getPorts() { return ports; } @@ -74,45 +118,50 @@ public String[] getNames() { return names; } - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); + /** + * @see #sizeRw + */ + @CheckForNull + public Long getSizeRw() { + return sizeRw; } - @JsonIgnoreProperties(ignoreUnknown = true) - public static class Port { - - @JsonProperty("IP") - private String ip; - - @JsonProperty("PrivatePort") - private Integer privatePort; - - @JsonProperty("PublicPort") - private Integer publicPort; - - @JsonProperty("Type") - private String type; + /** + * @see #sizeRootFs + */ + @CheckForNull + public Long getSizeRootFs() { + return sizeRootFs; + } - public String getIp() { - return ip; - } + /** + * @see #networkSettings + */ + @CheckForNull + public ContainerNetworkSettings getNetworkSettings() { + return networkSettings; + } - public Integer getPrivatePort() { - return privatePort; - } + /** + * @see #hostConfig + */ + @CheckForNull + public ContainerHostConfig getHostConfig() { + return hostConfig; + } - public Integer getPublicPort() { - return publicPort; - } + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } - public String getType() { - return type; - } + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); - } + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); } } diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java b/src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java new file mode 100644 index 000000000..43a5a94b1 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java @@ -0,0 +1,46 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +/** + * Used in {@link Container} + * + * @see Container + * @author Kanstantsin Shautsou + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ContainerHostConfig { + @JsonProperty("NetworkMode") + private String networkMode; + + public String getNetworkMode() { + return networkMode; + } + + /** + * @see #networkMode + */ + public ContainerHostConfig withNetworkMode(String networkMode) { + this.networkMode = networkMode; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java b/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java new file mode 100644 index 000000000..4bfde8bfd --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java @@ -0,0 +1,273 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.dockerjava.core.RemoteApiVersion; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; +import java.util.List; + +/** + * @see ContainerNetworkSettings + * @author Kanstantsin Shautsou + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ContainerNetwork { + /** + * FIXME verify + */ + @JsonProperty("IPAMConfig") + private Network.Ipam.Config ipamConfig; + + /** + * FIXME verify + */ + @JsonProperty("Links") + private List links; + + /** + * FIXME no docs, unknown field. + * Type picked from `docker/vendor/src/github.com/docker/engine-api/types/network/network.go` + * + * @since {@link RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("Aliases") + private List aliases; + + @JsonProperty("NetworkID") + private String networkID; + + @JsonProperty("EndpointID") + private String endpointId; + + @JsonProperty("Gateway") + private String gateway; + + @JsonProperty("IPAddress") + private String ipAddress; + + @JsonProperty("IPPrefixLen") + private Integer ipPrefixLen; + + @JsonProperty("IPv6Gateway") + private String ipV6Gateway; + + @JsonProperty("GlobalIPv6Address") + private String globalIPv6Address; + + @JsonProperty("GlobalIPv6PrefixLen") + private Integer globalIPv6PrefixLen; + + @JsonProperty("MacAddress") + private String macAddress; + + /** + * @see #aliases + */ + @CheckForNull + public List getAliases() { + return aliases; + } + + /** + * @see #aliases + */ + public ContainerNetwork withAliases(List aliases) { + this.aliases = aliases; + return this; + } + + /** + * @see #endpointId + */ + @CheckForNull + public String getEndpointId() { + return endpointId; + } + + /** + * @see #endpointId + */ + public ContainerNetwork withEndpointId(String endpointId) { + this.endpointId = endpointId; + return this; + } + + /** + * @see #gateway + */ + @CheckForNull + public String getGateway() { + return gateway; + } + + /** + * @see #gateway + */ + public ContainerNetwork withGateway(String gateway) { + this.gateway = gateway; + return this; + } + + /** + * @see #globalIPv6Address + */ + @CheckForNull + public String getGlobalIPv6Address() { + return globalIPv6Address; + } + + /** + * @see #globalIPv6Address + */ + public ContainerNetwork withGlobalIPv6Address(String globalIPv6Address) { + this.globalIPv6Address = globalIPv6Address; + return this; + } + + /** + * @see #globalIPv6PrefixLen + */ + @CheckForNull + public Integer getGlobalIPv6PrefixLen() { + return globalIPv6PrefixLen; + } + + /** + * @see #globalIPv6PrefixLen + */ + public ContainerNetwork withGlobalIPv6PrefixLen(Integer globalIPv6PrefixLen) { + this.globalIPv6PrefixLen = globalIPv6PrefixLen; + return this; + } + + /** + * @see #ipAddress + */ + @CheckForNull + public String getIpAddress() { + return ipAddress; + } + + /** + * @see #ipAddress + */ + public ContainerNetwork withIpAddress(String ipAddress) { + this.ipAddress = ipAddress; + return this; + } + + /** + * @see #ipamConfig + */ + @CheckForNull + public Network.Ipam.Config getIpamConfig() { + return ipamConfig; + } + + /** + * @see #ipamConfig + */ + public ContainerNetwork withIpamConfig(Network.Ipam.Config ipamConfig) { + this.ipamConfig = ipamConfig; + return this; + } + + /** + * @see #ipPrefixLen + */ + @CheckForNull + public Integer getIpPrefixLen() { + return ipPrefixLen; + } + + /** + * @see #ipPrefixLen + */ + public ContainerNetwork withIpPrefixLen(Integer ipPrefixLen) { + this.ipPrefixLen = ipPrefixLen; + return this; + } + + /** + * @see #ipV6Gateway + */ + @CheckForNull + public String getIpV6Gateway() { + return ipV6Gateway; + } + + /** + * @see #ipV6Gateway + */ + public ContainerNetwork withIpV6Gateway(String ipV6Gateway) { + this.ipV6Gateway = ipV6Gateway; + return this; + } + + /** + * @see #links + */ + @CheckForNull + public List getLinks() { + return links; + } + + /** + * @see #links + */ + public ContainerNetwork withLinks(List links) { + this.links = links; + return this; + } + + /** + * @see #macAddress + */ + @CheckForNull + public String getMacAddress() { + return macAddress; + } + + /** + * @see #macAddress + */ + public ContainerNetwork withMacAddress(String macAddress) { + this.macAddress = macAddress; + return this; + } + + /** + * @see #networkID + */ + @CheckForNull + public String getNetworkID() { + return networkID; + } + + /** + * @see #networkID + */ + public ContainerNetwork withNetworkID(String networkID) { + this.networkID = networkID; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java b/src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java new file mode 100644 index 000000000..7f4b17be5 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java @@ -0,0 +1,55 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.dockerjava.core.RemoteApiVersion; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import java.util.Map; + +/** + * Sub-object in {@link Container} + * + * @see Container + * @since {@link RemoteApiVersion#VERSION_1_22} + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ContainerNetworkSettings { + /** + * @since {@link RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("Networks") + private Map networks; + + /** + * @see #networks + */ + public Map getNetworks() { + return networks; + } + + /** + * @see #networks + */ + public ContainerNetworkSettings withNetworks(Map networks) { + this.networks = networks; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerPort.java b/src/main/java/com/github/dockerjava/api/model/ContainerPort.java new file mode 100644 index 000000000..09f718ef6 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/ContainerPort.java @@ -0,0 +1,108 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; + +/** + * @author Kanstantsin Shautsou + * @see Container + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ContainerPort { + + @JsonProperty("IP") + private String ip; + + @JsonProperty("PrivatePort") + private Integer privatePort; + + @JsonProperty("PublicPort") + private Integer publicPort; + + @JsonProperty("Type") + private String type; + + /** + * @see #ip + */ + @CheckForNull + public String getIp() { + return ip; + } + + /** + * @see #ip + */ + public ContainerPort withIp(String ip) { + this.ip = ip; + return this; + } + + /** + * @see #privatePort + */ + @CheckForNull + public Integer getPrivatePort() { + return privatePort; + } + + /** + * @see #privatePort + */ + public ContainerPort withPrivatePort(Integer privatePort) { + this.privatePort = privatePort; + return this; + } + + /** + * @see #publicPort + */ + @CheckForNull + public Integer getPublicPort() { + return publicPort; + } + + /** + * @see #publicPort + */ + public ContainerPort withPublicPort(Integer publicPort) { + this.publicPort = publicPort; + return this; + } + + /** + * @see #type + */ + @CheckForNull + public String getType() { + return type; + } + + /** + * @see #type + */ + public ContainerPort withType(String type) { + this.type = type; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } +} 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 edad5cfcb..912439357 100644 --- a/src/main/java/com/github/dockerjava/api/model/HostConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/HostConfig.java @@ -1,15 +1,22 @@ package com.github.dockerjava.api.model; -import javax.annotation.CheckForNull; - -import org.apache.commons.lang.builder.ToStringBuilder; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.dockerjava.core.RemoteApiVersion; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; +import java.util.List; +/** + * Used in `/containers/create`, and in inspect container. + * TODO exclude usage for 2 different models. + */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) public class HostConfig { @@ -20,6 +27,42 @@ public class HostConfig { @JsonProperty("BlkioWeight") private Integer blkioWeight; + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("BlkioWeightDevice") + private List blkioWeightDevice; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("BlkioDeviceReadBps") + private List blkioDeviceReadBps; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("BlkioDeviceReadIOps") + private List blkioDeviceReadIOps; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("BlkioDeviceWriteBps") + private List blkioDeviceWriteBps; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("BlkioDeviceWriteIOps") + private List blkioDeviceWriteIOps; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("MemorySwappiness") + private Integer memorySwappiness; + @JsonProperty("CapAdd") private Capability[] capAdd; @@ -35,6 +78,12 @@ public class HostConfig { @JsonProperty("CpuShares") private Integer cpuShares; + /** + * @since ~{@link RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("CpuQuota") + private Integer cpuQuota; + @JsonProperty("CpusetCpus") private String cpusetCpus; @@ -68,12 +117,30 @@ public class HostConfig { @JsonProperty("MemorySwap") private Long memorySwap; + /** + * @since {@link RemoteApiVersion#VERSION_1_21} + */ + @JsonProperty("MemoryReservation") + private Long memoryReservation; + + /** + * @since {@link RemoteApiVersion#VERSION_1_21} + */ + @JsonProperty("KernelMemory") + private Long kernelMemory; + @JsonProperty("NetworkMode") private String networkMode; @JsonProperty("OomKillDisable") private Boolean oomKillDisable; + /** + * @since {@link RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("OomScoreAdj") + private Boolean oomScoreAdj; + @JsonProperty("PortBindings") private Ports portBindings; @@ -98,6 +165,31 @@ public class HostConfig { @JsonProperty("PidMode") private String pidMode; + /** + * @since {@link RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("SecurityOpt") + private List securityOpts; + + /** + * @since {@link RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("CgroupParent") + private String cgroupParent; + + /** + * @since {@link RemoteApiVersion#VERSION_1_21} + */ + @JsonProperty("VolumeDriver") + private String volumeDriver; + + /** + * @since {@link RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("ShmSize") + private String shmSize; + + @JsonIgnore public Bind[] getBinds() { return (binds == null) ? new Bind[0] : binds.getBinds(); @@ -214,124 +306,486 @@ public String getPidMode() { return pidMode; } + /** + * @see #blkioDeviceReadBps + */ + @CheckForNull + public List getBlkioDeviceReadBps() { + return blkioDeviceReadBps; + } + + /** + * @see #blkioDeviceReadIOps + */ + @CheckForNull + public List getBlkioDeviceReadIOps() { + return blkioDeviceReadIOps; + } + + /** + * @see #blkioDeviceWriteBps + */ + @CheckForNull + public List getBlkioDeviceWriteBps() { + return blkioDeviceWriteBps; + } + + /** + * @see #blkioDeviceWriteIOps + */ + @CheckForNull + public List getBlkioDeviceWriteIOps() { + return blkioDeviceWriteIOps; + } + + /** + * @see #blkioWeightDevice + */ + @CheckForNull + public List getBlkioWeightDevice() { + return blkioWeightDevice; + } + + /** + * @see #oomScoreAdj + */ + @CheckForNull + public Boolean getOomScoreAdj() { + return oomScoreAdj; + } + + /** + * @see #cpuQuota + */ + @CheckForNull + public Integer getCpuQuota() { + return cpuQuota; + } + + /** + * @see #kernelMemory + */ + @CheckForNull + public Long getKernelMemory() { + return kernelMemory; + } + + /** + * @see #memoryReservation + */ + @CheckForNull + public Long getMemoryReservation() { + return memoryReservation; + } + + /** + * @see #memorySwappiness + */ + @CheckForNull + public Integer getMemorySwappiness() { + return memorySwappiness; + } + + /** + * @see #oomKillDisable + */ + @CheckForNull + public Boolean getOomKillDisable() { + return oomKillDisable; + } + + /** + * @see #securityOpts + */ + @CheckForNull + public List getSecurityOpts() { + return securityOpts; + } + + /** + * @see #cgroupParent + */ + @CheckForNull + public String getCgroupParent() { + return cgroupParent; + } + + /** + * @see #shmSize + */ + @CheckForNull + public String getShmSize() { + return shmSize; + } + + /** + * @see #volumeDriver + */ + @CheckForNull + public String getVolumeDriver() { + return volumeDriver; + } + @JsonIgnore public void setBinds(Bind... binds) { this.binds = new Binds(binds); } - public void setBlkioWeight(Integer blkioWeight) { - this.blkioWeight = blkioWeight; + @JsonIgnore + public void setLinks(Link... links) { + this.links = new Links(links); } - public void setCpuPeriod(Integer cpuPeriod) { - this.cpuPeriod = cpuPeriod; + // auto-generated builder setters + /** + * @see #binds + */ + public HostConfig withBinds(Binds binds) { + this.binds = binds; + return this; } - public void setCpuShares(Integer cpuShares) { - this.cpuShares = cpuShares; + /** + * @see #blkioDeviceReadBps + */ + public HostConfig withBlkioDeviceReadBps(List blkioDeviceReadBps) { + this.blkioDeviceReadBps = blkioDeviceReadBps; + return this; } - public void setCpusetCpus(String cpusetCpus) { - this.cpusetCpus = cpusetCpus; + /** + * @see #blkioDeviceReadIOps + */ + public HostConfig withBlkioDeviceReadIOps(List blkioDeviceReadIOps) { + this.blkioDeviceReadIOps = blkioDeviceReadIOps; + return this; } - public void setCpusetMems(String cpusetMems) { - this.cpusetMems = cpusetMems; + /** + * @see #blkioDeviceWriteBps + */ + public HostConfig withBlkioDeviceWriteBps(List blkioDeviceWriteBps) { + this.blkioDeviceWriteBps = blkioDeviceWriteBps; + return this; + } + + /** + * @see #blkioDeviceWriteIOps + */ + public HostConfig withBlkioDeviceWriteIOps(List blkioDeviceWriteIOps) { + this.blkioDeviceWriteIOps = blkioDeviceWriteIOps; + return this; + } + + /** + * @see #blkioWeight + */ + public HostConfig withBlkioWeight(Integer blkioWeight) { + this.blkioWeight = blkioWeight; + return this; } - public void setCapAdd(Capability[] capAdd) { + /** + * @see #blkioWeightDevice + */ + public HostConfig withBlkioWeightDevice(List blkioWeightDevice) { + this.blkioWeightDevice = blkioWeightDevice; + return this; + } + + /** + * @see #capAdd + */ + public HostConfig withCapAdd(Capability[] capAdd) { this.capAdd = capAdd; + return this; } - public void setCapDrop(Capability[] capDrop) { + /** + * @see #capDrop + */ + public HostConfig withCapDrop(Capability[] capDrop) { this.capDrop = capDrop; + return this; + } + + /** + * @see #cgroupParent + */ + public HostConfig withCgroupParent(String cgroupParent) { + this.cgroupParent = cgroupParent; + return this; } - public void setContainerIDFile(String containerIDFile) { + /** + * @see #containerIDFile + */ + public HostConfig withContainerIDFile(String containerIDFile) { this.containerIDFile = containerIDFile; + return this; + } + + /** + * @see #cpuPeriod + */ + public HostConfig withCpuPeriod(Integer cpuPeriod) { + this.cpuPeriod = cpuPeriod; + return this; + } + + /** + * @see #cpuQuota + */ + public HostConfig withCpuQuota(Integer cpuQuota) { + this.cpuQuota = cpuQuota; + return this; + } + + /** + * @see #cpusetCpus + */ + public HostConfig withCpusetCpus(String cpusetCpus) { + this.cpusetCpus = cpusetCpus; + return this; + } + + /** + * @see #cpusetMems + */ + public HostConfig withCpusetMems(String cpusetMems) { + this.cpusetMems = cpusetMems; + return this; } - public void setDevices(Device[] devices) { + /** + * @see #cpuShares + */ + public HostConfig withCpuShares(Integer cpuShares) { + this.cpuShares = cpuShares; + return this; + } + + /** + * @see #devices + */ + public HostConfig withDevices(Device[] devices) { this.devices = devices; + return this; } - public void setDns(String[] dns) { + /** + * @see #dns + */ + public HostConfig withDns(String[] dns) { this.dns = dns; + return this; } - public void setDnsSearch(String[] dnsSearch) { + /** + * @see #dnsSearch + */ + public HostConfig withDnsSearch(String[] dnsSearch) { this.dnsSearch = dnsSearch; + return this; } - public void setExtraHosts(String[] extraHosts) { + /** + * @see #extraHosts + */ + public HostConfig withExtraHosts(String[] extraHosts) { this.extraHosts = extraHosts; + return this; } - @JsonIgnore - public void setLinks(Link... links) { - this.links = new Links(links); + /** + * @see #kernelMemory + */ + public HostConfig withKernelMemory(Long kernelMemory) { + this.kernelMemory = kernelMemory; + return this; } - @JsonIgnore - public void setLogConfig(LogConfig logConfig) { + /** + * @see #links + */ + public HostConfig withLinks(Links links) { + this.links = links; + return this; + } + + /** + * @see #logConfig + */ + public HostConfig withLogConfig(LogConfig logConfig) { this.logConfig = logConfig; + return this; } - public void setLxcConf(LxcConf[] lxcConf) { + /** + * @see #lxcConf + */ + public HostConfig withLxcConf(LxcConf[] lxcConf) { this.lxcConf = lxcConf; + return this; } - public void setMemory(Long memory) { + /** + * @see #memory + */ + public HostConfig withMemory(Long memory) { this.memory = memory; + return this; + } + + /** + * @see #memoryReservation + */ + public HostConfig withMemoryReservation(Long memoryReservation) { + this.memoryReservation = memoryReservation; + return this; } - public void setMemorySwap(Long memorySwap) { + /** + * @see #memorySwap + */ + public HostConfig withMemorySwap(Long memorySwap) { this.memorySwap = memorySwap; + return this; } - public void setNetworkMode(String networkMode) { + /** + * @see #memorySwappiness + */ + public HostConfig withMemorySwappiness(Integer memorySwappiness) { + this.memorySwappiness = memorySwappiness; + return this; + } + + /** + * @see #networkMode + */ + public HostConfig withNetworkMode(String networkMode) { this.networkMode = networkMode; + return this; } - public void setOomKillDisable(Boolean oomKillDisable) { + /** + * @see #oomKillDisable + */ + public HostConfig withOomKillDisable(Boolean oomKillDisable) { this.oomKillDisable = oomKillDisable; + return this; + } + + /** + * @see #oomScoreAdj + */ + public HostConfig withOomScoreAdj(Boolean oomScoreAdj) { + this.oomScoreAdj = oomScoreAdj; + return this; } - public void setPortBindings(Ports portBindings) { + /** + * @see #pidMode + */ + public HostConfig withPidMode(String pidMode) { + this.pidMode = pidMode; + return this; + } + + /** + * @see #portBindings + */ + public HostConfig withPortBindings(Ports portBindings) { this.portBindings = portBindings; + return this; } - public void setPrivileged(Boolean privileged) { + /** + * @see #privileged + */ + public HostConfig withPrivileged(Boolean privileged) { this.privileged = privileged; + return this; } - public void setPublishAllPorts(Boolean publishAllPorts) { + /** + * @see #publishAllPorts + */ + public HostConfig withPublishAllPorts(Boolean publishAllPorts) { this.publishAllPorts = publishAllPorts; + return this; } - public void setReadonlyRootfs(Boolean readonlyRootfs) { + /** + * @see #readonlyRootfs + */ + public HostConfig withReadonlyRootfs(Boolean readonlyRootfs) { this.readonlyRootfs = readonlyRootfs; + return this; } - public void setRestartPolicy(RestartPolicy restartPolicy) { + /** + * @see #restartPolicy + */ + public HostConfig withRestartPolicy(RestartPolicy restartPolicy) { this.restartPolicy = restartPolicy; + return this; + } + + /** + * @see #securityOpts + */ + public HostConfig withSecurityOpts(List securityOpts) { + this.securityOpts = securityOpts; + return this; + } + + /** + * @see #shmSize + */ + public HostConfig withShmSize(String shmSize) { + this.shmSize = shmSize; + return this; } - public void setUlimits(Ulimit[] ulimits) { + /** + * @see #ulimits + */ + public HostConfig withUlimits(Ulimit[] ulimits) { this.ulimits = ulimits; + return this; } - public void setVolumesFrom(VolumesFrom[] volumesFrom) { - this.volumesFrom = volumesFrom; + /** + * @see #volumeDriver + */ + public HostConfig withVolumeDriver(String volumeDriver) { + this.volumeDriver = volumeDriver; + return this; } - public void setPidMode(String pidMode) { - this.pidMode = pidMode; + /** + * @see #volumesFrom + */ + public HostConfig withVolumesFrom(VolumesFrom[] volumesFrom) { + this.volumesFrom = volumesFrom; + return this; } + // end of auto-generated @Override public String toString() { return ToStringBuilder.reflectionToString(this); } + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } } diff --git a/src/main/java/com/github/dockerjava/api/model/Info.java b/src/main/java/com/github/dockerjava/api/model/Info.java index 0e4816cce..7270eceb8 100644 --- a/src/main/java/com/github/dockerjava/api/model/Info.java +++ b/src/main/java/com/github/dockerjava/api/model/Info.java @@ -1,29 +1,80 @@ package com.github.dockerjava.api.model; -import java.util.List; - -import org.apache.commons.lang.builder.ToStringBuilder; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; +import java.util.List; +import java.util.Map; /** + * Used for `/info` * * @author Konstantin Pelykh (kpelykh@gmail.com) - * */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) public class Info { + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("Architecture") + private String architecture; + @JsonProperty("Containers") private Integer containers; + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("ContainersStopped") + private Integer containersStopped; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("ContainersPaused") + private Integer containersPaused; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("ContainersRunning") + private Integer containersRunning; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("CpuCfsPeriod") + private Boolean cpuCfsPeriod; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("CpuCfsQuota") + private Boolean cpuCfsQuota; + + @JsonProperty("CPUShares") + private Boolean cpuShares; + + @JsonProperty("CPUSet") + private Boolean cpuSet; + @JsonProperty("Debug") private Boolean debug; + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_21} + */ + @JsonProperty("DiscoveryBackend") + private String discoveryBackend; + @JsonProperty("DockerRootDir") private String dockerRootDir; @@ -31,17 +82,53 @@ public class Info { private String driver; @JsonProperty("DriverStatus") - private List driverStatuses; + private List> driverStatuses; + + @JsonProperty("SystemStatus") + private List systemStatus; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("Plugins") + private Map> plugins; @JsonProperty("ExecutionDriver") private String executionDriver; + @JsonProperty("LoggingDriver") + private String loggingDriver; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("ExperimentalBuild") + private Boolean experimentalBuild; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("HttpProxy") + private String httpProxy; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("HttpsProxy") + private String httpsProxy; + @JsonProperty("ID") private String id; @JsonProperty("IPv4Forwarding") private Boolean ipv4Forwarding; + @JsonProperty("BridgeNfIptables") + private Boolean bridgeNfIptables; + + @JsonProperty("BridgeNfIp6tables") + private Boolean bridgeNfIp6tables; + @JsonProperty("Images") private Integer images; @@ -73,7 +160,7 @@ public class Info { private Integer ncpu; @JsonProperty("NEventsListener") - private Long nEventListener; + private Integer nEventsListener; @JsonProperty("NFd") private Integer nfd; @@ -81,113 +168,872 @@ public class Info { @JsonProperty("NGoroutines") private Integer nGoroutines; + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("NoProxy") + private String noProxy; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("OomKillDisable") + private Boolean oomKillDisable; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("OSType") + private String osType; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("OomScoreAdj") + private Integer oomScoreAdj; + @JsonProperty("OperatingSystem") private String operatingSystem; + @JsonProperty("RegistryConfig") + private InfoRegistryConfig registryConfig; + @JsonProperty("Sockets") private String[] sockets; @JsonProperty("SwapLimit") private Boolean swapLimit; - public Boolean isDebug() { - return debug; + /** + * @since ~{@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("SystemTime") + private String systemTime; + + /** + * @since ~{@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_21} + */ + @JsonProperty("ServerVersion") + private String serverVersion; + + @JsonProperty("ClusterStore") + private String clusterStore; + + @JsonProperty("ClusterAdvertise") + private String clusterAdvertise; + + /** + * @see #architecture + */ + @CheckForNull + public String getArchitecture() { + return architecture; + } + + /** + * @see #architecture + */ + public Info withArchitecture(String architecture) { + this.architecture = architecture; + return this; } + /** + * @see #containers + */ + @CheckForNull public Integer getContainers() { return containers; } + /** + * @see #containers + */ + public Info withContainers(Integer containers) { + this.containers = containers; + return this; + } + + /** + * @see #containersPaused + */ + @CheckForNull + public Integer getContainersPaused() { + return containersPaused; + } + + /** + * @see #containersPaused + */ + public Info withContainersPaused(Integer containersPaused) { + this.containersPaused = containersPaused; + return this; + } + + /** + * @see #containersRunning + */ + @CheckForNull + public Integer getContainersRunning() { + return containersRunning; + } + + /** + * @see #containersRunning + */ + public Info withContainersRunning(Integer containersRunning) { + this.containersRunning = containersRunning; + return this; + } + + /** + * @see #containersStopped + */ + @CheckForNull + public Integer getContainersStopped() { + return containersStopped; + } + + /** + * @see #containersStopped + */ + public Info withContainersStopped(Integer containersStopped) { + this.containersStopped = containersStopped; + return this; + } + + /** + * @see #cpuCfsPeriod + */ + @CheckForNull + public Boolean getCpuCfsPeriod() { + return cpuCfsPeriod; + } + + /** + * @see #cpuCfsPeriod + */ + public Info withCpuCfsPeriod(Boolean cpuCfsPeriod) { + this.cpuCfsPeriod = cpuCfsPeriod; + return this; + } + + /** + * @see #cpuCfsQuota + */ + @CheckForNull + public Boolean getCpuCfsQuota() { + return cpuCfsQuota; + } + + /** + * @see #cpuCfsQuota + */ + public Info withCpuCfsQuota(Boolean cpuCfsQuota) { + this.cpuCfsQuota = cpuCfsQuota; + return this; + } + + /** + * @see #cpuShares + */ + @CheckForNull + public Boolean getCpuShares() { + return cpuShares; + } + + /** + * @see #cpuShares + */ + public Info withCpuShares(Boolean cpuShares) { + this.cpuShares = cpuShares; + return this; + } + + /** + * @see #cpuSet + */ + @CheckForNull + public Boolean getCpuSet() { + return cpuSet; + } + + /** + * @see #cpuSet + */ + public Info withCpuSet(Boolean cpuSet) { + this.cpuSet = cpuSet; + return this; + } + + /** + * @see #debug + */ + @CheckForNull + public Boolean getDebug() { + return debug; + } + + /** + * @see #debug + */ + public Info withDebug(Boolean debug) { + this.debug = debug; + return this; + } + + /** + * @see #discoveryBackend + */ + @CheckForNull + public String getDiscoveryBackend() { + return discoveryBackend; + } + + /** + * @see #discoveryBackend + */ + public Info withDiscoveryBackend(String discoveryBackend) { + this.discoveryBackend = discoveryBackend; + return this; + } + + /** + * @see #dockerRootDir + */ + @CheckForNull public String getDockerRootDir() { return dockerRootDir; } + /** + * @see #dockerRootDir + */ + public Info withDockerRootDir(String dockerRootDir) { + this.dockerRootDir = dockerRootDir; + return this; + } + + /** + * @see #driver + */ + @CheckForNull public String getDriver() { return driver; } - public List getDriverStatuses() { + /** + * @see #driver + */ + public Info withDriver(String driver) { + this.driver = driver; + return this; + } + + /** + * @see #driverStatuses + */ + @CheckForNull + public List> getDriverStatuses() { return driverStatuses; } - public Integer getImages() { - return images; + /** + * @see #driverStatuses + */ + public Info withDriverStatuses(List> driverStatuses) { + this.driverStatuses = driverStatuses; + return this; + } + + /** + * @see #executionDriver + */ + @CheckForNull + public String getExecutionDriver() { + return executionDriver; + } + + /** + * @see #executionDriver + */ + public Info withExecutionDriver(String executionDriver) { + this.executionDriver = executionDriver; + return this; + } + + /** + * @see #loggingDriver + */ + @CheckForNull + public String getLoggingDriver() { + return loggingDriver; + } + + /** + * @see #loggingDriver + */ + public Info withLoggingDriver(String loggingDriver) { + this.loggingDriver = loggingDriver; + return this; } - public String getID() { + /** + * @see #experimentalBuild + */ + @CheckForNull + public Boolean getExperimentalBuild() { + return experimentalBuild; + } + + /** + * @see #experimentalBuild + */ + public Info withExperimentalBuild(Boolean experimentalBuild) { + this.experimentalBuild = experimentalBuild; + return this; + } + + /** + * @see #httpProxy + */ + @CheckForNull + public String getHttpProxy() { + return httpProxy; + } + + /** + * @see #httpProxy + */ + public Info withHttpProxy(String httpProxy) { + this.httpProxy = httpProxy; + return this; + } + + /** + * @see #httpsProxy + */ + @CheckForNull + public String getHttpsProxy() { + return httpsProxy; + } + + /** + * @see #httpsProxy + */ + public Info withHttpsProxy(String httpsProxy) { + this.httpsProxy = httpsProxy; + return this; + } + + /** + * @see #id + */ + @CheckForNull + public String getId() { return id; } - public Boolean getIPv4Forwarding() { - return ipv4Forwarding; + /** + * @see #id + */ + public Info withId(String id) { + this.id = id; + return this; + } + + /** + * @see #images + */ + @CheckForNull + public Integer getImages() { + return images; + } + + /** + * @see #images + */ + public Info withImages(Integer images) { + this.images = images; + return this; } + /** + * @see #indexServerAddress + */ + @CheckForNull public String getIndexServerAddress() { return indexServerAddress; } + /** + * @see #indexServerAddress + */ + public Info withIndexServerAddress(String indexServerAddress) { + this.indexServerAddress = indexServerAddress; + return this; + } + + /** + * @see #initPath + */ + @CheckForNull public String getInitPath() { return initPath; } + /** + * @see #initPath + */ + public Info withInitPath(String initPath) { + this.initPath = initPath; + return this; + } + + /** + * @see #initSha1 + */ + @CheckForNull public String getInitSha1() { return initSha1; } + /** + * @see #initSha1 + */ + public Info withInitSha1(String initSha1) { + this.initSha1 = initSha1; + return this; + } + + /** + * @see #ipv4Forwarding + */ + @CheckForNull + public Boolean getIPv4Forwarding() { + return ipv4Forwarding; + } + + /** + * @see #ipv4Forwarding + */ + public Info withIPv4Forwarding(Boolean ipv4Forwarding) { + this.ipv4Forwarding = ipv4Forwarding; + return this; + } + + /** + * @see #bridgeNfIptables + */ + @CheckForNull + public Boolean getBridgeNfIptables() { + return bridgeNfIptables; + } + + /** + * @see #bridgeNfIptables + */ + public Info withBridgeNfIptables(Boolean bridgeNfIptables) { + this.bridgeNfIptables = bridgeNfIptables; + return this; + } + + /** + * @see #bridgeNfIp6tables + */ + @CheckForNull + public Boolean getBridgeNfIp6tables() { + return bridgeNfIp6tables; + } + + /** + * @see #bridgeNfIp6tables + */ + public Info withBridgeNfIp6tables(Boolean bridgeNfIp6tables) { + this.bridgeNfIp6tables = bridgeNfIp6tables; + return this; + } + + /** + * @see #kernelVersion + */ + @CheckForNull public String getKernelVersion() { return kernelVersion; } + /** + * @see #kernelVersion + */ + public Info withKernelVersion(String kernelVersion) { + this.kernelVersion = kernelVersion; + return this; + } + + /** + * @see #labels + */ + @CheckForNull public String[] getLabels() { return labels; } - public String[] getSockets() { - return sockets; + /** + * @see #labels + */ + public Info withLabels(String[] labels) { + this.labels = labels; + return this; } - public Boolean isMemoryLimit() { + /** + * @see #memoryLimit + */ + @CheckForNull + public Boolean getMemoryLimit() { return memoryLimit; } - public Long getnEventListener() { - return nEventListener; + /** + * @see #memoryLimit + */ + public Info withMemoryLimit(Boolean memoryLimit) { + this.memoryLimit = memoryLimit; + return this; } + /** + * @see #memTotal + */ + @CheckForNull public Long getMemTotal() { return memTotal; } + /** + * @see #memTotal + */ + public Info withMemTotal(Long memTotal) { + this.memTotal = memTotal; + return this; + } + + /** + * @see #name + */ + @CheckForNull public String getName() { return name; } + /** + * @see #name + */ + public Info withName(String name) { + this.name = name; + return this; + } + + /** + * @see #ncpu + */ + @CheckForNull public Integer getNCPU() { return ncpu; } + /** + * @see #ncpu + */ + public Info withNCPU(Integer ncpu) { + this.ncpu = ncpu; + return this; + } + + /** + * @see #nEventsListener + */ + @CheckForNull + public Integer getNEventsListener() { + return nEventsListener; + } + + /** + * @see #nEventsListener + */ + public Info withNEventsListener(Integer nEventListener) { + this.nEventsListener = nEventListener; + return this; + } + + /** + * @see #nfd + */ + @CheckForNull public Integer getNFd() { return nfd; } + /** + * @see #nfd + */ + public Info withNFd(Integer nfd) { + this.nfd = nfd; + return this; + } + + /** + * @see #nGoroutines + */ + @CheckForNull public Integer getNGoroutines() { return nGoroutines; } + /** + * @see #nGoroutines + */ + public Info withNGoroutines(Integer nGoroutines) { + this.nGoroutines = nGoroutines; + return this; + } + + /** + * @see #noProxy + */ + @CheckForNull + public String getNoProxy() { + return noProxy; + } + + /** + * @see #noProxy + */ + public Info withNoProxy(String noProxy) { + this.noProxy = noProxy; + return this; + } + + /** + * @see #oomKillDisable + */ + @CheckForNull + public Boolean getOomKillDisable() { + return oomKillDisable; + } + + /** + * @see #oomKillDisable + */ + public Info withOomKillDisable(Boolean oomKillDisable) { + this.oomKillDisable = oomKillDisable; + return this; + } + + /** + * @see #oomScoreAdj + */ + @CheckForNull + public Integer getOomScoreAdj() { + return oomScoreAdj; + } + + /** + * @see #oomScoreAdj + */ + public Info withOomScoreAdj(Integer oomScoreAdj) { + this.oomScoreAdj = oomScoreAdj; + return this; + } + + /** + * @see #operatingSystem + */ + @CheckForNull public String getOperatingSystem() { return operatingSystem; } + /** + * @see #operatingSystem + */ + public Info withOperatingSystem(String operatingSystem) { + this.operatingSystem = operatingSystem; + return this; + } + + /** + * @see #osType + */ + @CheckForNull + public String getOsType() { + return osType; + } + + /** + * @see #osType + */ + public Info withOsType(String osType) { + this.osType = osType; + return this; + } + + /** + * @see #plugins + */ + @CheckForNull + public Map> getPlugins() { + return plugins; + } + + /** + * @see #plugins + */ + public Info withPlugins(Map> plugins) { + this.plugins = plugins; + return this; + } + + /** + * @see #registryConfig + */ + @CheckForNull + public InfoRegistryConfig getRegistryConfig() { + return registryConfig; + } + + /** + * @see #registryConfig + */ + public Info withRegistryConfig(InfoRegistryConfig registryConfig) { + this.registryConfig = registryConfig; + return this; + } + + /** + * @see #serverVersion + */ + @CheckForNull + public String getServerVersion() { + return serverVersion; + } + + /** + * @see #serverVersion + */ + public Info withServerVersion(String serverVersion) { + this.serverVersion = serverVersion; + return this; + } + + /** + * @see #clusterStore + */ + @CheckForNull + public String getClusterStore() { + return clusterStore; + } + + /** + * @see #clusterStore + */ + public Info withClusterStore(String clusterStore) { + this.clusterStore = clusterStore; + return this; + } + + /** + * @see #clusterAdvertise + */ + @CheckForNull + public String getClusterAdvertise() { + return clusterAdvertise; + } + + /** + * @see #clusterAdvertise + */ + public Info withClusterAdvertise(String clusterAdvertise) { + this.clusterAdvertise = clusterAdvertise; + return this; + } + + /** + * @see #sockets + */ + @CheckForNull + public String[] getSockets() { + return sockets; + } + + /** + * @see #sockets + */ + public Info withSockets(String[] sockets) { + this.sockets = sockets; + return this; + } + + /** + * @see #swapLimit + */ + @CheckForNull public Boolean getSwapLimit() { return swapLimit; } - public String getExecutionDriver() { - return executionDriver; + /** + * @see #swapLimit + */ + public Info withSwapLimit(Boolean swapLimit) { + this.swapLimit = swapLimit; + return this; + } + + /** + * @see #systemStatus + */ + @CheckForNull + public List getSystemStatus() { + return systemStatus; + } + + /** + * @see #systemStatus + */ + public Info withSystemStatus(List systemStatus) { + this.systemStatus = systemStatus; + return this; + } + + /** + * @see #systemTime + */ + @CheckForNull + public String getSystemTime() { + return systemTime; + } + + /** + * @see #systemTime + */ + public Info withSystemTime(String systemTime) { + this.systemTime = systemTime; + return this; } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } } diff --git a/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java b/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java new file mode 100644 index 000000000..cc67994a5 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java @@ -0,0 +1,189 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; +import java.util.List; +import java.util.Map; + +/** + * @since ~{@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public final class InfoRegistryConfig { + @JsonProperty("IndexConfigs") + private Map indexConfigs; + + @JsonProperty("InsecureRegistryCIDRs") + private List insecureRegistryCIDRs; + + /** + * //FIXME unknown field + */ + @JsonProperty("Mirrors") + private Object mirrors; + + /** + * @see #indexConfigs + */ + @CheckForNull + public Map getIndexConfigs() { + return indexConfigs; + } + + /** + * @see #indexConfigs + */ + public InfoRegistryConfig withIndexConfigs(Map indexConfigs) { + this.indexConfigs = indexConfigs; + return this; + } + + /** + * @see #insecureRegistryCIDRs + */ + @CheckForNull + public List getInsecureRegistryCIDRs() { + return insecureRegistryCIDRs; + } + + /** + * @see #insecureRegistryCIDRs + */ + public InfoRegistryConfig withInsecureRegistryCIDRs(List insecureRegistryCIDRs) { + this.insecureRegistryCIDRs = insecureRegistryCIDRs; + return this; + } + + /** + * @see #mirrors + */ + @CheckForNull + public Object getMirrors() { + return mirrors; + } + + /** + * @see #mirrors + */ + public InfoRegistryConfig withMirrors(Object mirrors) { + this.mirrors = mirrors; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + /** + * @since ~{@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ + @JsonIgnoreProperties(ignoreUnknown = true) + public static final class IndexConfig { + @JsonProperty("Mirrors") + private String mirrors; + + @JsonProperty("Name") + private String name; + + @JsonProperty("Official") + private Boolean official; + + @JsonProperty("Secure") + private Boolean secure; + + /** + * @see #mirrors + */ + @CheckForNull + public String getMirrors() { + return mirrors; + } + + /** + * @see #mirrors + */ + public IndexConfig withMirrors(String mirrors) { + this.mirrors = mirrors; + return this; + } + + /** + * @see #name + */ + @CheckForNull + public String getName() { + return name; + } + + /** + * @see #name + */ + public IndexConfig withName(String name) { + this.name = name; + return this; + } + + /** + * @see #official + */ + @CheckForNull + public Boolean getOfficial() { + return official; + } + + /** + * @see #official + */ + public IndexConfig withOfficial(Boolean official) { + this.official = official; + return this; + } + + /** + * @see #secure + */ + @CheckForNull + public Boolean getSecure() { + return secure; + } + + /** + * @see #secure + */ + public IndexConfig withSecure(Boolean secure) { + this.secure = secure; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java b/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java index 64c954ec9..680048c18 100644 --- a/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java +++ b/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java @@ -11,6 +11,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.github.dockerjava.core.RemoteApiVersion; +import javax.annotation.CheckForNull; + /** * * @author Marcus Linke @@ -208,6 +210,15 @@ public String toString() { @JsonIgnoreProperties(ignoreUnknown = true) public static class Network { + @JsonProperty("IPAMConfig") + private String ipamConfig; + + /** + * @since {@link RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("NetworkID") + private String networkID; + @JsonProperty("EndpointID") private String endpointId; @@ -232,6 +243,11 @@ public static class Network { @JsonProperty("MacAddress") private String macAddress; + @CheckForNull + public String getNetworkID() { + return networkID; + } + public String getEndpointId() { return endpointId; } diff --git a/src/main/java/com/github/dockerjava/api/model/UpdateContainerResponse.java b/src/main/java/com/github/dockerjava/api/model/UpdateContainerResponse.java new file mode 100644 index 000000000..b1b1188d0 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/UpdateContainerResponse.java @@ -0,0 +1,28 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.dockerjava.core.RemoteApiVersion; + +import javax.annotation.CheckForNull; +import java.util.List; + +/** + * @author Kanstantsin Shautsou + * @see com.github.dockerjava.api.command.UpdateContainerCmd + * @see + * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.22/ + * @since {@link RemoteApiVersion#VERSION_1_22} + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class UpdateContainerResponse extends ResponseItem { + private static final long serialVersionUID = 1L; + + @JsonProperty("Warnings") + private List warnings; + + @CheckForNull + public List getWarnings() { + return warnings; + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/Version.java b/src/main/java/com/github/dockerjava/api/model/Version.java index aca548987..004c85f22 100644 --- a/src/main/java/com/github/dockerjava/api/model/Version.java +++ b/src/main/java/com/github/dockerjava/api/model/Version.java @@ -1,14 +1,19 @@ package com.github.dockerjava.api.model; -import org.apache.commons.lang.builder.ToStringBuilder; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.dockerjava.api.command.VersionCmd; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; /** + * Used for `/version` * * @author Konstantin Pelykh (kpelykh@gmail.com) - * + * @see VersionCmd */ @JsonIgnoreProperties(ignoreUnknown = true) public class Version { @@ -34,6 +39,18 @@ public class Version { @JsonProperty("Version") private String version; + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("BuildTime") + private String buildTime; + + /** + * @since ~{@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} + */ + @JsonProperty("Experimental") + private Boolean experimental; + public String getVersion() { return version; } @@ -62,8 +79,34 @@ public String getApiVersion() { return apiVersion; } + /** + * @see #buildTime + */ + @CheckForNull + public String getBuildTime() { + return buildTime; + } + + /** + * @see #experimental + */ + @CheckForNull + public Boolean getExperimental() { + return experimental; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this); } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } } diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java index 59e18bc85..9d342e249 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -55,6 +55,7 @@ import com.github.dockerjava.api.command.TagImageCmd; import com.github.dockerjava.api.command.TopContainerCmd; import com.github.dockerjava.api.command.UnpauseContainerCmd; +import com.github.dockerjava.api.command.UpdateContainerCmd; import com.github.dockerjava.api.command.VersionCmd; import com.github.dockerjava.api.command.WaitContainerCmd; import com.github.dockerjava.api.model.AuthConfig; @@ -105,9 +106,12 @@ import com.github.dockerjava.core.command.TagImageCmdImpl; import com.github.dockerjava.core.command.TopContainerCmdImpl; import com.github.dockerjava.core.command.UnpauseContainerCmdImpl; +import com.github.dockerjava.core.command.UpdateContainerCmdImpl; import com.github.dockerjava.core.command.VersionCmdImpl; import com.github.dockerjava.core.command.WaitContainerCmdImpl; +import javax.annotation.Nonnull; + /** * @author Konstantin Pelykh (kpelykh@gmail.com) * @see "https://github.com/docker/docker/blob/master/api/client/commands.go" @@ -355,6 +359,11 @@ public KillContainerCmd killContainerCmd(String containerId) { return new KillContainerCmdImpl(getDockerCmdExecFactory().createKillContainerCmdExec(), containerId); } + @Override + public UpdateContainerCmd updateContainerCmd(@Nonnull String containerId) { + return new UpdateContainerCmdImpl(getDockerCmdExecFactory().createUpdateContainerCmdExec(), containerId); + } + @Override public RestartContainerCmd restartContainerCmd(String containerId) { return new RestartContainerCmdImpl(getDockerCmdExecFactory().createRestartContainerCmdExec(), containerId); diff --git a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java index 1dd93f466..e15cccc88 100644 --- a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java +++ b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java @@ -12,7 +12,7 @@ /** * Bean to encapsulate the version of the Docker Remote (REST) * API - *

+ *

* Contains the minor and major version of the API as well as operations to compare API versions. * * @author Marcus Thiesen diff --git a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java index 6b5cea08a..e03acbf7f 100644 --- a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java @@ -33,9 +33,8 @@ import com.github.dockerjava.api.model.VolumesFrom; /** - * * Creates a new container. - * + * `/containers/create` */ @JsonInclude(Include.NON_NULL) public class CreateContainerCmdImpl extends AbstrDockerCmd implements @@ -100,6 +99,12 @@ public class CreateContainerCmdImpl extends AbstrDockerCmd binds) { @Override public CreateContainerCmd withBlkioWeight(Integer blkioWeight) { checkNotNull(blkioWeight, "blkioWeight was not specified"); - hostConfig.setBlkioWeight(blkioWeight); + hostConfig.withBlkioWeight(blkioWeight); return this; } @Override public CreateContainerCmd withCapAdd(Capability... capAdd) { checkNotNull(capAdd, "capAdd was not specified"); - hostConfig.setCapAdd(capAdd); + hostConfig.withCapAdd(capAdd); return this; } @@ -456,7 +470,7 @@ public CreateContainerCmd withCapAdd(List capAdd) { @Override public CreateContainerCmd withCapDrop(Capability... capDrop) { checkNotNull(capDrop, "capDrop was not specified"); - hostConfig.setCapDrop(capDrop); + hostConfig.withCapDrop(capDrop); return this; } @@ -482,42 +496,42 @@ public CreateContainerCmd withCmd(List cmd) { @Override public CreateContainerCmd withContainerIDFile(String containerIDFile) { checkNotNull(containerIDFile, "no containerIDFile was specified"); - hostConfig.setContainerIDFile(containerIDFile); + hostConfig.withContainerIDFile(containerIDFile); return this; } @Override public CreateContainerCmd withCpuPeriod(Integer cpuPeriod) { checkNotNull(cpuPeriod, "cpuPeriod was not specified"); - hostConfig.setCpuPeriod(cpuPeriod); + hostConfig.withCpuPeriod(cpuPeriod); return this; } @Override public CreateContainerCmd withCpusetCpus(String cpusetCpus) { checkNotNull(cpusetCpus, "cpusetCpus was not specified"); - hostConfig.setCpusetCpus(cpusetCpus); + hostConfig.withCpusetCpus(cpusetCpus); return this; } @Override public CreateContainerCmd withCpusetMems(String cpusetMems) { checkNotNull(cpusetMems, "cpusetMems was not specified"); - hostConfig.setCpusetMems(cpusetMems); + hostConfig.withCpusetMems(cpusetMems); return this; } @Override public CreateContainerCmd withCpuShares(Integer cpuShares) { checkNotNull(cpuShares, "cpuShares was not specified"); - hostConfig.setCpuShares(cpuShares); + hostConfig.withCpuShares(cpuShares); return this; } @Override public CreateContainerCmd withDevices(Device... devices) { checkNotNull(devices, "devices was not specified"); - this.hostConfig.setDevices(devices); + this.hostConfig.withDevices(devices); return this; } @@ -530,7 +544,7 @@ public CreateContainerCmd withDevices(List devices) { @Override public CreateContainerCmd withDns(String... dns) { checkNotNull(dns, "dns was not specified"); - this.hostConfig.setDns(dns); + this.hostConfig.withDns(dns); return this; } @@ -543,7 +557,7 @@ public CreateContainerCmd withDns(List dns) { @Override public CreateContainerCmd withDnsSearch(String... dnsSearch) { checkNotNull(dnsSearch, "dnsSearch was not specified"); - this.hostConfig.setDnsSearch(dnsSearch); + this.hostConfig.withDnsSearch(dnsSearch); return this; } @@ -593,6 +607,13 @@ public CreateContainerCmd withExposedPorts(ExposedPort... exposedPorts) { return this; } + @Override + public CreateContainerCmd withStopSignal(String stopSignal) { + checkNotNull(stopSignal, "stopSignal wasn't specified."); + this.stopSignal = stopSignal; + return this; + } + @Override public CreateContainerCmd withExposedPorts(List exposedPorts) { checkNotNull(exposedPorts, "exposedPorts was not specified"); @@ -602,7 +623,7 @@ public CreateContainerCmd withExposedPorts(List exposedPorts) { @Override public CreateContainerCmd withExtraHosts(String... extraHosts) { checkNotNull(extraHosts, "extraHosts was not specified"); - this.hostConfig.setExtraHosts(extraHosts); + this.hostConfig.withExtraHosts(extraHosts); return this; } @@ -649,7 +670,7 @@ public CreateContainerCmd withLinks(List links) { @Override public CreateContainerCmd withLxcConf(LxcConf... lxcConf) { checkNotNull(lxcConf, "lxcConf was not specified"); - this.hostConfig.setLxcConf(lxcConf); + this.hostConfig.withLxcConf(lxcConf); return this; } @@ -662,7 +683,7 @@ public CreateContainerCmd withLxcConf(List lxcConf) { @Override public CreateContainerCmd withLogConfig(LogConfig logConfig) { checkNotNull(logConfig, "logConfig was not specified"); - this.hostConfig.setLogConfig(logConfig); + this.hostConfig.withLogConfig(logConfig); return this; } @@ -676,14 +697,14 @@ public CreateContainerCmd withMacAddress(String macAddress) { @Override public CreateContainerCmd withMemory(Long memory) { checkNotNull(memory, "memory was not specified"); - hostConfig.setMemory(memory); + hostConfig.withMemory(memory); return this; } @Override public CreateContainerCmd withMemorySwap(Long memorySwap) { checkNotNull(memorySwap, "memorySwap was not specified"); - hostConfig.setMemorySwap(memorySwap); + hostConfig.withMemorySwap(memorySwap); return this; } @@ -704,21 +725,21 @@ public CreateContainerCmd withNetworkDisabled(Boolean disableNetwork) { @Override public CreateContainerCmd withNetworkMode(String networkMode) { checkNotNull(networkMode, "networkMode was not specified"); - this.hostConfig.setNetworkMode(networkMode); + this.hostConfig.withNetworkMode(networkMode); return this; } @Override public CreateContainerCmd withOomKillDisable(Boolean oomKillDisable) { checkNotNull(oomKillDisable, "oomKillDisable was not specified"); - hostConfig.setOomKillDisable(oomKillDisable); + hostConfig.withOomKillDisable(oomKillDisable); return this; } @Override public CreateContainerCmd withPortBindings(PortBinding... portBindings) { checkNotNull(portBindings, "portBindings was not specified"); - this.hostConfig.setPortBindings(new Ports(portBindings)); + this.hostConfig.withPortBindings(new Ports(portBindings)); return this; } @@ -731,7 +752,7 @@ public CreateContainerCmd withPortBindings(List portBindings) { @Override public CreateContainerCmd withPortBindings(Ports portBindings) { checkNotNull(portBindings, "portBindings was not specified"); - this.hostConfig.setPortBindings(portBindings); + this.hostConfig.withPortBindings(portBindings); return this; } @@ -751,28 +772,28 @@ public CreateContainerCmd withPortSpecs(List portSpecs) { @Override public CreateContainerCmd withPrivileged(Boolean privileged) { checkNotNull(privileged, "no privileged was specified"); - this.hostConfig.setPrivileged(privileged); + this.hostConfig.withPrivileged(privileged); return this; } @Override public CreateContainerCmd withPublishAllPorts(Boolean publishAllPorts) { checkNotNull(publishAllPorts, "no publishAllPorts was specified"); - this.hostConfig.setPublishAllPorts(publishAllPorts); + this.hostConfig.withPublishAllPorts(publishAllPorts); return this; } @Override public CreateContainerCmd withReadonlyRootfs(Boolean readonlyRootfs) { checkNotNull(readonlyRootfs, "no readonlyRootfs was specified"); - hostConfig.setReadonlyRootfs(readonlyRootfs); + hostConfig.withReadonlyRootfs(readonlyRootfs); return this; } @Override public CreateContainerCmd withRestartPolicy(RestartPolicy restartPolicy) { checkNotNull(restartPolicy, "restartPolicy was not specified"); - this.hostConfig.setRestartPolicy(restartPolicy); + this.hostConfig.withRestartPolicy(restartPolicy); return this; } @@ -800,7 +821,7 @@ public CreateContainerCmd withTty(Boolean tty) { @Override public CreateContainerCmd withUlimits(Ulimit... ulimits) { checkNotNull(ulimits, "no ulimits was specified"); - hostConfig.setUlimits(ulimits); + hostConfig.withUlimits(ulimits); return this; } @@ -833,7 +854,7 @@ public CreateContainerCmd withVolumes(List volumes) { @Override public CreateContainerCmd withVolumesFrom(VolumesFrom... volumesFrom) { checkNotNull(volumesFrom, "volumesFrom was not specified"); - this.hostConfig.setVolumesFrom(volumesFrom); + this.hostConfig.withVolumesFrom(volumesFrom); return this; } @@ -853,7 +874,7 @@ public CreateContainerCmd withWorkingDir(String workingDir) { @Override public CreateContainerCmd withPidMode(String pidMode) { checkNotNull(pidMode, "pidMode was not specified"); - this.hostConfig.setPidMode(pidMode); + this.hostConfig.withPidMode(pidMode); return this; } diff --git a/src/main/java/com/github/dockerjava/core/command/UpdateContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/UpdateContainerCmdImpl.java new file mode 100644 index 000000000..ee95842b2 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/UpdateContainerCmdImpl.java @@ -0,0 +1,264 @@ +package com.github.dockerjava.core.command; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.dockerjava.api.command.UpdateContainerCmd; +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.api.model.UpdateContainerResponse; +import com.github.dockerjava.core.RemoteApiVersion; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; + +/** + * @author Kanstantsin Shautsou + * @see + * https://docs.docker.com/engine/reference/api/docker_remote_api_v1.22/ + * @since {@link RemoteApiVersion#VERSION_1_22} + */ +public class UpdateContainerCmdImpl extends AbstrDockerCmd + implements UpdateContainerCmd { + + @JsonIgnoreProperties + private String containerId; + + @JsonProperty("BlkioWeight") + private Integer blkioWeight; + + @JsonProperty("CpuShares") + private Integer cpuShares; + + @JsonProperty("CpuPeriod") + private Integer cpuPeriod; + + @JsonProperty("CpuQuota") + private Integer cpuQuota; + + @JsonProperty("CpusetCpus") + private String cpusetCpus; + + @JsonProperty("CpusetMems") + private String cpusetMems; + + @JsonProperty("Memory") + private Long memory; + + @JsonProperty("MemorySwap") + private Long memorySwap; + + @JsonProperty("MemoryReservation") + private Long memoryReservation; + + @JsonProperty("KernelMemory") + private Long kernelMemory; + + public UpdateContainerCmdImpl() { + super(null); + } + + public UpdateContainerCmdImpl(UpdateContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + /** + * @see #blkioWeight + */ + @CheckForNull + public Integer getBlkioWeight() { + return blkioWeight; + } + + /** + * @see #blkioWeight + */ + public UpdateContainerCmd withBlkioWeight(Integer blkioWeight) { + this.blkioWeight = blkioWeight; + return this; + } + + /** + * @see #containerId + */ + @CheckForNull + public String getContainerId() { + return containerId; + } + + /** + * @see #containerId + */ + public UpdateContainerCmd withContainerId(String containerId) { + this.containerId = containerId; + return this; + } + + /** + * @see #cpuPeriod + */ + @CheckForNull + public Integer getCpuPeriod() { + return cpuPeriod; + } + + /** + * @see #cpuPeriod + */ + public UpdateContainerCmd withCpuPeriod(Integer cpuPeriod) { + this.cpuPeriod = cpuPeriod; + return this; + } + + /** + * @see #cpuQuota + */ + @CheckForNull + public Integer getCpuQuota() { + return cpuQuota; + } + + /** + * @see #cpuQuota + */ + public UpdateContainerCmd withCpuQuota(Integer cpuQuota) { + this.cpuQuota = cpuQuota; + return this; + } + + /** + * @see #cpusetCpus + */ + @CheckForNull + public String getCpusetCpus() { + return cpusetCpus; + } + + /** + * @see #cpusetCpus + */ + public UpdateContainerCmd withCpusetCpus(String cpusetCpus) { + this.cpusetCpus = cpusetCpus; + return this; + } + + /** + * @see #cpusetMems + */ + @CheckForNull + public String getCpusetMems() { + return cpusetMems; + } + + /** + * @see #cpusetMems + */ + public UpdateContainerCmd withCpusetMems(String cpusetMems) { + this.cpusetMems = cpusetMems; + return this; + } + + /** + * @see #cpuShares + */ + @CheckForNull + public Integer getCpuShares() { + return cpuShares; + } + + /** + * @see #cpuShares + */ + public UpdateContainerCmd withCpuShares(Integer cpuShares) { + this.cpuShares = cpuShares; + return this; + } + + /** + * @see #kernelMemory + */ + @CheckForNull + public Long getKernelMemory() { + return kernelMemory; + } + + /** + * @see #kernelMemory + */ + public UpdateContainerCmd withKernelMemory(Long kernelMemory) { + this.kernelMemory = kernelMemory; + return this; + } + + /** + * @see #memory + */ + @CheckForNull + public Long getMemory() { + return memory; + } + + /** + * @see #memory + */ + public UpdateContainerCmd withMemory(Long memory) { + this.memory = memory; + return this; + } + + /** + * @see #memoryReservation + */ + @CheckForNull + public Long getMemoryReservation() { + return memoryReservation; + } + + /** + * @see #memoryReservation + */ + public UpdateContainerCmd withMemoryReservation(Long memoryReservation) { + this.memoryReservation = memoryReservation; + return this; + } + + /** + * @see #memorySwap + */ + @CheckForNull + public Long getMemorySwap() { + return memorySwap; + } + + /** + * @see #memorySwap + */ + public UpdateContainerCmd withMemorySwap(Long memorySwap) { + this.memorySwap = memorySwap; + return this; + } + + /** + * @throws NotFoundException No such container + */ + @Override + public UpdateContainerResponse exec() throws NotFoundException { + return super.exec(); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index 2c5b2b077..4716877af 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -17,6 +17,7 @@ import javax.ws.rs.client.ClientResponseFilter; import javax.ws.rs.client.WebTarget; +import com.github.dockerjava.api.command.UpdateContainerCmd; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; @@ -410,6 +411,12 @@ public KillContainerCmd.Exec createKillContainerCmdExec() { return new KillContainerCmdExec(getBaseResource(), getDockerClientConfig()); } + + @Override + public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { + return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + @Override public RestartContainerCmd.Exec createRestartContainerCmdExec() { return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig()); diff --git a/src/main/java/com/github/dockerjava/jaxrs/UpdateContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/UpdateContainerCmdExec.java new file mode 100644 index 000000000..474d7338e --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/UpdateContainerCmdExec.java @@ -0,0 +1,36 @@ +package com.github.dockerjava.jaxrs; + +import com.github.dockerjava.api.command.UpdateContainerCmd; +import com.github.dockerjava.api.model.UpdateContainerResponse; +import com.github.dockerjava.core.DockerClientConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import static javax.ws.rs.client.Entity.entity; + +/** + * Update container settings. + * + * @author Kanstantsin Shautsou + */ +public class UpdateContainerCmdExec extends AbstrSyncDockerCmdExec + implements UpdateContainerCmd.Exec { + private static final Logger LOGGER = LoggerFactory.getLogger(UpdateContainerCmdExec.class); + + public UpdateContainerCmdExec(WebTarget baseResource, DockerClientConfig dockerClientConfig) { + super(baseResource, dockerClientConfig); + } + + @Override + protected UpdateContainerResponse execute(UpdateContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/update") + .resolveTemplate("id", command.getContainerId()); + + LOGGER.trace("POST: {}", webResource); + return webResource.request().accept(MediaType.APPLICATION_JSON) + .post(entity(command, MediaType.APPLICATION_JSON), UpdateContainerResponse.class); + } +} diff --git a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java index 1eca3a9df..1210c56bc 100644 --- a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java @@ -47,6 +47,7 @@ import com.github.dockerjava.api.command.TagImageCmd; import com.github.dockerjava.api.command.TopContainerCmd; import com.github.dockerjava.api.command.UnpauseContainerCmd; +import com.github.dockerjava.api.command.UpdateContainerCmd; import com.github.dockerjava.api.command.VersionCmd; import com.github.dockerjava.api.command.WaitContainerCmd; import com.github.dockerjava.core.DockerClientConfig; @@ -98,6 +99,7 @@ import com.github.dockerjava.netty.exec.TagImageCmdExec; import com.github.dockerjava.netty.exec.TopContainerCmdExec; import com.github.dockerjava.netty.exec.UnpauseContainerCmdExec; +import com.github.dockerjava.netty.exec.UpdateContainerCmdExec; import com.github.dockerjava.netty.exec.VersionCmdExec; import com.github.dockerjava.netty.exec.WaitContainerCmdExec; @@ -458,6 +460,11 @@ public KillContainerCmd.Exec createKillContainerCmdExec() { return new KillContainerCmdExec(getBaseResource(), getDockerClientConfig()); } + @Override + public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { + return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + @Override public RestartContainerCmd.Exec createRestartContainerCmdExec() { return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig()); diff --git a/src/main/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExec.java new file mode 100644 index 000000000..3c88dead8 --- /dev/null +++ b/src/main/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExec.java @@ -0,0 +1,34 @@ +package com.github.dockerjava.netty.exec; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.github.dockerjava.api.command.UpdateContainerCmd; +import com.github.dockerjava.api.model.UpdateContainerResponse; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.netty.MediaType; +import com.github.dockerjava.netty.WebTarget; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +/** + * @author Kanstantsin Shautsou + */ +public class UpdateContainerCmdExec extends AbstrSyncDockerCmdExec + implements UpdateContainerCmd.Exec { + private static final Logger LOGGER = LoggerFactory.getLogger(UpdateContainerCmdExec.class); + + public UpdateContainerCmdExec(WebTarget baseResource, DockerClientConfig dockerClientConfig) { + super(baseResource, dockerClientConfig); + } + + @Override + protected UpdateContainerResponse execute(UpdateContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/update") + .resolveTemplate("id", command.getContainerId()); + + LOGGER.trace("POST: {}", webResource); + return webResource.request().accept(MediaType.APPLICATION_JSON) + .post(command, new TypeReference() { + }); + } +} diff --git a/src/test/java/com/github/dockerjava/api/command/InspectExecResponseTest.java b/src/test/java/com/github/dockerjava/api/command/InspectExecResponseTest.java new file mode 100644 index 000000000..cb9264d9f --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/command/InspectExecResponseTest.java @@ -0,0 +1,56 @@ +package com.github.dockerjava.api.command; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.core.RemoteApiVersion; +import org.testng.annotations.Test; + +import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.core.IsNull.notNullValue; +import static org.hamcrest.core.IsNull.nullValue; + +/** + * @author Kanstantsin Shautsou + */ +public class InspectExecResponseTest { + + @Test + public void test_1_22_SerDer1() throws Exception { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().uncheckedSimpleType(InspectExecResponse.class); + + final InspectExecResponse execResponse = testRoundTrip(RemoteApiVersion.VERSION_1_22, + "/exec/ID/1.json", + type + ); + + assertThat(execResponse, notNullValue()); + + assertThat(execResponse.getId(), + is("1ca2ca598fab202f86dd9281196c405456069013958a475396b707e85c56473b")); + assertThat(execResponse.isRunning(), is(false)); + assertThat(execResponse.getExitCode(), is(nullValue())); + + final InspectExecResponse.ProcessConfig processConfig = execResponse.getProcessConfig(); + assertThat(processConfig, notNullValue()); + assertThat(processConfig.isTty(), is(false)); + assertThat(processConfig.getEntryPoint(), is("/bin/bash")); + assertThat(processConfig.getArguments(), hasSize(0)); + assertThat(processConfig.isPrivileged(), is(false)); + assertThat(processConfig.getUser(), isEmptyString()); + + + assertThat(execResponse.isOpenStdin(), is(false)); + assertThat(execResponse.isOpenStderr(), is(true)); + assertThat(execResponse.isOpenStdout(), is(true)); + assertThat(execResponse.getCanRemove(), is(false)); + assertThat(execResponse.getContainerID(), + is("ffa39805f089af3099e36452a985481f96170a9dff40be69d34d1722c7660d38")); + + assertThat(execResponse.getDetachKeys(), isEmptyString()); + } +} diff --git a/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java b/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java index 8f5bd64f3..db1553e33 100644 --- a/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java +++ b/src/test/java/com/github/dockerjava/api/model/AuthConfigTest.java @@ -1,25 +1,64 @@ package com.github.dockerjava.api.model; -import static org.testng.Assert.assertEquals; - -import org.testng.annotations.BeforeMethod; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.core.RemoteApiVersion; import org.testng.annotations.Test; -public class AuthConfigTest { +import java.io.IOException; - private AuthConfig authConfig; +import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.notNullValue; +import static org.testng.Assert.assertEquals; - @BeforeMethod - public void setUp() throws Exception { - authConfig = new AuthConfig() - .withEmail("foo") - .withPassword("bar") - .withRegistryAddress("baz") - .withUsername("qux"); - } +public class AuthConfigTest { @Test public void defaultServerAddress() throws Exception { assertEquals(new AuthConfig().getRegistryAddress(), "https://index.docker.io/v1/"); } + + @Test + public void serderDocs1() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().uncheckedSimpleType(AuthConfig.class); + + final AuthConfig authConfig = testRoundTrip(RemoteApiVersion.VERSION_1_22, + "/other/AuthConfig/docs1.json", + type + ); + + assertThat(authConfig, notNullValue()); + assertThat(authConfig.getUsername(), is("jdoe")); + assertThat(authConfig.getPassword(), is("secret")); + assertThat(authConfig.getEmail(), is("jdoe@acme.com")); + + final AuthConfig authConfig1 = new AuthConfig().withUsername("jdoe") + .withPassword("secret") + .withEmail("jdoe@acme.com"); + + assertThat(authConfig1, equalTo(authConfig)); + } + + @Test + public void serderDocs2() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().uncheckedSimpleType(AuthConfig.class); + + final AuthConfig authConfig = testRoundTrip(RemoteApiVersion.VERSION_1_22, + "/other/AuthConfig/docs2.json", + type + ); + + assertThat(authConfig, notNullValue()); + assertThat(authConfig.getRegistrytoken(), is("9cbaf023786cd7...")); + + + final AuthConfig authConfig1 = new AuthConfig().withRegistrytoken("9cbaf023786cd7..."); + + assertThat(authConfig1, equalTo(authConfig)); + } } diff --git a/src/test/java/com/github/dockerjava/api/model/ContainerTest.java b/src/test/java/com/github/dockerjava/api/model/ContainerTest.java new file mode 100644 index 000000000..a143e6c57 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/ContainerTest.java @@ -0,0 +1,44 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.CollectionType; +import com.github.dockerjava.core.RemoteApiVersion; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.List; + +import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.core.IsEqual.equalTo; + +/** + * @author Kanstantsin Shautsou + */ +public class ContainerTest { + + @Test + public void serderJson1() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + final CollectionType type = mapper.getTypeFactory().constructCollectionType(List.class, Container.class); + + final List containers = testRoundTrip(RemoteApiVersion.VERSION_1_22, + "containers/json/filter1.json", + type + ); + + assertThat(containers.size(), equalTo(1)); + + final Container container = containers.get(0); + + assertThat(container.getImageId(), + equalTo("sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efe7ec9")); + assertThat(container.getSizeRootFs(), equalTo(1113554L)); + + final ContainerHostConfig hostConfig = container.getHostConfig(); + assertThat(hostConfig, notNullValue()); + assertThat(hostConfig.getNetworkMode(), equalTo("default")); + } + +} diff --git a/src/test/java/com/github/dockerjava/api/model/IdentifierTest.java b/src/test/java/com/github/dockerjava/api/model/IdentifierTest.java index e8d4703db..eb458ab4c 100644 --- a/src/test/java/com/github/dockerjava/api/model/IdentifierTest.java +++ b/src/test/java/com/github/dockerjava/api/model/IdentifierTest.java @@ -1,9 +1,14 @@ package com.github.dockerjava.api.model; -import junit.framework.TestCase; -public class IdentifierTest extends TestCase { +import org.testng.annotations.Test; +import static org.testng.Assert.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +public class IdentifierTest { + + @Test public void testFromCompoundString() throws Exception { Identifier i1 = Identifier.fromCompoundString("10.0.0.1/jim"); diff --git a/src/test/java/com/github/dockerjava/api/model/InfoTest.java b/src/test/java/com/github/dockerjava/api/model/InfoTest.java new file mode 100644 index 000000000..6d4c76471 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/InfoTest.java @@ -0,0 +1,172 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.api.model.InfoRegistryConfig.IndexConfig; +import org.hamcrest.CoreMatchers; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_22; +import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasEntry; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +/** + * @author Kanstantsin Shautsou + */ +public class InfoTest { + + @Test + public void serder1Json() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().constructType(Info.class); + + final Info info = testRoundTrip(VERSION_1_22, + "info/1.json", + type + ); + + final List> driverStatus = asList( + asList("Root Dir", "/mnt/sda1/var/lib/docker/aufs"), + asList("Backing Filesystem", "extfs"), + asList("Dirs", "31"), + asList("Dirperm1 Supported", "true") + ); + + final Map> plugins = new LinkedHashMap<>(); + plugins.put("Volume", singletonList("local")); + plugins.put("Network", asList("bridge", "null", "host")); + plugins.put("Authorization", null); + + assertThat(info, notNullValue()); + assertThat(info.getArchitecture(), equalTo("x86_64")); + assertThat(info.getContainersStopped(), is(3)); + assertThat(info.getContainersPaused(), is(10)); + assertThat(info.getContainersRunning(), is(2)); + assertThat(info.getCpuCfsPeriod(), is(true)); + + // not available in this dump + assertThat(info.getCpuCfsQuota(), is(true)); + assertThat(info.getDiscoveryBackend(), nullValue()); + assertThat(info.getOomScoreAdj(), nullValue()); + + assertThat(info.getDriverStatuses(), notNullValue()); + assertThat(info.getDriverStatuses(), hasSize(4)); + assertThat(info.getDriverStatuses(), equalTo(driverStatus)); + + assertThat(info.getNGoroutines(), is(40)); + + assertThat(info.getSystemStatus(), CoreMatchers.nullValue()); + + assertThat(info.getPlugins(), equalTo(plugins)); + assertThat(info.getPlugins(), hasEntry("Volume", singletonList("local"))); + assertThat(info.getPlugins(), hasEntry("Authorization", null)); + + assertThat(info.getExperimentalBuild(), is(false)); + + assertThat(info.getHttpProxy(), isEmptyString()); + assertThat(info.getHttpsProxy(), isEmptyString()); + assertThat(info.getNoProxy(), isEmptyString()); + assertThat(info.getOomKillDisable(), is(true)); + assertThat(info.getOsType(), equalTo("linux")); + + final InfoRegistryConfig registryConfig = info.getRegistryConfig(); + assertThat(registryConfig, notNullValue()); + final List cidRs = registryConfig.getInsecureRegistryCIDRs(); + assertThat(cidRs, notNullValue()); + assertThat(cidRs, contains("127.0.0.0/8")); + + final Map indexConfigs = registryConfig.getIndexConfigs(); + assertThat(indexConfigs, notNullValue()); + final IndexConfig indexConfig = new IndexConfig().withMirrors(null).withName("docker.io") + .withSecure(true).withOfficial(true); + assertThat(indexConfigs, hasEntry("docker.io", indexConfig)); + assertThat(registryConfig.getMirrors(), nullValue()); + + assertThat(info.getSystemTime(), is("2016-02-17T14:56:35.212841831Z")); + assertThat(info.getServerVersion(), is("1.10.1")); + + assertThat(info.getCpuSet(), is(true)); + assertThat(info.getCpuShares(), is(true)); + assertThat(info.getIPv4Forwarding(), is(true)); + assertThat(info.getBridgeNfIptables(), is(true)); + assertThat(info.getBridgeNfIp6tables(), is(true)); + assertThat(info.getDebug(), is(true)); + assertThat(info.getNFd(), is(24)); + assertThat(info.getOomKillDisable(), is(true)); + assertThat(info.getLoggingDriver(), is("json-file")); + assertThat(info.getOperatingSystem(), + is("Boot2Docker 1.10.1 (TCL 6.4.1); master : b03e158 - Thu Feb 11 22:34:01 UTC 2016")); + assertThat(info.getClusterStore(), is("")); + + + final Info withInfo = new Info().withArchitecture("x86_64") + .withContainers(2) + .withContainersRunning(2) + .withContainersPaused(10) + .withContainersStopped(3) + .withImages(13) + .withId("HLN2:5SBU:SRQR:CQI6:AB52:LZZ2:DED5:REDM:BU73:JFHE:R37A:5HMX") + .withDriver("aufs") + .withDriverStatuses(driverStatus) + .withSystemStatus(null) + .withPlugins(plugins) + .withMemoryLimit(true) + .withSwapLimit(true) + .withCpuCfsPeriod(true) + .withCpuCfsQuota(true) + .withCpuShares(true) + .withCpuSet(true) + .withIPv4Forwarding(true) + .withBridgeNfIptables(true) + .withBridgeNfIp6tables(true) + .withDebug(true) + .withNFd(24) + .withOomKillDisable(true) + .withNGoroutines(40) + .withSystemTime("2016-02-17T14:56:35.212841831Z") + .withExecutionDriver("native-0.2") + .withLoggingDriver("json-file") + .withNEventsListener(0) + .withKernelVersion("4.1.17-boot2docker") + .withOperatingSystem("Boot2Docker 1.10.1 (TCL 6.4.1); master : b03e158 - Thu Feb 11 22:34:01 UTC 2016") + .withOsType("linux") + .withIndexServerAddress("https://index.docker.io/v1/") + .withRegistryConfig(registryConfig) + .withInitSha1("") + .withInitPath("/usr/local/bin/docker") + .withNCPU(1) + .withMemTotal(1044574208L) + .withDockerRootDir("/mnt/sda1/var/lib/docker") + .withHttpProxy("") + .withHttpsProxy("") + .withNoProxy("") + .withName("docker-java") + .withLabels(new String[]{"provider=virtualbox"}) + .withExperimentalBuild(false) + .withServerVersion("1.10.1") + .withClusterStore("") + .withClusterAdvertise("") + //shredinger-fields + .withDiscoveryBackend(null) + .withOomScoreAdj(null) + .withSockets(null) + ; + + assertThat(info, is(withInfo)); + } +} diff --git a/src/test/java/com/github/dockerjava/api/model/VersionTest.java b/src/test/java/com/github/dockerjava/api/model/VersionTest.java new file mode 100644 index 000000000..c32d93069 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/VersionTest.java @@ -0,0 +1,40 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.core.RemoteApiVersion; +import org.testng.annotations.Test; + +import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.notNullValue; + +/** + * @author Kanstantsin Shautsou + */ +public class VersionTest { + + @Test + public void testSerDer1() throws Exception { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().uncheckedSimpleType(Version.class); + + final Version version = testRoundTrip(RemoteApiVersion.VERSION_1_22, + "/version/1.json", + type + ); + + assertThat(version, notNullValue()); + + assertThat(version.getVersion(), is("1.10.1")); + assertThat(version.getApiVersion(), is("1.22")); + assertThat(version.getGitCommit(), is("9e83765")); + assertThat(version.getGoVersion(), is("go1.5.3")); + assertThat(version.getOperatingSystem(), is("linux")); + assertThat(version.getArch(), is("amd64")); + assertThat(version.getKernelVersion(), is("4.1.17-boot2docker")); + assertThat(version.getBuildTime(), is("2016-02-11T20:39:58.688092588+00:00")); + } + +} diff --git a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java index 8ddc481b3..1375cc9b6 100644 --- a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java +++ b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.List; +import com.github.dockerjava.core.RemoteApiVersion; import org.apache.commons.io.IOUtils; import org.apache.commons.io.LineIterator; import org.apache.commons.lang.StringUtils; @@ -39,7 +40,7 @@ public abstract class AbstractDockerClientTest extends Assert { public static final Logger LOG = LoggerFactory.getLogger(AbstractDockerClientTest.class); - private String apiVersion = "1.21"; + private RemoteApiVersion apiVersion = RemoteApiVersion.VERSION_1_22; protected DockerClient dockerClient; @@ -54,7 +55,9 @@ public void beforeTest() throws Exception { LOG.info("======================= BEFORETEST ======================="); LOG.info("Connecting to Docker server"); - dockerClient = DockerClientBuilder.getInstance(config()).withDockerCmdExecFactory(dockerCmdExecFactory).build(); + dockerClient = DockerClientBuilder.getInstance(config()) + .withDockerCmdExecFactory(dockerCmdExecFactory) + .build(); try { dockerClient.inspectImageCmd("busybox").exec(); diff --git a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java index cf49a669e..b2b86601c 100644 --- a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java +++ b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java @@ -235,6 +235,11 @@ public KillContainerCmd.Exec createKillContainerCmdExec() { return delegate.createKillContainerCmdExec(); } + @Override + public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { + return delegate.createUpdateContainerCmdExec(); + } + @Override public RestartContainerCmd.Exec createRestartContainerCmdExec() { return delegate.createRestartContainerCmdExec(); 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 dba1a1a34..7800a8c12 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -1,33 +1,5 @@ package com.github.dockerjava.core.command; -import static com.github.dockerjava.api.model.Capability.MKNOD; -import static com.github.dockerjava.api.model.Capability.NET_ADMIN; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasItemInArray; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.isEmptyString; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.startsWith; - -import java.lang.reflect.Method; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.exception.ConflictException; @@ -35,6 +7,7 @@ import com.github.dockerjava.api.model.Bind; import com.github.dockerjava.api.model.Device; import com.github.dockerjava.api.model.ExposedPort; +import com.github.dockerjava.api.model.Frame; import com.github.dockerjava.api.model.Link; import com.github.dockerjava.api.model.LogConfig; import com.github.dockerjava.api.model.Ports; @@ -43,9 +16,38 @@ import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.api.model.VolumesFrom; import com.github.dockerjava.client.AbstractDockerClientTest; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.TimeUnit; + +import static com.github.dockerjava.api.model.Capability.MKNOD; +import static com.github.dockerjava.api.model.Capability.NET_ADMIN; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItemInArray; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; @Test(groups = "integration") public class CreateContainerCmdImplTest extends AbstractDockerClientTest { + public static final String BUSYBOX_IMAGE = "busybox"; @BeforeTest public void beforeTest() throws Exception { @@ -72,7 +74,7 @@ public void createContainerWithExistingName() throws DockerException { String containerName = "generated_" + new SecureRandom().nextInt(); - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("env") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("env") .withName(containerName).exec(); LOG.info("Created container {}", container.toString()); @@ -80,7 +82,7 @@ public void createContainerWithExistingName() throws DockerException { assertThat(container.getId(), not(isEmptyString())); try { - dockerClient.createContainerCmd("busybox").withCmd("env").withName(containerName).exec(); + dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("env").withName(containerName).exec(); fail("expected ConflictException"); } catch (ConflictException e) { } @@ -91,7 +93,7 @@ public void createContainerWithVolume() throws DockerException { Volume volume = new Volume("/var/log"); - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withVolumes(volume) + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withVolumes(volume) .withCmd("true").exec(); LOG.info("Created container {}", container.toString()); @@ -114,7 +116,7 @@ public void createContainerWithReadOnlyVolume() throws DockerException { Volume volume = new Volume("/srv/test"); - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withVolumes(volume) + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withVolumes(volume) .withCmd("true").exec(); LOG.info("Created container {}", container.toString()); @@ -144,7 +146,7 @@ public void createContainerWithVolumesFrom() throws DockerException { Bind bind2 = new Bind("/src/webapp2", volume2); // create a running container with bind mounts - CreateContainerResponse container1 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + CreateContainerResponse container1 = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("sleep", "9999") .withName(container1Name) .withBinds(bind1, bind2).exec(); LOG.info("Created container1 {}", container1.toString()); @@ -157,7 +159,7 @@ public void createContainerWithVolumesFrom() throws DockerException { assertThat(inspectContainerResponse1, mountedVolumes(containsInAnyOrder(volume1, volume2))); // create a second container with volumes from first container - CreateContainerResponse container2 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + CreateContainerResponse container2 = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("sleep", "9999") .withVolumesFrom(new VolumesFrom(container1Name)).exec(); LOG.info("Created container2 {}", container2.toString()); @@ -187,7 +189,7 @@ public void createContainerWithVolumesFrom() throws DockerException { @Test public void createContainerWithEnv() throws Exception { - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withEnv("VARIABLE=success") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withEnv("VARIABLE=success") .withCmd("env").exec(); LOG.info("Created container {}", container.toString()); @@ -206,7 +208,7 @@ public void createContainerWithEnv() throws Exception { @Test public void createContainerWithHostname() throws Exception { - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withHostName("docker-java") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withHostName("docker-java") .withCmd("env").exec(); LOG.info("Created container {}", container.toString()); @@ -225,7 +227,7 @@ public void createContainerWithHostname() throws Exception { @Test public void createContainerWithName() throws DockerException { - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withName("container") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container") .withCmd("env").exec(); LOG.info("Created container {}", container.toString()); @@ -237,7 +239,7 @@ public void createContainerWithName() throws DockerException { assertThat(inspectContainerResponse.getName(), equalTo("/container")); try { - dockerClient.createContainerCmd("busybox").withName("container").withCmd("env").exec(); + dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container").withCmd("env").exec(); fail("Expected ConflictException"); } catch (ConflictException e) { } @@ -247,7 +249,7 @@ public void createContainerWithName() throws DockerException { @Test public void createContainerWithLink() throws DockerException { - CreateContainerResponse container1 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + CreateContainerResponse container1 = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("sleep", "9999") .withName("container1").exec(); LOG.info("Created container1 {}", container1.toString()); assertThat(container1.getId(), not(isEmptyString())); @@ -259,21 +261,21 @@ public void createContainerWithLink() throws DockerException { LOG.info("Container1 Inspect: {}", inspectContainerResponse1.toString()); assertThat(inspectContainerResponse1.getState().getRunning(), is(true)); - CreateContainerResponse container2 = dockerClient.createContainerCmd("busybox").withName("container2") + CreateContainerResponse container2 = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container2") .withCmd("env").withLinks(new Link("container1", "container1Link")).exec(); LOG.info("Created container {}", container2.toString()); assertThat(container2.getId(), not(isEmptyString())); InspectContainerResponse inspectContainerResponse2 = dockerClient.inspectContainerCmd(container2.getId()) .exec(); - assertThat(inspectContainerResponse2.getHostConfig().getLinks(), equalTo(new Link[] {new Link("container1", + assertThat(inspectContainerResponse2.getHostConfig().getLinks(), equalTo(new Link[]{new Link("container1", "container1Link")})); } @Test public void createContainerWithCapAddAndCapDrop() throws DockerException { - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCapAdd(NET_ADMIN) + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCapAdd(NET_ADMIN) .withCapDrop(MKNOD).exec(); LOG.info("Created container {}", container.toString()); @@ -293,7 +295,7 @@ public void createContainerWithDns() throws DockerException { String aDnsServer = "8.8.8.8"; String anotherDnsServer = "8.8.4.4"; - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("true") .withDns(aDnsServer, anotherDnsServer).exec(); LOG.info("Created container {}", container.toString()); @@ -309,7 +311,7 @@ public void createContainerWithDns() throws DockerException { @Test public void createContainerWithEntrypoint() throws DockerException { - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withName("container") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container") .withEntrypoint("sleep", "9999").exec(); LOG.info("Created container {}", container.toString()); @@ -327,7 +329,7 @@ public void createContainerWithExtraHosts() throws DockerException { String[] extraHosts = {"dockerhost:127.0.0.1", "otherhost:10.0.0.1"}; - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withName("container") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container") .withExtraHosts(extraHosts).exec(); LOG.info("Created container {}", container.toString()); @@ -343,7 +345,7 @@ public void createContainerWithExtraHosts() throws DockerException { @Test public void createContainerWithDevices() throws DockerException { - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("sleep", "9999") .withDevices(new Device("rwm", "/dev/nulo", "/dev/zero")).exec(); LOG.info("Created container {}", container.toString()); @@ -367,7 +369,7 @@ public void createContainerWithPortBindings() throws DockerException { portBindings.bind(tcp23, Ports.binding(11023)); portBindings.bind(tcp23, Ports.binding(11024)); - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); LOG.info("Created container {}", container.toString()); @@ -392,7 +394,7 @@ public void createContainerWithPortBindings() throws DockerException { @Test public void createContainerWithLinking() throws DockerException { - CreateContainerResponse container1 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + CreateContainerResponse container1 = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("sleep", "9999") .withName("container1").exec(); LOG.info("Created container1 {}", container1.toString()); @@ -416,7 +418,7 @@ public void createContainerWithLinking() throws DockerException { assertThat(inspectContainerResponse1.getState().getExitCode(), is(equalTo(0))); } - CreateContainerResponse container2 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + CreateContainerResponse container2 = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("sleep", "9999") .withName("container2").withLinks(new Link("container1", "container1Link")).exec(); LOG.info("Created container2 {}", container2.toString()); @@ -430,7 +432,7 @@ public void createContainerWithLinking() throws DockerException { assertThat(inspectContainerResponse2.getId(), not(isEmptyString())); assertThat(inspectContainerResponse2.getHostConfig(), is(notNullValue())); assertThat(inspectContainerResponse2.getHostConfig().getLinks(), is(notNullValue())); - assertThat(inspectContainerResponse2.getHostConfig().getLinks(), equalTo(new Link[] {new Link("container1", + assertThat(inspectContainerResponse2.getHostConfig().getLinks(), equalTo(new Link[]{new Link("container1", "container1Link")})); assertThat(inspectContainerResponse2.getId(), startsWith(container2.getId())); assertThat(inspectContainerResponse2.getName(), equalTo("/container2")); @@ -443,7 +445,7 @@ public void createContainerWithRestartPolicy() throws DockerException { RestartPolicy restartPolicy = RestartPolicy.onFailureRestart(5); - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("sleep", "9999") .withRestartPolicy(restartPolicy).exec(); LOG.info("Created container {}", container.toString()); @@ -458,7 +460,7 @@ public void createContainerWithRestartPolicy() throws DockerException { @Test public void createContainerWithPidMode() throws DockerException { - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("true") .withPidMode("host").exec(); LOG.info("Created container {}", container.toString()); @@ -479,7 +481,7 @@ public void createContainerWithPidMode() throws DockerException { @Test public void createContainerWithNetworkMode() throws DockerException { - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("true") .withNetworkMode("host").exec(); LOG.info("Created container {}", container.toString()); @@ -494,7 +496,7 @@ public void createContainerWithNetworkMode() throws DockerException { @Test public void createContainerWithMacAddress() throws DockerException { - CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE) .withMacAddress("00:80:41:ae:fd:7e").withCmd("true").exec(); LOG.info("Created container {}", container.toString()); @@ -511,7 +513,7 @@ public void createContainerWithULimits() throws DockerException { Ulimit[] ulimits = {new Ulimit("nproc", 709, 1026), new Ulimit("nofile", 1024, 4096)}; - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withName("container") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container") .withUlimits(ulimits).exec(); LOG.info("Created container {}", container.toString()); @@ -532,7 +534,7 @@ public void createContainerWithLabels() throws DockerException { labels.put("com.github.dockerjava.null", null); labels.put("com.github.dockerjava.Boolean", "true"); - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("sleep", "9999") .withLabels(labels).exec(); LOG.info("Created container {}", container.toString()); @@ -550,7 +552,7 @@ public void createContainerWithLabels() throws DockerException { public void createContainerWithLogConfig() throws DockerException { LogConfig logConfig = new LogConfig(LogConfig.LoggingType.NONE, null); - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withLogConfig(logConfig).exec(); + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withLogConfig(logConfig).exec(); LOG.info("Created container {}", container.toString()); @@ -561,4 +563,58 @@ public void createContainerWithLogConfig() throws DockerException { // null becomes empty string assertEquals(inspectContainerResponse.getHostConfig().getLogConfig().type, logConfig.type); } + + /** + * https://github.com/calavera/docker/blob/3781cde61ff10b1d9114ae5b4c5c1d1b2c20a1ee/integration-cli/docker_cli_run_unix_test.go#L319-L333 + */ + @Test + public void testWithStopSignal() throws Exception { + Integer signal = 10; // SIGUSR1 in busybox + + CreateContainerResponse resp = dockerClient.createContainerCmd(BUSYBOX_IMAGE) + .withCmd("/bin/sh", "-c", "trap 'echo \"exit trapped 10\"; exit 10' USR1; while true; do sleep 1; done") + .withAttachStdin(true) + .withTty(true) + .withStopSignal(signal.toString()) + .exec(); + final String containerId = resp.getId(); + assertThat(containerId, not(isEmptyString())); + dockerClient.startContainerCmd(containerId).exec(); + + InspectContainerResponse inspect = dockerClient.inspectContainerCmd(containerId).exec(); + assertThat(inspect.getState().getRunning(), is(true)); + + dockerClient.stopContainerCmd(containerId).exec(); + Thread.sleep(TimeUnit.SECONDS.toMillis(3)); + + inspect = dockerClient.inspectContainerCmd(containerId).exec(); + assertThat(inspect.getState().getRunning(), is(false)); + assertThat(inspect.getState().getExitCode(), is(signal)); + + StringBuilder stringBuilder = new StringBuilder(); + final StringBuilderLogReader callback = new StringBuilderLogReader(stringBuilder); + dockerClient.logContainerCmd(containerId) + .withStdErr(true) + .withStdOut(true) + .withTailAll() + .exec(callback) + .awaitCompletion(); + + String log = callback.builder.toString(); + assertThat(log, is("exit trapped 10")); + } + + private static class StringBuilderLogReader extends LogContainerResultCallback { + public StringBuilder builder; + + public StringBuilderLogReader(StringBuilder builder) { + this.builder = builder; + } + + @Override + public void onNext(Frame item) { + builder.append(new String(item.getPayload()).trim()); + super.onNext(item); + } + } } diff --git a/src/test/java/com/github/dockerjava/core/command/InspectExecCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/InspectExecCmdImplTest.java index f40ee7e69..a21a312aa 100644 --- a/src/test/java/com/github/dockerjava/core/command/InspectExecCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/InspectExecCmdImplTest.java @@ -1,14 +1,19 @@ package com.github.dockerjava.core.command; +import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_22; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; import java.io.IOException; import java.lang.reflect.Method; import java.security.SecureRandom; +import com.github.dockerjava.core.RemoteApiVersion; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -97,6 +102,8 @@ public void inspectExec() throws Exception { @Test(groups = "ignoreInCircleCi") public void inspectExecNetworkSettings() throws IOException { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + String containerName = "generated_" + new SecureRandom().nextInt(); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") @@ -112,8 +119,19 @@ public void inspectExecNetworkSettings() throws IOException { assertThat(exec.getId(), not(isEmptyString())); InspectExecResponse inspectExecResponse = dockerClient.inspectExecCmd(exec.getId()).exec(); - assertThat(inspectExecResponse.getExitCode(), is(0)); - - assertNotNull(inspectExecResponse.getContainer().getNetworkSettings().getNetworks().get("bridge")); + assertThat(inspectExecResponse.getExitCode(), is(nullValue())); + assertThat(inspectExecResponse.isOpenStdin(), is(false)); + assertThat(inspectExecResponse.isOpenStdout(), is(true)); + assertThat(inspectExecResponse.isRunning(), is(false)); + assertThat(inspectExecResponse.getCanRemove(), is(false)); + assertThat(inspectExecResponse.getContainerID(), is(container.getId())); + + final InspectExecResponse.Container inspectContainer = inspectExecResponse.getContainer(); + if (apiVersion.isGreaterOrEqual(VERSION_1_22)) { + assertThat(inspectContainer, nullValue()); + } else { + assertThat(inspectContainer, notNullValue()); + assertNotNull(inspectContainer.getNetworkSettings().getNetworks().get("bridge")); + } } } diff --git a/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java index 0718c7700..913ed9474 100644 --- a/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java @@ -1,5 +1,7 @@ package com.github.dockerjava.core.command; +import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_22; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -8,6 +10,7 @@ import java.lang.reflect.Method; +import com.github.dockerjava.core.RemoteApiVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.ITestResult; @@ -50,6 +53,7 @@ public void afterMethod(ITestResult result) { @Test(groups = "ignoreInCircleCi") public void testStopContainer() throws DockerException { + final RemoteApiVersion apiVersion = getVersion(dockerClient); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); LOG.info("Created container: {}", container.toString()); @@ -63,7 +67,13 @@ public void testStopContainer() throws DockerException { LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false))); - assertThat(inspectContainerResponse.getState().getExitCode(), not(equalTo(0))); + + final Integer exitCode = inspectContainerResponse.getState().getExitCode(); + if (apiVersion.equals(VERSION_1_22)) { + assertThat(exitCode, is(0)); + } else { + assertThat(exitCode, not(0)); + } } @Test diff --git a/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java new file mode 100644 index 000000000..76708f889 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java @@ -0,0 +1,114 @@ +package com.github.dockerjava.core.command; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.exception.DockerException; +import com.github.dockerjava.api.model.HostConfig; +import com.github.dockerjava.api.model.UpdateContainerResponse; +import com.github.dockerjava.client.AbstractDockerClientTest; +import com.github.dockerjava.core.RemoteApiVersion; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.lang.reflect.Method; + +import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; +import static org.hamcrest.core.IsNull.notNullValue; + +/** + * @author Kanstantsin Shautsou + */ +@Test(groups = "integration") +public class UpdateContainerCmdImplTest extends AbstractDockerClientTest { + + public static final String BUSYBOX_IMAGE = "busybox"; + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test(groups = "ignoreInCircleCi") + public void updateContainer() throws DockerException, IOException { + CreateContainerResponse response = dockerClient.createContainerCmd(BUSYBOX_IMAGE) + .withCmd("sleep", "9999") + .exec(); + String containerId = response.getId(); + dockerClient.startContainerCmd(containerId).exec(); + + InspectContainerResponse inspectBefore = dockerClient.inspectContainerCmd(containerId).exec(); + final HostConfig beforeHostConfig = inspectBefore.getHostConfig(); + + final UpdateContainerResponse updateResponse = dockerClient.updateContainerCmd(containerId) + .withBlkioWeight(300) + .withCpuShares(512) + .withCpuPeriod(100000) + .withCpuQuota(50000) +// .withCpusetCpus("0") // depends on env + .withCpusetMems("0") + .withMemory(314572800L) + .withMemorySwap(514288000L) + .withMemoryReservation(209715200L) +// .withKernelMemory(52428800) Can not update kernel memory to a running container, please stop it first. + .exec(); + + // docker toolbox 1.10.1 + assertThat(updateResponse.getWarnings(), hasSize(1)); + assertThat(updateResponse.getWarnings().get(0), + is("Your kernel does not support Block I/O weight. Weight discarded.")); + + InspectContainerResponse inspectAfter = dockerClient.inspectContainerCmd(containerId).exec(); + final HostConfig afterHostConfig = inspectAfter.getHostConfig(); + + assertThat(afterHostConfig.getMemory(), + is(314572800L)); + +// assertThat(afterHostConfig.getBlkioWeight(), is(300)); + assertThat(afterHostConfig.getCpuShares(), is(512)); + assertThat(afterHostConfig.getCpuPeriod(), is(100000)); + assertThat(afterHostConfig.getCpuQuota(), is(50000)); + assertThat(afterHostConfig.getCpusetMems(), is("0")); + + assertThat(afterHostConfig.getMemoryReservation(), is(209715200L)); + assertThat(afterHostConfig.getMemorySwap(), is(514288000L)); + + } + + @Test(enabled = false, description = "impossible to serder because model bundled in cmd") + public void serDerDocs1() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().uncheckedSimpleType(UpdateContainerCmdImpl.class); + + final UpdateContainerCmdImpl upd = testRoundTrip(RemoteApiVersion.VERSION_1_22, + "/containers/container/update/docs.json", + type + ); + + assertThat(upd, notNullValue()); + } +} diff --git a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileStatementAddTest.java b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileStatementAddTest.java index 47d570d8c..102b113e3 100644 --- a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileStatementAddTest.java +++ b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileStatementAddTest.java @@ -2,7 +2,6 @@ import com.github.dockerjava.api.exception.DockerClientException; import com.google.common.base.Optional; -import junit.framework.TestCase; import org.hamcrest.Matcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -14,9 +13,9 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.is; -public class DockerfileStatementAddTest extends TestCase { +public class DockerfileStatementAddTest { - private static final Logger log = LoggerFactory.getLogger(DockerfileStatementAddTest.class); + private static final Logger LOG = LoggerFactory.getLogger(DockerfileStatementAddTest.class); @DataProvider(name = "valid scenarios") public Object[][] validScenarios() { diff --git a/src/test/java/com/github/dockerjava/netty/exec/InspectExecCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/InspectExecCmdExecTest.java index ecf5ed568..3d2b55e24 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/InspectExecCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/InspectExecCmdExecTest.java @@ -1,14 +1,19 @@ package com.github.dockerjava.netty.exec; +import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_22; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; import java.io.IOException; import java.lang.reflect.Method; import java.security.SecureRandom; +import com.github.dockerjava.core.RemoteApiVersion; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -99,6 +104,7 @@ public void inspectExec() throws Exception { @Test(groups = "ignoreInCircleCi") public void inspectExecNetworkSettings() throws IOException { + final RemoteApiVersion apiVersion = getVersion(dockerClient); String containerName = "generated_" + new SecureRandom().nextInt(); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") @@ -114,8 +120,19 @@ public void inspectExecNetworkSettings() throws IOException { assertThat(exec.getId(), not(isEmptyString())); InspectExecResponse inspectExecResponse = dockerClient.inspectExecCmd(exec.getId()).exec(); - assertThat(inspectExecResponse.getExitCode(), is(0)); - - assertNotNull(inspectExecResponse.getContainer().getNetworkSettings().getNetworks().get("bridge")); + assertThat(inspectExecResponse.getExitCode(), is(nullValue())); + assertThat(inspectExecResponse.isOpenStdin(), is(false)); + assertThat(inspectExecResponse.isOpenStdout(), is(true)); + assertThat(inspectExecResponse.isRunning(), is(false)); + assertThat(inspectExecResponse.getCanRemove(), is(false)); + assertThat(inspectExecResponse.getContainerID(), is(container.getId())); + + final InspectExecResponse.Container inspectContainer = inspectExecResponse.getContainer(); + if (apiVersion.isGreaterOrEqual(VERSION_1_22)) { + assertThat(inspectContainer, nullValue()); + } else { + assertThat(inspectContainer, notNullValue()); + assertNotNull(inspectContainer.getNetworkSettings().getNetworks().get("bridge")); + } } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java index 01bf74458..b3f545a42 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java @@ -1,5 +1,7 @@ package com.github.dockerjava.netty.exec; +import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_22; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -8,6 +10,7 @@ import java.lang.reflect.Method; +import com.github.dockerjava.core.RemoteApiVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.ITestResult; @@ -50,6 +53,7 @@ public void afterMethod(ITestResult result) { @Test(groups = "ignoreInCircleCi") public void testStopContainer() throws DockerException { + final RemoteApiVersion apiVersion = getVersion(dockerClient); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); LOG.info("Created container: {}", container.toString()); @@ -63,7 +67,13 @@ public void testStopContainer() throws DockerException { LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false))); - assertThat(inspectContainerResponse.getState().getExitCode(), not(equalTo(0))); + + final Integer exitCode = inspectContainerResponse.getState().getExitCode(); + if (apiVersion.equals(VERSION_1_22)) { + assertThat(exitCode, is(0)); + } else { + assertThat(exitCode, not(0)); + } } @Test diff --git a/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java new file mode 100644 index 000000000..94c8242e5 --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java @@ -0,0 +1,98 @@ +package com.github.dockerjava.netty.exec; + +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.exception.DockerException; +import com.github.dockerjava.api.model.HostConfig; +import com.github.dockerjava.api.model.UpdateContainerResponse; +import com.github.dockerjava.netty.AbstractNettyDockerClientTest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.lang.reflect.Method; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.collection.IsCollectionWithSize.hasSize; + +/** + * @author Kanstantsin Shautsou + */ +@Test(groups = "integration") +public class UpdateContainerCmdExecTest extends AbstractNettyDockerClientTest { + public static final Logger LOG = LoggerFactory.getLogger(UpdateContainerCmdExecTest.class); + private static final String BUSYBOX_IMAGE = "busybox"; + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void updateContainer() throws DockerException, IOException { + CreateContainerResponse response = dockerClient.createContainerCmd(BUSYBOX_IMAGE) + .withCmd("sleep", "9999") + .exec(); + String containerId = response.getId(); + dockerClient.startContainerCmd(containerId).exec(); + + InspectContainerResponse inspectBefore = dockerClient.inspectContainerCmd(containerId).exec(); + final HostConfig beforeHostConfig = inspectBefore.getHostConfig(); + + final UpdateContainerResponse updateResponse = dockerClient.updateContainerCmd(containerId) + .withBlkioWeight(300) + .withCpuShares(512) + .withCpuPeriod(100000) + .withCpuQuota(50000) +// .withCpusetCpus("0") // depends on env + .withCpusetMems("0") + .withMemory(314572800L) + .withMemorySwap(514288000L) + .withMemoryReservation(209715200L) +// .withKernelMemory(52428800) Can not update kernel memory to a running container, please stop it first. + .exec(); + + // docker toolbox 1.10.1 + assertThat(updateResponse.getWarnings(), hasSize(1)); + assertThat(updateResponse.getWarnings().get(0), + is("Your kernel does not support Block I/O weight. Weight discarded.")); + + InspectContainerResponse inspectAfter = dockerClient.inspectContainerCmd(containerId).exec(); + final HostConfig afterHostConfig = inspectAfter.getHostConfig(); + + assertThat(afterHostConfig.getMemory(), + is(314572800L)); + +// assertThat(afterHostConfig.getBlkioWeight(), is(300)); + assertThat(afterHostConfig.getCpuShares(), is(512)); + assertThat(afterHostConfig.getCpuPeriod(), is(100000)); + assertThat(afterHostConfig.getCpuQuota(), is(50000)); + assertThat(afterHostConfig.getCpusetMems(), is("0")); + + assertThat(afterHostConfig.getMemoryReservation(), is(209715200L)); + assertThat(afterHostConfig.getMemorySwap(), is(514288000L)); + } + +} diff --git a/src/test/java/com/github/dockerjava/test/serdes/JSONSamples.java b/src/test/java/com/github/dockerjava/test/serdes/JSONSamples.java new file mode 100644 index 000000000..1b5337aa6 --- /dev/null +++ b/src/test/java/com/github/dockerjava/test/serdes/JSONSamples.java @@ -0,0 +1,66 @@ +package com.github.dockerjava.test.serdes; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.core.RemoteApiVersion; +import org.apache.commons.io.FileUtils; + +import java.io.File; +import java.io.IOException; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotSame; + +/** + * Samples helper + * + * @author Kanstantsin Shautsou + */ +public class JSONSamples { + + /** + * Access to samples storage. + * + * @param version docker version of json sample + * @param context path to file for interested dump + * @return Content of JSON sample + * @throws IOException + */ + public static String getSampleContent(RemoteApiVersion version, String context) throws IOException { + File resource = new File("src/test/resources/samples/" + version.getVersion() + "/" + context); + return FileUtils.readFileToString(resource, "UTF-8"); + } + + public static TClass testRoundTrip(RemoteApiVersion version, String context, + JavaType type) throws IOException { + ObjectMapper mapper = new ObjectMapper(); + final TClass tObject = mapper.readValue(getSampleContent(version, context), type); + return testRoundTrip(tObject, type); + } + + /** + * Same as {@link JSONTestHelper#testRoundTrip(java.lang.Object, java.lang.Class)} + * but via {@link TypeReference} + */ + public static TClass testRoundTrip(TClass item, JavaType type) + throws IOException, AssertionError { + ObjectMapper mapper = new ObjectMapper(); + + String serialized1 = mapper.writeValueAsString(item); + JsonNode json1 = mapper.readTree(serialized1); + + TClass deserialized1 = mapper.readValue(serialized1, type); + String serialized2 = mapper.writeValueAsString(deserialized1); + + JsonNode json2 = mapper.readTree(serialized2); + TClass deserialized2 = mapper.readValue(serialized2, type); + + assertEquals(json2, json1, "JSONs must be equal after the second roundtrip"); + assertEquals(deserialized2, deserialized2, "Objects must be equal after the second roundtrip"); + assertNotSame(deserialized2, deserialized1, "Objects must be not the same"); + + return deserialized2; + } +} diff --git a/src/test/java/com/github/dockerjava/test/serdes/JSONTestHelper.java b/src/test/java/com/github/dockerjava/test/serdes/JSONTestHelper.java index 8cacb6c5e..99a90f0af 100644 --- a/src/test/java/com/github/dockerjava/test/serdes/JSONTestHelper.java +++ b/src/test/java/com/github/dockerjava/test/serdes/JSONTestHelper.java @@ -29,10 +29,6 @@ /** * Provides helper methods for serialization-deserialization tests. * - *

- * TODO: Create helper that loads json files from simple folder structure using a type, version number, and name. - *

- * * @author Oleg Nenashev */ public class JSONTestHelper { diff --git a/src/test/resources/samples/1.22/containers/container/json/1.json b/src/test/resources/samples/1.22/containers/container/json/1.json new file mode 100644 index 000000000..6cb71cc82 --- /dev/null +++ b/src/test/resources/samples/1.22/containers/container/json/1.json @@ -0,0 +1,151 @@ +{ + "Id": "095351afe7b4995dfb3e965f9cfd3a07b1fe69198c50085a2cb7c2b5a5c9b62f", + "Created": "2016-02-16T22:40:51.465045919Z", + "Path": "echo", + "Args": [], + "State": { + "Status": "created", + "Running": false, + "Paused": false, + "Restarting": false, + "OOMKilled": false, + "Dead": false, + "Pid": 0, + "ExitCode": 0, + "Error": "", + "StartedAt": "0001-01-01T00:00:00Z", + "FinishedAt": "0001-01-01T00:00:00Z" + }, + "Image": "sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efe7ec9", + "ResolvConfPath": "", + "HostnamePath": "", + "HostsPath": "", + "LogPath": "", + "Name": "/drunk_golick", + "RestartCount": 0, + "Driver": "aufs", + "MountLabel": "", + "ProcessLabel": "", + "AppArmorProfile": "", + "ExecIDs": null, + "HostConfig": { + "Binds": null, + "ContainerIDFile": "", + "LogConfig": { + "Type": "json-file", + "Config": {} + }, + "NetworkMode": "default", + "PortBindings": null, + "RestartPolicy": { + "Name": "", + "MaximumRetryCount": 0 + }, + "VolumeDriver": "", + "VolumesFrom": null, + "CapAdd": null, + "CapDrop": null, + "Dns": null, + "DnsOptions": null, + "DnsSearch": null, + "ExtraHosts": null, + "GroupAdd": null, + "IpcMode": "", + "Links": null, + "OomScoreAdj": 0, + "PidMode": "", + "Privileged": false, + "PublishAllPorts": false, + "ReadonlyRootfs": false, + "SecurityOpt": null, + "UTSMode": "", + "ShmSize": 67108864, + "ConsoleSize": [ + 0, + 0 + ], + "Isolation": "", + "CpuShares": 0, + "CgroupParent": "", + "BlkioWeight": 0, + "BlkioWeightDevice": null, + "BlkioDeviceReadBps": null, + "BlkioDeviceWriteBps": null, + "BlkioDeviceReadIOps": null, + "BlkioDeviceWriteIOps": null, + "CpuPeriod": 0, + "CpuQuota": 0, + "CpusetCpus": "", + "CpusetMems": "", + "Devices": null, + "KernelMemory": 0, + "Memory": 0, + "MemoryReservation": 0, + "MemorySwap": 0, + "MemorySwappiness": -1, + "OomKillDisable": false, + "PidsLimit": 0, + "Ulimits": null + }, + "GraphDriver": { + "Name": "aufs", + "Data": null + }, + "Mounts": [], + "Config": { + "Hostname": "095351afe7b4", + "Domainname": "", + "User": "", + "AttachStdin": false, + "AttachStdout": false, + "AttachStderr": false, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Env": null, + "Cmd": [ + "echo" + ], + "Image": "busybox", + "Volumes": null, + "WorkingDir": "", + "Entrypoint": null, + "OnBuild": null, + "Labels": {} + }, + "NetworkSettings": { + "Bridge": "", + "SandboxID": "", + "HairpinMode": false, + "LinkLocalIPv6Address": "", + "LinkLocalIPv6PrefixLen": 0, + "Ports": null, + "SandboxKey": "", + "SecondaryIPAddresses": null, + "SecondaryIPv6Addresses": null, + "EndpointID": "", + "Gateway": "", + "GlobalIPv6Address": "", + "GlobalIPv6PrefixLen": 0, + "IPAddress": "", + "IPPrefixLen": 0, + "IPv6Gateway": "", + "MacAddress": "", + "Networks": { + "bridge": { + "IPAMConfig": null, + "Links": null, + "Aliases": null, + "NetworkID": "", + "EndpointID": "", + "Gateway": "", + "IPAddress": "", + "IPPrefixLen": 0, + "IPv6Gateway": "", + "GlobalIPv6Address": "", + "GlobalIPv6PrefixLen": 0, + "MacAddress": "" + } + } + } +} diff --git a/src/test/resources/samples/1.22/containers/container/update/docs.json b/src/test/resources/samples/1.22/containers/container/update/docs.json new file mode 100644 index 000000000..9d26fcb2f --- /dev/null +++ b/src/test/resources/samples/1.22/containers/container/update/docs.json @@ -0,0 +1,12 @@ +{ + "BlkioWeight": 300, + "CpuShares": 512, + "CpuPeriod": 100000, + "CpuQuota": 50000, + "CpusetCpus": "0,1", + "CpusetMems": "0", + "Memory": 314572800, + "MemorySwap": 514288000, + "MemoryReservation": 209715200, + "KernelMemory": 52428800 +} diff --git a/src/test/resources/samples/1.22/containers/create/docs.json b/src/test/resources/samples/1.22/containers/create/docs.json new file mode 100644 index 000000000..4bafc3cb5 --- /dev/null +++ b/src/test/resources/samples/1.22/containers/create/docs.json @@ -0,0 +1,131 @@ +{ + "Hostname": "", + "Domainname": "", + "User": "", + "AttachStdin": false, + "AttachStdout": true, + "AttachStderr": true, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Env": [ + "FOO=bar", + "BAZ=quux" + ], + "Cmd": [ + "date" + ], + "Entrypoint": "", + "Image": "ubuntu", + "Labels": { + "com.example.vendor": "Acme", + "com.example.license": "GPL", + "com.example.version": "1.0" + }, + "Mounts": [ + { + "Name": "fac362...80535", + "Source": "/data", + "Destination": "/data", + "Driver": "local", + "Mode": "ro,Z", + "RW": false, + "Propagation": "" + } + ], + "WorkingDir": "", + "NetworkDisabled": false, + "MacAddress": "12:34:56:78:9a:bc", + "ExposedPorts": { + "22/tcp": {} + }, + "StopSignal": "SIGTERM", + "HostConfig": { + "Binds": [ + "/tmp:/tmp" + ], + "Links": [ + "redis3:redis" + ], + "Memory": 0, + "MemorySwap": 0, + "MemoryReservation": 0, + "KernelMemory": 0, + "CpuShares": 512, + "CpuPeriod": 100000, + "CpuQuota": 50000, + "CpusetCpus": "0,1", + "CpusetMems": "0,1", + "BlkioWeight": 300, + "BlkioWeightDevice": [ + {} + ], + "BlkioDeviceReadBps": [ + {} + ], + "BlkioDeviceReadIOps": [ + {} + ], + "BlkioDeviceWriteBps": [ + {} + ], + "BlkioDeviceWriteIOps": [ + {} + ], + "MemorySwappiness": 60, + "OomKillDisable": false, + "OomScoreAdj": 500, + "PortBindings": { + "22/tcp": [ + { + "HostPort": "11022" + } + ] + }, + "PublishAllPorts": false, + "Privileged": false, + "ReadonlyRootfs": false, + "Dns": [ + "8.8.8.8" + ], + "DnsOptions": [ + "" + ], + "DnsSearch": [ + "" + ], + "ExtraHosts": null, + "VolumesFrom": [ + "parent", + "other:ro" + ], + "CapAdd": [ + "NET_ADMIN" + ], + "CapDrop": [ + "MKNOD" + ], + "GroupAdd": [ + "newgroup" + ], + "RestartPolicy": { + "Name": "", + "MaximumRetryCount": 0 + }, + "NetworkMode": "bridge", + "Devices": [], + "Ulimits": [ + {} + ], + "LogConfig": { + "Type": "json-file", + "Config": {} + }, + "SecurityOpt": [ + "" + ], + "CgroupParent": "", + "VolumeDriver": "", + "ShmSize": 67108864 + } +} diff --git a/src/test/resources/samples/1.22/containers/json/filter1.json b/src/test/resources/samples/1.22/containers/json/filter1.json new file mode 100644 index 000000000..159e62da6 --- /dev/null +++ b/src/test/resources/samples/1.22/containers/json/filter1.json @@ -0,0 +1,37 @@ +[ + { + "Id": "095351afe7b4995dfb3e965f9cfd3a07b1fe69198c50085a2cb7c2b5a5c9b62f", + "Names": [ + "/drunk_golick" + ], + "Image": "busybox", + "ImageID": "sha256:0cb40641836c461bc97c793971d84d758371ed682042457523e4ae701efe7ec9", + "Command": "echo", + "Created": 1455662451, + "Ports": [], + "SizeRootFs": 1113554, + "Labels": {}, + "Status": "Up Less than a second", + "HostConfig": { + "NetworkMode": "default" + }, + "NetworkSettings": { + "Networks": { + "bridge": { + "IPAMConfig": null, + "Links": null, + "Aliases": null, + "NetworkID": "", + "EndpointID": "f69f5cff77b527c829bc45d71ba8c5eabca005ef3a8da8c7ee88c13ffc1ab602", + "Gateway": "172.17.0.1", + "IPAddress": "172.17.0.2", + "IPPrefixLen": 16, + "IPv6Gateway": "", + "GlobalIPv6Address": "", + "GlobalIPv6PrefixLen": 0, + "MacAddress": "02:42:ac:11:00:02" + } + } + } + } +] diff --git a/src/test/resources/samples/1.22/exec/ID/1.json b/src/test/resources/samples/1.22/exec/ID/1.json new file mode 100644 index 000000000..f06c807af --- /dev/null +++ b/src/test/resources/samples/1.22/exec/ID/1.json @@ -0,0 +1,18 @@ +{ + "ID": "1ca2ca598fab202f86dd9281196c405456069013958a475396b707e85c56473b", + "Running": false, + "ExitCode": null, + "ProcessConfig": { + "tty": false, + "entrypoint": "/bin/bash", + "arguments": [], + "privileged": false, + "user": "" + }, + "OpenStdin": false, + "OpenStderr": true, + "OpenStdout": true, + "CanRemove": false, + "ContainerID": "ffa39805f089af3099e36452a985481f96170a9dff40be69d34d1722c7660d38", + "DetachKeys": "" +} diff --git a/src/test/resources/samples/1.22/info/1.json b/src/test/resources/samples/1.22/info/1.json new file mode 100644 index 000000000..42ceb1b6e --- /dev/null +++ b/src/test/resources/samples/1.22/info/1.json @@ -0,0 +1,91 @@ +{ + "ID": "HLN2:5SBU:SRQR:CQI6:AB52:LZZ2:DED5:REDM:BU73:JFHE:R37A:5HMX", + "Containers": 2, + "ContainersRunning": 2, + "ContainersPaused": 10, + "ContainersStopped": 3, + "Images": 13, + "Driver": "aufs", + "DriverStatus": [ + [ + "Root Dir", + "/mnt/sda1/var/lib/docker/aufs" + ], + [ + "Backing Filesystem", + "extfs" + ], + [ + "Dirs", + "31" + ], + [ + "Dirperm1 Supported", + "true" + ] + ], + "SystemStatus": null, + "Plugins": { + "Volume": [ + "local" + ], + "Network": [ + "bridge", + "null", + "host" + ], + "Authorization": null + }, + "MemoryLimit": true, + "SwapLimit": true, + "CpuCfsPeriod": true, + "CpuCfsQuota": true, + "CPUShares": true, + "CPUSet": true, + "IPv4Forwarding": true, + "BridgeNfIptables": true, + "BridgeNfIp6tables": true, + "Debug": true, + "NFd": 24, + "OomKillDisable": true, + "NGoroutines": 40, + "SystemTime": "2016-02-17T14:56:35.212841831Z", + "ExecutionDriver": "native-0.2", + "LoggingDriver": "json-file", + "NEventsListener": 0, + "KernelVersion": "4.1.17-boot2docker", + "OperatingSystem": "Boot2Docker 1.10.1 (TCL 6.4.1); master : b03e158 - Thu Feb 11 22:34:01 UTC 2016", + "OSType": "linux", + "Architecture": "x86_64", + "IndexServerAddress": "https://index.docker.io/v1/", + "RegistryConfig": { + "InsecureRegistryCIDRs": [ + "127.0.0.0/8" + ], + "IndexConfigs": { + "docker.io": { + "Name": "docker.io", + "Mirrors": null, + "Secure": true, + "Official": true + } + }, + "Mirrors": null + }, + "InitSha1": "", + "InitPath": "/usr/local/bin/docker", + "NCPU": 1, + "MemTotal": 1044574208, + "DockerRootDir": "/mnt/sda1/var/lib/docker", + "HttpProxy": "", + "HttpsProxy": "", + "NoProxy": "", + "Name": "docker-java", + "Labels": [ + "provider=virtualbox" + ], + "ExperimentalBuild": false, + "ServerVersion": "1.10.1", + "ClusterStore": "", + "ClusterAdvertise": "" +} diff --git a/src/test/resources/samples/1.22/info/docs.json b/src/test/resources/samples/1.22/info/docs.json new file mode 100644 index 000000000..537a0a1d2 --- /dev/null +++ b/src/test/resources/samples/1.22/info/docs.json @@ -0,0 +1,76 @@ +{ + "Architecture": "x86_64", + "Containers": 11, + "ContainersRunning": 7, + "ContainersStopped": 3, + "ContainersPaused": 1, + "CpuCfsPeriod": true, + "CpuCfsQuota": true, + "Debug": false, + "DiscoveryBackend": "etcd://localhost:2379", + "DockerRootDir": "/var/lib/docker", + "Driver": "btrfs", + "DriverStatus": [ + [ + "" + ] + ], + "SystemStatus": [ + [ + "State", + "Healthy" + ] + ], + "Plugins": { + "Volume": [ + "local" + ], + "Network": [ + "null", + "host", + "bridge" + ] + }, + "ExecutionDriver": "native-0.1", + "ExperimentalBuild": false, + "HttpProxy": "http://test:test@localhost:8080", + "HttpsProxy": "https://test:test@localhost:8080", + "ID": "7TRN:IPZB:QYBB:VPBQ:UMPP:KARE:6ZNR:XE6T:7EWV:PKF4:ZOJD:TPYS", + "IPv4Forwarding": true, + "Images": 16, + "IndexServerAddress": "https://index.docker.io/v1/", + "InitPath": "/usr/bin/docker", + "InitSha1": "", + "KernelVersion": "3.12.0-1-amd64", + "Labels": [ + "storage=ssd" + ], + "MemTotal": 2099236864, + "MemoryLimit": true, + "NCPU": 1, + "NEventsListener": 0, + "NFd": 11, + "NGoroutines": 21, + "Name": "prod-server-42", + "NoProxy": "9.81.1.160", + "OomKillDisable": true, + "OSType": "linux", + "OomScoreAdj": 500, + "OperatingSystem": "Boot2Docker", + "RegistryConfig": { + "IndexConfigs": { + "docker.io": { + "Mirrors": null, + "Name": "docker.io", + "Official": true, + "Secure": true + } + }, + "InsecureRegistryCIDRs": [ + "127.0.0.0/8" + ] + }, + "SwapLimit": false, + "SystemTime": "2015-03-10T11:11:23.730591467-07:00", + "ServerVersion": "1.9.0" +} diff --git a/src/test/resources/samples/1.22/other/AuthConfig/docs1.json b/src/test/resources/samples/1.22/other/AuthConfig/docs1.json new file mode 100644 index 000000000..5f712fb62 --- /dev/null +++ b/src/test/resources/samples/1.22/other/AuthConfig/docs1.json @@ -0,0 +1,5 @@ +{ + "username": "jdoe", + "password": "secret", + "email": "jdoe@acme.com" +} diff --git a/src/test/resources/samples/1.22/other/AuthConfig/docs2.json b/src/test/resources/samples/1.22/other/AuthConfig/docs2.json new file mode 100644 index 000000000..8ac70c20a --- /dev/null +++ b/src/test/resources/samples/1.22/other/AuthConfig/docs2.json @@ -0,0 +1,3 @@ +{ + "registrytoken": "9cbaf023786cd7..." +} diff --git a/src/test/resources/samples/1.22/version/1.json b/src/test/resources/samples/1.22/version/1.json new file mode 100644 index 000000000..454c767ba --- /dev/null +++ b/src/test/resources/samples/1.22/version/1.json @@ -0,0 +1,10 @@ +{ + "Version": "1.10.1", + "ApiVersion": "1.22", + "GitCommit": "9e83765", + "GoVersion": "go1.5.3", + "Os": "linux", + "Arch": "amd64", + "KernelVersion": "4.1.17-boot2docker", + "BuildTime": "2016-02-11T20:39:58.688092588+00:00" +} From 0d2562e8da848bd3480d7aff981f6e7dae968f87 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 3 Mar 2016 00:57:25 +0300 Subject: [PATCH 041/855] @Nonnull annotation --- .../github/dockerjava/api/command/UpdateContainerCmd.java | 5 ++++- .../dockerjava/core/command/UpdateContainerCmdImpl.java | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java index 3dc7a0773..d7e32e445 100644 --- a/src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java @@ -1,11 +1,14 @@ package com.github.dockerjava.api.command; import com.github.dockerjava.api.model.UpdateContainerResponse; +import com.github.dockerjava.core.RemoteApiVersion; import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; /** * @author Kanstantsin Shautsou + * @since {@link RemoteApiVersion#VERSION_1_22} */ public interface UpdateContainerCmd extends SyncDockerCmd { @CheckForNull @@ -16,7 +19,7 @@ public interface UpdateContainerCmd extends SyncDockerCmd Date: Thu, 3 Mar 2016 01:07:34 +0300 Subject: [PATCH 042/855] Don't enforce api version for tests. --- .../github/dockerjava/client/AbstractDockerClientTest.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java index 1375cc9b6..4c8750ecc 100644 --- a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java +++ b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java @@ -10,7 +10,6 @@ import java.util.ArrayList; import java.util.List; -import com.github.dockerjava.core.RemoteApiVersion; import org.apache.commons.io.IOUtils; import org.apache.commons.io.LineIterator; import org.apache.commons.lang.StringUtils; @@ -40,8 +39,6 @@ public abstract class AbstractDockerClientTest extends Assert { public static final Logger LOG = LoggerFactory.getLogger(AbstractDockerClientTest.class); - private RemoteApiVersion apiVersion = RemoteApiVersion.VERSION_1_22; - protected DockerClient dockerClient; protected TestDockerCmdExecFactory dockerCmdExecFactory = initTestDockerCmdExecFactory(); @@ -82,7 +79,7 @@ protected DockerClientConfig config(String password) { builder = builder.withRegistryPassword(password); } - return builder.withApiVersion(apiVersion).build(); + return builder.build(); } public void afterTest() { From 2f35beda98f8b5edb1a1c9efa993ef1a0d758cc0 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 3 Mar 2016 01:08:32 +0300 Subject: [PATCH 043/855] Condition test --- .../core/command/InspectExecCmdImplTest.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/github/dockerjava/core/command/InspectExecCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/InspectExecCmdImplTest.java index a21a312aa..d86bcc39e 100644 --- a/src/test/java/com/github/dockerjava/core/command/InspectExecCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/InspectExecCmdImplTest.java @@ -119,12 +119,19 @@ public void inspectExecNetworkSettings() throws IOException { assertThat(exec.getId(), not(isEmptyString())); InspectExecResponse inspectExecResponse = dockerClient.inspectExecCmd(exec.getId()).exec(); - assertThat(inspectExecResponse.getExitCode(), is(nullValue())); + + if (apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_22)) { + assertThat(inspectExecResponse.getExitCode(), is(nullValue())); + assertThat(inspectExecResponse.getCanRemove(), is(false)); + assertThat(inspectExecResponse.getContainerID(), is(container.getId())); + } else { + assertThat(inspectExecResponse.getExitCode(), is(0)); + assertNotNull(inspectExecResponse.getContainer().getNetworkSettings().getNetworks().get("bridge")); + } + assertThat(inspectExecResponse.isOpenStdin(), is(false)); assertThat(inspectExecResponse.isOpenStdout(), is(true)); assertThat(inspectExecResponse.isRunning(), is(false)); - assertThat(inspectExecResponse.getCanRemove(), is(false)); - assertThat(inspectExecResponse.getContainerID(), is(container.getId())); final InspectExecResponse.Container inspectContainer = inspectExecResponse.getContainer(); if (apiVersion.isGreaterOrEqual(VERSION_1_22)) { From 5400925fbdd9b1482cff23a1b304ae2804150792 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 3 Mar 2016 01:14:41 +0300 Subject: [PATCH 044/855] Test update only for >= 1.22 --- .../core/command/UpdateContainerCmdImplTest.java | 9 ++++++++- .../netty/exec/UpdateContainerCmdExecTest.java | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java index 76708f889..c230fbb02 100644 --- a/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java @@ -10,6 +10,7 @@ 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; @@ -20,6 +21,7 @@ import java.lang.reflect.Method; import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; @@ -55,6 +57,12 @@ public void afterMethod(ITestResult result) { @Test(groups = "ignoreInCircleCi") public void updateContainer() throws DockerException, IOException { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + + if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_22)) { + throw new SkipException("API version should be >= 1.22"); + } + CreateContainerResponse response = dockerClient.createContainerCmd(BUSYBOX_IMAGE) .withCmd("sleep", "9999") .exec(); @@ -62,7 +70,6 @@ public void updateContainer() throws DockerException, IOException { dockerClient.startContainerCmd(containerId).exec(); InspectContainerResponse inspectBefore = dockerClient.inspectContainerCmd(containerId).exec(); - final HostConfig beforeHostConfig = inspectBefore.getHostConfig(); final UpdateContainerResponse updateResponse = dockerClient.updateContainerCmd(containerId) .withBlkioWeight(300) diff --git a/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java index 94c8242e5..e2907dc8a 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java @@ -5,10 +5,12 @@ import com.github.dockerjava.api.exception.DockerException; import com.github.dockerjava.api.model.HostConfig; import com.github.dockerjava.api.model.UpdateContainerResponse; +import com.github.dockerjava.core.RemoteApiVersion; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.ITestResult; +import org.testng.SkipException; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeMethod; @@ -18,6 +20,7 @@ import java.io.IOException; import java.lang.reflect.Method; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; @@ -52,6 +55,12 @@ public void afterMethod(ITestResult result) { @Test public void updateContainer() throws DockerException, IOException { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + + if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_22)) { + throw new SkipException("API version should be >= 1.22"); + } + CreateContainerResponse response = dockerClient.createContainerCmd(BUSYBOX_IMAGE) .withCmd("sleep", "9999") .exec(); From e149beea150086099a4218fa704b983b8afb7c91 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 3 Mar 2016 01:52:15 +0300 Subject: [PATCH 045/855] Condition test --- .../netty/exec/InspectExecCmdExecTest.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/github/dockerjava/netty/exec/InspectExecCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/InspectExecCmdExecTest.java index 3d2b55e24..d0bb5ca1f 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/InspectExecCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/InspectExecCmdExecTest.java @@ -120,12 +120,19 @@ public void inspectExecNetworkSettings() throws IOException { assertThat(exec.getId(), not(isEmptyString())); InspectExecResponse inspectExecResponse = dockerClient.inspectExecCmd(exec.getId()).exec(); - assertThat(inspectExecResponse.getExitCode(), is(nullValue())); + + if (apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_22)) { + assertThat(inspectExecResponse.getExitCode(), is(nullValue())); + assertThat(inspectExecResponse.getCanRemove(), is(false)); + assertThat(inspectExecResponse.getContainerID(), is(container.getId())); + } else { + assertThat(inspectExecResponse.getExitCode(), is(0)); + assertNotNull(inspectExecResponse.getContainer().getNetworkSettings().getNetworks().get("bridge")); + } + assertThat(inspectExecResponse.isOpenStdin(), is(false)); assertThat(inspectExecResponse.isOpenStdout(), is(true)); assertThat(inspectExecResponse.isRunning(), is(false)); - assertThat(inspectExecResponse.getCanRemove(), is(false)); - assertThat(inspectExecResponse.getContainerID(), is(container.getId())); final InspectExecResponse.Container inspectContainer = inspectExecResponse.getContainer(); if (apiVersion.isGreaterOrEqual(VERSION_1_22)) { From b1d77c51d9fbc4e6d5c60e4a51bd7c196e90675e Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 3 Mar 2016 02:10:02 +0300 Subject: [PATCH 046/855] Fix unrelable test. --- .../api/command/InspectContainerResponse.java | 63 +++++++++++++++++++ .../command/StartContainerCmdImplTest.java | 17 ++--- .../netty/exec/StartContainerCmdExecTest.java | 23 ++++--- 3 files changed, 87 insertions(+), 16 deletions(-) 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 3a49a4dd4..d19bc0329 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java @@ -462,5 +462,68 @@ public String getMode() { public Boolean getRW() { return rw; } + + /** + * @see #destination + */ + public Mount withDestination(Volume destination) { + this.destination = destination; + return this; + } + + /** + * @see #driver + */ + public Mount withDriver(String driver) { + this.driver = driver; + return this; + } + + /** + * @see #mode + */ + public Mount withMode(String mode) { + this.mode = mode; + return this; + } + + /** + * @see #name + */ + public Mount withName(String name) { + this.name = name; + return this; + } + + /** + * @see #rw + */ + public Mount withRw(Boolean rw) { + this.rw = rw; + return this; + } + + /** + * @see #source + */ + public Mount withSource(String source) { + this.source = source; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } } } diff --git a/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java index 0bc2c9b1a..a2f1e51d8 100644 --- a/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java @@ -7,6 +7,7 @@ import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; @@ -15,6 +16,7 @@ import java.lang.reflect.Method; import java.util.Arrays; +import java.util.List; import java.util.UUID; import org.testng.ITestResult; @@ -92,15 +94,16 @@ public void startContainerWithVolumes() throws DockerException { assertThat(inspectContainerResponse, mountedVolumes(containsInAnyOrder(volume1, volume2))); - assertThat(inspectContainerResponse.getMounts().size(), equalTo(2)); + final List mounts = inspectContainerResponse.getMounts(); - assertThat(inspectContainerResponse.getMounts().get(0).getDestination(), equalTo(volume1)); - assertThat(inspectContainerResponse.getMounts().get(0).getMode(), equalTo("ro")); - assertThat(inspectContainerResponse.getMounts().get(0).getRW(), equalTo(Boolean.FALSE)); + assertThat(mounts, hasSize(2)); - assertThat(inspectContainerResponse.getMounts().get(1).getDestination(), equalTo(volume2)); - assertThat(inspectContainerResponse.getMounts().get(1).getMode(), equalTo("rw")); - assertThat(inspectContainerResponse.getMounts().get(1).getRW(), equalTo(Boolean.TRUE)); + final InspectContainerResponse.Mount mount1 = new InspectContainerResponse.Mount() + .withRw(false).withMode("ro").withDestination(volume1).withSource("/src/webapp1"); + final InspectContainerResponse.Mount mount2 = new InspectContainerResponse.Mount() + .withRw(true).withMode("rw").withDestination(volume2).withSource("/src/webapp2"); + + assertThat(mounts, containsInAnyOrder(mount1, mount2)); } @Test diff --git a/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java index 02b7cd51b..6c70c1f07 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java @@ -7,6 +7,7 @@ import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; @@ -15,6 +16,7 @@ import java.lang.reflect.Method; import java.util.Arrays; +import java.util.List; import java.util.UUID; import org.testng.ITestResult; @@ -73,8 +75,10 @@ public void startContainerWithVolumes() throws DockerException { Volume volume2 = new Volume("/opt/webapp2"); - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withVolumes(volume1, volume2) - .withCmd("true").withBinds(new Bind("/src/webapp1", volume1, ro), new Bind("/src/webapp2", volume2)) + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withVolumes(volume1, volume2) + .withCmd("true") + .withBinds(new Bind("/src/webapp1", volume1, ro), new Bind("/src/webapp2", volume2)) .exec(); LOG.info("Created container {}", container.toString()); @@ -93,15 +97,16 @@ public void startContainerWithVolumes() throws DockerException { assertThat(inspectContainerResponse, mountedVolumes(containsInAnyOrder(volume1, volume2))); - assertThat(inspectContainerResponse.getMounts().size(), equalTo(2)); + final List mounts = inspectContainerResponse.getMounts(); - assertThat(inspectContainerResponse.getMounts().get(0).getDestination(), equalTo(volume1)); - assertThat(inspectContainerResponse.getMounts().get(0).getMode(), equalTo("ro")); - assertThat(inspectContainerResponse.getMounts().get(0).getRW(), equalTo(Boolean.FALSE)); + assertThat(mounts, hasSize(2)); - assertThat(inspectContainerResponse.getMounts().get(1).getDestination(), equalTo(volume2)); - assertThat(inspectContainerResponse.getMounts().get(1).getMode(), equalTo("rw")); - assertThat(inspectContainerResponse.getMounts().get(1).getRW(), equalTo(Boolean.TRUE)); + final InspectContainerResponse.Mount mount1 = new InspectContainerResponse.Mount() + .withRw(false).withMode("ro").withDestination(volume1).withSource("/src/webapp1"); + final InspectContainerResponse.Mount mount2 = new InspectContainerResponse.Mount() + .withRw(true).withMode("rw").withDestination(volume2).withSource("/src/webapp2"); + + assertThat(mounts, containsInAnyOrder(mount1, mount2)); } @Test From a0ec66f12c396e56e6148fc3e69fe2713620202a Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 4 Mar 2016 13:09:27 +0300 Subject: [PATCH 047/855] Fix versioning Auth issues for unknown API connections. Signed-off-by: Kanstantsin Shautsou --- .../dockerjava/core/RemoteApiVersion.java | 2 +- .../dockerjava/jaxrs/AbstrDockerCmdExec.java | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java index e15cccc88..992125414 100644 --- a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java +++ b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java @@ -60,7 +60,7 @@ public class RemoteApiVersion implements Serializable { /** * Unknown, docker doesn't reflect reality. I.e. we implemented method, but for javadoc it not clear when it was added. */ - private static final RemoteApiVersion UNKNOWN_VERSION = new RemoteApiVersion(0, 0) { + public static final RemoteApiVersion UNKNOWN_VERSION = new RemoteApiVersion(0, 0) { @Override public boolean isGreaterOrEqual(final RemoteApiVersion other) { diff --git a/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java index 750114b11..ad819468a 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java +++ b/src/main/java/com/github/dockerjava/jaxrs/AbstrDockerCmdExec.java @@ -1,11 +1,14 @@ package com.github.dockerjava.jaxrs; +import static com.github.dockerjava.core.RemoteApiVersion.UNKNOWN_VERSION; +import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_19; import static com.google.common.base.Preconditions.checkNotNull; import java.io.IOException; import javax.ws.rs.client.WebTarget; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.commons.codec.binary.Base64; import com.fasterxml.jackson.databind.ObjectMapper; @@ -46,10 +49,18 @@ protected String registryAuth(AuthConfig authConfig) { protected String registryConfigs(AuthConfigurations authConfigs) { try { final String json; - if (dockerClientConfig.getApiVersion().isGreaterOrEqual(RemoteApiVersion.VERSION_1_19)) { - json = new ObjectMapper().writeValueAsString(authConfigs.getConfigs()); + final ObjectMapper objectMapper = new ObjectMapper(); + final RemoteApiVersion apiVersion = dockerClientConfig.getApiVersion(); + + if (apiVersion.equals(UNKNOWN_VERSION)) { + ObjectNode rootNode = objectMapper.valueToTree(authConfigs.getConfigs()); // all registries + final ObjectNode authNodes = objectMapper.valueToTree(authConfigs); // wrapped in "configs":{} + rootNode.setAll(authNodes); // merge 2 variants + json = rootNode.toString(); + } else if (apiVersion.isGreaterOrEqual(VERSION_1_19)) { + json = objectMapper.writeValueAsString(authConfigs.getConfigs()); } else { - json = new ObjectMapper().writeValueAsString(authConfigs); + json = objectMapper.writeValueAsString(authConfigs); } return Base64.encodeBase64String(json.getBytes()); From 241257cc8d53bb1de394358d18d7d57984a21501 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 4 Mar 2016 16:37:06 +0300 Subject: [PATCH 048/855] Fix netty auth. --- .../dockerjava/jaxrs/BuildImageCmdExec.java | 10 ++++++---- .../netty/exec/AbstrDockerCmdExec.java | 17 ++++++++++++++--- .../netty/exec/BuildImageCmdExec.java | 5 +++-- .../netty/exec/BuildImageCmdExecTest.java | 7 +++++-- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java index ec6be7fe1..dc642f1a6 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java @@ -37,7 +37,7 @@ public BuildImageCmdExec(WebTarget baseResource, DockerClientConfig dockerClient private Invocation.Builder resourceWithOptionalAuthConfig(BuildImageCmd command, Invocation.Builder request) { final AuthConfigurations authConfigs = firstNonNull(command.getBuildAuthConfigs(), getBuildAuthConfigs()); - if (authConfigs != null) { + if (authConfigs != null && !authConfigs.getConfigs().isEmpty()) { request = request.header("X-Registry-Config", registryConfigs(authConfigs)); } return request; @@ -113,8 +113,10 @@ protected AbstractCallbackNotifier callbackNotifier(BuildImag LOGGER.trace("POST: {}", webTarget); - return new POSTCallbackNotifier<>(new JsonStreamProcessor<>(BuildResponseItem.class), resultCallback, - resourceWithOptionalAuthConfig(command, webTarget.request()).accept(MediaType.TEXT_PLAIN), entity( - command.getTarInputStream(), "application/tar")); + return new POSTCallbackNotifier<>(new JsonStreamProcessor<>(BuildResponseItem.class), + resultCallback, + resourceWithOptionalAuthConfig(command, webTarget.request()).accept(MediaType.TEXT_PLAIN), + entity(command.getTarInputStream(), "application/tar") + ); } } diff --git a/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java index 5cf36a0a4..85763b403 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/AbstrDockerCmdExec.java @@ -1,9 +1,12 @@ package com.github.dockerjava.netty.exec; +import static com.github.dockerjava.core.RemoteApiVersion.UNKNOWN_VERSION; +import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_19; import static com.google.common.base.Preconditions.checkNotNull; import java.io.IOException; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.apache.commons.codec.binary.Base64; import com.fasterxml.jackson.databind.ObjectMapper; @@ -45,10 +48,18 @@ protected String registryAuth(AuthConfig authConfig) { protected String registryConfigs(AuthConfigurations authConfigs) { try { final String json; - if (dockerClientConfig.getApiVersion().isGreaterOrEqual(RemoteApiVersion.VERSION_1_19)) { - json = new ObjectMapper().writeValueAsString(authConfigs.getConfigs()); + final ObjectMapper objectMapper = new ObjectMapper(); + final RemoteApiVersion apiVersion = dockerClientConfig.getApiVersion(); + + if (apiVersion.equals(UNKNOWN_VERSION)) { + ObjectNode rootNode = objectMapper.valueToTree(authConfigs.getConfigs()); // all registries + final ObjectNode authNodes = objectMapper.valueToTree(authConfigs); // wrapped in "configs":{} + rootNode.setAll(authNodes); // merge 2 variants + json = rootNode.toString(); + } else if (apiVersion.isGreaterOrEqual(VERSION_1_19)) { + json = objectMapper.writeValueAsString(authConfigs.getConfigs()); } else { - json = new ObjectMapper().writeValueAsString(authConfigs); + json = objectMapper.writeValueAsString(authConfigs); } return Base64.encodeBase64String(json.getBytes()); 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 ba09fa743..155ceef6a 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java @@ -28,7 +28,7 @@ public BuildImageCmdExec(WebTarget baseResource, DockerClientConfig dockerClient private InvocationBuilder resourceWithOptionalAuthConfig(BuildImageCmd command, InvocationBuilder request) { final AuthConfigurations authConfigs = firstNonNull(command.getBuildAuthConfigs(), getBuildAuthConfigs()); - if (authConfigs != null) { + if (authConfigs != null && !authConfigs.getConfigs().isEmpty()) { request = request.header("X-Registry-Config", registryConfigs(authConfigs)); } return request; @@ -96,7 +96,8 @@ protected Void execute0(BuildImageCmd command, ResultCallback LOGGER.trace("POST: {}", webTarget); InvocationBuilder builder = resourceWithOptionalAuthConfig(command, webTarget.request()) - .accept(MediaType.APPLICATION_JSON).header("Content-Type", "application/tar") + .accept(MediaType.APPLICATION_JSON) + .header("Content-Type", "application/tar") .header("encoding", "gzip"); builder.post(new TypeReference() { 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 8a19c7eb9..1299cf6ae 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java @@ -287,8 +287,11 @@ public void testBuildFromPrivateRegistry() throws Exception { AuthConfigurations authConfigurations = new AuthConfigurations(); authConfigurations.addConfig(authConfig); - imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true).withBuildAuthConfigs(authConfigurations) - .exec(new BuildImageResultCallback()).awaitImageId(); + imageId = dockerClient.buildImageCmd(baseDir) + .withNoCache(true) + .withBuildAuthConfigs(authConfigurations) + .exec(new BuildImageResultCallback()) + .awaitImageId(); inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); assertThat(inspectImageResponse, not(nullValue())); From ac439d50b7b227fadde209da10a09b6fc3be7bc2 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Fri, 4 Mar 2016 21:29:34 +0100 Subject: [PATCH 049/855] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1fd6b848..76b00b30d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,13 @@ Change Log --- Notes -* The upcoming release will contain multiple API breaking changes therefore the major version switch. It will support a subset of v.1.21 of the docker remote API. It also includes an experimental netty based implementation of `DockerCmdExecFactory` that probably will replace the current jersey/httpclient based one in a later release. +* The upcoming release will contain multiple API breaking changes therefore the major version switch. It will support a subset of v.1.22 of the docker remote API. It also includes an experimental netty based implementation of `DockerCmdExecFactory` that probably will replace the current jersey/httpclient based one in a later release. * The configuration has been changed to better match the docker CLI configuration options. The properties file was renamed from `docker.io.properties` to `docker-java.properties`. See README.md for details. All changes +* [#488] (https://github.com/docker-java/docker-java/pull/488) Support remote API 1.22 subset + Included in 3.0.0-RC2 * [#486] (https://github.com/docker-java/docker-java/pull/486) Fix NegativeArraySizeException in awaitCompletion() * [#472] (https://github.com/docker-java/docker-java/pull/472) Exec start command: detect end of STDIN stream From 7c27d149876c19bb233f7dc865bee163a0aa601e Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Fri, 4 Mar 2016 21:45:52 +0100 Subject: [PATCH 050/855] [maven-release-plugin] prepare release docker-java-3.0.0-RC3 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2b5fe2119..1c5d9d1c4 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-SNAPSHOT + 3.0.0-RC3 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 + docker-java-3.0.0-RC3 From d084518e82cbddc2ea9dcc32a6255edf63931331 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Fri, 4 Mar 2016 21:45:57 +0100 Subject: [PATCH 051/855] [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 1c5d9d1c4..2b5fe2119 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-RC3 + 3.0.0-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 - docker-java-3.0.0-RC3 + HEAD From d4d07280bef7649e7025c3d84492b1ff11b9d565 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Fri, 4 Mar 2016 21:50:00 +0100 Subject: [PATCH 052/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76b00b30d..9a91e105f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Notes All changes +Included in 3.0.0-RC3 * [#488] (https://github.com/docker-java/docker-java/pull/488) Support remote API 1.22 subset Included in 3.0.0-RC2 From b3b6315656c846852554166e91b1a35323e914d2 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Fri, 4 Mar 2016 21:51:15 +0100 Subject: [PATCH 053/855] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4205fa95e..0822de006 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Run build without integration tests: com.github.docker-java docker-java - 2.2.1 + 2.2.3 ### Latest release candidate @@ -72,7 +72,7 @@ Run build without integration tests: com.github.docker-java docker-java - 3.0.0-RC2 + 3.0.0-RC3 ### Latest development version From 6d90bc30c4c1c8132be89570039ac2dc90fe6226 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Fri, 4 Mar 2016 21:54:30 +0100 Subject: [PATCH 054/855] Update README.md --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0822de006..3601be462 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ Java API client for [Docker](http://docs.docker.io/ "Docker") -Supports a subset of the Docker Remote API [v1.19](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.19.md), Docker Server version 1.7.x - The current implementation is based on Jersey 2.x and therefore classpath incompatible with older Jersey 1.x dependent libraries! Developer forum for [docker-java](https://groups.google.com/forum/?#!forum/docker-java-dev "docker-java") @@ -16,7 +14,6 @@ Developer forum for [docker-java](https://groups.google.com/forum/?#!forum/docke * Java 1.7 * Maven 3.0.5 -* Docker 1.7.x If you need SSL, then you'll need to put your `*.pem` file into `~/.docker/`, if you're using boot2docker, do this: @@ -60,6 +57,7 @@ Run build without integration tests: ## Docker-Java maven dependencies ### Latest release version +Supports a subset of the Docker Remote API [v1.19](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.19.md), Docker Server version 1.7.x com.github.docker-java @@ -68,6 +66,7 @@ Run build without integration tests: ### Latest release candidate +Supports a subset of the Docker Remote API [v1.22](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.22.md), Docker Server version 1.10.x com.github.docker-java @@ -76,6 +75,8 @@ Run build without integration tests: ### Latest development version +Supports a subset of the Docker Remote API [v1.22](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.22.md), Docker Server version 1.10.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 ad8643f54e808d2eeca6657c14f0b02afe198ddd Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 10 Mar 2016 00:51:32 +0300 Subject: [PATCH 055/855] Cleanup modifiers. --- .../github/dockerjava/api/DockerClient.java | 108 ++++---- .../dockerjava/api/command/AuthCmd.java | 8 +- .../dockerjava/api/command/BuildImageCmd.java | 64 ++--- .../dockerjava/api/command/CommitCmd.java | 86 +++---- .../api/command/ConnectToNetworkCmd.java | 10 +- .../api/command/ContainerDiffCmd.java | 10 +- .../command/CopyArchiveFromContainerCmd.java | 16 +- .../api/command/CopyFileFromContainerCmd.java | 16 +- .../api/command/CreateContainerCmd.java | 238 +++++++++--------- .../api/command/CreateImageCmd.java | 14 +- .../api/command/CreateNetworkCmd.java | 16 +- .../api/command/CreateVolumeCmd.java | 14 +- .../api/command/DisconnectFromNetworkCmd.java | 10 +- .../dockerjava/api/command/DockerCmd.java | 2 +- .../api/command/DockerCmdAsyncExec.java | 2 +- .../api/command/DockerCmdExecFactory.java | 102 ++++---- .../api/command/DockerCmdSyncExec.java | 2 +- .../dockerjava/api/command/EventsCmd.java | 22 +- .../dockerjava/api/command/ExecCreateCmd.java | 24 +- .../dockerjava/api/command/ExecStartCmd.java | 20 +- .../dockerjava/api/command/InfoCmd.java | 2 +- .../api/command/InspectContainerCmd.java | 8 +- .../api/command/InspectExecCmd.java | 8 +- .../api/command/InspectImageCmd.java | 8 +- .../api/command/InspectNetworkCmd.java | 8 +- .../api/command/InspectVolumeCmd.java | 6 +- .../api/command/KillContainerCmd.java | 12 +- .../api/command/ListContainersCmd.java | 32 +-- .../dockerjava/api/command/ListImagesCmd.java | 18 +- .../api/command/ListNetworksCmd.java | 4 +- .../api/command/ListVolumesCmd.java | 6 +- .../api/command/LogContainerCmd.java | 34 +-- .../api/command/PauseContainerCmd.java | 8 +- .../dockerjava/api/command/PingCmd.java | 2 +- .../dockerjava/api/command/PullImageCmd.java | 18 +- .../dockerjava/api/command/PushImageCmd.java | 16 +- .../api/command/RemoveContainerCmd.java | 16 +- .../api/command/RemoveImageCmd.java | 16 +- .../api/command/RemoveNetworkCmd.java | 8 +- .../api/command/RemoveVolumeCmd.java | 8 +- .../api/command/RestartContainerCmd.java | 12 +- .../dockerjava/api/command/SaveImageCmd.java | 12 +- .../api/command/SearchImagesCmd.java | 6 +- .../api/command/StartContainerCmd.java | 4 +- .../dockerjava/api/command/StatsCmd.java | 6 +- .../api/command/StopContainerCmd.java | 12 +- .../dockerjava/api/command/SyncDockerCmd.java | 2 +- .../dockerjava/api/command/TagImageCmd.java | 20 +- .../api/command/TopContainerCmd.java | 12 +- .../api/command/UnpauseContainerCmd.java | 8 +- .../api/command/UpdateContainerCmd.java | 38 +-- .../dockerjava/api/command/VersionCmd.java | 2 +- .../api/command/WaitContainerCmd.java | 8 +- .../dockerjava/api/model/LogConfig.java | 4 +- .../dockerjava/core/GoLangFileMatch.java | 4 +- .../github/dockerjava/netty/MediaType.java | 2 +- .../netty/handler/HttpRequestProvider.java | 2 +- .../checkstyle/checkstyle-config.xml | 3 +- 58 files changed, 589 insertions(+), 590 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java index 4ae45ec89..3ceabf3e7 100644 --- a/src/main/java/com/github/dockerjava/api/DockerClient.java +++ b/src/main/java/com/github/dockerjava/api/DockerClient.java @@ -64,48 +64,48 @@ // https://godoc.org/github.com/fsouza/go-dockerclient public interface DockerClient extends Closeable { - public AuthConfig authConfig() throws DockerException; + AuthConfig authConfig() throws DockerException; /** * Authenticate with the server, useful for checking authentication. */ - public AuthCmd authCmd(); + AuthCmd authCmd(); - public InfoCmd infoCmd(); + InfoCmd infoCmd(); - public PingCmd pingCmd(); + PingCmd pingCmd(); - public VersionCmd versionCmd(); + VersionCmd versionCmd(); /** * * IMAGE API * */ - public PullImageCmd pullImageCmd(@Nonnull String repository); + PullImageCmd pullImageCmd(@Nonnull String repository); - public PushImageCmd pushImageCmd(@Nonnull String name); + PushImageCmd pushImageCmd(@Nonnull String name); - public PushImageCmd pushImageCmd(@Nonnull Identifier identifier); + PushImageCmd pushImageCmd(@Nonnull Identifier identifier); - public CreateImageCmd createImageCmd(@Nonnull String repository, @Nonnull InputStream imageStream); + CreateImageCmd createImageCmd(@Nonnull String repository, @Nonnull InputStream imageStream); - public SearchImagesCmd searchImagesCmd(@Nonnull String term); + SearchImagesCmd searchImagesCmd(@Nonnull String term); - public RemoveImageCmd removeImageCmd(@Nonnull String imageId); + RemoveImageCmd removeImageCmd(@Nonnull String imageId); - public ListImagesCmd listImagesCmd(); + ListImagesCmd listImagesCmd(); - public InspectImageCmd inspectImageCmd(@Nonnull String imageId); + InspectImageCmd inspectImageCmd(@Nonnull String imageId); - public SaveImageCmd saveImageCmd(@Nonnull String name); + SaveImageCmd saveImageCmd(@Nonnull String name); /** * * CONTAINER API * */ - public ListContainersCmd listContainersCmd(); + ListContainersCmd listContainersCmd(); - public CreateContainerCmd createContainerCmd(@Nonnull String image); + CreateContainerCmd createContainerCmd(@Nonnull String image); /** * Creates a new {@link StartContainerCmd} for the container with the given ID. The command can then be further customized by using @@ -116,23 +116,23 @@ public interface DockerClient extends Closeable { *

* This command corresponds to the /containers/{id}/start endpoint of the Docker Remote API. */ - public StartContainerCmd startContainerCmd(@Nonnull String containerId); + StartContainerCmd startContainerCmd(@Nonnull String containerId); - public ExecCreateCmd execCreateCmd(@Nonnull String containerId); + ExecCreateCmd execCreateCmd(@Nonnull String containerId); - public InspectContainerCmd inspectContainerCmd(@Nonnull String containerId); + InspectContainerCmd inspectContainerCmd(@Nonnull String containerId); - public RemoveContainerCmd removeContainerCmd(@Nonnull String containerId); + RemoveContainerCmd removeContainerCmd(@Nonnull String containerId); - public WaitContainerCmd waitContainerCmd(@Nonnull String containerId); + WaitContainerCmd waitContainerCmd(@Nonnull String containerId); - public AttachContainerCmd attachContainerCmd(@Nonnull String containerId); + AttachContainerCmd attachContainerCmd(@Nonnull String containerId); - public ExecStartCmd execStartCmd(@Nonnull String containerId); + ExecStartCmd execStartCmd(@Nonnull String containerId); - public InspectExecCmd inspectExecCmd(@Nonnull String execId); + InspectExecCmd inspectExecCmd(@Nonnull String execId); - public LogContainerCmd logContainerCmd(@Nonnull String containerId); + LogContainerCmd logContainerCmd(@Nonnull String containerId); /** * Copy resource from container to local machine. @@ -144,7 +144,7 @@ public interface DockerClient extends Closeable { * @return created command * @since {@link RemoteApiVersion#VERSION_1_20} */ - public CopyArchiveFromContainerCmd copyArchiveFromContainerCmd(@Nonnull String containerId, @Nonnull String resource); + CopyArchiveFromContainerCmd copyArchiveFromContainerCmd(@Nonnull String containerId, @Nonnull String resource); /** * Copy resource from container to local machine. @@ -158,7 +158,7 @@ public interface DockerClient extends Closeable { * @deprecated since docker API version 1.20, replaced by {@link #copyArchiveFromContainerCmd(String, String)} */ @Deprecated - public CopyFileFromContainerCmd copyFileFromContainerCmd(@Nonnull String containerId, @Nonnull String resource); + CopyFileFromContainerCmd copyFileFromContainerCmd(@Nonnull String containerId, @Nonnull String resource); /** * Copy archive from local machine to remote container @@ -168,13 +168,13 @@ public interface DockerClient extends Closeable { * @return created command * @since {@link RemoteApiVersion#VERSION_1_20} */ - public CopyArchiveToContainerCmd copyArchiveToContainerCmd(@Nonnull String containerId); + CopyArchiveToContainerCmd copyArchiveToContainerCmd(@Nonnull String containerId); - public ContainerDiffCmd containerDiffCmd(@Nonnull String containerId); + ContainerDiffCmd containerDiffCmd(@Nonnull String containerId); - public StopContainerCmd stopContainerCmd(@Nonnull String containerId); + StopContainerCmd stopContainerCmd(@Nonnull String containerId); - public KillContainerCmd killContainerCmd(@Nonnull String containerId); + KillContainerCmd killContainerCmd(@Nonnull String containerId); /** * Update container settings @@ -183,51 +183,51 @@ public interface DockerClient extends Closeable { * @return command * @since {@link RemoteApiVersion#VERSION_1_22} */ - public UpdateContainerCmd updateContainerCmd(@Nonnull String containerId); + UpdateContainerCmd updateContainerCmd(@Nonnull String containerId); - public RestartContainerCmd restartContainerCmd(@Nonnull String containerId); + RestartContainerCmd restartContainerCmd(@Nonnull String containerId); - public CommitCmd commitCmd(@Nonnull String containerId); + CommitCmd commitCmd(@Nonnull String containerId); - public BuildImageCmd buildImageCmd(); + BuildImageCmd buildImageCmd(); - public BuildImageCmd buildImageCmd(File dockerFileOrFolder); + BuildImageCmd buildImageCmd(File dockerFileOrFolder); - public BuildImageCmd buildImageCmd(InputStream tarInputStream); + BuildImageCmd buildImageCmd(InputStream tarInputStream); - public TopContainerCmd topContainerCmd(String containerId); + TopContainerCmd topContainerCmd(String containerId); - public TagImageCmd tagImageCmd(String imageId, String repository, String tag); + TagImageCmd tagImageCmd(String imageId, String repository, String tag); - public PauseContainerCmd pauseContainerCmd(String containerId); + PauseContainerCmd pauseContainerCmd(String containerId); - public UnpauseContainerCmd unpauseContainerCmd(String containerId); + UnpauseContainerCmd unpauseContainerCmd(String containerId); - public EventsCmd eventsCmd(); + EventsCmd eventsCmd(); - public StatsCmd statsCmd(String containerId); + StatsCmd statsCmd(String containerId); - public CreateVolumeCmd createVolumeCmd(); + CreateVolumeCmd createVolumeCmd(); - public InspectVolumeCmd inspectVolumeCmd(String name); + InspectVolumeCmd inspectVolumeCmd(String name); - public RemoveVolumeCmd removeVolumeCmd(String name); + RemoveVolumeCmd removeVolumeCmd(String name); - public ListVolumesCmd listVolumesCmd(); + ListVolumesCmd listVolumesCmd(); - public ListNetworksCmd listNetworksCmd(); + ListNetworksCmd listNetworksCmd(); - public InspectNetworkCmd inspectNetworkCmd(); + InspectNetworkCmd inspectNetworkCmd(); - public CreateNetworkCmd createNetworkCmd(); + CreateNetworkCmd createNetworkCmd(); - public RemoveNetworkCmd removeNetworkCmd(@Nonnull String networkId); + RemoveNetworkCmd removeNetworkCmd(@Nonnull String networkId); - public ConnectToNetworkCmd connectToNetworkCmd(); + ConnectToNetworkCmd connectToNetworkCmd(); - public DisconnectFromNetworkCmd disconnectFromNetworkCmd(); + DisconnectFromNetworkCmd disconnectFromNetworkCmd(); @Override - public void close() throws IOException; + void close() throws IOException; } diff --git a/src/main/java/com/github/dockerjava/api/command/AuthCmd.java b/src/main/java/com/github/dockerjava/api/command/AuthCmd.java index 236b0f326..a92b1593b 100644 --- a/src/main/java/com/github/dockerjava/api/command/AuthCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/AuthCmd.java @@ -15,9 +15,9 @@ public interface AuthCmd extends SyncDockerCmd { @CheckForNull - public AuthConfig getAuthConfig(); + AuthConfig getAuthConfig(); - public AuthCmd withAuthConfig(@Nonnull AuthConfig authConfig); + AuthCmd withAuthConfig(@Nonnull AuthConfig authConfig); /** * @return The status. Based on it's value you may mean you need to authorise your account, e.g.: "Account created. Please see the @@ -26,9 +26,9 @@ public interface AuthCmd extends SyncDockerCmd { * If you're not authorised (e.g. bad password). */ @Override - public AuthResponse exec() throws UnauthorizedException; + AuthResponse exec() throws UnauthorizedException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } 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 3f3ca5a5e..d11c86c7f 100644 --- a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java @@ -25,10 +25,10 @@ public interface BuildImageCmd extends AsyncDockerCmd getBuildArgs(); + Map getBuildArgs(); // setters - public BuildImageCmd withTag(String tag); + BuildImageCmd withTag(String tag); - public BuildImageCmd withRemote(URI remote); + BuildImageCmd withRemote(URI remote); - public BuildImageCmd withBaseDirectory(File baseDirectory); + BuildImageCmd withBaseDirectory(File baseDirectory); - public BuildImageCmd withDockerfile(File dockerfile); + BuildImageCmd withDockerfile(File dockerfile); - public BuildImageCmd withNoCache(Boolean noCache); + BuildImageCmd withNoCache(Boolean noCache); - public BuildImageCmd withRemove(Boolean rm); + BuildImageCmd withRemove(Boolean rm); - public BuildImageCmd withForcerm(Boolean forcerm); + BuildImageCmd withForcerm(Boolean forcerm); - public BuildImageCmd withQuiet(Boolean quiet); + BuildImageCmd withQuiet(Boolean quiet); - public BuildImageCmd withPull(Boolean pull); + BuildImageCmd withPull(Boolean pull); - public BuildImageCmd withMemory(Long memory); + BuildImageCmd withMemory(Long memory); - public BuildImageCmd withMemswap(Long memswap); + BuildImageCmd withMemswap(Long memswap); - public BuildImageCmd withCpushares(String cpushares); + BuildImageCmd withCpushares(String cpushares); - public BuildImageCmd withCpusetcpus(String cpusetcpus); + BuildImageCmd withCpusetcpus(String cpusetcpus); /** * @since {@link RemoteApiVersion#VERSION_1_21} */ - public BuildImageCmd withBuildArg(String key, String value); + BuildImageCmd withBuildArg(String key, String value); // setters lib specific - public BuildImageCmd withBuildAuthConfigs(AuthConfigurations authConfig); + BuildImageCmd withBuildAuthConfigs(AuthConfigurations authConfig); - public BuildImageCmd withTarInputStream(@Nonnull InputStream tarInputStream); + BuildImageCmd withTarInputStream(@Nonnull InputStream tarInputStream); - public static interface Exec extends DockerCmdAsyncExec { + interface Exec extends DockerCmdAsyncExec { } } 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 81bc70e0c..c5da5bab6 100644 --- a/src/main/java/com/github/dockerjava/api/command/CommitCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CommitCmd.java @@ -15,112 +15,112 @@ public interface CommitCmd extends SyncDockerCmd { @CheckForNull - public String getAuthor(); + String getAuthor(); @CheckForNull - public String getContainerId(); + String getContainerId(); @CheckForNull - public String[] getEnv(); + String[] getEnv(); @CheckForNull - public ExposedPorts getExposedPorts(); + ExposedPorts getExposedPorts(); @CheckForNull - public String getHostname(); + String getHostname(); @CheckForNull - public Integer getMemory(); + Integer getMemory(); @CheckForNull - public Integer getMemorySwap(); + Integer getMemorySwap(); @CheckForNull - public String getMessage(); + String getMessage(); @CheckForNull - public String[] getPortSpecs(); + String[] getPortSpecs(); @CheckForNull - public String getRepository(); + String getRepository(); @CheckForNull - public String getTag(); + String getTag(); @CheckForNull - public String getUser(); + String getUser(); @CheckForNull - public Volumes getVolumes(); + Volumes getVolumes(); @CheckForNull - public String getWorkingDir(); + String getWorkingDir(); @CheckForNull - public Boolean hasPauseEnabled(); + Boolean hasPauseEnabled(); @CheckForNull - public Boolean isOpenStdin(); + Boolean isOpenStdin(); @CheckForNull - public Boolean isStdinOnce(); + Boolean isStdinOnce(); @CheckForNull - public Boolean isTty(); + Boolean isTty(); - public CommitCmd withAttachStderr(Boolean attachStderr); + CommitCmd withAttachStderr(Boolean attachStderr); - public CommitCmd withAttachStdin(Boolean attachStdin); + CommitCmd withAttachStdin(Boolean attachStdin); - public CommitCmd withAttachStdout(Boolean attachStdout); + CommitCmd withAttachStdout(Boolean attachStdout); - public CommitCmd withAuthor(String author); + CommitCmd withAuthor(String author); - public CommitCmd withCmd(String... cmd); + CommitCmd withCmd(String... cmd); - public CommitCmd withContainerId(@Nonnull String containerId); + CommitCmd withContainerId(@Nonnull String containerId); - public CommitCmd withDisableNetwork(Boolean disableNetwork); + CommitCmd withDisableNetwork(Boolean disableNetwork); - public CommitCmd withEnv(String... env); + CommitCmd withEnv(String... env); - public CommitCmd withExposedPorts(ExposedPorts exposedPorts); + CommitCmd withExposedPorts(ExposedPorts exposedPorts); - public CommitCmd withHostname(String hostname); + CommitCmd withHostname(String hostname); - public CommitCmd withMemory(Integer memory); + CommitCmd withMemory(Integer memory); - public CommitCmd withMemorySwap(Integer memorySwap); + CommitCmd withMemorySwap(Integer memorySwap); - public CommitCmd withMessage(String message); + CommitCmd withMessage(String message); - public CommitCmd withOpenStdin(Boolean openStdin); + CommitCmd withOpenStdin(Boolean openStdin); - public CommitCmd withPause(Boolean pause); + CommitCmd withPause(Boolean pause); - public CommitCmd withPortSpecs(String... portSpecs); + CommitCmd withPortSpecs(String... portSpecs); - public CommitCmd withRepository(String repository); + CommitCmd withRepository(String repository); - public CommitCmd withStdinOnce(Boolean stdinOnce); + CommitCmd withStdinOnce(Boolean stdinOnce); - public CommitCmd withTag(String tag); + CommitCmd withTag(String tag); - public CommitCmd withTty(Boolean tty); + CommitCmd withTty(Boolean tty); - public CommitCmd withUser(String user); + CommitCmd withUser(String user); - public CommitCmd withVolumes(Volumes volumes); + CommitCmd withVolumes(Volumes volumes); - public CommitCmd withWorkingDir(String workingDir); + CommitCmd withWorkingDir(String workingDir); /** * @throws NotFoundException * No such container */ @Override - public String exec() throws NotFoundException; + String exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/ConnectToNetworkCmd.java b/src/main/java/com/github/dockerjava/api/command/ConnectToNetworkCmd.java index cf76e2ec3..cd5c57774 100644 --- a/src/main/java/com/github/dockerjava/api/command/ConnectToNetworkCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ConnectToNetworkCmd.java @@ -13,15 +13,15 @@ public interface ConnectToNetworkCmd extends SyncDockerCmd { @CheckForNull - public String getNetworkId(); + String getNetworkId(); @CheckForNull - public String getContainerId(); + String getContainerId(); - public ConnectToNetworkCmd withNetworkId(@Nonnull String networkId); + ConnectToNetworkCmd withNetworkId(@Nonnull String networkId); - public ConnectToNetworkCmd withContainerId(@Nonnull String containerId); + ConnectToNetworkCmd withContainerId(@Nonnull String containerId); - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/ContainerDiffCmd.java b/src/main/java/com/github/dockerjava/api/command/ContainerDiffCmd.java index cc3bfa757..b64a13233 100644 --- a/src/main/java/com/github/dockerjava/api/command/ContainerDiffCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ContainerDiffCmd.java @@ -13,12 +13,12 @@ public interface ContainerDiffCmd extends SyncDockerCmd> { @CheckForNull - public String getContainerId(); + String getContainerId(); - public ContainerDiffCmd withContainerId(@Nonnull String containerId); + ContainerDiffCmd withContainerId(@Nonnull String containerId); @Override - public String toString(); + String toString(); /** * @throws NotFoundException @@ -29,9 +29,9 @@ public interface ContainerDiffCmd extends SyncDockerCmd> { * unexpected http status code */ @Override - public List exec() throws NotFoundException; + List exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec> { + interface Exec extends DockerCmdSyncExec> { } } diff --git a/src/main/java/com/github/dockerjava/api/command/CopyArchiveFromContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CopyArchiveFromContainerCmd.java index 56b24d24d..4ed28c01f 100644 --- a/src/main/java/com/github/dockerjava/api/command/CopyArchiveFromContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CopyArchiveFromContainerCmd.java @@ -10,19 +10,19 @@ public interface CopyArchiveFromContainerCmd extends SyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); @CheckForNull - public String getHostPath(); + String getHostPath(); @CheckForNull - public String getResource(); + String getResource(); - public CopyArchiveFromContainerCmd withContainerId(@Nonnull String containerId); + CopyArchiveFromContainerCmd withContainerId(@Nonnull String containerId); - public CopyArchiveFromContainerCmd withHostPath(String hostPath); + CopyArchiveFromContainerCmd withHostPath(String hostPath); - public CopyArchiveFromContainerCmd withResource(@Nonnull String resource); + CopyArchiveFromContainerCmd withResource(@Nonnull String resource); /** * Its the responsibility of the caller to consume and/or close the {@link InputStream} to prevent connection leaks. @@ -31,8 +31,8 @@ public interface CopyArchiveFromContainerCmd extends SyncDockerCmd * No such container */ @Override - public InputStream exec() throws NotFoundException; + InputStream exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/CopyFileFromContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CopyFileFromContainerCmd.java index 8786ca57f..5dc920ed0 100644 --- a/src/main/java/com/github/dockerjava/api/command/CopyFileFromContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CopyFileFromContainerCmd.java @@ -10,19 +10,19 @@ public interface CopyFileFromContainerCmd extends SyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); @CheckForNull - public String getHostPath(); + String getHostPath(); @CheckForNull - public String getResource(); + String getResource(); - public CopyFileFromContainerCmd withContainerId(@Nonnull String containerId); + CopyFileFromContainerCmd withContainerId(@Nonnull String containerId); - public CopyFileFromContainerCmd withHostPath(String hostPath); + CopyFileFromContainerCmd withHostPath(String hostPath); - public CopyFileFromContainerCmd withResource(@Nonnull String resource); + CopyFileFromContainerCmd withResource(@Nonnull String resource); /** * Its the responsibility of the caller to consume and/or close the {@link InputStream} to prevent connection leaks. @@ -31,8 +31,8 @@ public interface CopyFileFromContainerCmd extends SyncDockerCmd { * No such container */ @Override - public InputStream exec() throws NotFoundException; + InputStream exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java index 972739898..1454a5f80 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java @@ -24,310 +24,310 @@ public interface CreateContainerCmd extends SyncDockerCmd { @CheckForNull - public Bind[] getBinds(); + Bind[] getBinds(); /** * @since 1.19 */ @CheckForNull - public Integer getBlkioWeight(); + Integer getBlkioWeight(); @CheckForNull - public Capability[] getCapAdd(); + Capability[] getCapAdd(); @CheckForNull - public Capability[] getCapDrop(); + Capability[] getCapDrop(); @CheckForNull - public String[] getCmd(); + String[] getCmd(); /** * @since 1.19 */ @CheckForNull - public Integer getCpuPeriod(); + Integer getCpuPeriod(); @CheckForNull - public String getCpusetCpus(); + String getCpusetCpus(); /** * @since 1.19 */ @CheckForNull - public String getCpusetMems(); + String getCpusetMems(); @CheckForNull - public Integer getCpuShares(); + Integer getCpuShares(); @CheckForNull - public Device[] getDevices(); + Device[] getDevices(); @CheckForNull - public String[] getDns(); + String[] getDns(); @CheckForNull - public String[] getDnsSearch(); + String[] getDnsSearch(); @CheckForNull - public String getDomainName(); + String getDomainName(); @CheckForNull - public String[] getEntrypoint(); + String[] getEntrypoint(); @CheckForNull - public String[] getEnv(); + String[] getEnv(); @CheckForNull - public ExposedPort[] getExposedPorts(); + ExposedPort[] getExposedPorts(); @CheckForNull - public String getStopSignal(); + String getStopSignal(); @CheckForNull - public String[] getExtraHosts(); + String[] getExtraHosts(); @CheckForNull - public String getHostName(); + String getHostName(); @CheckForNull - public String getImage(); + String getImage(); @CheckForNull Map getLabels(); @CheckForNull - public Link[] getLinks(); + Link[] getLinks(); @CheckForNull - public LogConfig getLogConfig(); + LogConfig getLogConfig(); @CheckForNull - public LxcConf[] getLxcConf(); + LxcConf[] getLxcConf(); @CheckForNull - public String getMacAddress(); + String getMacAddress(); @CheckForNull - public Long getMemory(); + Long getMemory(); @CheckForNull - public Long getMemorySwap(); + Long getMemorySwap(); @CheckForNull - public String getName(); + String getName(); @CheckForNull - public String getNetworkMode(); + String getNetworkMode(); @CheckForNull - public Ports getPortBindings(); + Ports getPortBindings(); @CheckForNull - public String[] getPortSpecs(); + String[] getPortSpecs(); @CheckForNull - public RestartPolicy getRestartPolicy(); + RestartPolicy getRestartPolicy(); @CheckForNull - public Ulimit[] getUlimits(); + Ulimit[] getUlimits(); @CheckForNull - public String getUser(); + String getUser(); @CheckForNull - public Volume[] getVolumes(); + Volume[] getVolumes(); @CheckForNull - public VolumesFrom[] getVolumesFrom(); + VolumesFrom[] getVolumesFrom(); @CheckForNull - public String getWorkingDir(); + String getWorkingDir(); @CheckForNull - public Boolean isAttachStderr(); + Boolean isAttachStderr(); @CheckForNull - public Boolean isAttachStdin(); + Boolean isAttachStdin(); @CheckForNull - public Boolean isAttachStdout(); + Boolean isAttachStdout(); @CheckForNull - public Boolean isNetworkDisabled(); + Boolean isNetworkDisabled(); /** * @since 1.19 */ @CheckForNull - public Boolean isOomKillDisable(); + Boolean isOomKillDisable(); @CheckForNull - public Boolean isPrivileged(); + Boolean isPrivileged(); @CheckForNull - public Boolean isPublishAllPorts(); + Boolean isPublishAllPorts(); @CheckForNull - public Boolean isReadonlyRootfs(); + Boolean isReadonlyRootfs(); @CheckForNull - public Boolean isStdInOnce(); + Boolean isStdInOnce(); @CheckForNull - public Boolean isStdinOpen(); + Boolean isStdinOpen(); @CheckForNull - public String getPidMode(); + String getPidMode(); @CheckForNull - public Boolean isTty(); + Boolean isTty(); - public CreateContainerCmd withAttachStderr(Boolean attachStderr); + CreateContainerCmd withAttachStderr(Boolean attachStderr); - public CreateContainerCmd withAttachStdin(Boolean attachStdin); + CreateContainerCmd withAttachStdin(Boolean attachStdin); - public CreateContainerCmd withAttachStdout(Boolean attachStdout); + CreateContainerCmd withAttachStdout(Boolean attachStdout); - public CreateContainerCmd withBinds(Bind... binds); + CreateContainerCmd withBinds(Bind... binds); - public CreateContainerCmd withBinds(List binds); + CreateContainerCmd withBinds(List binds); /** * @since 1.19 */ - public CreateContainerCmd withBlkioWeight(Integer blkioWeight); + CreateContainerCmd withBlkioWeight(Integer blkioWeight); /** * Add linux kernel capability to the container. For example: * adding {@link Capability#MKNOD} allows the container to create special files using the 'mknod' command. */ - public CreateContainerCmd withCapAdd(Capability... capAdd); + CreateContainerCmd withCapAdd(Capability... capAdd); /** * Add linux kernel capability to the container. For example: * adding {@link Capability#MKNOD} allows the container to create special files using the 'mknod' command. */ - public CreateContainerCmd withCapAdd(List capAdd); + CreateContainerCmd withCapAdd(List capAdd); /** * Drop linux kernel capability from the container. For example: * dropping {@link Capability#CHOWN} prevents the container from changing the owner of any files. */ - public CreateContainerCmd withCapDrop(Capability... capDrop); + CreateContainerCmd withCapDrop(Capability... capDrop); /** * Drop linux kernel capability from the container. For example: * dropping {@link Capability#CHOWN} prevents the container from changing the owner of any files. */ - public CreateContainerCmd withCapDrop(List capDrop); + CreateContainerCmd withCapDrop(List capDrop); - public CreateContainerCmd withCmd(String... cmd); + CreateContainerCmd withCmd(String... cmd); - public CreateContainerCmd withCmd(List cmd); + CreateContainerCmd withCmd(List cmd); - public CreateContainerCmd withContainerIDFile(String containerIDFile); + CreateContainerCmd withContainerIDFile(String containerIDFile); /** * @since 1.19 */ - public CreateContainerCmd withCpuPeriod(Integer cpuPeriod); + CreateContainerCmd withCpuPeriod(Integer cpuPeriod); - public CreateContainerCmd withCpusetCpus(String cpusetCpus); + CreateContainerCmd withCpusetCpus(String cpusetCpus); /** * @since 1.19 */ - public CreateContainerCmd withCpusetMems(String cpusetMems); + CreateContainerCmd withCpusetMems(String cpusetMems); - public CreateContainerCmd withCpuShares(Integer cpuShares); + CreateContainerCmd withCpuShares(Integer cpuShares); /** * Add host devices to the container */ - public CreateContainerCmd withDevices(Device... devices); + CreateContainerCmd withDevices(Device... devices); /** * Add host devices to the container */ - public CreateContainerCmd withDevices(List devices); + CreateContainerCmd withDevices(List devices); /** * Set custom DNS servers */ - public CreateContainerCmd withDns(String... dns); + CreateContainerCmd withDns(String... dns); /** * Set custom DNS servers */ - public CreateContainerCmd withDns(List dns); + CreateContainerCmd withDns(List dns); /** * Set custom DNS search domains */ - public CreateContainerCmd withDnsSearch(String... dnsSearch); + CreateContainerCmd withDnsSearch(String... dnsSearch); /** * Set custom DNS search domains */ - public CreateContainerCmd withDnsSearch(List dnsSearch); + CreateContainerCmd withDnsSearch(List dnsSearch); - public CreateContainerCmd withDomainName(String domainName); + CreateContainerCmd withDomainName(String domainName); - public CreateContainerCmd withEntrypoint(String... entrypoint); + CreateContainerCmd withEntrypoint(String... entrypoint); - public CreateContainerCmd withEntrypoint(List entrypoint); + CreateContainerCmd withEntrypoint(List entrypoint); - public CreateContainerCmd withEnv(String... env); + CreateContainerCmd withEnv(String... env); - public CreateContainerCmd withEnv(List env); + CreateContainerCmd withEnv(List env); - public CreateContainerCmd withExposedPorts(ExposedPort... exposedPorts); + CreateContainerCmd withExposedPorts(ExposedPort... exposedPorts); - public CreateContainerCmd withStopSignal(String stopSignal); + CreateContainerCmd withStopSignal(String stopSignal); - public CreateContainerCmd withExposedPorts(List exposedPorts); + CreateContainerCmd withExposedPorts(List exposedPorts); /** * Add hostnames to /etc/hosts in the container */ - public CreateContainerCmd withExtraHosts(String... extraHosts); + CreateContainerCmd withExtraHosts(String... extraHosts); /** * Add hostnames to /etc/hosts in the container */ - public CreateContainerCmd withExtraHosts(List extraHosts); + CreateContainerCmd withExtraHosts(List extraHosts); - public CreateContainerCmd withHostName(String hostName); + CreateContainerCmd withHostName(String hostName); - public CreateContainerCmd withImage(String image); + CreateContainerCmd withImage(String image); - public CreateContainerCmd withLabels(Map labels); + CreateContainerCmd withLabels(Map labels); /** * Add link to another container. */ - public CreateContainerCmd withLinks(Link... links); + CreateContainerCmd withLinks(Link... links); /** * Add link to another container. */ - public CreateContainerCmd withLinks(List links); + CreateContainerCmd withLinks(List links); - public CreateContainerCmd withLogConfig(LogConfig logConfig); + CreateContainerCmd withLogConfig(LogConfig logConfig); - public CreateContainerCmd withLxcConf(LxcConf... lxcConf); + CreateContainerCmd withLxcConf(LxcConf... lxcConf); - public CreateContainerCmd withLxcConf(List lxcConf); + CreateContainerCmd withLxcConf(List lxcConf); - public CreateContainerCmd withMacAddress(String macAddress); + CreateContainerCmd withMacAddress(String macAddress); - public CreateContainerCmd withMemory(Long memory); + CreateContainerCmd withMemory(Long memory); - public CreateContainerCmd withMemorySwap(Long memorySwap); + CreateContainerCmd withMemorySwap(Long memorySwap); - public CreateContainerCmd withName(String name); + CreateContainerCmd withName(String name); - public CreateContainerCmd withNetworkDisabled(Boolean disableNetwork); + CreateContainerCmd withNetworkDisabled(Boolean disableNetwork); /** * Set the Network mode for the container @@ -339,73 +339,73 @@ public interface CreateContainerCmd extends SyncDockerCmd * */ - public CreateContainerCmd withNetworkMode(String networkMode); + CreateContainerCmd withNetworkMode(String networkMode); /** * @since 1.19 */ - public CreateContainerCmd withOomKillDisable(Boolean oomKillDisable); + CreateContainerCmd withOomKillDisable(Boolean oomKillDisable); /** * Add one or more {@link PortBinding}s. This corresponds to the --publish (-p) option of the * docker run CLI command. */ - public CreateContainerCmd withPortBindings(PortBinding... portBindings); + CreateContainerCmd withPortBindings(PortBinding... portBindings); /** * Add one or more {@link PortBinding}s. This corresponds to the --publish (-p) option of the * docker run CLI command. */ - public CreateContainerCmd withPortBindings(List portBindings); + CreateContainerCmd withPortBindings(List portBindings); /** * Add the port bindings that are contained in the given {@link Ports} object. * * @see #withPortBindings(PortBinding...) */ - public CreateContainerCmd withPortBindings(Ports portBindings); + CreateContainerCmd withPortBindings(Ports portBindings); - public CreateContainerCmd withPortSpecs(String... portSpecs); + CreateContainerCmd withPortSpecs(String... portSpecs); - public CreateContainerCmd withPortSpecs(List portSpecs); + CreateContainerCmd withPortSpecs(List portSpecs); - public CreateContainerCmd withPrivileged(Boolean privileged); + CreateContainerCmd withPrivileged(Boolean privileged); - public CreateContainerCmd withPublishAllPorts(Boolean publishAllPorts); + CreateContainerCmd withPublishAllPorts(Boolean publishAllPorts); - public CreateContainerCmd withReadonlyRootfs(Boolean readonlyRootfs); + CreateContainerCmd withReadonlyRootfs(Boolean readonlyRootfs); /** * Set custom {@link RestartPolicy} for the container. Defaults to {@link RestartPolicy#noRestart()} */ - public CreateContainerCmd withRestartPolicy(RestartPolicy restartPolicy); + CreateContainerCmd withRestartPolicy(RestartPolicy restartPolicy); - public CreateContainerCmd withStdInOnce(Boolean stdInOnce); + CreateContainerCmd withStdInOnce(Boolean stdInOnce); - public CreateContainerCmd withStdinOpen(Boolean stdinOpen); + CreateContainerCmd withStdinOpen(Boolean stdinOpen); - public CreateContainerCmd withTty(Boolean tty); + CreateContainerCmd withTty(Boolean tty); - public CreateContainerCmd withUlimits(Ulimit... ulimits); + CreateContainerCmd withUlimits(Ulimit... ulimits); - public CreateContainerCmd withUlimits(List ulimits); + CreateContainerCmd withUlimits(List ulimits); - public CreateContainerCmd withUser(String user); + CreateContainerCmd withUser(String user); - public CreateContainerCmd withVolumes(Volume... volumes); + CreateContainerCmd withVolumes(Volume... volumes); - public CreateContainerCmd withVolumes(List volumes); + CreateContainerCmd withVolumes(List volumes); - public CreateContainerCmd withVolumesFrom(VolumesFrom... volumesFrom); + CreateContainerCmd withVolumesFrom(VolumesFrom... volumesFrom); - public CreateContainerCmd withVolumesFrom(List volumesFrom); + CreateContainerCmd withVolumesFrom(List volumesFrom); - public CreateContainerCmd withWorkingDir(String workingDir); + CreateContainerCmd withWorkingDir(String workingDir); /** * Set the PID (Process) Namespace mode for the container, 'host': use the host's PID namespace inside the container */ - public CreateContainerCmd withPidMode(String pidMode); + CreateContainerCmd withPidMode(String pidMode); /** * @throws NotFoundException @@ -414,8 +414,8 @@ public interface CreateContainerCmd extends SyncDockerCmd { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/CreateImageCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateImageCmd.java index db10a374c..86935cd10 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateImageCmd.java @@ -8,34 +8,34 @@ public interface CreateImageCmd extends SyncDockerCmd { @CheckForNull - public String getRepository(); + String getRepository(); @CheckForNull - public String getTag(); + String getTag(); @CheckForNull - public InputStream getImageStream(); + InputStream getImageStream(); /** * @param repository * the repository to import to */ - public CreateImageCmd withRepository(@Nonnull String repository); + CreateImageCmd withRepository(@Nonnull String repository); /** * @param imageStream * the InputStream of the tar file */ - public CreateImageCmd withImageStream(InputStream imageStream); + CreateImageCmd withImageStream(InputStream imageStream); /** * @param tag * any tag for this image * @deprecated use repo:tag format for repository */ - public CreateImageCmd withTag(String tag); + CreateImageCmd withTag(String tag); - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } 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 82b4ac18c..6ad26b605 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateNetworkCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateNetworkCmd.java @@ -17,26 +17,26 @@ public interface CreateNetworkCmd extends SyncDockerCmd { @CheckForNull - public String getName(); + String getName(); @CheckForNull - public String getDriver(); + String getDriver(); @CheckForNull - public Network.Ipam getIpam(); + Network.Ipam getIpam(); /** The new network's name. Required. */ - public CreateNetworkCmd withName(@Nonnull String name); + CreateNetworkCmd withName(@Nonnull String name); /** Optional custom IP scheme for the network. */ - public CreateNetworkCmd withIpamConfig(Ipam.Config config); + CreateNetworkCmd withIpamConfig(Ipam.Config config); /** Name of the network driver to use. Defaults to bridge. */ - public CreateNetworkCmd withDriver(String driver); + CreateNetworkCmd withDriver(String driver); /** Driver specific options */ - public CreateNetworkCmd withOptions(Map options); + CreateNetworkCmd withOptions(Map options); - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/CreateVolumeCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateVolumeCmd.java index 801fb6122..3d052033f 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateVolumeCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateVolumeCmd.java @@ -7,32 +7,32 @@ public interface CreateVolumeCmd extends SyncDockerCmd { @CheckForNull - public String getName(); + String getName(); @CheckForNull - public String getDriver(); + String getDriver(); @CheckForNull - public Map getDriverOpts(); + Map getDriverOpts(); /** * @param name * - The new volume’s name. If not specified, Docker generates a name. */ - public CreateVolumeCmd withName(String name); + CreateVolumeCmd withName(String name); /** * @param driver * - Name of the volume driver to use. Defaults to local for the name. */ - public CreateVolumeCmd withDriver(String driver); + CreateVolumeCmd withDriver(String driver); /** * @param driverOpts * - A mapping of driver options and values. These options are passed directly to the driver and are driver specific. */ - public CreateVolumeCmd withDriverOpts(Map driverOpts); + CreateVolumeCmd withDriverOpts(Map driverOpts); - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/DisconnectFromNetworkCmd.java b/src/main/java/com/github/dockerjava/api/command/DisconnectFromNetworkCmd.java index a2452416b..ca870ef37 100644 --- a/src/main/java/com/github/dockerjava/api/command/DisconnectFromNetworkCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/DisconnectFromNetworkCmd.java @@ -13,15 +13,15 @@ public interface DisconnectFromNetworkCmd extends SyncDockerCmd { @CheckForNull - public String getNetworkId(); + String getNetworkId(); @CheckForNull - public String getContainerId(); + String getContainerId(); - public DisconnectFromNetworkCmd withNetworkId(@Nonnull String networkId); + DisconnectFromNetworkCmd withNetworkId(@Nonnull String networkId); - public DisconnectFromNetworkCmd withContainerId(@Nonnull String containerId); + DisconnectFromNetworkCmd withContainerId(@Nonnull String containerId); - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmd.java b/src/main/java/com/github/dockerjava/api/command/DockerCmd.java index 27aad850b..ea3ecf0d9 100644 --- a/src/main/java/com/github/dockerjava/api/command/DockerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmd.java @@ -5,6 +5,6 @@ public interface DockerCmd extends Closeable { @Override - public void close(); + void close(); } diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdAsyncExec.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdAsyncExec.java index dfd2a371e..52b16d3c3 100644 --- a/src/main/java/com/github/dockerjava/api/command/DockerCmdAsyncExec.java +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdAsyncExec.java @@ -4,6 +4,6 @@ public interface DockerCmdAsyncExec, A_RES_T> { - public Void exec(CMD_T command, ResultCallback resultCallback); + Void exec(CMD_T command, ResultCallback resultCallback); } diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java index fcaad81fc..8cc42cf15 100644 --- a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java @@ -9,109 +9,109 @@ public interface DockerCmdExecFactory extends Closeable { - public void init(DockerClientConfig dockerClientConfig); + void init(DockerClientConfig dockerClientConfig); - public AuthCmd.Exec createAuthCmdExec(); + AuthCmd.Exec createAuthCmdExec(); - public InfoCmd.Exec createInfoCmdExec(); + InfoCmd.Exec createInfoCmdExec(); - public PingCmd.Exec createPingCmdExec(); + PingCmd.Exec createPingCmdExec(); - public ExecCreateCmd.Exec createExecCmdExec(); + ExecCreateCmd.Exec createExecCmdExec(); - public VersionCmd.Exec createVersionCmdExec(); + VersionCmd.Exec createVersionCmdExec(); - public PullImageCmd.Exec createPullImageCmdExec(); + PullImageCmd.Exec createPullImageCmdExec(); - public PushImageCmd.Exec createPushImageCmdExec(); + PushImageCmd.Exec createPushImageCmdExec(); - public SaveImageCmd.Exec createSaveImageCmdExec(); + SaveImageCmd.Exec createSaveImageCmdExec(); - public CreateImageCmd.Exec createCreateImageCmdExec(); + CreateImageCmd.Exec createCreateImageCmdExec(); - public SearchImagesCmd.Exec createSearchImagesCmdExec(); + SearchImagesCmd.Exec createSearchImagesCmdExec(); - public RemoveImageCmd.Exec createRemoveImageCmdExec(); + RemoveImageCmd.Exec createRemoveImageCmdExec(); - public ListImagesCmd.Exec createListImagesCmdExec(); + ListImagesCmd.Exec createListImagesCmdExec(); - public InspectImageCmd.Exec createInspectImageCmdExec(); + InspectImageCmd.Exec createInspectImageCmdExec(); - public ListContainersCmd.Exec createListContainersCmdExec(); + ListContainersCmd.Exec createListContainersCmdExec(); - public CreateContainerCmd.Exec createCreateContainerCmdExec(); + CreateContainerCmd.Exec createCreateContainerCmdExec(); - public StartContainerCmd.Exec createStartContainerCmdExec(); + StartContainerCmd.Exec createStartContainerCmdExec(); - public InspectContainerCmd.Exec createInspectContainerCmdExec(); + InspectContainerCmd.Exec createInspectContainerCmdExec(); - public RemoveContainerCmd.Exec createRemoveContainerCmdExec(); + RemoveContainerCmd.Exec createRemoveContainerCmdExec(); - public WaitContainerCmd.Exec createWaitContainerCmdExec(); + WaitContainerCmd.Exec createWaitContainerCmdExec(); - public AttachContainerCmd.Exec createAttachContainerCmdExec(); + AttachContainerCmd.Exec createAttachContainerCmdExec(); - public ExecStartCmd.Exec createExecStartCmdExec(); + ExecStartCmd.Exec createExecStartCmdExec(); - public InspectExecCmd.Exec createInspectExecCmdExec(); + InspectExecCmd.Exec createInspectExecCmdExec(); - public LogContainerCmd.Exec createLogContainerCmdExec(); + LogContainerCmd.Exec createLogContainerCmdExec(); - public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec(); + CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec(); - public CopyArchiveFromContainerCmd.Exec createCopyArchiveFromContainerCmdExec(); + CopyArchiveFromContainerCmd.Exec createCopyArchiveFromContainerCmdExec(); - public CopyArchiveToContainerCmd.Exec createCopyArchiveToContainerCmdExec(); + CopyArchiveToContainerCmd.Exec createCopyArchiveToContainerCmdExec(); - public StopContainerCmd.Exec createStopContainerCmdExec(); + StopContainerCmd.Exec createStopContainerCmdExec(); - public ContainerDiffCmd.Exec createContainerDiffCmdExec(); + ContainerDiffCmd.Exec createContainerDiffCmdExec(); - public KillContainerCmd.Exec createKillContainerCmdExec(); + KillContainerCmd.Exec createKillContainerCmdExec(); UpdateContainerCmd.Exec createUpdateContainerCmdExec(); - public RestartContainerCmd.Exec createRestartContainerCmdExec(); + RestartContainerCmd.Exec createRestartContainerCmdExec(); - public CommitCmd.Exec createCommitCmdExec(); + CommitCmd.Exec createCommitCmdExec(); - public BuildImageCmd.Exec createBuildImageCmdExec(); + BuildImageCmd.Exec createBuildImageCmdExec(); - public TopContainerCmd.Exec createTopContainerCmdExec(); + TopContainerCmd.Exec createTopContainerCmdExec(); - public TagImageCmd.Exec createTagImageCmdExec(); + TagImageCmd.Exec createTagImageCmdExec(); - public PauseContainerCmd.Exec createPauseContainerCmdExec(); + PauseContainerCmd.Exec createPauseContainerCmdExec(); - public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec(); + UnpauseContainerCmd.Exec createUnpauseContainerCmdExec(); - public EventsCmd.Exec createEventsCmdExec(); + EventsCmd.Exec createEventsCmdExec(); - public StatsCmd.Exec createStatsCmdExec(); + StatsCmd.Exec createStatsCmdExec(); - public CreateVolumeCmd.Exec createCreateVolumeCmdExec(); + CreateVolumeCmd.Exec createCreateVolumeCmdExec(); - public InspectVolumeCmd.Exec createInspectVolumeCmdExec(); + InspectVolumeCmd.Exec createInspectVolumeCmdExec(); - public RemoveVolumeCmd.Exec createRemoveVolumeCmdExec(); + RemoveVolumeCmd.Exec createRemoveVolumeCmdExec(); - public ListVolumesCmd.Exec createListVolumesCmdExec(); + ListVolumesCmd.Exec createListVolumesCmdExec(); - public ListNetworksCmd.Exec createListNetworksCmdExec(); + ListNetworksCmd.Exec createListNetworksCmdExec(); - public InspectNetworkCmd.Exec createInspectNetworkCmdExec(); + InspectNetworkCmd.Exec createInspectNetworkCmdExec(); - public CreateNetworkCmd.Exec createCreateNetworkCmdExec(); + CreateNetworkCmd.Exec createCreateNetworkCmdExec(); - public RemoveNetworkCmd.Exec createRemoveNetworkCmdExec(); + RemoveNetworkCmd.Exec createRemoveNetworkCmdExec(); - public ConnectToNetworkCmd.Exec createConnectToNetworkCmdExec(); + ConnectToNetworkCmd.Exec createConnectToNetworkCmdExec(); - public DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec(); + DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec(); - public DockerCmdExecFactory withSSLContext(SSLContext sslContext); + DockerCmdExecFactory withSSLContext(SSLContext sslContext); @Override - public void close() throws IOException; + void close() throws IOException; } diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdSyncExec.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdSyncExec.java index 678b4afe1..a4cd40707 100644 --- a/src/main/java/com/github/dockerjava/api/command/DockerCmdSyncExec.java +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdSyncExec.java @@ -2,6 +2,6 @@ public interface DockerCmdSyncExec, RES_T> { - public RES_T exec(CMD_T command); + RES_T exec(CMD_T command); } diff --git a/src/main/java/com/github/dockerjava/api/command/EventsCmd.java b/src/main/java/com/github/dockerjava/api/command/EventsCmd.java index 8c03270df..c52706226 100644 --- a/src/main/java/com/github/dockerjava/api/command/EventsCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/EventsCmd.java @@ -13,56 +13,56 @@ public interface EventsCmd extends AsyncDockerCmd { @CheckForNull - public Map> getFilters(); + Map> getFilters(); @CheckForNull - public String getSince(); + String getSince(); @CheckForNull - public String getUntil(); + String getUntil(); /** * @param container * - container to filter */ - public EventsCmd withContainerFilter(String... container); + EventsCmd withContainerFilter(String... container); /** * @param event * - event to filter (pull | create | attach | start | stop | kill) */ - public EventsCmd withEventFilter(String... event); + EventsCmd withEventFilter(String... event); /** * @param image * - image to filter */ - public EventsCmd withImageFilter(String... image); + EventsCmd withImageFilter(String... image); /** * @param label * - label to filter */ - public EventsCmd withLabelFilter(String... label); + EventsCmd withLabelFilter(String... label); /** * @param labels * - labels to filter (map of names and values) */ - public EventsCmd withLabelFilter(Map labels); + EventsCmd withLabelFilter(Map labels); /** * @param since * - Show all events created since timestamp */ - public EventsCmd withSince(String since); + EventsCmd withSince(String since); /** * @param until * - Show all events created until timestamp */ - public EventsCmd withUntil(String until); + EventsCmd withUntil(String until); - public static interface Exec extends DockerCmdAsyncExec { + interface Exec extends DockerCmdAsyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java b/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java index 67ffe5818..fe2329290 100644 --- a/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java @@ -6,33 +6,33 @@ public interface ExecCreateCmd extends SyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); @CheckForNull - public Boolean hasAttachStderrEnabled(); + Boolean hasAttachStderrEnabled(); @CheckForNull - public Boolean hasAttachStdinEnabled(); + Boolean hasAttachStdinEnabled(); @CheckForNull - public Boolean hasAttachStdoutEnabled(); + Boolean hasAttachStdoutEnabled(); @CheckForNull - public Boolean hasTtyEnabled(); + Boolean hasTtyEnabled(); - public ExecCreateCmd withAttachStderr(Boolean attachStderr); + ExecCreateCmd withAttachStderr(Boolean attachStderr); - public ExecCreateCmd withAttachStdin(Boolean attachStdin); + ExecCreateCmd withAttachStdin(Boolean attachStdin); - public ExecCreateCmd withAttachStdout(Boolean attachStdout); + ExecCreateCmd withAttachStdout(Boolean attachStdout); - public ExecCreateCmd withCmd(String... cmd); + ExecCreateCmd withCmd(String... cmd); - public ExecCreateCmd withContainerId(@Nonnull String containerId); + ExecCreateCmd withContainerId(@Nonnull String containerId); - public ExecCreateCmd withTty(Boolean tty); + ExecCreateCmd withTty(Boolean tty); - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/ExecStartCmd.java b/src/main/java/com/github/dockerjava/api/command/ExecStartCmd.java index e102ef71b..6d151be61 100644 --- a/src/main/java/com/github/dockerjava/api/command/ExecStartCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ExecStartCmd.java @@ -12,24 +12,24 @@ public interface ExecStartCmd extends AsyncDockerCmd { @CheckForNull - public String getExecId(); + String getExecId(); @CheckForNull - public Boolean hasDetachEnabled(); + Boolean hasDetachEnabled(); @CheckForNull - public Boolean hasTtyEnabled(); + Boolean hasTtyEnabled(); @CheckForNull - public InputStream getStdin(); + InputStream getStdin(); - public ExecStartCmd withDetach(Boolean detach); + ExecStartCmd withDetach(Boolean detach); - public ExecStartCmd withExecId(@Nonnull String execId); + ExecStartCmd withExecId(@Nonnull String execId); - public ExecStartCmd withTty(Boolean tty); + ExecStartCmd withTty(Boolean tty); - public ExecStartCmd withStdIn(InputStream stdin); + ExecStartCmd withStdIn(InputStream stdin); /** * @@ -37,9 +37,9 @@ public interface ExecStartCmd extends AsyncDockerCmd { * No such exec instance */ @Override - public > T exec(T resultCallback); + > T exec(T resultCallback); - public static interface Exec extends DockerCmdAsyncExec { + interface Exec extends DockerCmdAsyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/InfoCmd.java b/src/main/java/com/github/dockerjava/api/command/InfoCmd.java index 257c3bec1..5dead0f45 100644 --- a/src/main/java/com/github/dockerjava/api/command/InfoCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/InfoCmd.java @@ -4,7 +4,7 @@ public interface InfoCmd extends SyncDockerCmd { - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java index b5fbe212f..cb782c64d 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java @@ -8,17 +8,17 @@ public interface InspectContainerCmd extends SyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); - public InspectContainerCmd withContainerId(@Nonnull String containerId); + InspectContainerCmd withContainerId(@Nonnull String containerId); /** * @throws NotFoundException * No such container */ @Override - public InspectContainerResponse exec() throws NotFoundException; + InspectContainerResponse exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/InspectExecCmd.java b/src/main/java/com/github/dockerjava/api/command/InspectExecCmd.java index d1c6b48f1..fdb2577c4 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectExecCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectExecCmd.java @@ -8,17 +8,17 @@ public interface InspectExecCmd extends SyncDockerCmd { @CheckForNull - public String getExecId(); + String getExecId(); - public InspectExecCmd withExecId(@Nonnull String execId); + InspectExecCmd withExecId(@Nonnull String execId); /** * @throws NotFoundException * if no such exec has been found */ @Override - public InspectExecResponse exec() throws NotFoundException; + InspectExecResponse exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/InspectImageCmd.java b/src/main/java/com/github/dockerjava/api/command/InspectImageCmd.java index 253c31e78..411a71bcb 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectImageCmd.java @@ -11,18 +11,18 @@ public interface InspectImageCmd extends SyncDockerCmd { @CheckForNull - public String getImageId(); + String getImageId(); - public InspectImageCmd withImageId(@Nonnull String imageId); + InspectImageCmd withImageId(@Nonnull String imageId); /** * @throws NotFoundException * No such image */ @Override - public InspectImageResponse exec() throws NotFoundException; + InspectImageResponse exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/InspectNetworkCmd.java b/src/main/java/com/github/dockerjava/api/command/InspectNetworkCmd.java index 18394879a..2e5536731 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectNetworkCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectNetworkCmd.java @@ -15,17 +15,17 @@ public interface InspectNetworkCmd extends SyncDockerCmd { @CheckForNull - public String getNetworkId(); + String getNetworkId(); - public InspectNetworkCmd withNetworkId(@Nonnull String networkId); + InspectNetworkCmd withNetworkId(@Nonnull String networkId); /** * @throws NotFoundException * No such network */ @Override - public Network exec() throws NotFoundException; + Network exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/InspectVolumeCmd.java b/src/main/java/com/github/dockerjava/api/command/InspectVolumeCmd.java index bf08e18b4..73d552d22 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectVolumeCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectVolumeCmd.java @@ -10,14 +10,14 @@ */ public interface InspectVolumeCmd extends SyncDockerCmd { - public String getName(); + String getName(); /** * @param name * - The volume’s name. */ - public InspectVolumeCmd withName(@Nonnull String name); + InspectVolumeCmd withName(@Nonnull String name); - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/KillContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/KillContainerCmd.java index aca3902c0..e64d7b393 100644 --- a/src/main/java/com/github/dockerjava/api/command/KillContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/KillContainerCmd.java @@ -11,23 +11,23 @@ public interface KillContainerCmd extends SyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); @CheckForNull - public String getSignal(); + String getSignal(); - public KillContainerCmd withContainerId(@Nonnull String containerId); + KillContainerCmd withContainerId(@Nonnull String containerId); - public KillContainerCmd withSignal(String signal); + KillContainerCmd withSignal(String signal); /** * @throws NotFoundException * No such container */ @Override - public Void exec() throws NotFoundException; + Void exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java b/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java index f55089393..7c6c9acec 100644 --- a/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ListContainersCmd.java @@ -14,78 +14,78 @@ public interface ListContainersCmd extends SyncDockerCmd> { @CheckForNull - public String getBeforeId(); + String getBeforeId(); @CheckForNull - public Map> getFilters(); + Map> getFilters(); @CheckForNull - public Integer getLimit(); + Integer getLimit(); @CheckForNull - public String getSinceId(); + String getSinceId(); @CheckForNull - public Boolean hasShowAllEnabled(); + Boolean hasShowAllEnabled(); @CheckForNull - public Boolean hasShowSizeEnabled(); + Boolean hasShowSizeEnabled(); /** * @param before * - Show only containers created before Id, include non-running ones. */ - public ListContainersCmd withBefore(String before); + ListContainersCmd withBefore(String before); /** * @param exitcode * - Show only containers that exited with the passed exitcode. */ - public ListContainersCmd withExitcodeFilter(Integer exitcode); + ListContainersCmd withExitcodeFilter(Integer exitcode); /** * @param status * - Show only containers with the passed status (created|restarting|running|paused|exited). */ - public ListContainersCmd withStatusFilter(String status); + ListContainersCmd withStatusFilter(String status); /** * @param labels * - Show only containers with the passed labels. */ - public ListContainersCmd withLabelFilter(String... labels); + ListContainersCmd withLabelFilter(String... labels); /** * @param labels * - Show only containers with the passed labels. Labels is a {@link Map} that contains label keys and values */ - public ListContainersCmd withLabelFilter(Map labels); + ListContainersCmd withLabelFilter(Map labels); /** * @param limit * - Show `limit` last created containers, include non-running ones. There is no limit by default. */ - public ListContainersCmd withLimit(Integer limit); + ListContainersCmd withLimit(Integer limit); /** * @param showAll * - Show all containers. Only running containers are shown by default. */ - public ListContainersCmd withShowAll(Boolean showAll); + ListContainersCmd withShowAll(Boolean showAll); /** * @param showSize * - Show the containers sizes. This is false by default. */ - public ListContainersCmd withShowSize(Boolean showSize); + ListContainersCmd withShowSize(Boolean showSize); /** * @param since * - Show only containers created since Id, include non-running ones. */ - public ListContainersCmd withSince(String since); + ListContainersCmd withSince(String since); - public static interface Exec extends DockerCmdSyncExec> { + interface Exec extends DockerCmdSyncExec> { } } diff --git a/src/main/java/com/github/dockerjava/api/command/ListImagesCmd.java b/src/main/java/com/github/dockerjava/api/command/ListImagesCmd.java index 7dee8c918..7741df743 100644 --- a/src/main/java/com/github/dockerjava/api/command/ListImagesCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ListImagesCmd.java @@ -13,38 +13,38 @@ public interface ListImagesCmd extends SyncDockerCmd> { @CheckForNull - public Map> getFilters(); + Map> getFilters(); - public String getImageNameFilter(); + String getImageNameFilter(); @CheckForNull - public Boolean hasShowAllEnabled(); + Boolean hasShowAllEnabled(); /** * Show all images (by default filter out the intermediate images used to build) */ - public ListImagesCmd withShowAll(Boolean showAll); + ListImagesCmd withShowAll(Boolean showAll); - public ListImagesCmd withImageNameFilter(String imageName); + ListImagesCmd withImageNameFilter(String imageName); /** * Filter dangling images */ - public ListImagesCmd withDanglingFilter(Boolean dangling); + ListImagesCmd withDanglingFilter(Boolean dangling); /** * @param labels * - string array in the form ["key"] or ["key=value"] or a mix of both */ - public ListImagesCmd withLabelFilter(String... label); + ListImagesCmd withLabelFilter(String... label); /** * @param labels * - {@link Map} of labels that contains label keys and values */ - public ListImagesCmd withLabelFilter(Map labels); + ListImagesCmd withLabelFilter(Map labels); - public static interface Exec extends DockerCmdSyncExec> { + interface Exec extends DockerCmdSyncExec> { } } diff --git a/src/main/java/com/github/dockerjava/api/command/ListNetworksCmd.java b/src/main/java/com/github/dockerjava/api/command/ListNetworksCmd.java index dd3c89c7b..23d92151c 100644 --- a/src/main/java/com/github/dockerjava/api/command/ListNetworksCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ListNetworksCmd.java @@ -16,12 +16,12 @@ public interface ListNetworksCmd extends SyncDockerCmd> { @CheckForNull - public Map> getFilters(); + Map> getFilters(); ListNetworksCmd withNameFilter(String... networkName); ListNetworksCmd withIdFilter(String... networkId); - public static interface Exec extends DockerCmdSyncExec> { + interface Exec extends DockerCmdSyncExec> { } } diff --git a/src/main/java/com/github/dockerjava/api/command/ListVolumesCmd.java b/src/main/java/com/github/dockerjava/api/command/ListVolumesCmd.java index a049aa20f..88c6ee291 100644 --- a/src/main/java/com/github/dockerjava/api/command/ListVolumesCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ListVolumesCmd.java @@ -13,14 +13,14 @@ public interface ListVolumesCmd extends SyncDockerCmd { @CheckForNull - public Map> getFilters(); + Map> getFilters(); /** * @param dangling * - Show dangling volumes filter */ - public ListVolumesCmd withDanglingFilter(Boolean dangling); + ListVolumesCmd withDanglingFilter(Boolean dangling); - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/LogContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/LogContainerCmd.java index bb3081ce4..53674cbaa 100644 --- a/src/main/java/com/github/dockerjava/api/command/LogContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/LogContainerCmd.java @@ -29,54 +29,54 @@ public interface LogContainerCmd extends AsyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); @CheckForNull - public Integer getTail(); + Integer getTail(); @CheckForNull - public Boolean hasFollowStreamEnabled(); + Boolean hasFollowStreamEnabled(); @CheckForNull - public Boolean hasTimestampsEnabled(); + Boolean hasTimestampsEnabled(); @CheckForNull - public Boolean hasStdoutEnabled(); + Boolean hasStdoutEnabled(); @CheckForNull - public Boolean hasStderrEnabled(); + Boolean hasStderrEnabled(); @CheckForNull - public Integer getSince(); + Integer getSince(); - public LogContainerCmd withContainerId(@Nonnull String containerId); + LogContainerCmd withContainerId(@Nonnull String containerId); /** * Following the stream means the resulting {@link InputStream} returned by {@link #exec()} reads infinitely. So a * {@link InputStream#read()} MAY BLOCK FOREVER as long as no data is streamed from the docker host to {@link DockerClient}! */ - public LogContainerCmd withFollowStream(Boolean followStream); + LogContainerCmd withFollowStream(Boolean followStream); - public LogContainerCmd withTimestamps(Boolean timestamps); + LogContainerCmd withTimestamps(Boolean timestamps); - public LogContainerCmd withStdOut(Boolean stdout); + LogContainerCmd withStdOut(Boolean stdout); - public LogContainerCmd withStdErr(Boolean stderr); + LogContainerCmd withStdErr(Boolean stderr); - public LogContainerCmd withTailAll(); + LogContainerCmd withTailAll(); - public LogContainerCmd withTail(Integer tail); + LogContainerCmd withTail(Integer tail); - public LogContainerCmd withSince(Integer since); + LogContainerCmd withSince(Integer since); /** * @throws com.github.dockerjava.api.NotFoundException * No such container */ @Override - public > T exec(T resultCallback); + > T exec(T resultCallback); - public static interface Exec extends DockerCmdAsyncExec { + interface Exec extends DockerCmdAsyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/PauseContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/PauseContainerCmd.java index 74a4c86bc..813c40d50 100644 --- a/src/main/java/com/github/dockerjava/api/command/PauseContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/PauseContainerCmd.java @@ -15,18 +15,18 @@ public interface PauseContainerCmd extends SyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); - public PauseContainerCmd withContainerId(@Nonnull String containerId); + PauseContainerCmd withContainerId(@Nonnull String containerId); /** * @throws NotFoundException * No such container */ @Override - public Void exec() throws NotFoundException; + Void exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/PingCmd.java b/src/main/java/com/github/dockerjava/api/command/PingCmd.java index 07de7e959..54b81b981 100644 --- a/src/main/java/com/github/dockerjava/api/command/PingCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/PingCmd.java @@ -6,7 +6,7 @@ */ public interface PingCmd extends SyncDockerCmd { - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/PullImageCmd.java b/src/main/java/com/github/dockerjava/api/command/PullImageCmd.java index 319fecd14..8127f7b1f 100644 --- a/src/main/java/com/github/dockerjava/api/command/PullImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/PullImageCmd.java @@ -14,24 +14,24 @@ public interface PullImageCmd extends AsyncDockerCmd { @CheckForNull - public String getRepository(); + String getRepository(); @CheckForNull - public String getTag(); + String getTag(); @CheckForNull - public String getRegistry(); + String getRegistry(); - public AuthConfig getAuthConfig(); + AuthConfig getAuthConfig(); - public PullImageCmd withRepository(@Nonnull String repository); + PullImageCmd withRepository(@Nonnull String repository); - public PullImageCmd withTag(String tag); + PullImageCmd withTag(String tag); - public PullImageCmd withRegistry(String registry); + PullImageCmd withRegistry(String registry); - public PullImageCmd withAuthConfig(AuthConfig authConfig); + PullImageCmd withAuthConfig(AuthConfig authConfig); - public static interface Exec extends DockerCmdAsyncExec { + interface Exec extends DockerCmdAsyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/PushImageCmd.java b/src/main/java/com/github/dockerjava/api/command/PushImageCmd.java index 8b9f3961e..abd86c53c 100644 --- a/src/main/java/com/github/dockerjava/api/command/PushImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/PushImageCmd.java @@ -17,35 +17,35 @@ public interface PushImageCmd extends AsyncDockerCmd { @CheckForNull - public AuthConfig getAuthConfig(); + AuthConfig getAuthConfig(); @CheckForNull - public String getName(); + String getName(); @CheckForNull - public String getTag(); + String getTag(); /** * @param name * The name, e.g. "alexec/busybox" or just "busybox" if you want to default. Not null. */ - public PushImageCmd withName(@Nonnull String name); + PushImageCmd withName(@Nonnull String name); /** * @param tag * The image's tag. Not null. */ - public PushImageCmd withTag(String tag); + PushImageCmd withTag(String tag); - public PushImageCmd withAuthConfig(AuthConfig authConfig); + PushImageCmd withAuthConfig(AuthConfig authConfig); /** * @throws NotFoundException * No such image */ @Override - public > T exec(T resultCallback); + > T exec(T resultCallback); - public static interface Exec extends DockerCmdAsyncExec { + interface Exec extends DockerCmdAsyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/RemoveContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/RemoveContainerCmd.java index bcc700d03..0a057af81 100644 --- a/src/main/java/com/github/dockerjava/api/command/RemoveContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/RemoveContainerCmd.java @@ -16,28 +16,28 @@ public interface RemoveContainerCmd extends SyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); @CheckForNull - public Boolean hasRemoveVolumesEnabled(); + Boolean hasRemoveVolumesEnabled(); @CheckForNull - public Boolean hasForceEnabled(); + Boolean hasForceEnabled(); - public RemoveContainerCmd withContainerId(@Nonnull String containerId); + RemoveContainerCmd withContainerId(@Nonnull String containerId); - public RemoveContainerCmd withRemoveVolumes(Boolean removeVolumes); + RemoveContainerCmd withRemoveVolumes(Boolean removeVolumes); - public RemoveContainerCmd withForce(Boolean force); + RemoveContainerCmd withForce(Boolean force); /** * @throws NotFoundException * No such container */ @Override - public Void exec() throws NotFoundException; + Void exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/RemoveImageCmd.java b/src/main/java/com/github/dockerjava/api/command/RemoveImageCmd.java index cfd9c36cd..a1942b69b 100644 --- a/src/main/java/com/github/dockerjava/api/command/RemoveImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/RemoveImageCmd.java @@ -13,35 +13,35 @@ public interface RemoveImageCmd extends SyncDockerCmd { @CheckForNull - public String getImageId(); + String getImageId(); @CheckForNull - public Boolean hasForceEnabled(); + Boolean hasForceEnabled(); @CheckForNull - public Boolean hasNoPruneEnabled(); + Boolean hasNoPruneEnabled(); - public RemoveImageCmd withImageId(@Nonnull String imageId); + RemoveImageCmd withImageId(@Nonnull String imageId); /** * force parameter to force delete of an image, even if it's tagged in multiple repositories */ - public RemoveImageCmd withForce(Boolean force); + RemoveImageCmd withForce(Boolean force); /** * noprune parameter to prevent the deletion of parent images * */ - public RemoveImageCmd withNoPrune(Boolean noPrune); + RemoveImageCmd withNoPrune(Boolean noPrune); /** * @throws NotFoundException * No such image */ @Override - public Void exec() throws NotFoundException; + Void exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/RemoveNetworkCmd.java b/src/main/java/com/github/dockerjava/api/command/RemoveNetworkCmd.java index 3dcb428e2..b6ad0e652 100644 --- a/src/main/java/com/github/dockerjava/api/command/RemoveNetworkCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/RemoveNetworkCmd.java @@ -14,17 +14,17 @@ public interface RemoveNetworkCmd extends SyncDockerCmd { @CheckForNull - public String getNetworkId(); + String getNetworkId(); - public RemoveNetworkCmd withNetworkId(@Nonnull String networkId); + RemoveNetworkCmd withNetworkId(@Nonnull String networkId); /** * @throws NotFoundException * No such network */ @Override - public Void exec() throws NotFoundException; + Void exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/RemoveVolumeCmd.java b/src/main/java/com/github/dockerjava/api/command/RemoveVolumeCmd.java index ba136af25..c21ad240d 100644 --- a/src/main/java/com/github/dockerjava/api/command/RemoveVolumeCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/RemoveVolumeCmd.java @@ -12,9 +12,9 @@ */ public interface RemoveVolumeCmd extends SyncDockerCmd { - public String getName(); + String getName(); - public RemoveVolumeCmd withName(@Nonnull String name); + RemoveVolumeCmd withName(@Nonnull String name); /** * @throws NotFoundException @@ -23,8 +23,8 @@ public interface RemoveVolumeCmd extends SyncDockerCmd { * Volume is in use and cannot be removed */ @Override - public Void exec() throws NotFoundException; + Void exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/RestartContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/RestartContainerCmd.java index d15666437..5dcc59c24 100644 --- a/src/main/java/com/github/dockerjava/api/command/RestartContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/RestartContainerCmd.java @@ -15,23 +15,23 @@ public interface RestartContainerCmd extends SyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); @CheckForNull - public Integer getTimeout(); + Integer getTimeout(); - public RestartContainerCmd withContainerId(@Nonnull String containerId); + RestartContainerCmd withContainerId(@Nonnull String containerId); - public RestartContainerCmd withtTimeout(Integer timeout); + RestartContainerCmd withtTimeout(Integer timeout); /** * @throws NotFoundException * No such container */ @Override - public Void exec() throws NotFoundException; + Void exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/SaveImageCmd.java b/src/main/java/com/github/dockerjava/api/command/SaveImageCmd.java index 272a2d564..aee9011cb 100644 --- a/src/main/java/com/github/dockerjava/api/command/SaveImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/SaveImageCmd.java @@ -10,22 +10,22 @@ public interface SaveImageCmd extends SyncDockerCmd { @CheckForNull - public String getName(); + String getName(); @CheckForNull - public String getTag(); + String getTag(); /** * @param name * The name, e.g. "alexec/busybox" or just "busybox" if you want to default. Not null. */ - public SaveImageCmd withName(@Nonnull String name); + SaveImageCmd withName(@Nonnull String name); /** * @param tag * The image's tag. Not null. */ - public SaveImageCmd withTag(String tag); + SaveImageCmd withTag(String tag); /** * Its the responsibility of the caller to consume and/or close the {@link InputStream} to prevent connection leaks. @@ -33,9 +33,9 @@ public interface SaveImageCmd extends SyncDockerCmd { * @throws NotFoundException * No such image */ - public InputStream exec() throws NotFoundException; + InputStream exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/SearchImagesCmd.java b/src/main/java/com/github/dockerjava/api/command/SearchImagesCmd.java index 42cd6917e..2bc87cc73 100644 --- a/src/main/java/com/github/dockerjava/api/command/SearchImagesCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/SearchImagesCmd.java @@ -17,11 +17,11 @@ public interface SearchImagesCmd extends SyncDockerCmd> { @CheckForNull - public String getTerm(); + String getTerm(); - public SearchImagesCmd withTerm(@Nonnull String term); + SearchImagesCmd withTerm(@Nonnull String term); - public static interface Exec extends DockerCmdSyncExec> { + interface Exec extends DockerCmdSyncExec> { } } diff --git a/src/main/java/com/github/dockerjava/api/command/StartContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/StartContainerCmd.java index 4be500b4f..e82f7f433 100644 --- a/src/main/java/com/github/dockerjava/api/command/StartContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/StartContainerCmd.java @@ -24,8 +24,8 @@ public interface StartContainerCmd extends SyncDockerCmd { * Container already started */ @Override - public Void exec() throws NotFoundException, NotModifiedException; + Void exec() throws NotFoundException, NotModifiedException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/StatsCmd.java b/src/main/java/com/github/dockerjava/api/command/StatsCmd.java index d2d7fe385..6085a810b 100644 --- a/src/main/java/com/github/dockerjava/api/command/StatsCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/StatsCmd.java @@ -12,10 +12,10 @@ public interface StatsCmd extends AsyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); - public StatsCmd withContainerId(@Nonnull String containerId); + StatsCmd withContainerId(@Nonnull String containerId); - public static interface Exec extends DockerCmdAsyncExec { + interface Exec extends DockerCmdAsyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/StopContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/StopContainerCmd.java index 2c99a5fd5..3b39fec9c 100644 --- a/src/main/java/com/github/dockerjava/api/command/StopContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/StopContainerCmd.java @@ -18,14 +18,14 @@ public interface StopContainerCmd extends SyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); @CheckForNull - public Integer getTimeout(); + Integer getTimeout(); - public StopContainerCmd withContainerId(@Nonnull String containerId); + StopContainerCmd withContainerId(@Nonnull String containerId); - public StopContainerCmd withTimeout(Integer timeout); + StopContainerCmd withTimeout(Integer timeout); /** * @throws NotFoundException @@ -34,9 +34,9 @@ public interface StopContainerCmd extends SyncDockerCmd { * Container already stopped */ @Override - public Void exec() throws NotFoundException, NotModifiedException; + Void exec() throws NotFoundException, NotModifiedException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/SyncDockerCmd.java b/src/main/java/com/github/dockerjava/api/command/SyncDockerCmd.java index 4bc55fec6..2105f7b80 100644 --- a/src/main/java/com/github/dockerjava/api/command/SyncDockerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/SyncDockerCmd.java @@ -2,6 +2,6 @@ public interface SyncDockerCmd extends DockerCmd { - public RES_T exec(); + RES_T exec(); } diff --git a/src/main/java/com/github/dockerjava/api/command/TagImageCmd.java b/src/main/java/com/github/dockerjava/api/command/TagImageCmd.java index 08b1411ff..07c8cd335 100644 --- a/src/main/java/com/github/dockerjava/api/command/TagImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/TagImageCmd.java @@ -17,28 +17,28 @@ public interface TagImageCmd extends SyncDockerCmd { @CheckForNull - public String getImageId(); + String getImageId(); @CheckForNull - public String getRepository(); + String getRepository(); @CheckForNull - public String getTag(); + String getTag(); @CheckForNull - public Boolean hasForceEnabled(); + Boolean hasForceEnabled(); - public TagImageCmd withImageId(@Nonnull String imageId); + TagImageCmd withImageId(@Nonnull String imageId); - public TagImageCmd withRepository(String repository); + TagImageCmd withRepository(String repository); - public TagImageCmd withTag(String tag); + TagImageCmd withTag(String tag); - public TagImageCmd withForce(); + TagImageCmd withForce(); - public TagImageCmd withForce(Boolean force); + TagImageCmd withForce(Boolean force); - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/TopContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/TopContainerCmd.java index edde72628..7cf2cee46 100644 --- a/src/main/java/com/github/dockerjava/api/command/TopContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/TopContainerCmd.java @@ -11,23 +11,23 @@ public interface TopContainerCmd extends SyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); @CheckForNull - public String getPsArgs(); + String getPsArgs(); - public TopContainerCmd withContainerId(@Nonnull String containerId); + TopContainerCmd withContainerId(@Nonnull String containerId); - public TopContainerCmd withPsArgs(String psArgs); + TopContainerCmd withPsArgs(String psArgs); /** * @throws NotFoundException * No such container */ @Override - public TopContainerResponse exec() throws NotFoundException; + TopContainerResponse exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/UnpauseContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/UnpauseContainerCmd.java index 8b751e55c..28c2e7d36 100644 --- a/src/main/java/com/github/dockerjava/api/command/UnpauseContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/UnpauseContainerCmd.java @@ -15,18 +15,18 @@ public interface UnpauseContainerCmd extends SyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); - public UnpauseContainerCmd withContainerId(@Nonnull String containerId); + UnpauseContainerCmd withContainerId(@Nonnull String containerId); /** * @throws NotFoundException * No such container */ @Override - public Void exec() throws NotFoundException; + Void exec() throws NotFoundException; - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java index d7e32e445..a834b7ba0 100644 --- a/src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/UpdateContainerCmd.java @@ -15,51 +15,51 @@ public interface UpdateContainerCmd extends SyncDockerCmd { - public static interface Exec extends DockerCmdSyncExec { + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/WaitContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/WaitContainerCmd.java index 6512e48d4..daa4e5d3c 100644 --- a/src/main/java/com/github/dockerjava/api/command/WaitContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/WaitContainerCmd.java @@ -15,18 +15,18 @@ public interface WaitContainerCmd extends AsyncDockerCmd { @CheckForNull - public String getContainerId(); + String getContainerId(); - public WaitContainerCmd withContainerId(@Nonnull String containerId); + WaitContainerCmd withContainerId(@Nonnull String containerId); /** * @throws NotFoundException * container not found */ @Override - public > T exec(T resultCallback); + > T exec(T resultCallback); - public static interface Exec extends DockerCmdAsyncExec { + interface Exec extends DockerCmdAsyncExec { } } 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 8c1bbdb86..f4fd0e958 100644 --- a/src/main/java/com/github/dockerjava/api/model/LogConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/LogConfig.java @@ -68,7 +68,7 @@ public LogConfig setConfig(Map config) { @JsonDeserialize(using = LoggingType.Deserializer.class) @JsonSerialize(using = LoggingType.Serializer.class) - public static enum LoggingType { + public enum LoggingType { DEFAULT("json-file"), JSON_FILE("json-file"), NONE("none"), @@ -81,7 +81,7 @@ public static enum LoggingType { private String type; - private LoggingType(String type) { + LoggingType(String type) { this.type = type; } diff --git a/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java b/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java index 62dce2adc..fa5dba722 100644 --- a/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java +++ b/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java @@ -245,7 +245,7 @@ private static final class ScanResult { public String pattern; - public ScanResult(boolean star, String chunk, String pattern) { + ScanResult(boolean star, String chunk, String pattern) { this.star = star; this.chunk = chunk; this.pattern = pattern; @@ -257,7 +257,7 @@ private static final class GetEscResult { public int chunkOffset; - public GetEscResult(char lo, int chunkOffset) { + GetEscResult(char lo, int chunkOffset) { this.lo = lo; this.chunkOffset = chunkOffset; } diff --git a/src/main/java/com/github/dockerjava/netty/MediaType.java b/src/main/java/com/github/dockerjava/netty/MediaType.java index fac3a95e0..f65ca913f 100644 --- a/src/main/java/com/github/dockerjava/netty/MediaType.java +++ b/src/main/java/com/github/dockerjava/netty/MediaType.java @@ -14,7 +14,7 @@ public enum MediaType { private String mediaType; - private MediaType(String mediaType) { + MediaType(String mediaType) { this.mediaType = mediaType; } diff --git a/src/main/java/com/github/dockerjava/netty/handler/HttpRequestProvider.java b/src/main/java/com/github/dockerjava/netty/handler/HttpRequestProvider.java index 0d861cc01..ff4e02b63 100644 --- a/src/main/java/com/github/dockerjava/netty/handler/HttpRequestProvider.java +++ b/src/main/java/com/github/dockerjava/netty/handler/HttpRequestProvider.java @@ -4,5 +4,5 @@ public interface HttpRequestProvider { - public HttpRequest getHttpRequest(String uri); + HttpRequest getHttpRequest(String uri); } diff --git a/src/test/resources/checkstyle/checkstyle-config.xml b/src/test/resources/checkstyle/checkstyle-config.xml index ea30a270d..33508c723 100644 --- a/src/test/resources/checkstyle/checkstyle-config.xml +++ b/src/test/resources/checkstyle/checkstyle-config.xml @@ -115,8 +115,7 @@ - - + From 970fbb60b8c07fd55371f5bcd2a5b22eefe6cc16 Mon Sep 17 00:00:00 2001 From: Matthew Avant Date: Wed, 9 Mar 2016 21:13:26 -0800 Subject: [PATCH 056/855] Expose cgroup-parent to the client --- .../dockerjava/api/command/CreateContainerCmd.java | 5 +++++ .../core/command/CreateContainerCmdImpl.java | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java index 1454a5f80..0181d86be 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java @@ -179,6 +179,9 @@ public interface CreateContainerCmd extends SyncDockerCmd Date: Fri, 11 Mar 2016 00:48:27 +0300 Subject: [PATCH 057/855] Update image inspect response. Closes #493 --- .../dockerjava/api/command/GraphDriver.java | 76 ++++ .../api/command/InspectImageResponse.java | 277 ++++++++++++++- .../dockerjava/api/model/ContainerConfig.java | 334 ++++++++++++++++-- .../api/command/InspectImageResponseTest.java | 163 +++++++++ .../samples/1.22/images/docImage/doc.json | 89 +++++ .../samples/1.22/images/image1/inspect1.json | 69 ++++ 6 files changed, 953 insertions(+), 55 deletions(-) create mode 100644 src/main/java/com/github/dockerjava/api/command/GraphDriver.java create mode 100644 src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java create mode 100644 src/test/resources/samples/1.22/images/docImage/doc.json create mode 100644 src/test/resources/samples/1.22/images/image1/inspect1.json diff --git a/src/main/java/com/github/dockerjava/api/command/GraphDriver.java b/src/main/java/com/github/dockerjava/api/command/GraphDriver.java new file mode 100644 index 000000000..6285195c4 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/GraphDriver.java @@ -0,0 +1,76 @@ +package com.github.dockerjava.api.command; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; + +/** + * Part of {@link InspectImageResponse} + * + * @author Kanstantsin Shautsou + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_21} + */ +public class GraphDriver { + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_21} + */ + @JsonProperty("Name") + private String name; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_21} + */ + @JsonProperty("Data") + private String data; + + + /** + * @see #data + */ + @CheckForNull + public String getData() { + return data; + } + + /** + * @see #data + */ + public GraphDriver withData(String data) { + this.data = data; + return this; + } + + /** + * @see #name + */ + @CheckForNull + public String getName() { + return name; + } + + /** + * @see #name + */ + public GraphDriver withName(String name) { + this.name = name; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/InspectImageResponse.java b/src/main/java/com/github/dockerjava/api/command/InspectImageResponse.java index db9184c6d..740a1b832 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectImageResponse.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectImageResponse.java @@ -1,11 +1,16 @@ package com.github.dockerjava.api.command; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.github.dockerjava.api.model.ContainerConfig; +import javax.annotation.CheckForNull; +import java.util.List; + /** * * @author Konstantin Pelykh (kpelykh@gmail.com) @@ -50,56 +55,292 @@ public class InspectImageResponse { @JsonProperty("Size") private Long size; - public String getId() { - return id; + @JsonProperty("RepoTags") + private List repoTags; + + @JsonProperty("RepoDigests") + private List repoDigests; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_21} + */ + @JsonProperty("VirtualSize") + private Long virtualSize; + + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_21} + */ + @JsonProperty("GraphDriver") + private GraphDriver graphDriver; + + /** + * @see #arch + */ + @CheckForNull + public String getArch() { + return arch; } - public String getParent() { - return parent; + /** + * @see #arch + */ + public InspectImageResponse withArch(String arch) { + this.arch = arch; + return this; } - public String getCreated() { - return created; + /** + * @see #author + */ + @CheckForNull + public String getAuthor() { + return author; + } + + /** + * @see #author + */ + public InspectImageResponse withAuthor(String author) { + this.author = author; + return this; + } + + /** + * @see #comment + */ + @CheckForNull + public String getComment() { + return comment; + } + + /** + * @see #comment + */ + public InspectImageResponse withComment(String comment) { + this.comment = comment; + return this; + } + + /** + * @see #config + */ + @CheckForNull + public ContainerConfig getConfig() { + return config; } + /** + * @see #config + */ + public InspectImageResponse withConfig(ContainerConfig config) { + this.config = config; + return this; + } + + /** + * @see #container + */ + @CheckForNull public String getContainer() { return container; } + /** + * @see #container + */ + public InspectImageResponse withContainer(String container) { + this.container = container; + return this; + } + + /** + * @see #containerConfig + */ + @CheckForNull public ContainerConfig getContainerConfig() { return containerConfig; } - public Long getSize() { - return size; + /** + * @see #containerConfig + */ + public InspectImageResponse withContainerConfig(ContainerConfig containerConfig) { + this.containerConfig = containerConfig; + return this; } - public String getDockerVersion() { - return dockerVersion; + /** + * @see #created + */ + @CheckForNull + public String getCreated() { + return created; } - public ContainerConfig getConfig() { - return config; + /** + * @see #created + */ + public InspectImageResponse withCreated(String created) { + this.created = created; + return this; } - public String getArch() { - return arch; + /** + * @see #dockerVersion + */ + @CheckForNull + public String getDockerVersion() { + return dockerVersion; } - public String getComment() { - return comment; + /** + * @see #dockerVersion + */ + public InspectImageResponse withDockerVersion(String dockerVersion) { + this.dockerVersion = dockerVersion; + return this; } - public String getAuthor() { - return author; + /** + * @see #id + */ + @CheckForNull + public String getId() { + return id; } + /** + * @see #id + */ + public InspectImageResponse withId(String id) { + this.id = id; + return this; + } + + /** + * @see #os + */ + @CheckForNull public String getOs() { return os; } + /** + * @see #os + */ + public InspectImageResponse withOs(String os) { + this.os = os; + return this; + } + + /** + * @see #parent + */ + @CheckForNull + public String getParent() { + return parent; + } + + /** + * @see #parent + */ + public InspectImageResponse withParent(String parent) { + this.parent = parent; + return this; + } + + /** + * @see #repoTags + */ + @CheckForNull + public List getRepoTags() { + return repoTags; + } + + /** + * @see #repoTags + */ + public InspectImageResponse withRepoTags(List repoTags) { + this.repoTags = repoTags; + return this; + } + + /** + * @see #size + */ + @CheckForNull + public Long getSize() { + return size; + } + + /** + * @see #size + */ + public InspectImageResponse withSize(Long size) { + this.size = size; + return this; + } + + /** + * @see #repoDigests + */ + @CheckForNull + public List getRepoDigests() { + return repoDigests; + } + + /** + * @see #repoDigests + */ + public InspectImageResponse withRepoDigests(List repoDigests) { + this.repoDigests = repoDigests; + return this; + } + + /** + * @see #graphDriver + */ + @CheckForNull + public GraphDriver getGraphDriver() { + return graphDriver; + } + + /** + * @see #graphDriver + */ + public InspectImageResponse withGraphDriver(GraphDriver graphDriver) { + this.graphDriver = graphDriver; + return this; + } + + /** + * @see #virtualSize + */ + @CheckForNull + public Long getVirtualSize() { + return virtualSize; + } + + /** + * @see #virtualSize + */ + public InspectImageResponse withVirtualSize(Long virtualSize) { + this.virtualSize = virtualSize; + return this; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this); } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } } diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java index d7f4b81ee..224da3272 100644 --- a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java @@ -1,19 +1,21 @@ package com.github.dockerjava.api.model; -import java.util.Map; - -import org.apache.commons.lang.builder.ToStringBuilder; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; +import java.util.Map; /** + * Used as part of 'images/IMAGE/someimage' response. * * @author Konstantin Pelykh (kpelykh@gmail.com) - * */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) @@ -87,88 +89,346 @@ public ExposedPort[] getExposedPorts() { return exposedPorts != null ? exposedPorts.getExposedPorts() : null; } - public Boolean isNetworkDisabled() { - return networkDisabled; + /** + * @see #attachStderr + */ + @CheckForNull + public Boolean getAttachStderr() { + return attachStderr; } + /** + * @see #attachStderr + */ + public ContainerConfig withAttachStderr(Boolean attachStderr) { + this.attachStderr = attachStderr; + return this; + } + + /** + * @see #attachStdin + */ + @CheckForNull + public Boolean getAttachStdin() { + return attachStdin; + } + + /** + * @see #attachStdin + */ + public ContainerConfig withAttachStdin(Boolean attachStdin) { + this.attachStdin = attachStdin; + return this; + } + + /** + * @see #attachStdout + */ + @CheckForNull + public Boolean getAttachStdout() { + return attachStdout; + } + + /** + * @see #attachStdout + */ + public ContainerConfig withAttachStdout(Boolean attachStdout) { + this.attachStdout = attachStdout; + return this; + } + + /** + * @see #cmd + */ + @CheckForNull + public String[] getCmd() { + return cmd; + } + + /** + * @see #cmd + */ + public ContainerConfig withCmd(String[] cmd) { + this.cmd = cmd; + return this; + } + + /** + * @see #domainName + */ + @CheckForNull public String getDomainName() { return domainName; } - public String getWorkingDir() { - return workingDir; + /** + * @see #domainName + */ + public ContainerConfig withDomainName(String domainName) { + this.domainName = domainName; + return this; + } + + /** + * @see #entrypoint + */ + @CheckForNull + public String[] getEntrypoint() { + return entrypoint; + } + + /** + * @see #entrypoint + */ + public ContainerConfig withEntrypoint(String[] entrypoint) { + this.entrypoint = entrypoint; + return this; + } + + /** + * @see #env + */ + @CheckForNull + public String[] getEnv() { + return env; } + /** + * @see #env + */ + public ContainerConfig withEnv(String[] env) { + this.env = env; + return this; + } + + /** + * @see #exposedPorts + */ + public ContainerConfig withExposedPorts(ExposedPorts exposedPorts) { + this.exposedPorts = exposedPorts; + return this; + } + + /** + * @see #hostName + */ + @CheckForNull public String getHostName() { return hostName; } - public String[] getPortSpecs() { - return portSpecs; + /** + * @see #hostName + */ + public ContainerConfig withHostName(String hostName) { + this.hostName = hostName; + return this; } - public String getUser() { - return user; + /** + * @see #image + */ + @CheckForNull + public String getImage() { + return image; } - public Boolean isTty() { - return tty; + /** + * @see #image + */ + public ContainerConfig withImage(String image) { + this.image = image; + return this; } - public Boolean isStdinOpen() { - return stdinOpen; + /** + * @see #labels + */ + @CheckForNull + public Map getLabels() { + return labels; } - public Boolean isStdInOnce() { - return stdInOnce; + /** + * @see #labels + */ + public ContainerConfig withLabels(Map labels) { + this.labels = labels; + return this; } + /** + * @see #macAddress + */ + @CheckForNull public String getMacAddress() { return macAddress; } - public Boolean isAttachStdin() { - return attachStdin; + /** + * @see #macAddress + */ + public ContainerConfig withMacAddress(String macAddress) { + this.macAddress = macAddress; + return this; } - public Boolean isAttachStdout() { - return attachStdout; + /** + * @see #networkDisabled + */ + @CheckForNull + public Boolean getNetworkDisabled() { + return networkDisabled; } - public Boolean isAttachStderr() { - return attachStderr; + /** + * @see #networkDisabled + */ + public ContainerConfig withNetworkDisabled(Boolean networkDisabled) { + this.networkDisabled = networkDisabled; + return this; } - public String[] getEnv() { - return env; + /** + * @see #onBuild + */ + @CheckForNull + public String[] getOnBuild() { + return onBuild; } - public String[] getCmd() { - return cmd; + /** + * @see #onBuild + */ + public ContainerConfig withOnBuild(String[] onBuild) { + this.onBuild = onBuild; + return this; } - public String getImage() { - return image; + /** + * @see #portSpecs + */ + @CheckForNull + public String[] getPortSpecs() { + return portSpecs; + } + + /** + * @see #portSpecs + */ + public ContainerConfig withPortSpecs(String[] portSpecs) { + this.portSpecs = portSpecs; + return this; + } + + /** + * @see #stdInOnce + */ + @CheckForNull + public Boolean getStdInOnce() { + return stdInOnce; } + /** + * @see #stdInOnce + */ + public ContainerConfig withStdInOnce(Boolean stdInOnce) { + this.stdInOnce = stdInOnce; + return this; + } + + /** + * @see #stdinOpen + */ + @CheckForNull + public Boolean getStdinOpen() { + return stdinOpen; + } + + /** + * @see #stdinOpen + */ + public ContainerConfig withStdinOpen(Boolean stdinOpen) { + this.stdinOpen = stdinOpen; + return this; + } + + /** + * @see #tty + */ + @CheckForNull + public Boolean getTty() { + return tty; + } + + /** + * @see #tty + */ + public ContainerConfig withTty(Boolean tty) { + this.tty = tty; + return this; + } + + /** + * @see #user + */ + @CheckForNull + public String getUser() { + return user; + } + + /** + * @see #user + */ + public ContainerConfig withUser(String user) { + this.user = user; + return this; + } + + /** + * @see #volumes + */ + @CheckForNull public Map getVolumes() { return volumes; } - public String[] getEntrypoint() { - return entrypoint; + /** + * @see #volumes + */ + public ContainerConfig withVolumes(Map volumes) { + this.volumes = volumes; + return this; } - public String[] getOnBuild() { - return onBuild; + /** + * @see #workingDir + */ + @CheckForNull + public String getWorkingDir() { + return workingDir; } - public Map getLabels() { - return labels; + /** + * @see #workingDir + */ + public ContainerConfig withWorkingDir(String workingDir) { + this.workingDir = workingDir; + return this; } @Override public String toString() { return ToStringBuilder.reflectionToString(this); } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } } diff --git a/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java b/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java new file mode 100644 index 000000000..0df990d00 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java @@ -0,0 +1,163 @@ +package com.github.dockerjava.api.command; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.api.model.ContainerConfig; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.Collections; + +import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_22; +import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; + +/** + * @author Kanstantsin Shautsou + */ +public class InspectImageResponseTest { + @Test + public void serder1_22Json() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().constructType(InspectImageResponse.class); + + final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, + "images/image1/inspect1.json", + type + ); + + final ContainerConfig config = new ContainerConfig() + .withAttachStderr(false) + .withAttachStdin(false) + .withAttachStdout(false) + .withCmd(null) + .withDomainName("") + .withEntrypoint(null) + .withEnv(new String[]{"HOME=/", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}) + .withExposedPorts(null) + .withHostName("aee9ba801acc") + .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") + .withLabels(null) + .withMacAddress(null) + .withNetworkDisabled(null) + .withOnBuild(new String[]{}) + .withStdinOpen(false) + .withPortSpecs(null) + .withStdInOnce(false) + .withTty(false) + .withUser("") + .withVolumes(null) + .withWorkingDir(""); + + final ContainerConfig containerConfig = new ContainerConfig() + .withAttachStderr(false) + .withAttachStdin(false) + .withAttachStdout(false) + .withCmd(new String[]{"/bin/sh", "-c", "#(nop) MAINTAINER hack@worldticket.net"}) + .withDomainName("") + .withEntrypoint(null) + .withEnv(new String[]{"HOME=/", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}) + .withExposedPorts(null) + .withHostName("aee9ba801acc") + .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") + .withLabels(null) + .withMacAddress(null) + .withNetworkDisabled(null) + .withOnBuild(new String[]{}) + .withStdinOpen(false) + .withPortSpecs(null) + .withStdInOnce(false) + .withTty(false) + .withUser("") + .withVolumes(null) + .withWorkingDir(""); + + assertThat(inspectImage, notNullValue()); + assertThat(inspectImage.getArch(), is("amd64")); + assertThat(inspectImage.getAuthor(), is("hack@worldticket.net")); + assertThat(inspectImage.getComment(), isEmptyString()); + + assertThat(inspectImage.getConfig(), notNullValue()); + assertThat(inspectImage.getConfig(), equalTo(config)); + + assertThat(inspectImage.getCreated(), is("2014-04-29T19:59:10.84997669Z")); + assertThat(inspectImage.getContainer(), is("aee9ba801acca0e648ffd91df204ba82ae85d97608a4864a019e2004d7e1b133")); + + assertThat(inspectImage.getContainerConfig(), notNullValue()); + assertThat(inspectImage.getContainerConfig(), equalTo(containerConfig)); + + assertThat(inspectImage.getDockerVersion(), is("0.8.1")); + assertThat(inspectImage.getId(), is("sha256:ee45fe0d1fcdf1a0f9c2d1e36c6f4b3202bbb2032f14d7c9312b27bfcf6aee24")); + assertThat(inspectImage.getOs(), is("linux")); + assertThat(inspectImage.getParent(), isEmptyString()); + assertThat(inspectImage.getSize(), is(0L)); + + assertThat(inspectImage.getRepoTags(), hasSize(1)); + assertThat(inspectImage.getRepoTags(), hasItem("hackmann/empty:latest")); + + final GraphDriver aufsGraphDriver = new GraphDriver().withName("aufs"); + final GraphDriver graphDriver = inspectImage.getGraphDriver(); + assertThat(graphDriver, notNullValue()); + assertThat(graphDriver, equalTo(aufsGraphDriver)); + assertThat(graphDriver.getName(), is("aufs")); + assertThat(graphDriver.getData(), nullValue()); + + assertThat(inspectImage.getVirtualSize(), is(0L)); + + + final InspectImageResponse inspectImageResponse = new InspectImageResponse().withArch("amd64") + .withAuthor("hack@worldticket.net") + .withComment("") + .withConfig(config) + .withContainer("aee9ba801acca0e648ffd91df204ba82ae85d97608a4864a019e2004d7e1b133") + .withContainerConfig(containerConfig) + .withCreated("2014-04-29T19:59:10.84997669Z") + .withDockerVersion("0.8.1") + .withId("sha256:ee45fe0d1fcdf1a0f9c2d1e36c6f4b3202bbb2032f14d7c9312b27bfcf6aee24") + .withOs("linux") + .withParent("") + .withSize(0L) + .withRepoTags(Collections.singletonList("hackmann/empty:latest")) + .withRepoDigests(Collections.emptyList()) + .withVirtualSize(0L) + .withGraphDriver(aufsGraphDriver); + + assertThat(inspectImage, equalTo(inspectImageResponse)); + } + + + @Test + public void serder1_22_doc() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().constructType(InspectImageResponse.class); + + final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, + "images/docImage/doc.json", + type + ); + + assertThat(inspectImage, notNullValue()); + + assertThat(inspectImage.getRepoDigests(), hasSize(1)); + assertThat(inspectImage.getRepoDigests(), + contains("localhost:5000/test/busybox/example@" + + "sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf") + ); + + assertThat(inspectImage.getRepoTags(), hasSize(3)); + assertThat(inspectImage.getRepoTags(), containsInAnyOrder( + "example:1.0", + "example:latest", + "example:stable" + )); + } +} \ No newline at end of file diff --git a/src/test/resources/samples/1.22/images/docImage/doc.json b/src/test/resources/samples/1.22/images/docImage/doc.json new file mode 100644 index 000000000..4cbb269c4 --- /dev/null +++ b/src/test/resources/samples/1.22/images/docImage/doc.json @@ -0,0 +1,89 @@ +{ + "Id": "85f05633ddc1c50679be2b16a0479ab6f7637f8884e0cfe0f4d20e1ebb3d6e7c", + "Container": "cb91e48a60d01f1e27028b4fc6819f4f290b3cf12496c8176ec714d0d390984a", + "Comment": "", + "Os": "linux", + "Architecture": "amd64", + "Parent": "91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c", + "ContainerConfig": { + "Tty": false, + "Hostname": "e611e15f9c9d", + "Volumes": null, + "Domainname": "", + "AttachStdout": false, + "PublishService": "", + "AttachStdin": false, + "OpenStdin": false, + "StdinOnce": false, + "NetworkDisabled": false, + "OnBuild": [], + "Image": "91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c", + "User": "", + "WorkingDir": "", + "Entrypoint": null, + "MacAddress": "", + "AttachStderr": false, + "Labels": { + "com.example.license": "GPL", + "com.example.version": "1.0", + "com.example.vendor": "Acme" + }, + "Env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ], + "ExposedPorts": null, + "Cmd": [ + "/bin/sh", + "-c", + "#(nop) LABEL com.example.vendor=Acme com.example.license=GPL com.example.version=1.0" + ] + }, + "DockerVersion": "1.9.0-dev", + "VirtualSize": 188359297, + "Size": 0, + "Author": "", + "Created": "2015-09-10T08:30:53.26995814Z", + "GraphDriver": { + "Name": "aufs", + "Data": null + }, + "RepoDigests": [ + "localhost:5000/test/busybox/example@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf" + ], + "RepoTags": [ + "example:1.0", + "example:latest", + "example:stable" + ], + "Config": { + "Image": "91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c", + "NetworkDisabled": false, + "OnBuild": [], + "StdinOnce": false, + "PublishService": "", + "AttachStdin": false, + "OpenStdin": false, + "Domainname": "", + "AttachStdout": false, + "Tty": false, + "Hostname": "e611e15f9c9d", + "Volumes": null, + "Cmd": [ + "/bin/bash" + ], + "ExposedPorts": null, + "Env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ], + "Labels": { + "com.example.vendor": "Acme", + "com.example.version": "1.0", + "com.example.license": "GPL" + }, + "Entrypoint": null, + "MacAddress": "", + "AttachStderr": false, + "WorkingDir": "", + "User": "" + } +} diff --git a/src/test/resources/samples/1.22/images/image1/inspect1.json b/src/test/resources/samples/1.22/images/image1/inspect1.json new file mode 100644 index 000000000..ef674df2b --- /dev/null +++ b/src/test/resources/samples/1.22/images/image1/inspect1.json @@ -0,0 +1,69 @@ +{ + "Id": "sha256:ee45fe0d1fcdf1a0f9c2d1e36c6f4b3202bbb2032f14d7c9312b27bfcf6aee24", + "RepoTags": [ + "hackmann/empty:latest" + ], + "RepoDigests": [], + "Parent": "", + "Comment": "", + "Created": "2014-04-29T19:59:10.84997669Z", + "Container": "aee9ba801acca0e648ffd91df204ba82ae85d97608a4864a019e2004d7e1b133", + "ContainerConfig": { + "Hostname": "aee9ba801acc", + "Domainname": "", + "User": "", + "AttachStdin": false, + "AttachStdout": false, + "AttachStderr": false, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Env": [ + "HOME=/", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ], + "Cmd": [ + "/bin/sh", + "-c", + "#(nop) MAINTAINER hack@worldticket.net" + ], + "Image": "511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158", + "Volumes": null, + "WorkingDir": "", + "Entrypoint": null, + "OnBuild": [], + "Labels": null + }, + "DockerVersion": "0.8.1", + "Author": "hack@worldticket.net", + "Config": { + "Hostname": "aee9ba801acc", + "Domainname": "", + "User": "", + "AttachStdin": false, + "AttachStdout": false, + "AttachStderr": false, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Env": [ + "HOME=/", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ], + "Cmd": null, + "Image": "511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158", + "Volumes": null, + "WorkingDir": "", + "Entrypoint": null, + "OnBuild": [], + "Labels": null + }, + "Architecture": "amd64", + "Os": "linux", + "Size": 0, + "VirtualSize": 0, + "GraphDriver": { + "Name": "aufs", + "Data": null + } +} From 5b6fb633c847473dfe4f265aa7fe58a1d89fa32d Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 11 Mar 2016 01:10:29 +0300 Subject: [PATCH 058/855] Fix typo in test --- .../github/dockerjava/client/DockerClientTest.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/github/dockerjava/client/DockerClientTest.java b/src/test/java/com/github/dockerjava/client/DockerClientTest.java index 72a09f0e5..b124fdc9a 100644 --- a/src/test/java/com/github/dockerjava/client/DockerClientTest.java +++ b/src/test/java/com/github/dockerjava/client/DockerClientTest.java @@ -50,20 +50,26 @@ public void afterMethod(ITestResult result) { @Test public void testRunShlex() throws DockerException { - String[] commands = new String[] {"true", + String[] commands = new String[] { + "true", "echo \"The Young Descendant of Tepes & Septette for the Dead Princess\"", "echo -n 'The Young Descendant of Tepes & Septette for the Dead Princess'", "/bin/sh -c echo Hello World", "/bin/sh -c echo 'Hello World'", "echo 'Night of Nights'", - "true && echo 'Night of Nights'"}; + "true && echo 'Night of Nights'" + }; for (String command : commands) { LOG.info("Running command: [{}]", command); - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd(commands).exec(); + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd(command) + .exec(); dockerClient.startContainerCmd(container.getId()); - int exitcode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback()) + int exitcode = dockerClient.waitContainerCmd(container.getId()) + .exec(new WaitContainerResultCallback()) .awaitStatusCode(); + assertThat(exitcode, equalTo(0)); } } From 8a27a63926bc9e595d3e0a24cdae2a7e1d0733ce Mon Sep 17 00:00:00 2001 From: Marcus Thiesen Date: Thu, 28 Jan 2016 20:09:06 +0100 Subject: [PATCH 059/855] Add aux to ResponseItem for API 1.22 As mentioned in Issue #437 Signed-off-by: Kanstantsin Shautsou --- .../dockerjava/api/model/ResponseItem.java | 67 ++++++++++++++++--- 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/ResponseItem.java b/src/main/java/com/github/dockerjava/api/model/ResponseItem.java index 586a49d63..12a090db8 100644 --- a/src/main/java/com/github/dockerjava/api/model/ResponseItem.java +++ b/src/main/java/com/github/dockerjava/api/model/ResponseItem.java @@ -1,15 +1,14 @@ package com.github.dockerjava.api.model; -import java.io.Serializable; - -import javax.annotation.CheckForNull; - -import org.apache.commons.lang.builder.ToStringBuilder; -import org.apache.commons.lang.builder.ToStringStyle; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import com.github.dockerjava.core.RemoteApiVersion; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +import javax.annotation.CheckForNull; +import java.io.Serializable; /** * Represents a pull response stream item @@ -48,6 +47,12 @@ public class ResponseItem implements Serializable { @JsonProperty("error") private String error; + /** + * @since {@link RemoteApiVersion#VERSION_1_22} + */ + @JsonProperty("aux") + private AuxDetail aux; + @CheckForNull public String getStream() { return stream; @@ -94,6 +99,14 @@ public String getError() { return error; } + /** + * @see #aux + */ + @CheckForNull + public AuxDetail getAux() { + return aux; + } + /** * Returns whether the error field indicates an error * @@ -135,7 +148,7 @@ public Long getStart() { @Override public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE).toString(); + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } } @@ -161,12 +174,46 @@ public String getMessage() { @Override public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE).toString(); + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } + } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static class AuxDetail implements Serializable { + private static final long serialVersionUID = 1L; + + @JsonProperty("Size") + private Integer size; + + @JsonProperty("Tag") + private String tag; + + @JsonProperty("Digest") + private String digest; + + @CheckForNull + public Integer getSize() { + return size; + } + + @CheckForNull + public String getTag() { + return tag; + } + + @CheckForNull + public String getDigest() { + return digest; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } } @Override public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE).toString(); + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); } } From 3b3399d5674d68590de4da2107ec56a6688a57d0 Mon Sep 17 00:00:00 2001 From: Alexander Koshevoy Date: Fri, 11 Mar 2016 15:01:51 +0300 Subject: [PATCH 060/855] Fixes skipping 0xff bytes from result stream returned by Netty implementation of copy file/archive commands --- pom.xml | 8 +++ .../handler/HttpResponseStreamHandler.java | 2 +- .../HttpResponseStreamHandlerTest.java | 51 +++++++++++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java diff --git a/pom.xml b/pom.xml index 2b5fe2119..9ee5cad51 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,7 @@ 1.3 1.6 2.3.3 + 1.10.19 2.2 @@ -195,6 +196,13 @@ test + + org.mockito + mockito-core + ${mockito.version} + test + + com.google.code.findbugs annotations diff --git a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java index d4f19f2e3..706228d04 100644 --- a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java +++ b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java @@ -81,7 +81,7 @@ public int read() throws IOException { } if (current != null && current.readableBytes() > 0) { - return current.readByte(); + return current.readByte() & 0xff; } else { return read(); } diff --git a/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java new file mode 100644 index 000000000..5d4c091d9 --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java @@ -0,0 +1,51 @@ +package com.github.dockerjava.netty.handler; + +import com.github.dockerjava.core.async.ResultCallbackTemplate; +import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufInputStream; +import io.netty.buffer.Unpooled; +import io.netty.channel.ChannelHandlerContext; +import org.apache.commons.io.IOUtils; +import org.mockito.Mockito; +import org.testng.Assert; +import org.testng.annotations.Test; + +import java.io.InputStream; + +/** + * @author Alexander Koshevoy + */ +public class HttpResponseStreamHandlerTest { + @Test + public void testNoBytesSkipped() throws Exception { + ResultCallbackTest callback = new ResultCallbackTest(); + HttpResponseStreamHandler streamHandler = new HttpResponseStreamHandler(callback); + ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); + ByteBuf buffer = generateByteBuf(); + streamHandler.channelRead0(ctx, buffer); + streamHandler.channelReadComplete(ctx); + + Assert.assertTrue(IOUtils.contentEquals(callback.getInputStream(), new ByteBufInputStream(buffer))); + } + + private ByteBuf generateByteBuf() { + byte[] array = new byte[256]; + for (int i = 0; i < array.length; i++) { + array[i] = (byte) i; + } + return Unpooled.copiedBuffer(array); + } + + private static class ResultCallbackTest extends ResultCallbackTemplate { + private InputStream stream; + + @Override + public void onNext(InputStream stream) { + this.stream = stream; + } + + public InputStream getInputStream() { + return stream; + } + } +} From c3ab3d215e2acf0a2569c060fbaede3ae973a4e2 Mon Sep 17 00:00:00 2001 From: tejksat Date: Sun, 20 Mar 2016 01:02:31 +0300 Subject: [PATCH 061/855] Integration test for copy archive cmd checking integrity of received binary file --- .../CopyArchiveFromContainerCmdExecTest.java | 40 ++++++++++++++++++ .../resources/testCopyFromArchive/binary.dat | Bin 0 -> 288 bytes 2 files changed, 40 insertions(+) create mode 100644 src/test/resources/testCopyFromArchive/binary.dat diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java index aa4dcc575..caec336a2 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java @@ -6,7 +6,14 @@ import java.io.InputStream; import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.io.IOUtils; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -16,6 +23,7 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.core.util.CompressArchiveUtil; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; @Test(groups = "integration") @@ -70,4 +78,36 @@ public void copyFromNonExistingContainer() throws Exception { } catch (NotFoundException ignored) { } } + + @Test + public void copyFromContainerBinaryFile() throws Exception { + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withName("docker-java-itest-copyFromContainerBinaryFile").exec(); + + LOG.info("Created container: {}", container); + assertThat(container.getId(), not(isEmptyOrNullString())); + + Path temp = Files.createTempFile("", ".tar.gz"); + Path binaryFile = Paths.get("src/test/resources/testCopyFromArchive/binary.dat"); + CompressArchiveUtil.tar(binaryFile, temp, true, false); + + try (InputStream uploadStream = Files.newInputStream(temp)) { + dockerClient.copyArchiveToContainerCmd(container.getId()).withTarInputStream(uploadStream).exec(); + } + + InputStream response = dockerClient.copyArchiveFromContainerCmd(container.getId(), "/binary.dat").exec(); + Boolean bytesAvailable = response.available() > 0; + assertTrue(bytesAvailable, "The file was not copied from the container."); + + try (TarArchiveInputStream tarInputStream = new TarArchiveInputStream(response)) { + TarArchiveEntry nextTarEntry = tarInputStream.getNextTarEntry(); + + assertEquals(nextTarEntry.getName(), "binary.dat"); + try (InputStream binaryFileInputStream = Files.newInputStream(binaryFile, StandardOpenOption.READ)) { + assertTrue(IOUtils.contentEquals(binaryFileInputStream, tarInputStream)); + } + + assertNull(tarInputStream.getNextTarEntry(), "Nothing except binary.dat is expected to be copied."); + } + } } diff --git a/src/test/resources/testCopyFromArchive/binary.dat b/src/test/resources/testCopyFromArchive/binary.dat new file mode 100644 index 0000000000000000000000000000000000000000..61bcc872c139dd1bc827058031947f132b91fa53 GIT binary patch literal 288 zcmV+*0pI>paAjj@VQe6Cd2M2EY;!CicVTp6XdrKObRi0Wfr5jCg@%WSiHeJijgF6y zk&=^?m6n&7nVOrNot~edp`xRtrKYE-sj922t*)=Iv9hzYwYImoxw^Z&y}rM|!NSAD z#m2|T$;!*j&Cbuz(bCh@)z;V8+1lIO-QM5e;o{@u<>u$;>FVq3?e6dJ@$&QZ_4fDp z`TG0({r>*|0RjUA1qKHQ2?`4g4Gs?w5fT#=6&4p585$cL9UdPbAtECrB_<~*DJm;0 zEiNxGF)}kWH8wXmIXXK$Jw87`K|(`BMMg(RNlHshO-@fxQBqS>RaRG6Sz23MU0z>c mVPa!sWoBn+X=-b1ZEkOHadLBXb#`}nd3t+%eSUg-e0_dnKZ{-f literal 0 HcmV?d00001 From 2f62af8bfb64eadde35c0329fb834a403dc60ec6 Mon Sep 17 00:00:00 2001 From: tejksat Date: Sun, 20 Mar 2016 01:11:28 +0300 Subject: [PATCH 062/855] Static import for assertion used, imports reformatted --- .../netty/handler/HttpResponseStreamHandlerTest.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java index 5d4c091d9..6652f3eba 100644 --- a/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java +++ b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java @@ -1,16 +1,18 @@ package com.github.dockerjava.netty.handler; -import com.github.dockerjava.core.async.ResultCallbackTemplate; +import static org.testng.Assert.assertTrue; + +import java.io.InputStream; + import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import org.apache.commons.io.IOUtils; import org.mockito.Mockito; -import org.testng.Assert; import org.testng.annotations.Test; -import java.io.InputStream; +import com.github.dockerjava.core.async.ResultCallbackTemplate; /** * @author Alexander Koshevoy @@ -25,7 +27,7 @@ public void testNoBytesSkipped() throws Exception { streamHandler.channelRead0(ctx, buffer); streamHandler.channelReadComplete(ctx); - Assert.assertTrue(IOUtils.contentEquals(callback.getInputStream(), new ByteBufInputStream(buffer))); + assertTrue(IOUtils.contentEquals(callback.getInputStream(), new ByteBufInputStream(buffer))); } private ByteBuf generateByteBuf() { From ec6ca9fb45f7686a4db81be07c7db96a9c94e8f0 Mon Sep 17 00:00:00 2001 From: lujian <254461627@qq.com> Date: Thu, 17 Mar 2016 10:13:41 +0800 Subject: [PATCH 063/855] RenameContainer Signed-off-by: Kanstantsin Shautsou --- .../github/dockerjava/api/DockerClient.java | 10 +++ .../api/command/DockerCmdExecFactory.java | 8 +++ .../api/command/RenameContainerCmd.java | 34 +++++++++ .../dockerjava/core/DockerClientImpl.java | 7 ++ .../core/command/RenameContainerCmdImpl.java | 52 ++++++++++++++ .../jaxrs/DockerCmdExecFactoryImpl.java | 6 ++ .../jaxrs/RenameContainerCmdExec.java | 30 ++++++++ .../netty/DockerCmdExecFactoryImpl.java | 7 ++ .../netty/exec/RenameContainerCmdExec.java | 29 ++++++++ .../core/TestDockerCmdExecFactory.java | 5 ++ .../command/RenameContainerCmdImplTest.java | 71 +++++++++++++++++++ .../exec/RenameContainerCmdExecTest.java | 71 +++++++++++++++++++ 12 files changed, 330 insertions(+) create mode 100644 src/main/java/com/github/dockerjava/api/command/RenameContainerCmd.java create mode 100644 src/main/java/com/github/dockerjava/core/command/RenameContainerCmdImpl.java create mode 100644 src/main/java/com/github/dockerjava/jaxrs/RenameContainerCmdExec.java create mode 100644 src/main/java/com/github/dockerjava/netty/exec/RenameContainerCmdExec.java create mode 100644 src/test/java/com/github/dockerjava/core/command/RenameContainerCmdImplTest.java create mode 100644 src/test/java/com/github/dockerjava/netty/exec/RenameContainerCmdExecTest.java diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java index 3ceabf3e7..978bd35ca 100644 --- a/src/main/java/com/github/dockerjava/api/DockerClient.java +++ b/src/main/java/com/github/dockerjava/api/DockerClient.java @@ -56,6 +56,7 @@ import com.github.dockerjava.api.command.UpdateContainerCmd; import com.github.dockerjava.api.command.VersionCmd; import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.command.RenameContainerCmd; import com.github.dockerjava.api.exception.DockerException; import com.github.dockerjava.api.model.AuthConfig; import com.github.dockerjava.api.model.Identifier; @@ -185,6 +186,15 @@ public interface DockerClient extends Closeable { */ UpdateContainerCmd updateContainerCmd(@Nonnull String containerId); + /** + * Rename container. + * + * @param containerId id of the container + * @return command + * @since {@link RemoteApiVersion#VERSION_1_17} + */ + RenameContainerCmd renameContainerCmd(@Nonnull String containerId); + RestartContainerCmd restartContainerCmd(@Nonnull String containerId); CommitCmd commitCmd(@Nonnull String containerId); diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java index 8cc42cf15..ae090e434 100644 --- a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java @@ -6,6 +6,7 @@ import javax.net.ssl.SSLContext; import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.RemoteApiVersion; public interface DockerCmdExecFactory extends Closeable { @@ -71,6 +72,13 @@ public interface DockerCmdExecFactory extends Closeable { UpdateContainerCmd.Exec createUpdateContainerCmdExec(); + /** + * Rename container. + * + * @since {@link RemoteApiVersion#VERSION_1_17} + */ + RenameContainerCmd.Exec createRenameContainerCmdExec(); + RestartContainerCmd.Exec createRestartContainerCmdExec(); CommitCmd.Exec createCommitCmdExec(); diff --git a/src/main/java/com/github/dockerjava/api/command/RenameContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/RenameContainerCmd.java new file mode 100644 index 000000000..bce20251f --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/RenameContainerCmd.java @@ -0,0 +1,34 @@ +package com.github.dockerjava.api.command; + +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.core.RemoteApiVersion; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +/** + * Rename a container. + * + * @since {@link RemoteApiVersion#VERSION_1_17} + */ +public interface RenameContainerCmd extends SyncDockerCmd { + + @CheckForNull + String getContainerId(); + + RenameContainerCmd withContainerId(@Nonnull String containerId); + + @CheckForNull + String getName(); + + RenameContainerCmd withName(@Nonnull String name); + + /** + * @throws NotFoundException No such container + */ + @Override + Void exec() throws NotFoundException; + + interface Exec extends DockerCmdSyncExec { + } +} diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java index 9d342e249..9f4f0f88b 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -58,6 +58,7 @@ import com.github.dockerjava.api.command.UpdateContainerCmd; import com.github.dockerjava.api.command.VersionCmd; import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.command.RenameContainerCmd; import com.github.dockerjava.api.model.AuthConfig; import com.github.dockerjava.api.model.Identifier; import com.github.dockerjava.core.command.AttachContainerCmdImpl; @@ -109,6 +110,7 @@ import com.github.dockerjava.core.command.UpdateContainerCmdImpl; import com.github.dockerjava.core.command.VersionCmdImpl; import com.github.dockerjava.core.command.WaitContainerCmdImpl; +import com.github.dockerjava.core.command.RenameContainerCmdImpl; import javax.annotation.Nonnull; @@ -364,6 +366,11 @@ public UpdateContainerCmd updateContainerCmd(@Nonnull String containerId) { return new UpdateContainerCmdImpl(getDockerCmdExecFactory().createUpdateContainerCmdExec(), containerId); } + @Override + public RenameContainerCmd renameContainerCmd(@Nonnull String containerId) { + return new RenameContainerCmdImpl(getDockerCmdExecFactory().createRenameContainerCmdExec(), containerId); + } + @Override public RestartContainerCmd restartContainerCmd(String containerId) { return new RestartContainerCmdImpl(getDockerCmdExecFactory().createRestartContainerCmdExec(), containerId); diff --git a/src/main/java/com/github/dockerjava/core/command/RenameContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/RenameContainerCmdImpl.java new file mode 100644 index 000000000..ebf3ebabf --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/RenameContainerCmdImpl.java @@ -0,0 +1,52 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.RenameContainerCmd; +import com.github.dockerjava.api.exception.NotFoundException; + +import javax.annotation.Nonnull; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class RenameContainerCmdImpl extends AbstrDockerCmd implements RenameContainerCmd { + + private String containerId; + + private String name; + + public RenameContainerCmdImpl(RenameContainerCmd.Exec exec, String containerId) { + super(exec); + withContainerId(containerId); + } + + @Override + public String getContainerId() { + return containerId; + } + + @Override + public String getName() { + return name; + } + + @Override + public RenameContainerCmd withContainerId(@Nonnull String containerId) { + checkNotNull(containerId, "containerId was not specified"); + this.containerId = containerId; + return this; + } + + @Override + public RenameContainerCmd withName(@Nonnull String name) { + checkNotNull(name, "name was not specified"); + this.name = name; + return this; + } + + /** + * @throws NotFoundException No such container + */ + @Override + public Void exec() throws NotFoundException { + return super.exec(); + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index 4716877af..f64cf4e2b 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -80,6 +80,7 @@ import com.github.dockerjava.api.command.UnpauseContainerCmd; import com.github.dockerjava.api.command.VersionCmd; import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.command.RenameContainerCmd; import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.core.DockerClientConfig; import com.github.dockerjava.core.LocalDirectorySSLConfig; @@ -417,6 +418,11 @@ public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig()); } + @Override + public RenameContainerCmd.Exec createRenameContainerCmdExec() { + return new RenameContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + @Override public RestartContainerCmd.Exec createRestartContainerCmdExec() { return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig()); diff --git a/src/main/java/com/github/dockerjava/jaxrs/RenameContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/RenameContainerCmdExec.java new file mode 100644 index 000000000..c747ea9b0 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/RenameContainerCmdExec.java @@ -0,0 +1,30 @@ +package com.github.dockerjava.jaxrs; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import com.github.dockerjava.api.command.RenameContainerCmd; +import com.github.dockerjava.core.DockerClientConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RenameContainerCmdExec extends AbstrSyncDockerCmdExec + implements RenameContainerCmd.Exec { + private static final Logger LOG = LoggerFactory.getLogger(RenameContainerCmdExec.class); + + public RenameContainerCmdExec(WebTarget baseResource, DockerClientConfig dockerClientConfig) { + super(baseResource, dockerClientConfig); + } + + @Override + protected Void execute(RenameContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/rename") + .resolveTemplate("id", command.getContainerId()) + .queryParam("name", command.getName()); + + LOG.trace("POST: {}", webResource); + webResource.request().accept(MediaType.APPLICATION_JSON).post(null); + + return null; + } +} diff --git a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java index 1210c56bc..08a0179a1 100644 --- a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java @@ -50,6 +50,7 @@ import com.github.dockerjava.api.command.UpdateContainerCmd; import com.github.dockerjava.api.command.VersionCmd; import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.command.RenameContainerCmd; import com.github.dockerjava.core.DockerClientConfig; import com.github.dockerjava.core.DockerClientImpl; import com.github.dockerjava.core.LocalDirectorySSLConfig; @@ -102,6 +103,7 @@ import com.github.dockerjava.netty.exec.UpdateContainerCmdExec; import com.github.dockerjava.netty.exec.VersionCmdExec; import com.github.dockerjava.netty.exec.WaitContainerCmdExec; +import com.github.dockerjava.netty.exec.RenameContainerCmdExec; import io.netty.bootstrap.Bootstrap; import io.netty.channel.ChannelInitializer; @@ -465,6 +467,11 @@ public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig()); } + @Override + public RenameContainerCmd.Exec createRenameContainerCmdExec() { + return new RenameContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + @Override public RestartContainerCmd.Exec createRestartContainerCmdExec() { return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig()); diff --git a/src/main/java/com/github/dockerjava/netty/exec/RenameContainerCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/RenameContainerCmdExec.java new file mode 100644 index 000000000..43f97e961 --- /dev/null +++ b/src/main/java/com/github/dockerjava/netty/exec/RenameContainerCmdExec.java @@ -0,0 +1,29 @@ +package com.github.dockerjava.netty.exec; + +import com.github.dockerjava.api.command.RenameContainerCmd; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.netty.MediaType; +import com.github.dockerjava.netty.WebTarget; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class RenameContainerCmdExec extends AbstrSyncDockerCmdExec + implements RenameContainerCmd.Exec { + private static final Logger LOG = LoggerFactory.getLogger(RenameContainerCmdExec.class); + + public RenameContainerCmdExec(WebTarget baseResource, DockerClientConfig dockerClientConfig) { + super(baseResource, dockerClientConfig); + } + + @Override + protected Void execute(RenameContainerCmd command) { + WebTarget webResource = getBaseResource().path("/containers/{id}/rename") + .resolveTemplate("id", command.getContainerId()) + .queryParam("name", command.getName()); + + LOG.trace("POST: {}", webResource); + webResource.request().accept(MediaType.APPLICATION_JSON).post(null); + + return null; + } +} diff --git a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java index b2b86601c..ba05ab4e3 100644 --- a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java +++ b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java @@ -240,6 +240,11 @@ public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { return delegate.createUpdateContainerCmdExec(); } + @Override + public RenameContainerCmd.Exec createRenameContainerCmdExec(){ + return delegate.createRenameContainerCmdExec(); + } + @Override public RestartContainerCmd.Exec createRestartContainerCmdExec() { return delegate.createRestartContainerCmdExec(); diff --git a/src/test/java/com/github/dockerjava/core/command/RenameContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RenameContainerCmdImplTest.java new file mode 100644 index 000000000..9f503a87b --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/RenameContainerCmdImplTest.java @@ -0,0 +1,71 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.exception.DockerException; +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.client.AbstractDockerClientTest; +import org.testng.ITestResult; +import org.testng.annotations.*; + +import java.lang.reflect.Method; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +@Test(groups = "integration") +public class RenameContainerCmdImplTest extends AbstractDockerClientTest { + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void renameContainer() throws DockerException { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); + + String name1 = inspectContainerResponse.getName(); + + dockerClient.renameContainerCmd(container.getId()) + .withName(getClass().getCanonicalName() + "renameContainer") + .exec(); + + InspectContainerResponse inspectContainerResponse2 = dockerClient.inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect After Rename: {}", inspectContainerResponse2.toString()); + + String name2 = inspectContainerResponse2.getName(); + + assertNotEquals(name1, name2); + + dockerClient.killContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = NotFoundException.class) + public void renameExistingContainer() throws DockerException, InterruptedException { + dockerClient.renameContainerCmd("non-existing") + .withName(getClass().getCanonicalName() + "renameExistingContainer") + .exec(); + } +} diff --git a/src/test/java/com/github/dockerjava/netty/exec/RenameContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RenameContainerCmdExecTest.java new file mode 100644 index 000000000..c176bc1d6 --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/exec/RenameContainerCmdExecTest.java @@ -0,0 +1,71 @@ +package com.github.dockerjava.netty.exec; + +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.exception.DockerException; +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.netty.AbstractNettyDockerClientTest; +import org.testng.ITestResult; +import org.testng.annotations.*; + +import java.lang.reflect.Method; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; + +@Test(groups = "integration") +public class RenameContainerCmdExecTest extends AbstractNettyDockerClientTest { + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void renameContainer() throws DockerException { + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + dockerClient.startContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); + + String name1 = inspectContainerResponse.getName(); + + dockerClient.renameContainerCmd(container.getId()) + .withName(getClass().getCanonicalName() + "renameContainer") + .exec(); + + InspectContainerResponse inspectContainerResponse2 = dockerClient.inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect After Rename: {}", inspectContainerResponse2.toString()); + + String name2 = inspectContainerResponse2.getName(); + + assertNotEquals(name1, name2); + + dockerClient.killContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = NotFoundException.class) + public void renameNonExistingContainer() throws DockerException, InterruptedException { + dockerClient.renameContainerCmd("non-existing") + .withName(getClass().getCanonicalName() + "renameExistingContainer") + .exec(); + } +} From 64061dfe828210c4c995245e68a8891ed0136a62 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 21 Mar 2016 00:13:47 +0300 Subject: [PATCH 064/855] Use annotation features instead custom check. --- .../core/command/CreateContainerCmdImplTest.java | 8 ++------ .../core/command/InspectContainerCmdImplTest.java | 9 ++------- .../netty/exec/CreateContainerCmdExecTest.java | 8 ++------ .../netty/exec/InspectContainerCmdExecTest.java | 9 ++------- 4 files changed, 8 insertions(+), 26 deletions(-) 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 7800a8c12..2567a3c28 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -69,7 +69,7 @@ public void afterMethod(ITestResult result) { super.afterMethod(result); } - @Test + @Test(expectedExceptions = ConflictException.class) public void createContainerWithExistingName() throws DockerException { String containerName = "generated_" + new SecureRandom().nextInt(); @@ -81,11 +81,7 @@ public void createContainerWithExistingName() throws DockerException { assertThat(container.getId(), not(isEmptyString())); - try { - dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("env").withName(containerName).exec(); - fail("expected ConflictException"); - } catch (ConflictException e) { - } + dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("env").withName(containerName).exec(); } @Test diff --git a/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java index e11ff6839..47ed11201 100644 --- a/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java @@ -63,14 +63,9 @@ public void inspectContainer() throws DockerException { } - @Test + @Test(expectedExceptions = NotFoundException.class) public void inspectNonExistingContainer() throws DockerException { - - try { - dockerClient.inspectContainerCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + dockerClient.inspectContainerCmd("non-existing").exec(); } @Test 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 9a6d4b354..fde1179ee 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java @@ -67,7 +67,7 @@ public void afterMethod(ITestResult result) { super.afterMethod(result); } - @Test + @Test(expectedExceptions = ConflictException.class) public void createContainerWithExistingName() throws DockerException { String containerName = "generated_" + new SecureRandom().nextInt(); @@ -79,11 +79,7 @@ public void createContainerWithExistingName() throws DockerException { assertThat(container.getId(), not(isEmptyString())); - try { - dockerClient.createContainerCmd("busybox").withCmd("env").withName(containerName).exec(); - fail("expected ConflictException"); - } catch (ConflictException e) { - } + dockerClient.createContainerCmd("busybox").withCmd("env").withName(containerName).exec(); } @Test diff --git a/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java index a07e23143..87fe3b48b 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java @@ -63,14 +63,9 @@ public void inspectContainer() throws DockerException { } - @Test + @Test(expectedExceptions = NotFoundException.class) public void inspectNonExistingContainer() throws DockerException { - - try { - dockerClient.inspectContainerCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + dockerClient.inspectContainerCmd("non-existing").exec(); } @Test From dfe3c43e887b6c1944bda664af3b7ed1760f3408 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 21 Mar 2016 00:31:43 +0300 Subject: [PATCH 065/855] Use hashcode, tostring, equals builders. --- .../core/command/CreateContainerCmdImpl.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java index 4f69e9ed0..bb9fcc318 100644 --- a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java @@ -5,6 +5,8 @@ import java.util.List; import java.util.Map; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -412,12 +414,6 @@ public String getCgroupParent() { return hostConfig.getCgroupParent(); } - @Override - public String toString() { - return new ToStringBuilder(this).append("create container ").append(name != null ? "name=" + name + " " : "") - .append(this).toString(); - } - @Override public CreateContainerCmd withAttachStderr(Boolean attachStderr) { checkNotNull(attachStderr, "attachStderr was not specified"); @@ -890,4 +886,18 @@ public CreateContainerCmd withPidMode(String pidMode) { return this; } + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } } From ab6443bbeafa1676732d5fa18ac43522afb77ed2 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 21 Mar 2016 00:32:44 +0300 Subject: [PATCH 066/855] Add test case for CgroupParent --- .../core/command/CreateContainerCmdImplTest.java | 14 ++++++++++++++ .../netty/exec/CreateContainerCmdExecTest.java | 14 ++++++++++++++ 2 files changed, 28 insertions(+) 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 2567a3c28..f2fd32b6a 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -613,4 +613,18 @@ public void onNext(Frame item) { super.onNext(item); } } + + @Test(groups = "ignoreInCircleCi") + public void createContainerWithCgroupParent() throws DockerException { + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCgroupParent("/parent").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainer = dockerClient.inspectContainerCmd(container.getId()).exec(); + + assertThat(inspectContainer.getHostConfig().getCgroupParent(), is("/parent")); + } } 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 fde1179ee..02c5cc54e 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java @@ -550,4 +550,18 @@ public void createContainerWithLogConfig() throws DockerException { // null becomes empty string assertEquals(inspectContainerResponse.getHostConfig().getLogConfig().type, logConfig.type); } + + @Test(groups = "ignoreInCircleCi") + public void createContainerWithCgroupParent() throws DockerException { + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCgroupParent("/parent").exec(); + + LOG.info("Created container {}", container.toString()); + + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainer = dockerClient.inspectContainerCmd(container.getId()).exec(); + + assertThat(inspectContainer.getHostConfig().getCgroupParent(), is("/parent")); + } } From cdc17cb2c1fdce31fa7ffe16d085f7143127f7d8 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 21 Mar 2016 01:26:11 +0300 Subject: [PATCH 067/855] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9a91e105f..f34102285 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,12 @@ Notes All changes +Included in 3.0.0-RC4 +* [#495] (https://github.com/docker-java/docker-java/pull/495) Add CgroupParent option for create cmd +* [#504] (https://github.com/docker-java/docker-java/pull/504) Rename container cmd +* [#500] (https://github.com/docker-java/docker-java/pull/500) Add aux to ResponseItem +* [#498] (https://github.com/docker-java/docker-java/issues/493) Expose RepoTags from inspect image command + Included in 3.0.0-RC3 * [#488] (https://github.com/docker-java/docker-java/pull/488) Support remote API 1.22 subset From 13c51b0fd863a2599d10cf3a70af141f3a861761 Mon Sep 17 00:00:00 2001 From: hongweiyi Date: Thu, 24 Mar 2016 11:16:24 +0800 Subject: [PATCH 068/855] Change execStartCmd arguments name. com.github.dockerjava.api.DockerClient#execStartCmd: argument name should be execId but not containerId. Signed-off-by: hongwei yi --- src/main/java/com/github/dockerjava/api/DockerClient.java | 2 +- .../java/com/github/dockerjava/core/DockerClientImpl.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java index 978bd35ca..4c0e2ed56 100644 --- a/src/main/java/com/github/dockerjava/api/DockerClient.java +++ b/src/main/java/com/github/dockerjava/api/DockerClient.java @@ -129,7 +129,7 @@ public interface DockerClient extends Closeable { AttachContainerCmd attachContainerCmd(@Nonnull String containerId); - ExecStartCmd execStartCmd(@Nonnull String containerId); + ExecStartCmd execStartCmd(@Nonnull String execId); InspectExecCmd inspectExecCmd(@Nonnull String execId); diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java index 9f4f0f88b..765f562bd 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -314,8 +314,8 @@ public AttachContainerCmd attachContainerCmd(String containerId) { } @Override - public ExecStartCmd execStartCmd(String containerId) { - return new ExecStartCmdImpl(getDockerCmdExecFactory().createExecStartCmdExec(), containerId); + public ExecStartCmd execStartCmd(String execId) { + return new ExecStartCmdImpl(getDockerCmdExecFactory().createExecStartCmdExec(), execId); } @Override From 1576aad228750341f3c15f22dd1ab7c12e748451 Mon Sep 17 00:00:00 2001 From: Hendrik Haddorp Date: Tue, 22 Mar 2016 22:54:23 +0100 Subject: [PATCH 069/855] Fixed verifyCertificatesExist for missing or wrong files. --- .../core/util/CertificateUtils.java | 5 +- .../core/util/CertificateUtilsTest.java | 51 +++++++++++++++++++ .../CertificateUtilsTest/allFilesExist/ca.pem | 0 .../allFilesExist/cert.pem | 0 .../allFilesExist/key.pem | 0 .../caAndCertMissing/key.pem | 0 .../caAndKeyMissing/cert.pem | 0 .../CertificateUtilsTest/caMissing/cert.pem | 0 .../CertificateUtilsTest/caMissing/key.pem | 0 .../certAndKeyMissing/ca.pem | 0 .../CertificateUtilsTest/certMissing/ca.pem | 0 .../CertificateUtilsTest/certMissing/key.pem | 0 .../CertificateUtilsTest/keyMissing/ca.pem | 0 .../CertificateUtilsTest/keyMissing/cert.pem | 0 14 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/github/dockerjava/core/util/CertificateUtilsTest.java create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/allFilesExist/ca.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/allFilesExist/cert.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/allFilesExist/key.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caAndCertMissing/key.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caAndKeyMissing/cert.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caMissing/cert.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caMissing/key.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/certAndKeyMissing/ca.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/certMissing/ca.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/certMissing/key.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/keyMissing/ca.pem create mode 100644 src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/keyMissing/cert.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 65e6544f1..562a954a7 100644 --- a/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java +++ b/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java @@ -32,12 +32,13 @@ private CertificateUtils() { public static boolean verifyCertificatesExist(String dockerCertPath) { String[] files = {"ca.pem", "cert.pem", "key.pem"}; + boolean result = true; for (String file : files) { File path = new File(dockerCertPath, file); - return path.exists(); + result &= path.exists(); } - return true; + return result; } public static KeyStore createKeyStore(final String dockerCertPath) throws NoSuchAlgorithmException, diff --git a/src/test/java/com/github/dockerjava/core/util/CertificateUtilsTest.java b/src/test/java/com/github/dockerjava/core/util/CertificateUtilsTest.java new file mode 100644 index 000000000..36c00c076 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/util/CertificateUtilsTest.java @@ -0,0 +1,51 @@ +package com.github.dockerjava.core.util; + +import org.testng.annotations.Test; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + +public class CertificateUtilsTest { + private static final String baseDir = CertificateUtilsTest.class.getResource( + CertificateUtilsTest.class.getSimpleName() + "/").getFile(); + + @Test + public void allFilesExist() { + assertThat(CertificateUtils.verifyCertificatesExist(baseDir + "allFilesExist"), is(true)); + } + + @Test + public void caAndCertAndKeyMissing() { + assertThat(CertificateUtils.verifyCertificatesExist(baseDir + "caAndCertAndKeyMissing"), is(false)); + } + + @Test + public void caAndCertMissing() { + assertThat(CertificateUtils.verifyCertificatesExist(baseDir + "caAndCertMissing"), is(false)); + } + + @Test + public void caAndKeyMissing() { + assertThat(CertificateUtils.verifyCertificatesExist(baseDir + "caAndKeyMissing"), is(false)); + } + + @Test + public void caMissing() { + assertThat(CertificateUtils.verifyCertificatesExist(baseDir + "caMissing"), is(false)); + } + + @Test + public void certAndKeyMissing() { + assertThat(CertificateUtils.verifyCertificatesExist(baseDir + "certAndKeyMissing"), is(false)); + } + + @Test + public void certMissing() { + assertThat(CertificateUtils.verifyCertificatesExist(baseDir + "certMissing"), is(false)); + } + + @Test + public void keyMissing() { + assertThat(CertificateUtils.verifyCertificatesExist(baseDir + "keyMissing"), is(false)); + } +} diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/allFilesExist/ca.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/allFilesExist/ca.pem new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/allFilesExist/cert.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/allFilesExist/cert.pem new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/allFilesExist/key.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/allFilesExist/key.pem new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caAndCertMissing/key.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caAndCertMissing/key.pem new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caAndKeyMissing/cert.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caAndKeyMissing/cert.pem new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caMissing/cert.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caMissing/cert.pem new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caMissing/key.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/caMissing/key.pem new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/certAndKeyMissing/ca.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/certAndKeyMissing/ca.pem new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/certMissing/ca.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/certMissing/ca.pem new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/certMissing/key.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/certMissing/key.pem new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/keyMissing/ca.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/keyMissing/ca.pem new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/keyMissing/cert.pem b/src/test/resources/com/github/dockerjava/core/util/CertificateUtilsTest/keyMissing/cert.pem new file mode 100644 index 000000000..e69de29bb From 7920d4822eb06524935ae04fd6af87668b68b388 Mon Sep 17 00:00:00 2001 From: Oleg Anastasyev Date: Tue, 15 Mar 2016 17:22:54 +0200 Subject: [PATCH 070/855] SELinux context support to volumes --- .../com/github/dockerjava/api/model/Bind.java | 77 ++++++++++++++----- .../dockerjava/api/model/SELContext.java | 45 +++++++++++ .../github/dockerjava/api/model/BindTest.java | 51 ++++++++++++ 3 files changed, 153 insertions(+), 20 deletions(-) create mode 100644 src/main/java/com/github/dockerjava/api/model/SELContext.java diff --git a/src/main/java/com/github/dockerjava/api/model/Bind.java b/src/main/java/com/github/dockerjava/api/model/Bind.java index bc7c8e4bb..bf02bbad2 100644 --- a/src/main/java/com/github/dockerjava/api/model/Bind.java +++ b/src/main/java/com/github/dockerjava/api/model/Bind.java @@ -4,8 +4,8 @@ import org.apache.commons.lang.builder.HashCodeBuilder; /** - * Represents a host path being bind mounted as a {@link Volume} in a Docker container. The Bind can be in read only or read write access - * mode. + * Represents a host path being bind mounted as a {@link Volume} in a Docker container. + * The Bind can be in read only or read write access mode. */ public class Bind { @@ -15,14 +15,24 @@ public class Bind { private AccessMode accessMode; + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_17} + */ + private SELContext secMode; + public Bind(String path, Volume volume) { - this(path, volume, AccessMode.DEFAULT); + this(path, volume, AccessMode.DEFAULT, SELContext.DEFAULT); } public Bind(String path, Volume volume, AccessMode accessMode) { + this(path, volume, accessMode, SELContext.DEFAULT); + } + + public Bind(String path, Volume volume, AccessMode accessMode, SELContext secMode) { this.path = path; this.volume = volume; this.accessMode = accessMode; + this.secMode = secMode; } public String getPath() { @@ -37,6 +47,10 @@ public AccessMode getAccessMode() { return accessMode; } + public SELContext getSecMode() { + return secMode; + } + /** * Parses a bind mount specification to a {@link Bind}. * @@ -50,19 +64,29 @@ public static Bind parse(String serialized) { try { String[] parts = serialized.split(":"); switch (parts.length) { - case 2: { - return new Bind(parts[0], new Volume(parts[1])); - } - case 3: { - AccessMode accessMode = AccessMode.valueOf(parts[2].toLowerCase()); - return new Bind(parts[0], new Volume(parts[1]), accessMode); - } - default: { - throw new IllegalArgumentException(); + case 2: { + return new Bind(parts[0], new Volume(parts[1])); + } + case 3: { + String[] flags = parts[2].split(","); + AccessMode accessMode = AccessMode.DEFAULT; + SELContext seMode = SELContext.DEFAULT; + for (String p : flags) { + if (p.length() == 2) { + accessMode = AccessMode.valueOf(p.toLowerCase()); + } else { + seMode = SELContext.fromString(p); + } } + + return new Bind(parts[0], new Volume(parts[1]), accessMode, seMode); + } + default: { + throw new IllegalArgumentException(); + } } } catch (Exception e) { - throw new IllegalArgumentException("Error parsing Bind '" + serialized + "'"); + throw new IllegalArgumentException("Error parsing Bind '" + serialized + "'", e); } } @@ -70,8 +94,12 @@ public static Bind parse(String serialized) { public boolean equals(Object obj) { if (obj instanceof Bind) { Bind other = (Bind) obj; - return new EqualsBuilder().append(path, other.getPath()).append(volume, other.getVolume()) - .append(accessMode, other.getAccessMode()).isEquals(); + return new EqualsBuilder() + .append(path, other.getPath()) + .append(volume, other.getVolume()) + .append(accessMode, other.getAccessMode()) + .append(secMode, other.getSecMode()) + .isEquals(); } else { return super.equals(obj); } @@ -79,18 +107,27 @@ public boolean equals(Object obj) { @Override public int hashCode() { - return new HashCodeBuilder().append(path).append(volume).append(accessMode).toHashCode(); + return new HashCodeBuilder() + .append(path) + .append(volume) + .append(accessMode) + .append(secMode) + .toHashCode(); } /** - * Returns a string representation of this {@link Bind} suitable for inclusion in a JSON message. The format is - * <host path>:<container path>:<access mode>, like the argument in {@link #parse(String)}. + * Returns a string representation of this {@link Bind} suitable for inclusion in a JSON message. + * The format is <host path>:<container path>:<access mode>, + * like the argument in {@link #parse(String)}. * * @return a string representation of this {@link Bind} */ @Override public String toString() { - return path + ":" + volume.getPath() + ":" + accessMode.toString(); + return String.format("%s:%s:%s%s", + path, + volume.getPath(), + accessMode.toString(), + secMode != SELContext.none ? "," + secMode.toString() : ""); } - } diff --git a/src/main/java/com/github/dockerjava/api/model/SELContext.java b/src/main/java/com/github/dockerjava/api/model/SELContext.java new file mode 100644 index 000000000..b3d199f6f --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/SELContext.java @@ -0,0 +1,45 @@ +package com.github.dockerjava.api.model; + +/** + * The context mode of bound volume in SELinux. + * Host path shared - can be used by all containers, private - by only this container + * + * @see http://www.projectatomic.io/blog/2015/06/using-volumes-with-docker-can-cause-problems-with-selinux/ + * @since 1.17 + */ +public enum SELContext { + /** no selinux */ + none(""), + + /** z option */ + shared("z"), + + /** Z option */ + single("Z"); + + /** + * The default {@link SELContext}: {@link #none} + */ + public static final SELContext DEFAULT = none; + + private String value; + + SELContext(String v) { + this.value = v; + } + + @Override + public String toString() { + return value; + } + + public static SELContext fromString(String p) { + switch (p) { + case "z": + return shared; + case "Z": + return single; + } + return none; + } +} diff --git a/src/test/java/com/github/dockerjava/api/model/BindTest.java b/src/test/java/com/github/dockerjava/api/model/BindTest.java index db5aec212..27c9dcb6b 100644 --- a/src/test/java/com/github/dockerjava/api/model/BindTest.java +++ b/src/test/java/com/github/dockerjava/api/model/BindTest.java @@ -14,6 +14,7 @@ public void parseUsingDefaultAccessMode() { assertEquals(bind.getPath(), "/host"); assertEquals(bind.getVolume().getPath(), "/container"); assertEquals(bind.getAccessMode(), AccessMode.DEFAULT); + assertEquals(bind.getSecMode(), SELContext.none); } @Test @@ -22,6 +23,7 @@ public void parseReadWrite() { assertEquals(bind.getPath(), "/host"); assertEquals(bind.getVolume().getPath(), "/container"); assertEquals(bind.getAccessMode(), rw); + assertEquals(bind.getSecMode(), SELContext.none); } @Test @@ -30,6 +32,40 @@ public void parseReadOnly() { assertEquals(bind.getPath(), "/host"); assertEquals(bind.getVolume().getPath(), "/container"); assertEquals(bind.getAccessMode(), ro); + assertEquals(bind.getSecMode(), SELContext.none); + } + + @Test + public void parseSELOnly() { + Bind bind = Bind.parse("/host:/container:Z"); + assertEquals(bind.getPath(), "/host"); + assertEquals(bind.getVolume().getPath(), "/container"); + assertEquals(bind.getAccessMode(), AccessMode.DEFAULT); + assertEquals(bind.getSecMode(), SELContext.single); + + bind = Bind.parse("/host:/container:z"); + assertEquals(bind.getPath(), "/host"); + assertEquals(bind.getVolume().getPath(), "/container"); + assertEquals(bind.getAccessMode(), AccessMode.DEFAULT); + assertEquals(bind.getSecMode(), SELContext.shared); + } + + @Test + public void parseReadWriteSEL() { + Bind bind = Bind.parse("/host:/container:rw,Z"); + assertEquals(bind.getPath(), "/host"); + assertEquals(bind.getVolume().getPath(), "/container"); + assertEquals(bind.getAccessMode(), rw); + assertEquals(bind.getSecMode(), SELContext.single); + } + + @Test + public void parseReadOnlySEL() { + Bind bind = Bind.parse("/host:/container:ro,z"); + assertEquals(bind.getPath(), "/host"); + assertEquals(bind.getVolume().getPath(), "/container"); + assertEquals(bind.getAccessMode(), ro); + assertEquals(bind.getSecMode(), SELContext.shared); } @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Error parsing Bind.*") @@ -62,4 +98,19 @@ public void toStringDefaultAccessMode() { assertEquals(Bind.parse("/host:/container").toString(), "/host:/container:rw"); } + @Test + public void toStringReadOnlySEL() { + assertEquals(Bind.parse("/host:/container:ro,Z").toString(), "/host:/container:ro,Z"); + } + + @Test + public void toStringReadWriteSEL() { + assertEquals(Bind.parse("/host:/container:rw,z").toString(), "/host:/container:rw,z"); + } + + @Test + public void toStringDefaultSEL() { + assertEquals(Bind.parse("/host:/container:Z").toString(), "/host:/container:rw,Z"); + } + } From 253f6d2375f2838badd6336d13810804173eba39 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 27 Mar 2016 21:21:25 +0300 Subject: [PATCH 071/855] Use Hamcrest matchers. --- .../github/dockerjava/api/model/BindTest.java | 73 ++++++++++--------- 1 file changed, 37 insertions(+), 36 deletions(-) diff --git a/src/test/java/com/github/dockerjava/api/model/BindTest.java b/src/test/java/com/github/dockerjava/api/model/BindTest.java index 27c9dcb6b..3204ee716 100644 --- a/src/test/java/com/github/dockerjava/api/model/BindTest.java +++ b/src/test/java/com/github/dockerjava/api/model/BindTest.java @@ -2,7 +2,8 @@ import static com.github.dockerjava.api.model.AccessMode.ro; import static com.github.dockerjava.api.model.AccessMode.rw; -import static org.testng.Assert.assertEquals; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; import org.testng.annotations.Test; @@ -11,61 +12,61 @@ public class BindTest { @Test public void parseUsingDefaultAccessMode() { Bind bind = Bind.parse("/host:/container"); - assertEquals(bind.getPath(), "/host"); - assertEquals(bind.getVolume().getPath(), "/container"); - assertEquals(bind.getAccessMode(), AccessMode.DEFAULT); - assertEquals(bind.getSecMode(), SELContext.none); + assertThat(bind.getPath(), is("/host")); + assertThat(bind.getVolume().getPath(), is("/container")); + assertThat(bind.getAccessMode(), is(AccessMode.DEFAULT)); + assertThat(bind.getSecMode(), is(SELContext.none)); } @Test public void parseReadWrite() { Bind bind = Bind.parse("/host:/container:rw"); - assertEquals(bind.getPath(), "/host"); - assertEquals(bind.getVolume().getPath(), "/container"); - assertEquals(bind.getAccessMode(), rw); - assertEquals(bind.getSecMode(), SELContext.none); + assertThat(bind.getPath(), is("/host")); + assertThat(bind.getVolume().getPath(), is("/container")); + assertThat(bind.getAccessMode(), is(rw)); + assertThat(bind.getSecMode(), is(SELContext.none)); } @Test public void parseReadOnly() { Bind bind = Bind.parse("/host:/container:ro"); - assertEquals(bind.getPath(), "/host"); - assertEquals(bind.getVolume().getPath(), "/container"); - assertEquals(bind.getAccessMode(), ro); - assertEquals(bind.getSecMode(), SELContext.none); + assertThat(bind.getPath(), is("/host")); + assertThat(bind.getVolume().getPath(), is("/container")); + assertThat(bind.getAccessMode(), is(ro)); + assertThat(bind.getSecMode(), is(SELContext.none)); } @Test public void parseSELOnly() { Bind bind = Bind.parse("/host:/container:Z"); - assertEquals(bind.getPath(), "/host"); - assertEquals(bind.getVolume().getPath(), "/container"); - assertEquals(bind.getAccessMode(), AccessMode.DEFAULT); - assertEquals(bind.getSecMode(), SELContext.single); - + assertThat(bind.getPath(), is("/host")); + assertThat(bind.getVolume().getPath(), is("/container")); + assertThat(bind.getAccessMode(), is(AccessMode.DEFAULT)); + assertThat(bind.getSecMode(), is(SELContext.single)); + bind = Bind.parse("/host:/container:z"); - assertEquals(bind.getPath(), "/host"); - assertEquals(bind.getVolume().getPath(), "/container"); - assertEquals(bind.getAccessMode(), AccessMode.DEFAULT); - assertEquals(bind.getSecMode(), SELContext.shared); + assertThat(bind.getPath(), is("/host")); + assertThat(bind.getVolume().getPath(), is("/container")); + assertThat(bind.getAccessMode(), is(AccessMode.DEFAULT)); + assertThat(bind.getSecMode(), is(SELContext.shared)); } @Test public void parseReadWriteSEL() { Bind bind = Bind.parse("/host:/container:rw,Z"); - assertEquals(bind.getPath(), "/host"); - assertEquals(bind.getVolume().getPath(), "/container"); - assertEquals(bind.getAccessMode(), rw); - assertEquals(bind.getSecMode(), SELContext.single); + assertThat(bind.getPath(), is("/host")); + assertThat(bind.getVolume().getPath(), is("/container")); + assertThat(bind.getAccessMode(), is(rw)); + assertThat(bind.getSecMode(), is(SELContext.single)); } @Test public void parseReadOnlySEL() { Bind bind = Bind.parse("/host:/container:ro,z"); - assertEquals(bind.getPath(), "/host"); - assertEquals(bind.getVolume().getPath(), "/container"); - assertEquals(bind.getAccessMode(), ro); - assertEquals(bind.getSecMode(), SELContext.shared); + assertThat(bind.getPath(), is("/host")); + assertThat(bind.getVolume().getPath(), is("/container")); + assertThat(bind.getAccessMode(), is(ro)); + assertThat(bind.getSecMode(), is(SELContext.shared)); } @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Error parsing Bind.*") @@ -85,32 +86,32 @@ public void parseNull() { @Test public void toStringReadOnly() { - assertEquals(Bind.parse("/host:/container:ro").toString(), "/host:/container:ro"); + assertThat(Bind.parse("/host:/container:ro").toString(), is("/host:/container:ro")); } @Test public void toStringReadWrite() { - assertEquals(Bind.parse("/host:/container:rw").toString(), "/host:/container:rw"); + assertThat(Bind.parse("/host:/container:rw").toString(), is("/host:/container:rw")); } @Test public void toStringDefaultAccessMode() { - assertEquals(Bind.parse("/host:/container").toString(), "/host:/container:rw"); + assertThat(Bind.parse("/host:/container").toString(), is("/host:/container:rw")); } @Test public void toStringReadOnlySEL() { - assertEquals(Bind.parse("/host:/container:ro,Z").toString(), "/host:/container:ro,Z"); + assertThat(Bind.parse("/host:/container:ro,Z").toString(), is("/host:/container:ro,Z")); } @Test public void toStringReadWriteSEL() { - assertEquals(Bind.parse("/host:/container:rw,z").toString(), "/host:/container:rw,z"); + assertThat(Bind.parse("/host:/container:rw,z").toString(), is("/host:/container:rw,z")); } @Test public void toStringDefaultSEL() { - assertEquals(Bind.parse("/host:/container:Z").toString(), "/host:/container:rw,Z"); + assertThat(Bind.parse("/host:/container:Z").toString(), is("/host:/container:rw,Z")); } } From de9f326ec68c63dd18176b028361046bb2c4cf82 Mon Sep 17 00:00:00 2001 From: Hendrik Haddorp Date: Tue, 22 Mar 2016 21:34:01 +0100 Subject: [PATCH 072/855] Mirrors is list and not a single String. --- .../api/model/InfoRegistryConfig.java | 6 +- .../github/dockerjava/api/model/InfoTest.java | 158 +++++++++++++++++ src/test/resources/samples/1.22/info/2.json | 165 ++++++++++++++++++ 3 files changed, 326 insertions(+), 3 deletions(-) create mode 100644 src/test/resources/samples/1.22/info/2.json diff --git a/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java b/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java index cc67994a5..956aaebe3 100644 --- a/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java @@ -96,7 +96,7 @@ public int hashCode() { @JsonIgnoreProperties(ignoreUnknown = true) public static final class IndexConfig { @JsonProperty("Mirrors") - private String mirrors; + private List mirrors; @JsonProperty("Name") private String name; @@ -111,14 +111,14 @@ public static final class IndexConfig { * @see #mirrors */ @CheckForNull - public String getMirrors() { + public List getMirrors() { return mirrors; } /** * @see #mirrors */ - public IndexConfig withMirrors(String mirrors) { + public IndexConfig withMirrors(List mirrors) { this.mirrors = mirrors; return this; } diff --git a/src/test/java/com/github/dockerjava/api/model/InfoTest.java b/src/test/java/com/github/dockerjava/api/model/InfoTest.java index 6d4c76471..806870ae6 100644 --- a/src/test/java/com/github/dockerjava/api/model/InfoTest.java +++ b/src/test/java/com/github/dockerjava/api/model/InfoTest.java @@ -7,6 +7,7 @@ import org.testng.annotations.Test; import java.io.IOException; +import java.util.Collections; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -169,4 +170,161 @@ public void serder1Json() throws IOException { assertThat(info, is(withInfo)); } + + @Test + public void serder2Json() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().constructType(Info.class); + + final Info info = testRoundTrip(VERSION_1_22, + "info/2.json", + type + ); + + final List> driverStatus = asList( + asList("Pool Name", "docker-253:2-17567992-pool"), + asList("Pool Blocksize", "65.54 kB"), + asList("Base Device Size", "107.4 GB"), + asList("Backing Filesystem", "ext4"), + asList("Data file", "/dev/loop0"), + asList("Metadata file", "/dev/loop1"), + asList("Data Space Used", "3.89 GB"), + asList("Data Space Total", "107.4 GB"), + asList("Data Space Available", "103.5 GB"), + asList("Metadata Space Used", "5.46 MB"), + asList("Metadata Space Total", "2.147 GB"), + asList("Metadata Space Available", "2.142 GB"), + asList("Udev Sync Supported", "true"), + asList("Deferred Removal Enabled", "false"), + asList("Deferred Deletion Enabled", "false"), + asList("Deferred Deleted Device Count", "0"), + asList("Data loop file", "/var/lib/docker/devicemapper/devicemapper/data"), + asList("Metadata loop file", "/var/lib/docker/devicemapper/devicemapper/metadata"), + asList("Library Version", "1.02.107-RHEL7 (2015-12-01)") + ); + + final Map> plugins = new LinkedHashMap<>(); + plugins.put("Volume", singletonList("local")); + plugins.put("Network", asList("null", "host", "bridge")); + plugins.put("Authorization", null); + + assertThat(info, notNullValue()); + assertThat(info.getArchitecture(), equalTo("x86_64")); + assertThat(info.getContainersStopped(), is(2)); + assertThat(info.getContainersPaused(), is(0)); + assertThat(info.getContainersRunning(), is(0)); + assertThat(info.getCpuCfsPeriod(), is(true)); + + // not available in this dump + assertThat(info.getCpuCfsQuota(), is(true)); + assertThat(info.getDiscoveryBackend(), nullValue()); + assertThat(info.getOomScoreAdj(), nullValue()); + + assertThat(info.getDriverStatuses(), notNullValue()); + assertThat(info.getDriverStatuses(), hasSize(19)); + assertThat(info.getDriverStatuses(), equalTo(driverStatus)); + + assertThat(info.getNGoroutines(), is(30)); + + assertThat(info.getSystemStatus(), CoreMatchers.nullValue()); + + assertThat(info.getPlugins(), equalTo(plugins)); + assertThat(info.getPlugins(), hasEntry("Volume", singletonList("local"))); + assertThat(info.getPlugins(), hasEntry("Authorization", null)); + + assertThat(info.getExperimentalBuild(), is(false)); + + assertThat(info.getHttpProxy(), isEmptyString()); + assertThat(info.getHttpsProxy(), isEmptyString()); + assertThat(info.getNoProxy(), isEmptyString()); + assertThat(info.getOomKillDisable(), is(true)); + assertThat(info.getOsType(), equalTo("linux")); + + final InfoRegistryConfig registryConfig = info.getRegistryConfig(); + assertThat(registryConfig, notNullValue()); + final List cidRs = registryConfig.getInsecureRegistryCIDRs(); + assertThat(cidRs, notNullValue()); + assertThat(cidRs, contains("127.0.0.0/8")); + + final Map indexConfigs = registryConfig.getIndexConfigs(); + assertThat(indexConfigs, notNullValue()); + final IndexConfig indexConfig = new IndexConfig().withMirrors(null).withName("docker.io") + .withSecure(true).withOfficial(true); + assertThat(indexConfigs, hasEntry("docker.io", indexConfig)); + final IndexConfig indexConfig2 = new IndexConfig().withMirrors(Collections.emptyList()).withName("somehost:80") + .withSecure(false).withOfficial(false); + assertThat(indexConfigs, hasEntry("somehost:80", indexConfig2)); + assertThat(registryConfig.getMirrors(), nullValue()); + + assertThat(info.getSystemTime(), is("2016-03-20T17:32:06.598846244+01:00")); + assertThat(info.getServerVersion(), is("1.10.2")); + + assertThat(info.getCpuSet(), is(true)); + assertThat(info.getCpuShares(), is(true)); + assertThat(info.getIPv4Forwarding(), is(true)); + assertThat(info.getBridgeNfIptables(), is(false)); + assertThat(info.getBridgeNfIp6tables(), is(false)); + assertThat(info.getDebug(), is(false)); + assertThat(info.getNFd(), is(13)); + assertThat(info.getOomKillDisable(), is(true)); + assertThat(info.getLoggingDriver(), is("json-file")); + assertThat(info.getOperatingSystem(), is("Red Hat Enterprise Linux Workstation 7.2 (Maipo)")); + assertThat(info.getClusterStore(), is("")); + + + final Info withInfo = new Info().withArchitecture("x86_64") + .withContainers(2) + .withContainersRunning(0) + .withContainersPaused(0) + .withContainersStopped(2) + .withImages(55) + .withId("H52J:52LG:YP4W:EHKY:SRK5:RYG6:ETWR:7AR3:MTFJ:PC6C:4YF2:NTN2") + .withDriver("devicemapper") + .withDriverStatuses(driverStatus) + .withSystemStatus(null) + .withPlugins(plugins) + .withMemoryLimit(true) + .withSwapLimit(true) + .withCpuCfsPeriod(true) + .withCpuCfsQuota(true) + .withCpuShares(true) + .withCpuSet(true) + .withIPv4Forwarding(true) + .withBridgeNfIptables(false) + .withBridgeNfIp6tables(false) + .withDebug(false) + .withNFd(13) + .withOomKillDisable(true) + .withNGoroutines(30) + .withSystemTime("2016-03-20T17:32:06.598846244+01:00") + .withExecutionDriver("native-0.2") + .withLoggingDriver("json-file") + .withNEventsListener(0) + .withKernelVersion("3.10.0-327.10.1.el7.x86_64") + .withOperatingSystem("Red Hat Enterprise Linux Workstation 7.2 (Maipo)") + .withOsType("linux") + .withIndexServerAddress("https://index.docker.io/v1/") + .withRegistryConfig(registryConfig) + .withInitSha1("672d65f3cf8816fbda421afeed7e52c0ca17d5e7") + .withInitPath("/usr/libexec/docker/dockerinit") + .withNCPU(8) + .withMemTotal(33350918144L) + .withDockerRootDir("/var/lib/docker") + .withHttpProxy("") + .withHttpsProxy("") + .withNoProxy("") + .withName("somename") + .withLabels(null) + .withExperimentalBuild(false) + .withServerVersion("1.10.2") + .withClusterStore("") + .withClusterAdvertise("") + //shredinger-fields + .withDiscoveryBackend(null) + .withOomScoreAdj(null) + .withSockets(null) + ; + + assertThat(info, is(withInfo)); + } } diff --git a/src/test/resources/samples/1.22/info/2.json b/src/test/resources/samples/1.22/info/2.json new file mode 100644 index 000000000..c30dca325 --- /dev/null +++ b/src/test/resources/samples/1.22/info/2.json @@ -0,0 +1,165 @@ +{ + "ID":"H52J:52LG:YP4W:EHKY:SRK5:RYG6:ETWR:7AR3:MTFJ:PC6C:4YF2:NTN2", + "Containers":2, + "ContainersRunning":0, + "ContainersPaused":0, + "ContainersStopped":2, + "Images":55, + "Driver":"devicemapper", + "DriverStatus":[ + [ + "Pool Name", + "docker-253:2-17567992-pool" + ], + [ + "Pool Blocksize", + "65.54 kB" + ], + [ + "Base Device Size", + "107.4 GB" + ], + [ + "Backing Filesystem", + "ext4" + ], + [ + "Data file", + "/dev/loop0" + ], + [ + "Metadata file", + "/dev/loop1" + ], + [ + "Data Space Used", + "3.89 GB" + ], + [ + "Data Space Total", + "107.4 GB" + ], + [ + "Data Space Available", + "103.5 GB" + ], + [ + "Metadata Space Used", + "5.46 MB" + ], + [ + "Metadata Space Total", + "2.147 GB" + ], + [ + "Metadata Space Available", + "2.142 GB" + ], + [ + "Udev Sync Supported", + "true" + ], + [ + "Deferred Removal Enabled", + "false" + ], + [ + "Deferred Deletion Enabled", + "false" + ], + [ + "Deferred Deleted Device Count", + "0" + ], + [ + "Data loop file", + "/var/lib/docker/devicemapper/devicemapper/data" + ], + [ + "Metadata loop file", + "/var/lib/docker/devicemapper/devicemapper/metadata" + ], + [ + "Library Version", + "1.02.107-RHEL7 (2015-12-01)" + ] + ], + "SystemStatus":null, + "Plugins":{ + "Volume":[ + "local" + ], + "Network":[ + "null", + "host", + "bridge" + ], + "Authorization":null + }, + "MemoryLimit":true, + "SwapLimit":true, + "CpuCfsPeriod":true, + "CpuCfsQuota":true, + "CPUShares":true, + "CPUSet":true, + "IPv4Forwarding":true, + "BridgeNfIptables":false, + "BridgeNfIp6tables":false, + "Debug":false, + "NFd":13, + "OomKillDisable":true, + "NGoroutines":30, + "SystemTime":"2016-03-20T17:32:06.598846244+01:00", + "ExecutionDriver":"native-0.2", + "LoggingDriver":"json-file", + "NEventsListener":0, + "KernelVersion":"3.10.0-327.10.1.el7.x86_64", + "PkgVersion":"docker-1.10.2-6.git0f5ac89.el7.x86_64", + "OperatingSystem":"Red Hat Enterprise Linux Workstation 7.2 (Maipo)", + "OSType":"linux", + "Architecture":"x86_64", + "IndexServerAddress":"https://index.docker.io/v1/", + "IndexServerName":"docker.io", + "RegistryConfig":{ + "InsecureRegistryCIDRs":[ + "127.0.0.0/8" + ], + "IndexConfigs":{ + "docker.io":{ + "Name":"docker.io", + "Mirrors":null, + "Secure":true, + "Official":true + }, + "somehost:80":{ + "Name":"somehost:80", + "Mirrors":[ + + ], + "Secure":false, + "Official":false + } + }, + "Mirrors":null + }, + "InitSha1":"672d65f3cf8816fbda421afeed7e52c0ca17d5e7", + "InitPath":"/usr/libexec/docker/dockerinit", + "NCPU":8, + "MemTotal":33350918144, + "DockerRootDir":"/var/lib/docker", + "HttpProxy":"", + "HttpsProxy":"", + "NoProxy":"", + "Name":"somename", + "Labels":null, + "ExperimentalBuild":false, + "ServerVersion":"1.10.2", + "ClusterStore":"", + "ClusterAdvertise":"", + "Registries":[ + { + "Name":"docker.io", + "Secure":true + } + ] +} From 33a25ed9096cef84133cc734db89bf9b8ce9c9c8 Mon Sep 17 00:00:00 2001 From: hongweiyi Date: Wed, 23 Mar 2016 22:31:14 +0800 Subject: [PATCH 073/855] DOCKER_TLS_VERIFY cannot be 'false' or empty Signed-off-by: hongwei yi --- .../dockerjava/core/DockerClientConfig.java | 5 ++- .../core/DockerClientConfigTest.java | 33 +++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java index 038c43cae..a03d6e086 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java @@ -13,7 +13,6 @@ import java.util.Properties; import java.util.Set; -import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; @@ -418,8 +417,8 @@ public final DockerClientConfigBuilder withDockerConfig(String dockerConfig) { } public final DockerClientConfigBuilder withDockerTlsVerify(String dockerTlsVerify) { - this.dockerTlsVerify = BooleanUtils.toBoolean(dockerTlsVerify.trim()) - || BooleanUtils.toBoolean(dockerTlsVerify.trim(), "1", "0"); + String trimmed = dockerTlsVerify.trim(); + this.dockerTlsVerify = "true".equalsIgnoreCase(trimmed) || "1".equals(trimmed); return this; } diff --git a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java index e87254b88..a363e12ec 100644 --- a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java +++ b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java @@ -2,8 +2,12 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.core.Is.is; import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; +import java.lang.reflect.Field; import java.net.URI; import java.util.Collections; import java.util.HashMap; @@ -176,4 +180,33 @@ public void testUnixHostScheme() throws Exception { new DockerClientConfig(URI.create("unix://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", null, false); } + + @Test + public void withDockerTlsVerify() throws Exception { + DockerClientConfig.DockerClientConfigBuilder builder = new DockerClientConfig.DockerClientConfigBuilder(); + Field field = builder.getClass().getDeclaredField("dockerTlsVerify"); + field.setAccessible(true); + + builder.withDockerTlsVerify(""); + assertThat(field.getBoolean(builder), is(false)); + + builder.withDockerTlsVerify("false"); + assertThat(field.getBoolean(builder), is(false)); + + builder.withDockerTlsVerify("FALSE"); + assertThat(field.getBoolean(builder), is(false)); + + builder.withDockerTlsVerify("true"); + assertThat(field.getBoolean(builder), is(true)); + + builder.withDockerTlsVerify("TRUE"); + assertThat(field.getBoolean(builder), is(true)); + + builder.withDockerTlsVerify("0"); + assertThat(field.getBoolean(builder), is(false)); + + builder.withDockerTlsVerify("1"); + assertThat(field.getBoolean(builder), is(true)); + } + } From 9639cb7bdf602887899feccdd639406e4c9323ca Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 28 Mar 2016 00:33:12 +0300 Subject: [PATCH 074/855] Refactor CertUtils. Support ECDSA and PrivateKey. --- .../core/util/CertificateUtils.java | 206 +++++++++++------- 1 file changed, 128 insertions(+), 78 deletions(-) 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 562a954a7..6e1925630 100644 --- a/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java +++ b/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java @@ -2,30 +2,38 @@ import java.io.BufferedReader; import java.io.File; -import java.io.FileReader; import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; import java.security.KeyFactory; -import java.security.KeyPair; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; -import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.spec.InvalidKeySpecException; import java.security.spec.PKCS8EncodedKeySpec; -import java.security.spec.X509EncodedKeySpec; import java.util.ArrayList; import java.util.List; -import org.apache.commons.io.IOUtils; +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.openssl.PEMKeyPair; import org.bouncycastle.openssl.PEMParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.annotation.CheckForNull; + +import static java.util.Objects.requireNonNull; public class CertificateUtils { + private static final Logger LOG = LoggerFactory.getLogger(CertificateUtils.class); + private CertificateUtils() { // utility class } @@ -41,115 +49,157 @@ public static boolean verifyCertificatesExist(String dockerCertPath) { return result; } + /** + * @param dockerCertPath with standard named files. + */ public static KeyStore createKeyStore(final String dockerCertPath) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, CertificateException, KeyStoreException { - KeyPair keyPair = loadPrivateKey(dockerCertPath); - List privateCertificates = loadCertificates(dockerCertPath); + return createKeyStore("key.pem", "cert.pem"); + } + + + @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE") + public static KeyStore createKeyStore(final String keypem, final String certpem) throws NoSuchAlgorithmException, + InvalidKeySpecException, IOException, CertificateException, KeyStoreException { + PrivateKey privateKey = loadPrivateKey(keypem); + requireNonNull(privateKey); + List privateCertificates = loadCertificates(certpem); KeyStore keyStore = KeyStore.getInstance("JKS"); keyStore.load(null); - keyStore.setKeyEntry("docker", keyPair.getPrivate(), "docker".toCharArray(), - privateCertificates.toArray(new Certificate[privateCertificates.size()])); + keyStore.setKeyEntry("docker", + privateKey, + "docker".toCharArray(), + privateCertificates.toArray(new Certificate[privateCertificates.size()]) + ); + return keyStore; } - public static KeyStore createTrustStore(final String dockerCertPath) throws IOException, CertificateException, - KeyStoreException, NoSuchAlgorithmException { - File caPath = new File(dockerCertPath, "ca.pem"); - BufferedReader reader = new BufferedReader(new FileReader(caPath)); - PEMParser pemParser = null; - - try { - pemParser = new PEMParser(reader); - X509CertificateHolder certificateHolder = (X509CertificateHolder) pemParser.readObject(); - Certificate caCertificate = new JcaX509CertificateConverter().setProvider("BC").getCertificate( - certificateHolder); - - KeyStore trustStore = KeyStore.getInstance("JKS"); - trustStore.load(null); - trustStore.setCertificateEntry("ca", caCertificate); - return trustStore; - - } finally { - if (pemParser != null) { - IOUtils.closeQuietly(pemParser); - } - - if (reader != null) { - IOUtils.closeQuietly(reader); - } + /** + * from "cert.pem" String + */ + private static List loadCertificates(final String certpem) throws IOException, + CertificateException { + final StringReader certReader = new StringReader(certpem); + try (BufferedReader reader = new BufferedReader(certReader)) { + return loadCertificates(reader); } - } - private static List loadCertificates(final String dockerCertPath) throws IOException, + /** + * "cert.pem" from reader + */ + private static List loadCertificates(final Reader reader) throws IOException, CertificateException { - File certificate = new File(dockerCertPath, "cert.pem"); - BufferedReader reader = new BufferedReader(new FileReader(certificate)); - PEMParser pemParser = null; - - try { + try (PEMParser pemParser = new PEMParser(reader)) { List certificates = new ArrayList<>(); - pemParser = new PEMParser(reader); + JcaX509CertificateConverter certificateConverter = new JcaX509CertificateConverter().setProvider("BC"); Object certObj = pemParser.readObject(); - while (certObj != null) { + if (certObj instanceof X509CertificateHolder) { X509CertificateHolder certificateHolder = (X509CertificateHolder) certObj; certificates.add(certificateConverter.getCertificate(certificateHolder)); - - certObj = pemParser.readObject(); } return certificates; - } finally { - if (pemParser != null) { - IOUtils.closeQuietly(pemParser); - } - - if (reader != null) { - IOUtils.closeQuietly(reader); - } } - } - private static KeyPair loadPrivateKey(final String dockerCertPath) throws IOException, NoSuchAlgorithmException, - InvalidKeySpecException { - File certificate = new File(dockerCertPath, "key.pem"); - BufferedReader reader = new BufferedReader(new FileReader(certificate)); - PEMParser pemParser = null; + /** + * Return private key ("key.pem") from Reader + */ + @CheckForNull + private static PrivateKey loadPrivateKey(final Reader reader) throws IOException, NoSuchAlgorithmException, + InvalidKeySpecException { + try (PEMParser pemParser = new PEMParser(reader)) { + Object readObject = pemParser.readObject(); + while (readObject != null) { + if (readObject instanceof PEMKeyPair) { + PEMKeyPair pemKeyPair = (PEMKeyPair) readObject; + PrivateKey privateKey = guessKey(pemKeyPair.getPrivateKeyInfo().getEncoded()); + if (privateKey != null) { + return privateKey; + } + } else if (readObject instanceof PrivateKeyInfo) { + PrivateKeyInfo privateKeyInfo = (PrivateKeyInfo) readObject; + PrivateKey privateKey = guessKey(privateKeyInfo.getEncoded()); + if (privateKey != null) { + return privateKey; + } + } else if (readObject instanceof ASN1ObjectIdentifier) { + // no idea how it can be used + final ASN1ObjectIdentifier asn1ObjectIdentifier = (ASN1ObjectIdentifier) readObject; + LOG.trace("Ignoring asn1ObjectIdentifier {}", asn1ObjectIdentifier); + } else { + LOG.warn("Unknown object '{}' from PEMParser", readObject); + } + + readObject = pemParser.readObject(); + } + } - try { - pemParser = new PEMParser(reader); + return null; + } - PEMKeyPair pemKeyPair = (PEMKeyPair) pemParser.readObject(); + @CheckForNull + private static PrivateKey guessKey(byte[] encodedKey) throws NoSuchAlgorithmException { + //no way to know, so iterate + for (String guessFactory : new String[]{"RSA", "ECDSA"}) { + try { + KeyFactory factory = KeyFactory.getInstance(guessFactory); - byte[] pemPrivateKeyEncoded = pemKeyPair.getPrivateKeyInfo().getEncoded(); - byte[] pemPublicKeyEncoded = pemKeyPair.getPublicKeyInfo().getEncoded(); + PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey); + return factory.generatePrivate(privateKeySpec); + } catch (InvalidKeySpecException ignore) { + } + } - KeyFactory factory = KeyFactory.getInstance("RSA"); + return null; + } - X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(pemPublicKeyEncoded); - PublicKey publicKey = factory.generatePublic(publicKeySpec); + /** + * Return KeyPair from "key.pem" + */ + @CheckForNull + private static PrivateKey loadPrivateKey(final String keypem) throws IOException, NoSuchAlgorithmException, + InvalidKeySpecException { + try (StringReader certReader = new StringReader(keypem); + BufferedReader reader = new BufferedReader(certReader)) { + return loadPrivateKey(reader); + } + } - PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(pemPrivateKeyEncoded); - PrivateKey privateKey = factory.generatePrivate(privateKeySpec); + /** + * "ca.pem" from String + */ + public static KeyStore createTrustStore(String capem) throws IOException, CertificateException, + KeyStoreException, NoSuchAlgorithmException { + try (Reader certReader = new StringReader(capem)) { + return createTrustStore(certReader); + } + } - return new KeyPair(publicKey, privateKey); + /** + * "ca.pem" from Reader + */ + 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); - } finally { - if (pemParser != null) { - IOUtils.closeQuietly(pemParser); - } + KeyStore trustStore = KeyStore.getInstance("JKS"); + trustStore.load(null); + trustStore.setCertificateEntry("ca", caCertificate); - if (reader != null) { - IOUtils.closeQuietly(reader); - } + return trustStore; } - } } From 3bde2a93e9a47d06485db7133c7dd8b4059b0aab Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Tue, 29 Mar 2016 20:27:49 +0200 Subject: [PATCH 075/855] Add test originated from netty impl --- .../CopyArchiveFromContainerCmdImplTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java index 0f9da6058..9b30dd891 100644 --- a/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java @@ -6,7 +6,14 @@ import java.io.InputStream; import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.nio.file.StandardOpenOption; +import org.apache.commons.compress.archivers.tar.TarArchiveEntry; +import org.apache.commons.compress.archivers.tar.TarArchiveInputStream; +import org.apache.commons.io.IOUtils; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -17,6 +24,7 @@ import com.github.dockerjava.api.exception.NotFoundException; import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.client.AbstractDockerClientTest; +import com.github.dockerjava.core.util.CompressArchiveUtil; @Test(groups = "integration") public class CopyArchiveFromContainerCmdImplTest extends AbstractDockerClientTest { @@ -70,4 +78,36 @@ public void copyFromNonExistingContainer() throws Exception { } catch (NotFoundException ignored) { } } + + @Test + public void copyFromContainerBinaryFile() throws Exception { + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withName("docker-java-itest-copyFromContainerBinaryFile").exec(); + + LOG.info("Created container: {}", container); + assertThat(container.getId(), not(isEmptyOrNullString())); + + Path temp = Files.createTempFile("", ".tar.gz"); + Path binaryFile = Paths.get("src/test/resources/testCopyFromArchive/binary.dat"); + CompressArchiveUtil.tar(binaryFile, temp, true, false); + + try (InputStream uploadStream = Files.newInputStream(temp)) { + dockerClient.copyArchiveToContainerCmd(container.getId()).withTarInputStream(uploadStream).exec(); + } + + InputStream response = dockerClient.copyArchiveFromContainerCmd(container.getId(), "/binary.dat").exec(); + Boolean bytesAvailable = response.available() > 0; + assertTrue(bytesAvailable, "The file was not copied from the container."); + + try (TarArchiveInputStream tarInputStream = new TarArchiveInputStream(response)) { + TarArchiveEntry nextTarEntry = tarInputStream.getNextTarEntry(); + + assertEquals(nextTarEntry.getName(), "binary.dat"); + try (InputStream binaryFileInputStream = Files.newInputStream(binaryFile, StandardOpenOption.READ)) { + assertTrue(IOUtils.contentEquals(binaryFileInputStream, tarInputStream)); + } + + assertNull(tarInputStream.getNextTarEntry(), "Nothing except binary.dat is expected to be copied."); + } + } } From ac89c92e9e2108467b60ac24d4d882cb122bce27 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Tue, 29 Mar 2016 20:48:19 +0200 Subject: [PATCH 076/855] Update CHANGELOG.md --- CHANGELOG.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f34102285..73d2220cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,10 +11,11 @@ Notes All changes Included in 3.0.0-RC4 -* [#495] (https://github.com/docker-java/docker-java/pull/495) Add CgroupParent option for create cmd -* [#504] (https://github.com/docker-java/docker-java/pull/504) Rename container cmd +* [#510] (https://github.com/docker-java/docker-java/pull/510) Add CgroupParent option for create cmd +* [#509] (https://github.com/docker-java/docker-java/pull/509) Implement container rename api * [#500] (https://github.com/docker-java/docker-java/pull/500) Add aux to ResponseItem -* [#498] (https://github.com/docker-java/docker-java/issues/493) Expose RepoTags from inspect image command +* [#498] (https://github.com/docker-java/docker-java/issues/498) Update image inspect response + Included in 3.0.0-RC3 * [#488] (https://github.com/docker-java/docker-java/pull/488) Support remote API 1.22 subset From 70489a23853e6b16eebc4782490ac32d0c4ead49 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Tue, 29 Mar 2016 20:52:05 +0200 Subject: [PATCH 077/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73d2220cf..8c5706377 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ All changes Included in 3.0.0-RC4 * [#510] (https://github.com/docker-java/docker-java/pull/510) Add CgroupParent option for create cmd * [#509] (https://github.com/docker-java/docker-java/pull/509) Implement container rename api +* [#501] (https://github.com/docker-java/docker-java/pull/501) Fix execution of copy file/archive command skips 0xFF bytes * [#500] (https://github.com/docker-java/docker-java/pull/500) Add aux to ResponseItem * [#498] (https://github.com/docker-java/docker-java/issues/498) Update image inspect response From 6870c6ab484d51c5f3a484317a37a99e871e570a Mon Sep 17 00:00:00 2001 From: Alejandro Mousist Date: Wed, 30 Mar 2016 17:15:13 -0300 Subject: [PATCH 078/855] Added shmsize build option --- .../dockerjava/api/command/BuildImageCmd.java | 5 +++++ .../dockerjava/core/command/BuildImageCmdImpl.java | 14 ++++++++++++++ .../github/dockerjava/jaxrs/BuildImageCmdExec.java | 4 ++++ .../dockerjava/netty/exec/BuildImageCmdExec.java | 4 ++++ 4 files changed, 27 insertions(+) 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 d11c86c7f..84f4e42c5 100644 --- a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java @@ -95,6 +95,9 @@ public interface BuildImageCmd extends AsyncDockerCmd getBuildArgs(); + @CheckForNull + long getShmsize(); + // setters BuildImageCmd withTag(String tag); @@ -134,6 +137,8 @@ public interface BuildImageCmd extends AsyncDockerCmd { } 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 ef57e84a4..d5a42f7a3 100644 --- a/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java @@ -50,6 +50,8 @@ public class BuildImageCmdImpl extends AbstrAsyncDockerCmd buildArgs; @@ -159,6 +161,11 @@ public InputStream getTarInputStream() { return tarInputStream; } + @Override + public long getShmsize() { + return shmsize; + } + // setters @Override @@ -284,6 +291,12 @@ public BuildImageCmd withBuildAuthConfigs(AuthConfigurations authConfigs) { return this; } + @Override + public BuildImageCmd withShmsize(long shmsize) { + this.shmsize = shmsize; + return this; + } + @Override public void close() { super.close(); @@ -294,4 +307,5 @@ public void close() { throw new RuntimeException(e); } } + } diff --git a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java index dc642f1a6..c94946e7e 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java @@ -108,6 +108,10 @@ protected AbstractCallbackNotifier callbackNotifier(BuildImag } } + if (command.getShmsize() != 0) { + webTarget = webTarget.queryParam("shmsize", command.getShmsize()); + } + webTarget.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.CHUNKED); webTarget.property(ClientProperties.CHUNKED_ENCODING_SIZE, 1024 * 1024); 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 155ceef6a..bf1be4713 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java @@ -93,6 +93,10 @@ protected Void execute0(BuildImageCmd command, ResultCallback } } + if (command.getShmsize() != 0) { + webTarget = webTarget.queryParam("shmsize", command.getShmsize()); + } + LOGGER.trace("POST: {}", webTarget); InvocationBuilder builder = resourceWithOptionalAuthConfig(command, webTarget.request()) From 8c7e12caf1d29c821d51dec29c7305afe9984fa2 Mon Sep 17 00:00:00 2001 From: Alejandro Mousist Date: Wed, 30 Mar 2016 23:10:04 -0300 Subject: [PATCH 079/855] Code style/design for shmsize build option (API v1_22) --- .../github/dockerjava/api/command/BuildImageCmd.java | 10 ++++++++-- .../dockerjava/core/command/BuildImageCmdImpl.java | 12 +++++++++--- .../github/dockerjava/jaxrs/BuildImageCmdExec.java | 2 +- .../dockerjava/netty/exec/BuildImageCmdExec.java | 2 +- 4 files changed, 19 insertions(+), 7 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 84f4e42c5..20b23e903 100644 --- a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java @@ -95,8 +95,11 @@ public interface BuildImageCmd extends AsyncDockerCmd getBuildArgs(); + /** + *@since {@link RemoteApiVersion#VERSION_1_22} + */ @CheckForNull - long getShmsize(); + Long getShmsize(); // setters @@ -137,7 +140,10 @@ public interface BuildImageCmd extends AsyncDockerCmd { } 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 d5a42f7a3..58f148cb6 100644 --- a/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java @@ -50,7 +50,7 @@ public class BuildImageCmdImpl extends AbstrAsyncDockerCmd callbackNotifier(BuildImag } } - if (command.getShmsize() != 0) { + if (command.getShmsize() != null) { webTarget = webTarget.queryParam("shmsize", command.getShmsize()); } 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 bf1be4713..f4ff04576 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java @@ -93,7 +93,7 @@ protected Void execute0(BuildImageCmd command, ResultCallback } } - if (command.getShmsize() != 0) { + if (command.getShmsize() != null) { webTarget = webTarget.queryParam("shmsize", command.getShmsize()); } From cb89d2b43a35e149a90fba5597e444525664125d Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Thu, 31 Mar 2016 20:37:39 +0200 Subject: [PATCH 080/855] Fix issue #531 --- .../dockerjava/netty/handler/FramedResponseStreamHandler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/github/dockerjava/netty/handler/FramedResponseStreamHandler.java b/src/main/java/com/github/dockerjava/netty/handler/FramedResponseStreamHandler.java index 0567050d2..f360ca756 100644 --- a/src/main/java/com/github/dockerjava/netty/handler/FramedResponseStreamHandler.java +++ b/src/main/java/com/github/dockerjava/netty/handler/FramedResponseStreamHandler.java @@ -62,6 +62,7 @@ protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Excep private int read(byte[] buf, int offset, int length) { length = Math.min(rawBuffer.readableBytes(), length); rawBuffer.readBytes(buf, offset, length); + rawBuffer.discardReadBytes(); return length; } From 866a3a0804b469abe267896052f63e463c82ddea Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Thu, 31 Mar 2016 20:54:35 +0200 Subject: [PATCH 081/855] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c5706377..6d7303448 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ Notes All changes Included in 3.0.0-RC4 +* [#528] (https://github.com/docker-java/docker-java/pull/528) Fix DOCKER_TLS_VERIFY cannot be 'false' or empty +* [#527] (https://github.com/docker-java/docker-java/pull/527) Fix `mirrors` field is list and not a single string #527 * [#510] (https://github.com/docker-java/docker-java/pull/510) Add CgroupParent option for create cmd * [#509] (https://github.com/docker-java/docker-java/pull/509) Implement container rename api * [#501] (https://github.com/docker-java/docker-java/pull/501) Fix execution of copy file/archive command skips 0xFF bytes From 6c0ad12668a7402d34f8fa7e86512ae04c58324a Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Thu, 31 Mar 2016 20:57:07 +0200 Subject: [PATCH 082/855] [maven-release-plugin] prepare release docker-java-3.0.0-RC4 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9ee5cad51..fcaa92a1c 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-SNAPSHOT + 3.0.0-RC4 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 + docker-java-3.0.0-RC4 From 90f719c65112dfb49ce2be3496aacbf05d35a58a Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Thu, 31 Mar 2016 20:57:12 +0200 Subject: [PATCH 083/855] [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 fcaa92a1c..9ee5cad51 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-RC4 + 3.0.0-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 - docker-java-3.0.0-RC4 + HEAD From 24866d0735cae435336e717ff97d15aca8d21cae Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Thu, 31 Mar 2016 21:45:34 +0200 Subject: [PATCH 084/855] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3601be462..ae6d5d620 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ Supports a subset of the Docker Remote API [v1.22](https://github.com/docker/doc com.github.docker-java docker-java - 3.0.0-RC3 + 3.0.0-RC4 ### Latest development version From 7ea7514627968ffb5361a59af1956c57f6f08210 Mon Sep 17 00:00:00 2001 From: Surya Gaddipati Date: Fri, 1 Apr 2016 11:14:00 -0500 Subject: [PATCH 085/855] Assign passed in volume opts to field --- .../com/github/dockerjava/core/command/CreateVolumeCmdImpl.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/github/dockerjava/core/command/CreateVolumeCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateVolumeCmdImpl.java index 13cb0ac83..46b12ebea 100644 --- a/src/main/java/com/github/dockerjava/core/command/CreateVolumeCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CreateVolumeCmdImpl.java @@ -61,6 +61,7 @@ public CreateVolumeCmdImpl withDriver(String driver) { @Override public CreateVolumeCmd withDriverOpts(Map driverOpts) { checkNotNull(driverOpts, "driverOpts was not specified"); + this.driverOpts = driverOpts; return this; } } From 284b26b58649ae9b00c36cb9ac383b46d7d1a5bd Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Thu, 7 Apr 2016 13:04:55 +0200 Subject: [PATCH 086/855] Clarify configuration for unix sockets --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ae6d5d620..9a155d0c4 100644 --- a/README.md +++ b/README.md @@ -33,9 +33,10 @@ listening on TCP port. To allow Docker server to use TCP add the following line DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock" -However you can force docker-java to use UNIX socket communication by configuring the following url: +However you can force docker-java to use UNIX socket communication by configure the following (see [Configuration](.#Configuration) for details): - unix:///var/run/docker.sock + DOCKER_HOST=unix:///var/run/docker.sock + DOCKER_TLS_VERIFY=0 More details about setting up Docker server can be found in official documentation: http://docs.docker.io/en/latest/use/basics/ From 042bf59db43f70eb9089d5f793dfcf62afb8aa47 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 8 Apr 2016 20:55:50 +0300 Subject: [PATCH 087/855] Use getters for objects --- .../api/command/CreateContainerCmd.java | 8 ++-- .../dockerjava/api/model/HostConfig.java | 40 +++++++++++-------- .../core/command/CreateContainerCmdImpl.java | 16 ++++---- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java index 0181d86be..ffcb01c98 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java @@ -159,16 +159,16 @@ public interface CreateContainerCmd extends SyncDockerCmd Date: Fri, 8 Apr 2016 21:26:16 +0300 Subject: [PATCH 088/855] GraphData is more complex structure. Fixes #538 --- .../dockerjava/api/command/GraphData.java | 86 ++++++++++ .../dockerjava/api/command/GraphDriver.java | 6 +- .../api/command/InspectImageResponseTest.java | 29 ++++ .../1.22/images/docImage/inspect_doc.json | 150 ++++++++++++++++++ 4 files changed, 268 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/github/dockerjava/api/command/GraphData.java create mode 100644 src/test/resources/samples/1.22/images/docImage/inspect_doc.json diff --git a/src/main/java/com/github/dockerjava/api/command/GraphData.java b/src/main/java/com/github/dockerjava/api/command/GraphData.java new file mode 100644 index 000000000..dc55810ba --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/GraphData.java @@ -0,0 +1,86 @@ +package com.github.dockerjava.api.command; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; + +/** + * part of {@link GraphDriver} + * @author Kanstantsin Shautsou + */ +public class GraphData { + @JsonProperty("DeviceId") + private String deviceId; + + @JsonProperty("DeviceName") + private String deviceName; + + @JsonProperty("DeviceSize") + private String deviceSize; + + /** + * @see #deviceId + */ + @CheckForNull + public String getDeviceId() { + return deviceId; + } + + /** + * @see #deviceId + */ + public GraphData withDeviceId(String deviceId) { + this.deviceId = deviceId; + return this; + } + + /** + * @see #deviceName + */ + @CheckForNull + public String getDeviceName() { + return deviceName; + } + + /** + * @see #deviceName + */ + public GraphData withDeviceName(String deviceName) { + this.deviceName = deviceName; + return this; + } + + /** + * @see #deviceSize + */ + @CheckForNull + public String getDeviceSize() { + return deviceSize; + } + + /** + * @see #deviceSize + */ + public GraphData withDeviceSize(String deviceSize) { + this.deviceSize = deviceSize; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/command/GraphDriver.java b/src/main/java/com/github/dockerjava/api/command/GraphDriver.java index 6285195c4..0d41364aa 100644 --- a/src/main/java/com/github/dockerjava/api/command/GraphDriver.java +++ b/src/main/java/com/github/dockerjava/api/command/GraphDriver.java @@ -24,21 +24,21 @@ public class GraphDriver { * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_21} */ @JsonProperty("Data") - private String data; + private GraphData data; /** * @see #data */ @CheckForNull - public String getData() { + public GraphData getData() { return data; } /** * @see #data */ - public GraphDriver withData(String data) { + public GraphDriver withData(GraphData data) { this.data = data; return this; } diff --git a/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java b/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java index 0df990d00..410d5b32a 100644 --- a/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java +++ b/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java @@ -160,4 +160,33 @@ public void serder1_22_doc() throws IOException { "example:stable" )); } + + @Test + public void serder1_22_inspect_doc() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().constructType(InspectImageResponse.class); + + final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, + "images/docImage/inspect_doc.json", + type + ); + + GraphData newGraphData = new GraphData() + .withDeviceId("5") + .withDeviceName("docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47") + .withDeviceSize("171798691840"); + + assertThat(inspectImage, notNullValue()); + GraphDriver graphDriver = inspectImage.getGraphDriver(); + assertThat(graphDriver, notNullValue()); + GraphData data = graphDriver.getData(); + + assertThat(data, is(newGraphData)); + + assertThat(data.getDeviceId(), is("5")); + assertThat(data.getDeviceName(), + is("docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47")); + assertThat(data.getDeviceSize(), + is("171798691840")); + } } \ No newline at end of file diff --git a/src/test/resources/samples/1.22/images/docImage/inspect_doc.json b/src/test/resources/samples/1.22/images/docImage/inspect_doc.json new file mode 100644 index 000000000..5ffc187cb --- /dev/null +++ b/src/test/resources/samples/1.22/images/docImage/inspect_doc.json @@ -0,0 +1,150 @@ +{ + "Id": "d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47", + "Created": "2015-06-08T16:18:02.505155285Z", + "Path": "bash", + "Args": [], + "State": { + "Running": false, + "Paused": false, + "Restarting": false, + "OOMKilled": false, + "Dead": false, + "Pid": 0, + "ExitCode": 0, + "Error": "", + "StartedAt": "2015-06-08T16:18:03.643865954Z", + "FinishedAt": "2015-06-08T16:57:06.448552862Z" + }, + "Image": "ded7cd95e059788f2586a51c275a4f151653779d6a7f4dad77c2bd34601d94e4", + "NetworkSettings": { + "Bridge": "", + "SandboxID": "6b4851d1903e16dd6a567bd526553a86664361f31036eaaa2f8454d6f4611f6f", + "HairpinMode": false, + "LinkLocalIPv6Address": "", + "LinkLocalIPv6PrefixLen": 0, + "Ports": {}, + "SandboxKey": "/var/run/docker/netns/6b4851d1903e", + "SecondaryIPAddresses": null, + "SecondaryIPv6Addresses": null, + "EndpointID": "7587b82f0dada3656fda26588aee72630c6fab1536d36e394b2bfbcf898c971d", + "Gateway": "172.17.0.1", + "GlobalIPv6Address": "", + "GlobalIPv6PrefixLen": 0, + "IPAddress": "172.17.0.2", + "IPPrefixLen": 16, + "IPv6Gateway": "", + "MacAddress": "02:42:ac:12:00:02", + "Networks": { + "bridge": { + "NetworkID": "7ea29fc1412292a2d7bba362f9253545fecdfa8ce9a6e37dd10ba8bee7129812", + "EndpointID": "7587b82f0dada3656fda26588aee72630c6fab1536d36e394b2bfbcf898c971d", + "Gateway": "172.17.0.1", + "IPAddress": "172.17.0.2", + "IPPrefixLen": 16, + "IPv6Gateway": "", + "GlobalIPv6Address": "", + "GlobalIPv6PrefixLen": 0, + "MacAddress": "02:42:ac:12:00:02" + } + } + }, + "ResolvConfPath": "/var/lib/docker/containers/d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47/resolv.conf", + "HostnamePath": "/var/lib/docker/containers/d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47/hostname", + "HostsPath": "/var/lib/docker/containers/d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47/hosts", + "LogPath": "/var/lib/docker/containers/d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47/d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47-json.log", + "Name": "/adoring_wozniak", + "RestartCount": 0, + "Driver": "devicemapper", + "MountLabel": "", + "ProcessLabel": "", + "Mounts": [ + { + "Source": "/data", + "Destination": "/data", + "Mode": "ro,Z", + "RW": false, + "Propagation": "" + } + ], + "AppArmorProfile": "", + "ExecIDs": null, + "HostConfig": { + "Binds": null, + "ContainerIDFile": "", + "Memory": 0, + "MemorySwap": 0, + "CpuShares": 0, + "CpuPeriod": 0, + "CpusetCpus": "", + "CpusetMems": "", + "CpuQuota": 0, + "BlkioWeight": 0, + "OomKillDisable": false, + "Privileged": false, + "PortBindings": {}, + "Links": null, + "PublishAllPorts": false, + "Dns": null, + "DnsSearch": null, + "DnsOptions": null, + "ExtraHosts": null, + "VolumesFrom": null, + "Devices": [], + "NetworkMode": "bridge", + "IpcMode": "", + "PidMode": "", + "UTSMode": "", + "CapAdd": null, + "CapDrop": null, + "RestartPolicy": { + "Name": "no", + "MaximumRetryCount": 0 + }, + "SecurityOpt": null, + "ReadonlyRootfs": false, + "Ulimits": null, + "LogConfig": { + "Type": "json-file", + "Config": {} + }, + "CgroupParent": "" + }, + "GraphDriver": { + "Name": "devicemapper", + "Data": { + "DeviceId": "5", + "DeviceName": "docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47", + "DeviceSize": "171798691840" + } + }, + "Config": { + "Hostname": "d2cc496561d6", + "Domainname": "", + "User": "", + "AttachStdin": true, + "AttachStdout": true, + "AttachStderr": true, + "ExposedPorts": null, + "Tty": true, + "OpenStdin": true, + "StdinOnce": true, + "Env": null, + "Cmd": [ + "bash" + ], + "Image": "fedora", + "Volumes": null, + "VolumeDriver": "", + "WorkingDir": "", + "Entrypoint": null, + "NetworkDisabled": false, + "MacAddress": "", + "OnBuild": null, + "Labels": {}, + "Memory": 0, + "MemorySwap": 0, + "CpuShares": 0, + "Cpuset": "", + "StopSignal": "SIGTERM" + } +} From 1ca5d26b2ab8edcd57c64b59f9fd0a1fc335ab78 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Fri, 8 Apr 2016 21:00:08 +0200 Subject: [PATCH 089/855] Update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6d7303448..196408717 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,11 @@ Notes All changes +* [#542] (https://github.com/docker-java/docker-java/pull/542) Fix large volumes of output from "docker exec" trigger out of memory error +* [#541] (https://github.com/docker-java/docker-java/pull/541) ImageInspectResponse.GraphDriver.Data is more complex structure +* [#534] (https://github.com/docker-java/docker-java/pull/534) Fix create volume command doesn't assign passed in volume driverOpts to field +* [#533] (https://github.com/docker-java/docker-java/pull/533) Added shmsize build option + Included in 3.0.0-RC4 * [#528] (https://github.com/docker-java/docker-java/pull/528) Fix DOCKER_TLS_VERIFY cannot be 'false' or empty * [#527] (https://github.com/docker-java/docker-java/pull/527) Fix `mirrors` field is list and not a single string #527 From 741492cd1181443e81af3b3475d97c5ff93141fa Mon Sep 17 00:00:00 2001 From: Mikhail Stepura Date: Thu, 14 Apr 2016 13:57:39 -0700 Subject: [PATCH 090/855] Use named daemon threads for callback processing --- .../dockerjava/jaxrs/async/AbstractCallbackNotifier.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java b/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java index aac5a94d6..86f528af6 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java +++ b/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java @@ -10,6 +10,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.ThreadFactory; import javax.ws.rs.ProcessingException; import javax.ws.rs.client.Invocation.Builder; @@ -18,6 +19,7 @@ import com.github.dockerjava.api.async.ResultCallback; import com.github.dockerjava.core.async.ResponseStreamProcessor; import com.github.dockerjava.jaxrs.util.WrappedResponseInputStream; +import com.google.common.util.concurrent.ThreadFactoryBuilder; public abstract class AbstractCallbackNotifier implements Callable { @@ -25,6 +27,9 @@ public abstract class AbstractCallbackNotifier implements Callable { private final ResultCallback resultCallback; + private static final ThreadFactory FACTORY = + new ThreadFactoryBuilder().setDaemon(true).setNameFormat("dockerjava-jaxrs-async-%d").build(); + protected final Builder requestBuilder; protected AbstractCallbackNotifier(ResponseStreamProcessor responseStreamProcessor, @@ -76,7 +81,7 @@ public Void call() throws Exception { public static Future startAsyncProcessing(AbstractCallbackNotifier callbackNotifier) { - ExecutorService executorService = Executors.newSingleThreadExecutor(); + ExecutorService executorService = Executors.newSingleThreadExecutor(FACTORY); Future response = executorService.submit(callbackNotifier); executorService.shutdown(); return response; From 2f88b39a4954a2ebc88a4ebdfe74a245c6183685 Mon Sep 17 00:00:00 2001 From: VU Minh Khang Date: Mon, 18 Apr 2016 00:20:48 +0200 Subject: [PATCH 091/855] Add setters in order to be able to construct network creation request --- .../com/github/dockerjava/api/model/Network.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 546904254..583441049 100644 --- a/src/main/java/com/github/dockerjava/api/model/Network.java +++ b/src/main/java/com/github/dockerjava/api/model/Network.java @@ -149,6 +149,18 @@ public String getIpRange() { public String getGateway() { return gateway; } + + public void setSubnet(String subnet) { + this.subnet = subnet; + } + + public void setIpRange(String ipRange) { + this.ipRange = ipRange; + } + + public void setGateway(String gateway) { + this.gateway = gateway; + } } } } From 14f64794c722522da59ec8b83d6dd17f95f8a54d Mon Sep 17 00:00:00 2001 From: VU Minh Khang Date: Mon, 18 Apr 2016 00:41:55 +0200 Subject: [PATCH 092/855] Fix NPE for withIpamConfig --- .../github/dockerjava/core/command/CreateNetworkCmdImpl.java | 3 +++ 1 file changed, 3 insertions(+) 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 c7d3b0abb..b07076dc5 100644 --- a/src/main/java/com/github/dockerjava/core/command/CreateNetworkCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CreateNetworkCmdImpl.java @@ -58,6 +58,9 @@ public CreateNetworkCmd withDriver(String driver) { @Override public CreateNetworkCmd withIpamConfig(Ipam.Config config) { + if (this.ipam == null) { + this.ipam = new Ipam(); + } this.ipam.getConfig().add(config); return this; } From 3ed7e7cf32943fbcf604eba3511faeb9c85f17e9 Mon Sep 17 00:00:00 2001 From: VU Minh Khang Date: Mon, 18 Apr 2016 00:54:25 +0200 Subject: [PATCH 093/855] Add test for network creation with ipam config --- .../dockerjava/core/command/CreateNetworkCmdImplTest.java | 5 +++-- .../dockerjava/netty/exec/CreateNetworkCmdExecTest.java | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) 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 eefeb535f..25225160b 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java @@ -40,8 +40,9 @@ public void afterMethod(ITestResult result) { public void createNetwork() throws DockerException { String networkName = "testNetwork"; - - CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd().withName(networkName).exec(); + Network.Ipam.Config config = new Network.Ipam.Config(); + config.setSubnet("10.67.79.0/24"); + CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd().withName(networkName).withIpamConfig(config).exec(); assertNotNull(createNetworkResponse.getId()); diff --git a/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java index fa9962826..cd5b788ed 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java @@ -40,8 +40,9 @@ public void afterMethod(ITestResult result) { public void createNetwork() throws DockerException { String networkName = "testNetwork"; - - CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd().withName(networkName).exec(); + Network.Ipam.Config config = new Network.Ipam.Config(); + config.setSubnet("10.67.79.0/24"); + CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd().withName(networkName).withIpamConfig(config).exec(); assertNotNull(createNetworkResponse.getId()); From 41355559bbbfd0b8ea258f81951a23bb03417d11 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Fri, 22 Apr 2016 20:25:37 +0200 Subject: [PATCH 094/855] rename netty worker threads --- .../github/dockerjava/netty/DockerCmdExecFactoryImpl.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java index 08a0179a1..8f704c7af 100644 --- a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java @@ -119,6 +119,7 @@ import io.netty.handler.codec.http.HttpClientCodec; import io.netty.handler.logging.LoggingHandler; import io.netty.handler.ssl.SslHandler; +import io.netty.util.concurrent.DefaultThreadFactory; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -148,6 +149,8 @@ */ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { + private static String threadPrefix = "dockerjava-netty"; + /* * useful links: * @@ -215,7 +218,7 @@ private interface NettyInitializer { private class UnixDomainSocketInitializer implements NettyInitializer { @Override public EventLoopGroup init(Bootstrap bootstrap, DockerClientConfig dockerClientConfig) { - EventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup(); + EventLoopGroup epollEventLoopGroup = new EpollEventLoopGroup(0, new DefaultThreadFactory(threadPrefix)); bootstrap.group(epollEventLoopGroup).channel(EpollDomainSocketChannel.class) .handler(new ChannelInitializer() { @Override @@ -235,7 +238,7 @@ public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException { private class InetSocketInitializer implements NettyInitializer { @Override public EventLoopGroup init(Bootstrap bootstrap, final DockerClientConfig dockerClientConfig) { - EventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(); + EventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(0, new DefaultThreadFactory(threadPrefix)); InetAddress addr = InetAddress.getLoopbackAddress(); From fa0a69a3dbee6a940a21e77e6868ac95f7fbd660 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Fri, 22 Apr 2016 20:40:48 +0200 Subject: [PATCH 095/855] [maven-release-plugin] prepare release docker-java-3.0.0-RC5 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9ee5cad51..17964e6b9 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-SNAPSHOT + 3.0.0-RC5 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 + docker-java-3.0.0-RC5 From f384eb4b293d498c3d0ac6adc3a51383ad1aede8 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Fri, 22 Apr 2016 20:40:53 +0200 Subject: [PATCH 096/855] [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 17964e6b9..9ee5cad51 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-RC5 + 3.0.0-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 - docker-java-3.0.0-RC5 + HEAD From 12e266bba47ad0a3e7f6b56a11a675b77a7b53b7 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Fri, 22 Apr 2016 20:48:10 +0200 Subject: [PATCH 097/855] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 196408717..2154f36a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ Notes All changes +Included in 3.0.0-RC5 + * [#542] (https://github.com/docker-java/docker-java/pull/542) Fix large volumes of output from "docker exec" trigger out of memory error * [#541] (https://github.com/docker-java/docker-java/pull/541) ImageInspectResponse.GraphDriver.Data is more complex structure * [#534] (https://github.com/docker-java/docker-java/pull/534) Fix create volume command doesn't assign passed in volume driverOpts to field From a760dd5954cc465b840c79640cc436608e64b49c Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Fri, 22 Apr 2016 20:48:40 +0200 Subject: [PATCH 098/855] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9a155d0c4..f2135f61b 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ Supports a subset of the Docker Remote API [v1.22](https://github.com/docker/doc com.github.docker-java docker-java - 3.0.0-RC4 + 3.0.0-RC5 ### Latest development version From 89330387bf90fbe2bde1dcc3bea87b11be47fa06 Mon Sep 17 00:00:00 2001 From: VU Minh Khang Date: Sat, 30 Apr 2016 14:24:44 +0200 Subject: [PATCH 099/855] Separate tests --- .../command/CreateNetworkCmdImplTest.java | 21 ++++++++++++++----- .../netty/exec/CreateNetworkCmdExecTest.java | 21 ++++++++++++++----- 2 files changed, 32 insertions(+), 10 deletions(-) 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 25225160b..c278f191b 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java @@ -5,11 +5,7 @@ import com.github.dockerjava.api.model.Network; import com.github.dockerjava.client.AbstractDockerClientTest; import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; +import org.testng.annotations.*; import java.lang.reflect.Method; @@ -39,6 +35,20 @@ public void afterMethod(ITestResult result) { @Test public void createNetwork() throws DockerException { + String networkName = "testNetwork"; + + CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd().withName(networkName).exec(); + + assertNotNull(createNetworkResponse.getId()); + + Network network = dockerClient.inspectNetworkCmd().withNetworkId(createNetworkResponse.getId()).exec(); + assertEquals(network.getName(), networkName); + assertEquals(network.getDriver(), "bridge"); + } + + @Test + public void createNetworkWithCustomConfig() throws DockerException { + String networkName = "testNetwork"; Network.Ipam.Config config = new Network.Ipam.Config(); config.setSubnet("10.67.79.0/24"); @@ -49,5 +59,6 @@ public void createNetwork() throws DockerException { Network network = dockerClient.inspectNetworkCmd().withNetworkId(createNetworkResponse.getId()).exec(); assertEquals(network.getName(), networkName); assertEquals(network.getDriver(), "bridge"); + assertEquals("10.67.79.0/24", network.getIpam().getConfig().iterator().next().getSubnet()); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java index cd5b788ed..974d684b8 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java @@ -5,11 +5,7 @@ import com.github.dockerjava.api.model.Network; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; +import org.testng.annotations.*; import java.lang.reflect.Method; @@ -39,6 +35,20 @@ public void afterMethod(ITestResult result) { @Test public void createNetwork() throws DockerException { + String networkName = "testNetwork"; + + CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd().withName(networkName).exec(); + + assertNotNull(createNetworkResponse.getId()); + + Network network = dockerClient.inspectNetworkCmd().withNetworkId(createNetworkResponse.getId()).exec(); + assertEquals(network.getName(), networkName); + assertEquals(network.getDriver(), "bridge"); + } + + @Test + public void createNetworkWithCustomConfig() throws DockerException { + String networkName = "testNetwork"; Network.Ipam.Config config = new Network.Ipam.Config(); config.setSubnet("10.67.79.0/24"); @@ -49,5 +59,6 @@ public void createNetwork() throws DockerException { Network network = dockerClient.inspectNetworkCmd().withNetworkId(createNetworkResponse.getId()).exec(); assertEquals(network.getName(), networkName); assertEquals(network.getDriver(), "bridge"); + assertEquals("10.67.79.0/24", network.getIpam().getConfig().iterator().next().getSubnet()); } } From b8f87dcf3897390414dd55f6cbe1016cd0859929 Mon Sep 17 00:00:00 2001 From: Yannick Lorenzati Date: Sat, 30 Apr 2016 14:40:41 +0200 Subject: [PATCH 100/855] docker java generate empty filter instead of no filter #557 --- .../java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java | 2 +- .../com/github/dockerjava/netty/exec/ListContainersCmdExec.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java index fd882b673..50311ef54 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java +++ b/src/main/java/com/github/dockerjava/jaxrs/ListContainersCmdExec.java @@ -37,7 +37,7 @@ protected List execute(ListContainersCmd command) { webTarget = webTarget.queryParam("limit", String.valueOf(command.getLimit())); } - if (command.getFilters() != null) { + if (command.getFilters() != null && !command.getFilters().isEmpty()) { webTarget = webTarget .queryParam("filters", urlPathSegmentEscaper().escape(FiltersEncoder.jsonEncode(command.getFilters()))); } diff --git a/src/main/java/com/github/dockerjava/netty/exec/ListContainersCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/ListContainersCmdExec.java index 219aebc4b..e5ab4b66b 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/ListContainersCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/ListContainersCmdExec.java @@ -36,7 +36,7 @@ protected List execute(ListContainersCmd command) { webTarget = webTarget.queryParam("limit", String.valueOf(command.getLimit())); } - if (command.getFilters() != null) { + if (command.getFilters() != null && !command.getFilters().isEmpty()) { webTarget = webTarget .queryParam("filters", urlPathSegmentEscaper().escape(FiltersEncoder.jsonEncode(command.getFilters()))); } From 4d605506b2a1512977103f9313259b503917d35d Mon Sep 17 00:00:00 2001 From: fb Date: Sat, 27 Feb 2016 11:11:47 +0100 Subject: [PATCH 101/855] implement links and aliases for user defined networks add missing network options add tests --- .../api/command/ConnectToNetworkCmd.java | 6 + .../api/command/CreateContainerCmd.java | 34 ++++- .../api/command/CreateNetworkCmd.java | 33 +++-- .../api/command/DisconnectFromNetworkCmd.java | 5 + .../api/model/ContainerNetwork.java | 73 +++++++++-- .../dockerjava/api/model/HostConfig.java | 12 ++ .../github/dockerjava/api/model/Network.java | 35 ++++- .../dockerjava/api/model/NetworkSettings.java | 90 +------------ .../core/command/ConnectToNetworkCmdImpl.java | 15 +++ .../core/command/CreateContainerCmdImpl.java | 122 ++++++++++++++++-- .../core/command/CreateNetworkCmdImpl.java | 51 +++++++- .../command/DisconnectFromNetworkCmdImpl.java | 14 ++ .../core/command/RemoveNetworkCmdImpl.java | 1 - .../command/ConnectToNetworkCmdImplTest.java | 52 +++++++- .../command/CreateContainerCmdImplTest.java | 106 +++++++++++++++ .../DisconnectFromNetworkCmdImplTest.java | 22 ++++ 16 files changed, 542 insertions(+), 129 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/ConnectToNetworkCmd.java b/src/main/java/com/github/dockerjava/api/command/ConnectToNetworkCmd.java index cd5c57774..0f384e043 100644 --- a/src/main/java/com/github/dockerjava/api/command/ConnectToNetworkCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ConnectToNetworkCmd.java @@ -1,5 +1,6 @@ package com.github.dockerjava.api.command; +import com.github.dockerjava.api.model.ContainerNetwork; import com.github.dockerjava.core.RemoteApiVersion; import javax.annotation.CheckForNull; @@ -18,10 +19,15 @@ public interface ConnectToNetworkCmd extends SyncDockerCmd { @CheckForNull String getContainerId(); + @CheckForNull + ContainerNetwork getContainerConfig(); + ConnectToNetworkCmd withNetworkId(@Nonnull String networkId); ConnectToNetworkCmd withContainerId(@Nonnull String containerId); + ConnectToNetworkCmd withContainerNetwork(@Nonnull ContainerNetwork endpointConfig); + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java index ffcb01c98..196763560 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java @@ -1,10 +1,5 @@ package com.github.dockerjava.api.command; -import java.util.List; -import java.util.Map; - -import javax.annotation.CheckForNull; - import com.github.dockerjava.api.exception.ConflictException; import com.github.dockerjava.api.exception.NotFoundException; import com.github.dockerjava.api.model.Bind; @@ -21,8 +16,15 @@ import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.api.model.VolumesFrom; +import javax.annotation.CheckForNull; +import java.util.List; +import java.util.Map; + public interface CreateContainerCmd extends SyncDockerCmd { + @CheckForNull + List getAliases(); + @CheckForNull Bind[] getBinds(); @@ -92,6 +94,12 @@ public interface CreateContainerCmd extends SyncDockerCmd getLabels(); @@ -185,6 +193,18 @@ public interface CreateContainerCmd extends SyncDockerCmd aliases); + CreateContainerCmd withAttachStderr(Boolean attachStderr); CreateContainerCmd withAttachStdin(Boolean attachStdin); @@ -304,6 +324,10 @@ public interface CreateContainerCmd extends SyncDockerCmd labels); /** 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 6ad26b605..39989bd13 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateNetworkCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateNetworkCmd.java @@ -1,14 +1,13 @@ package com.github.dockerjava.api.command; -import java.util.Map; - -import javax.annotation.CheckForNull; -import javax.annotation.Nonnull; - import com.github.dockerjava.api.model.Network; import com.github.dockerjava.api.model.Network.Ipam; import com.github.dockerjava.core.RemoteApiVersion; +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; +import java.util.Map; + /** * Create a network. * @@ -25,18 +24,36 @@ public interface CreateNetworkCmd extends SyncDockerCmd { @CheckForNull Network.Ipam getIpam(); + @CheckForNull + Map getOptions(); + + @CheckForNull + Boolean getCheckDuplicate(); + + @CheckForNull + Boolean getInternal(); + + @CheckForNull + Boolean getEnableIPv6(); + /** The new network's name. Required. */ CreateNetworkCmd withName(@Nonnull String name); - /** Optional custom IP scheme for the network. */ - CreateNetworkCmd withIpamConfig(Ipam.Config config); - /** Name of the network driver to use. Defaults to bridge. */ CreateNetworkCmd withDriver(String driver); + /** Ipam config, such es subnet, gateway and ip range of the network */ + CreateNetworkCmd withIpam(Ipam ipam); + /** Driver specific options */ CreateNetworkCmd withOptions(Map options); + CreateNetworkCmd withCheckDuplicate(boolean checkForDuplicate); + + CreateNetworkCmd withInternal(boolean internal); + + CreateNetworkCmd withEnableIpv6(boolean enableIpv6); + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/command/DisconnectFromNetworkCmd.java b/src/main/java/com/github/dockerjava/api/command/DisconnectFromNetworkCmd.java index ca870ef37..ce75172b4 100644 --- a/src/main/java/com/github/dockerjava/api/command/DisconnectFromNetworkCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/DisconnectFromNetworkCmd.java @@ -18,10 +18,15 @@ public interface DisconnectFromNetworkCmd extends SyncDockerCmd { @CheckForNull String getContainerId(); + @CheckForNull + Boolean getForce(); + DisconnectFromNetworkCmd withNetworkId(@Nonnull String networkId); DisconnectFromNetworkCmd withContainerId(@Nonnull String containerId); + DisconnectFromNetworkCmd withForce(@Nonnull Boolean force); + interface Exec extends DockerCmdSyncExec { } } diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java b/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java index 4bfde8bfd..9b2160e98 100644 --- a/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java +++ b/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java @@ -1,5 +1,6 @@ package com.github.dockerjava.api.model; +import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.github.dockerjava.core.RemoteApiVersion; @@ -8,9 +9,14 @@ import org.apache.commons.lang.builder.ToStringBuilder; import javax.annotation.CheckForNull; +import java.util.Arrays; import java.util.List; /** + * Types taken form + * {@see https://github.com/docker/engine-api/blob/release/1.10/types/network/network.go} + * Docker named it EndpointSettings + * * @see ContainerNetworkSettings * @author Kanstantsin Shautsou */ @@ -20,16 +26,16 @@ public class ContainerNetwork { * FIXME verify */ @JsonProperty("IPAMConfig") - private Network.Ipam.Config ipamConfig; + private Ipam ipamConfig; /** * FIXME verify */ @JsonProperty("Links") - private List links; + private Links links; /** - * FIXME no docs, unknown field. + * Add network-scoped alias for the container * Type picked from `docker/vendor/src/github.com/docker/engine-api/types/network/network.go` * * @since {@link RemoteApiVersion#VERSION_1_22} @@ -80,6 +86,14 @@ public ContainerNetwork withAliases(List aliases) { return this; } + /** + * @see #aliases + */ + public ContainerNetwork withAliases(String... aliases) { + this.aliases = Arrays.asList(aliases); + return this; + } + /** * @see #endpointId */ @@ -155,7 +169,7 @@ public String getIpAddress() { /** * @see #ipAddress */ - public ContainerNetwork withIpAddress(String ipAddress) { + public ContainerNetwork withIpv4Address(String ipAddress) { this.ipAddress = ipAddress; return this; } @@ -164,14 +178,14 @@ public ContainerNetwork withIpAddress(String ipAddress) { * @see #ipamConfig */ @CheckForNull - public Network.Ipam.Config getIpamConfig() { + public Ipam getIpamConfig() { return ipamConfig; } /** * @see #ipamConfig */ - public ContainerNetwork withIpamConfig(Network.Ipam.Config ipamConfig) { + public ContainerNetwork withIpamConfig(Ipam ipamConfig) { this.ipamConfig = ipamConfig; return this; } @@ -212,15 +226,24 @@ public ContainerNetwork withIpV6Gateway(String ipV6Gateway) { * @see #links */ @CheckForNull - public List getLinks() { - return links; + @JsonIgnore + public Link[] getLinks() { + return links == null ? new Link[0] : links.getLinks(); + } + + /** + * @see #links + */ + public ContainerNetwork withLinks(List links) { + this.links = new Links(links); + return this; } /** * @see #links */ - public ContainerNetwork withLinks(List links) { - this.links = links; + public ContainerNetwork withLinks(Link... links) { + this.links = new Links(links); return this; } @@ -270,4 +293,34 @@ public boolean equals(Object o) { public int hashCode() { return HashCodeBuilder.reflectionHashCode(this); } + + /** + * Docker named it EndpointIPAMConfig + */ + public static class Ipam { + + @JsonProperty("IPv4Address") + private String ipv4Address; + + @JsonProperty("IPv6Address") + private String ipv6Address; + + public String getIpv4Address() { + return ipv4Address; + } + + public String getIpv6Address() { + return ipv6Address; + } + + public Ipam withIpv4Address(String ipv4Address) { + this.ipv4Address = ipv4Address; + return this; + } + + public Ipam withIpv6Address(String ipv6Address) { + this.ipv6Address = ipv6Address; + return this; + } + } } 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 400ae29dd..19a6a9128 100644 --- a/src/main/java/com/github/dockerjava/api/model/HostConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/HostConfig.java @@ -11,6 +11,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import javax.annotation.CheckForNull; +import java.util.Arrays; import java.util.List; /** @@ -21,6 +22,8 @@ @JsonInclude(Include.NON_NULL) public class HostConfig { + private static final List PREDEFINED_NETWORKS = Arrays.asList("bridge", "host", "none"); + @JsonProperty("Binds") private Binds binds; @@ -410,6 +413,15 @@ public String getVolumeDriver() { return volumeDriver; } + /** + * Parse the network mode as specified at + * {@see https://github.com/docker/engine-api/blob/master/types/container/hostconfig_unix.go} + */ + @JsonIgnore + public boolean isUserDefinedNetwork() { + return networkMode != null && !PREDEFINED_NETWORKS.contains(networkMode) && !networkMode.startsWith("container:"); + } + @JsonIgnore public void setBinds(Bind... binds) { this.binds = new Binds(binds); 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 546904254..6f4114914 100644 --- a/src/main/java/com/github/dockerjava/api/model/Network.java +++ b/src/main/java/com/github/dockerjava/api/model/Network.java @@ -6,6 +6,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; @@ -111,16 +112,33 @@ public static class Ipam { private String driver; @JsonProperty("Config") - List config = new ArrayList<>(); + private List config = new ArrayList<>(); + + @JsonProperty("Options") + private Map options = null; public String getDriver() { return driver; } + public Map getOptions() { + return options; + } + public List getConfig() { return config; } + public Ipam withConfig(List ipamConfigs) { + config = ipamConfigs; + return this; + } + + public Ipam withConfig(Config... ipamConfigs) { + config = Arrays.asList(ipamConfigs); + return this; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(this); @@ -149,6 +167,21 @@ public String getIpRange() { public String getGateway() { return gateway; } + + public Config withSubnet(String subnet) { + this.subnet = subnet; + return this; + } + + public Config withIpRange(String ipRange) { + this.ipRange = ipRange; + return this; + } + + public Config withGateway(String gateway) { + this.gateway = gateway; + return this; + } } } } diff --git a/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java b/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java index 680048c18..1d523bf4b 100644 --- a/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java +++ b/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java @@ -3,15 +3,12 @@ */ package com.github.dockerjava.api.model; -import java.util.Map; - -import org.apache.commons.lang.builder.ToStringBuilder; - import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; import com.github.dockerjava.core.RemoteApiVersion; +import org.apache.commons.lang.builder.ToStringBuilder; -import javax.annotation.CheckForNull; +import java.util.Map; /** * @@ -76,7 +73,7 @@ public class NetworkSettings { private String macAddress; @JsonProperty("Networks") - private Map networks; + private Map networks; /** * @deprecated since {@link RemoteApiVersion#VERSION_1_21} @@ -135,7 +132,7 @@ public String getIpV6Gateway() { /** * @since {@link RemoteApiVersion#VERSION_1_21} */ - public Map getNetworks() { + public Map getNetworks() { return networks; } @@ -206,83 +203,4 @@ public Integer getGlobalIPv6PrefixLen() { public String toString() { return ToStringBuilder.reflectionToString(this); } - - @JsonIgnoreProperties(ignoreUnknown = true) - public static class Network { - - @JsonProperty("IPAMConfig") - private String ipamConfig; - - /** - * @since {@link RemoteApiVersion#VERSION_1_22} - */ - @JsonProperty("NetworkID") - private String networkID; - - @JsonProperty("EndpointID") - private String endpointId; - - @JsonProperty("Gateway") - private String gateway; - - @JsonProperty("IPAddress") - private String ipAddress; - - @JsonProperty("IPPrefixLen") - private Integer ipPrefixLen; - - @JsonProperty("IPv6Gateway") - private String ipV6Gateway; - - @JsonProperty("GlobalIPv6Address") - private String globalIPv6Address; - - @JsonProperty("GlobalIPv6PrefixLen") - private Integer globalIPv6PrefixLen; - - @JsonProperty("MacAddress") - private String macAddress; - - @CheckForNull - public String getNetworkID() { - return networkID; - } - - public String getEndpointId() { - return endpointId; - } - - public String getGateway() { - return gateway; - } - - public String getIpAddress() { - return ipAddress; - } - - public Integer getIpPrefixLen() { - return ipPrefixLen; - } - - public String getIpV6Gateway() { - return ipV6Gateway; - } - - public String getGlobalIPv6Address() { - return globalIPv6Address; - } - - public Integer getGlobalIPv6PrefixLen() { - return globalIPv6PrefixLen; - } - - public String getMacAddress() { - return macAddress; - } - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this); - } - } } diff --git a/src/main/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImpl.java index 7014704b1..93fd8abb8 100644 --- a/src/main/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImpl.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.github.dockerjava.api.command.ConnectToNetworkCmd; import com.github.dockerjava.api.command.DockerCmdSyncExec; +import com.github.dockerjava.api.model.ContainerNetwork; public class ConnectToNetworkCmdImpl extends AbstrDockerCmd implements ConnectToNetworkCmd { @@ -13,6 +14,9 @@ public class ConnectToNetworkCmdImpl extends AbstrDockerCmd execution) { super(execution); } @@ -27,6 +31,11 @@ public String getContainerId() { return containerId; } + @Override + public ContainerNetwork getContainerConfig() { + return endpointConfig; + } + @Override public ConnectToNetworkCmd withNetworkId(String networkId) { this.networkId = networkId; @@ -38,4 +47,10 @@ public ConnectToNetworkCmd withContainerId(String containerId) { this.containerId = containerId; return this; } + + @Override + public ConnectToNetworkCmd withContainerNetwork(ContainerNetwork endpointConfig) { + this.endpointConfig = endpointConfig; + return this; + } } diff --git a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java index 48b93a004..0b6944b04 100644 --- a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java @@ -1,14 +1,5 @@ package com.github.dockerjava.core.command; -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.List; -import java.util.Map; - -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -19,6 +10,7 @@ import com.github.dockerjava.api.exception.NotFoundException; import com.github.dockerjava.api.model.Bind; import com.github.dockerjava.api.model.Capability; +import com.github.dockerjava.api.model.ContainerNetwork; import com.github.dockerjava.api.model.Device; import com.github.dockerjava.api.model.ExposedPort; import com.github.dockerjava.api.model.ExposedPorts; @@ -33,6 +25,16 @@ import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.api.model.Volumes; import com.github.dockerjava.api.model.VolumesFrom; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import static com.google.common.base.Preconditions.checkNotNull; +import static java.util.Collections.singletonMap; /** * Creates a new container. @@ -113,6 +115,18 @@ public class CreateContainerCmdImpl extends AbstrDockerCmd labels; + @JsonProperty("NetworkingConfig") + private NetworkingConfig networkingConfig; + + @JsonIgnore + private String ipv4Address = null; + + @JsonIgnore + private String ipv6Address = null; + + @JsonIgnore + private List aliases = null; + public CreateContainerCmdImpl(CreateContainerCmd.Exec exec, String image) { super(exec); checkNotNull(image, "image was not specified"); @@ -127,9 +141,48 @@ public CreateContainerCmdImpl(CreateContainerCmd.Exec exec, String image) { */ @Override public CreateContainerResponse exec() throws NotFoundException, ConflictException { + //code flow taken from https://github.com/docker/docker/blob/master/runconfig/opts/parse.go + ContainerNetwork containerNetwork = null; + + if (ipv4Address != null || ipv6Address != null) { + containerNetwork = new ContainerNetwork() + .withIpamConfig(new ContainerNetwork.Ipam() + .withIpv4Address(ipv4Address) + .withIpv6Address(ipv6Address) + ); + + } + + if (hostConfig.isUserDefinedNetwork() && hostConfig.getLinks().length > 0) { + if (containerNetwork == null) { + containerNetwork = new ContainerNetwork(); + } + + containerNetwork.withLinks(hostConfig.getLinks()); + } + + if (aliases != null) { + if (containerNetwork == null) { + containerNetwork = new ContainerNetwork(); + } + + containerNetwork.withAliases(aliases); + } + + if (containerNetwork != null) { + networkingConfig = new NetworkingConfig() + .withEndpointsConfig(singletonMap(hostConfig.getNetworkMode(), containerNetwork)); + } + return super.exec(); } + @Override + @JsonIgnore + public List getAliases() { + return aliases; + } + @Override @JsonIgnore public Bind[] getBinds() { @@ -247,6 +300,16 @@ public String getImage() { return image; } + @Override + public String getIpv4Address() { + return ipv4Address; + } + + @Override + public String getIpv6Address() { + return ipv6Address; + } + @Override @JsonIgnore public Map getLabels() { @@ -414,6 +477,19 @@ public String getCgroupParent() { return hostConfig.getCgroupParent(); } + @Override + public CreateContainerCmd withAliases(String... aliases) { + this.aliases = Arrays.asList(aliases); + return this; + } + + @Override + public CreateContainerCmd withAliases(List aliases) { + checkNotNull(aliases, "aliases was not specified"); + this.aliases = aliases; + return this; + } + @Override public CreateContainerCmd withAttachStderr(Boolean attachStderr) { checkNotNull(attachStderr, "attachStderr was not specified"); @@ -648,6 +724,20 @@ public CreateContainerCmd withImage(String image) { return this; } + @Override + public CreateContainerCmd withIpv4Address(String ipv4Address) { + checkNotNull(ipv4Address, "no ipv4Address was specified"); + this.ipv4Address = ipv4Address; + return this; + } + + @Override + public CreateContainerCmd withIpv6Address(String ipv6Address) { + checkNotNull(ipv6Address, "no ipv6Address was specified"); + this.ipv6Address = ipv6Address; + return this; + } + @Override public CreateContainerCmd withLabels(Map labels) { checkNotNull(labels, "labels was not specified"); @@ -900,4 +990,18 @@ public boolean equals(Object o) { public int hashCode() { return HashCodeBuilder.reflectionHashCode(this); } + + public static class NetworkingConfig { + @JsonProperty("EndpointsConfig") + public Map endpointsConfig; + + public Map getEndpointsConfig() { + return endpointsConfig; + } + + public NetworkingConfig withEndpointsConfig(Map endpointsConfig) { + this.endpointsConfig = endpointsConfig; + return this; + } + } } 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 c7d3b0abb..834aa6905 100644 --- a/src/main/java/com/github/dockerjava/core/command/CreateNetworkCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CreateNetworkCmdImpl.java @@ -25,6 +25,15 @@ public class CreateNetworkCmdImpl extends AbstrDockerCmd options = new HashMap<>(); + @JsonProperty("CheckDuplicate") + private Boolean checkDuplicate; + + @JsonProperty("Internal") + private Boolean internal; + + @JsonProperty("EnableIPv6") + private Boolean enableIpv6; + public CreateNetworkCmdImpl(DockerCmdSyncExec execution) { super(execution); } @@ -44,6 +53,26 @@ public Network.Ipam getIpam() { return ipam; } + @Override + public Map getOptions() { + return options; + } + + @Override + public Boolean getCheckDuplicate() { + return checkDuplicate; + } + + @Override + public Boolean getInternal() { + return internal; + } + + @Override + public Boolean getEnableIPv6() { + return enableIpv6; + } + @Override public CreateNetworkCmd withName(String name) { this.name = name; @@ -57,8 +86,8 @@ public CreateNetworkCmd withDriver(String driver) { } @Override - public CreateNetworkCmd withIpamConfig(Ipam.Config config) { - this.ipam.getConfig().add(config); + public CreateNetworkCmd withIpam(Ipam ipam) { + this.ipam = ipam; return this; } @@ -67,4 +96,22 @@ public CreateNetworkCmd withOptions(Map options) { this.options = options; return this; } + + @Override + public CreateNetworkCmd withCheckDuplicate(boolean checkDuplicate) { + this.checkDuplicate = checkDuplicate; + return this; + } + + @Override + public CreateNetworkCmd withInternal(boolean internal) { + this.internal = internal; + return this; + } + + @Override + public CreateNetworkCmd withEnableIpv6(boolean enableIpv6) { + this.enableIpv6 = enableIpv6; + return this; + } } diff --git a/src/main/java/com/github/dockerjava/core/command/DisconnectFromNetworkCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/DisconnectFromNetworkCmdImpl.java index ae24946b6..b871b36c6 100644 --- a/src/main/java/com/github/dockerjava/core/command/DisconnectFromNetworkCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/DisconnectFromNetworkCmdImpl.java @@ -14,6 +14,9 @@ public class DisconnectFromNetworkCmdImpl extends AbstrDockerCmd execution) { super(execution); } @@ -28,6 +31,11 @@ public String getContainerId() { return containerId; } + @Override + public Boolean getForce() { + return force; + } + @Override public DisconnectFromNetworkCmd withNetworkId(String networkId) { this.networkId = networkId; @@ -39,4 +47,10 @@ public DisconnectFromNetworkCmd withContainerId(String containerId) { this.containerId = containerId; return this; } + + @Override + public DisconnectFromNetworkCmd withForce(Boolean force) { + this.force = force; + return this; + } } diff --git a/src/main/java/com/github/dockerjava/core/command/RemoveNetworkCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/RemoveNetworkCmdImpl.java index ced7279f9..cc9465244 100644 --- a/src/main/java/com/github/dockerjava/core/command/RemoveNetworkCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/RemoveNetworkCmdImpl.java @@ -14,7 +14,6 @@ public RemoveNetworkCmdImpl(DockerCmdSyncExec execution, @Override public String getNetworkId() { - return networkId; } diff --git a/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java index ad051e0bd..f67994de6 100644 --- a/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java @@ -1,7 +1,11 @@ package com.github.dockerjava.core.command; -import java.lang.reflect.Method; - +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.CreateNetworkResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.model.ContainerNetwork; +import com.github.dockerjava.api.model.Network; +import com.github.dockerjava.client.AbstractDockerClientTest; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -9,11 +13,8 @@ import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -import com.github.dockerjava.api.command.CreateContainerResponse; -import com.github.dockerjava.api.command.CreateNetworkResponse; -import com.github.dockerjava.api.command.InspectContainerResponse; -import com.github.dockerjava.api.model.Network; -import com.github.dockerjava.client.AbstractDockerClientTest; +import java.lang.reflect.Method; +import java.util.Collections; @Test(groups = "integration") public class ConnectToNetworkCmdImplTest extends AbstractDockerClientTest { @@ -56,4 +57,41 @@ public void connectToNetwork() throws InterruptedException { assertNotNull(inspectContainerResponse.getNetworkSettings().getNetworks().get("testNetwork")); } + + @Test + public void connectToNetworkWithContainerNetwork() throws InterruptedException { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + dockerClient.startContainerCmd(container.getId()).exec(); + + CreateNetworkResponse network = dockerClient.createNetworkCmd() + .withName("testNetwork") + .withIpam(new Network.Ipam() + .withConfig(new Network.Ipam.Config() + .withSubnet("10.100.100.0/24"))) + .exec(); + + dockerClient.connectToNetworkCmd() + .withNetworkId(network.getId()) + .withContainerId(container.getId()) + .withContainerNetwork(new ContainerNetwork() + .withAliases("testing") + .withIpamConfig(new ContainerNetwork.Ipam() + .withIpv4Address("10.100.100.100"))) + .exec(); + + Network updatedNetwork = dockerClient.inspectNetworkCmd().withNetworkId(network.getId()).exec(); + + Network.ContainerNetworkConfig containerNetworkConfig = updatedNetwork.getContainers().get(container.getId()); + assertNotNull(containerNetworkConfig); + assertEquals("10.100.100.100", containerNetworkConfig.getIpv4Address()); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + + ContainerNetwork testNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get("testNetwork"); + assertNotNull(testNetwork); + assertEquals(Collections.singletonList("testing"), testNetwork.getAliases()); + assertEquals("10.100.100.0", testNetwork.getGateway()); + assertEquals("10.100.100.100", testNetwork.getIpAddress()); + } } 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 f2fd32b6a..682edc4ce 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -1,15 +1,18 @@ package com.github.dockerjava.core.command; import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.CreateNetworkResponse; import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.exception.ConflictException; import com.github.dockerjava.api.exception.DockerException; import com.github.dockerjava.api.model.Bind; +import com.github.dockerjava.api.model.ContainerNetwork; import com.github.dockerjava.api.model.Device; import com.github.dockerjava.api.model.ExposedPort; import com.github.dockerjava.api.model.Frame; import com.github.dockerjava.api.model.Link; import com.github.dockerjava.api.model.LogConfig; +import com.github.dockerjava.api.model.Network; import com.github.dockerjava.api.model.Ports; import com.github.dockerjava.api.model.RestartPolicy; import com.github.dockerjava.api.model.Ulimit; @@ -22,10 +25,12 @@ import org.testng.annotations.BeforeMethod; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; +import org.testng.internal.junit.ArrayAsserts; 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; @@ -268,6 +273,107 @@ public void createContainerWithLink() throws DockerException { "container1Link")})); } + @Test + public void createContainerWithLinkInCustomNetwork() throws DockerException { + + CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd() + .withName("linkNet") + .exec(); + + assertNotNull(createNetworkResponse.getId()); + + CreateContainerResponse container1 = dockerClient.createContainerCmd(BUSYBOX_IMAGE) + .withNetworkMode("linkNet") + .withCmd("sleep", "9999") + .withName("container1") + .exec(); + + assertThat(container1.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container1.getId()).exec(); + + InspectContainerResponse inspectContainerResponse1 = dockerClient.inspectContainerCmd(container1.getId()) + .exec(); + LOG.info("Container1 Inspect: {}", inspectContainerResponse1.toString()); + assertThat(inspectContainerResponse1.getState().getRunning(), is(true)); + + CreateContainerResponse container2 = dockerClient.createContainerCmd(BUSYBOX_IMAGE) + .withNetworkMode("linkNet") + .withName("container2") + .withCmd("env") + .withLinks(new Link("container1", "container1Link")) + .exec(); + + LOG.info("Created container {}", container2.toString()); + assertThat(container2.getId(), not(isEmptyString())); + + InspectContainerResponse inspectContainerResponse2 = dockerClient.inspectContainerCmd(container2.getId()) + .exec(); + + ContainerNetwork linkNet = inspectContainerResponse2.getNetworkSettings().getNetworks().get("linkNet"); + assertNotNull(linkNet); + ArrayAsserts.assertArrayEquals(new Link[]{ new Link("container1", "container1Link")}, linkNet.getLinks()); + } + + @Test + public void createContainerWithCustomIp() throws DockerException { + + CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd() + .withIpam(new Network.Ipam() + .withConfig(new Network.Ipam.Config() + .withSubnet("10.100.101.0/24"))) + .withName("customIpNet") + .exec(); + + assertNotNull(createNetworkResponse.getId()); + + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE) + .withNetworkMode("customIpNet") + .withCmd("sleep", "9999") + .withName("container") + .withIpv4Address("10.100.101.100") + .exec(); + + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()) + .exec(); + + ContainerNetwork customIpNet = inspectContainerResponse.getNetworkSettings().getNetworks().get("customIpNet"); + assertNotNull(customIpNet); + assertEquals("10.100.101.0", customIpNet.getGateway()); + assertEquals("10.100.101.100", customIpNet.getIpAddress()); + } + + @Test + public void createContainerWithAlias() throws DockerException { + + CreateNetworkResponse createNetworkResponse = dockerClient.createNetworkCmd() + .withName("aliasNet") + .exec(); + + assertNotNull(createNetworkResponse.getId()); + + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE) + .withNetworkMode("aliasNet") + .withCmd("sleep", "9999") + .withName("container") + .withAliases("server") + .exec(); + + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()) + .exec(); + + ContainerNetwork aliasNet = inspectContainerResponse.getNetworkSettings().getNetworks().get("aliasNet"); + assertEquals(Collections.singletonList("server"), aliasNet.getAliases()); + } + @Test public void createContainerWithCapAddAndCapDrop() throws DockerException { diff --git a/src/test/java/com/github/dockerjava/core/command/DisconnectFromNetworkCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/DisconnectFromNetworkCmdImplTest.java index 7f94c5a0f..c4219b54e 100644 --- a/src/test/java/com/github/dockerjava/core/command/DisconnectFromNetworkCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/DisconnectFromNetworkCmdImplTest.java @@ -56,4 +56,26 @@ public void disconnectFromNetwork() throws InterruptedException { assertFalse(updatedNetwork.getContainers().containsKey(container.getId())); } + + @Test + public void forceDisconnectFromNetwork() throws InterruptedException { + + CreateNetworkResponse network = dockerClient.createNetworkCmd().withName("testNetwork").exec(); + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withNetworkMode("testNetwork") + .withCmd("sleep", "9999") + .exec(); + + dockerClient.startContainerCmd(container.getId()).exec(); + + dockerClient.disconnectFromNetworkCmd() + .withNetworkId(network.getId()) + .withContainerId(container.getId()) + .withForce(true) + .exec(); + + Network updatedNetwork = dockerClient.inspectNetworkCmd().withNetworkId(network.getId()).exec(); + assertFalse(updatedNetwork.getContainers().containsKey(container.getId())); + } } From 54d34f0c00e0ba6b81b05e82d782f050b165cff6 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Mon, 2 May 2016 21:34:59 +0200 Subject: [PATCH 102/855] Fix issue #560 --- .../netty/handler/FramedResponseStreamHandler.java | 2 +- .../github/dockerjava/netty/handler/HttpResponseHandler.java | 5 ++++- .../netty/handler/JsonResponseCallbackHandler.java | 1 + 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/netty/handler/FramedResponseStreamHandler.java b/src/main/java/com/github/dockerjava/netty/handler/FramedResponseStreamHandler.java index f360ca756..534894a99 100644 --- a/src/main/java/com/github/dockerjava/netty/handler/FramedResponseStreamHandler.java +++ b/src/main/java/com/github/dockerjava/netty/handler/FramedResponseStreamHandler.java @@ -45,7 +45,7 @@ public FramedResponseStreamHandler(ResultCallback resultCallback) { @Override protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { - rawBuffer.writeBytes(msg.copy(), 0, msg.readableBytes()); + rawBuffer.writeBytes(msg, 0, msg.readableBytes()); Frame frame = null; diff --git a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseHandler.java b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseHandler.java index 571fa9be5..9986e10e9 100644 --- a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseHandler.java +++ b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseHandler.java @@ -120,6 +120,9 @@ public void close() { } private String getBodyAsMessage(ByteBuf body) { - return body.readBytes(body.readableBytes()).toString(Charset.forName("UTF-8")); + String result = body.readBytes(body.readableBytes()).toString(Charset.forName("UTF-8")); + body.discardReadBytes(); + body.release(); + return result; } } diff --git a/src/main/java/com/github/dockerjava/netty/handler/JsonResponseCallbackHandler.java b/src/main/java/com/github/dockerjava/netty/handler/JsonResponseCallbackHandler.java index b5f76ab73..db20d6216 100644 --- a/src/main/java/com/github/dockerjava/netty/handler/JsonResponseCallbackHandler.java +++ b/src/main/java/com/github/dockerjava/netty/handler/JsonResponseCallbackHandler.java @@ -30,6 +30,7 @@ public JsonResponseCallbackHandler(TypeReference typeReference, ResultCallbac protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { byte[] buffer = new byte[msg.readableBytes()]; msg.readBytes(buffer); + msg.discardReadBytes(); T object = null; From 1ab6e63c4c6eb30baa66771d97f244735565dc0b Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Mon, 2 May 2016 21:49:39 +0200 Subject: [PATCH 103/855] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2154f36a7..f88303a1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ Notes All changes +* [#563] (https://github.com/docker-java/docker-java/pull/563) Fix memory leak in netty implementation of DockerCmdExecFactory + Included in 3.0.0-RC5 * [#542] (https://github.com/docker-java/docker-java/pull/542) Fix large volumes of output from "docker exec" trigger out of memory error From 90ff0bd99b490a3eb4553f36c222a7c5d3881af6 Mon Sep 17 00:00:00 2001 From: VU Minh Khang Date: Thu, 5 May 2016 20:43:46 +0200 Subject: [PATCH 104/855] Fix imports --- .../dockerjava/core/command/CreateNetworkCmdImplTest.java | 6 +++++- .../dockerjava/netty/exec/CreateNetworkCmdExecTest.java | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) 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 c278f191b..f56a89f64 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java @@ -5,7 +5,11 @@ import com.github.dockerjava.api.model.Network; import com.github.dockerjava.client.AbstractDockerClientTest; import org.testng.ITestResult; -import org.testng.annotations.*; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; import java.lang.reflect.Method; diff --git a/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java index 974d684b8..35602ddd9 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java @@ -5,7 +5,11 @@ import com.github.dockerjava.api.model.Network; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; import org.testng.ITestResult; -import org.testng.annotations.*; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; import java.lang.reflect.Method; From 4431df9c0dee7d6d75554c27a59c5157caf6b395 Mon Sep 17 00:00:00 2001 From: VU Minh Khang Date: Fri, 6 May 2016 10:20:46 +0200 Subject: [PATCH 105/855] Fix test names --- .../dockerjava/core/command/CreateNetworkCmdImplTest.java | 2 +- .../github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 f56a89f64..4875ba7c5 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateNetworkCmdImplTest.java @@ -51,7 +51,7 @@ public void createNetwork() throws DockerException { } @Test - public void createNetworkWithCustomConfig() throws DockerException { + public void createNetworkWithIpamConfig() throws DockerException { String networkName = "testNetwork"; Network.Ipam.Config config = new Network.Ipam.Config(); diff --git a/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java index 35602ddd9..63f2eb620 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateNetworkCmdExecTest.java @@ -51,7 +51,7 @@ public void createNetwork() throws DockerException { } @Test - public void createNetworkWithCustomConfig() throws DockerException { + public void createNetworkWithIpamConfig() throws DockerException { String networkName = "testNetwork"; Network.Ipam.Config config = new Network.Ipam.Config(); From 0f0353a95a22748a52e99856596bcc32c670b419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Warcha=C5=82?= Date: Fri, 6 May 2016 11:57:27 +0200 Subject: [PATCH 106/855] Throws exception when WaitContainerResultCallback timeouts Fixes #570 --- .../command/WaitContainerResultCallback.java | 4 +- .../command/WaitContainerCmdImplTest.java | 55 ++++++++++++++----- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/command/WaitContainerResultCallback.java b/src/main/java/com/github/dockerjava/core/command/WaitContainerResultCallback.java index feb7916e7..df415d555 100644 --- a/src/main/java/com/github/dockerjava/core/command/WaitContainerResultCallback.java +++ b/src/main/java/com/github/dockerjava/core/command/WaitContainerResultCallback.java @@ -56,7 +56,9 @@ public Integer awaitStatusCode() { */ public Integer awaitStatusCode(long timeout, TimeUnit timeUnit) { try { - awaitCompletion(timeout, timeUnit); + if (!awaitCompletion(timeout, timeUnit)) { + throw new DockerClientException("Awaiting status code timeout."); + } } catch (InterruptedException e) { throw new DockerClientException("Awaiting status code interrupted: ", e); } diff --git a/src/test/java/com/github/dockerjava/core/command/WaitContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/WaitContainerCmdImplTest.java index 8de80573c..0e69d00f0 100644 --- a/src/test/java/com/github/dockerjava/core/command/WaitContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/WaitContainerCmdImplTest.java @@ -1,13 +1,12 @@ package com.github.dockerjava.core.command; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.isEmptyString; -import static org.hamcrest.Matchers.not; - -import java.lang.reflect.Method; - +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.exception.DockerClientException; +import com.github.dockerjava.api.exception.DockerException; +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.api.model.WaitResponse; +import com.github.dockerjava.client.AbstractDockerClientTest; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -15,12 +14,11 @@ import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -import com.github.dockerjava.api.exception.DockerException; -import com.github.dockerjava.api.exception.NotFoundException; -import com.github.dockerjava.api.command.CreateContainerResponse; -import com.github.dockerjava.api.command.InspectContainerResponse; -import com.github.dockerjava.api.model.WaitResponse; -import com.github.dockerjava.client.AbstractDockerClientTest; +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; @Test(groups = "integration") public class WaitContainerCmdImplTest extends AbstractDockerClientTest { @@ -74,7 +72,7 @@ public void testWaitNonExistingContainer() throws DockerException { WaitContainerResultCallback callback = new WaitContainerResultCallback() { public void onNext(WaitResponse waitResponse) { fail("expected NotFoundException"); - }; + } }; dockerClient.waitContainerCmd("non-existing").exec(callback).awaitStatusCode(); @@ -104,4 +102,31 @@ public void testWaitContainerAbort() throws Exception { assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false))); } + + @Test + public void testWaitContainerTimeout() throws Exception { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + + WaitContainerResultCallback callback = dockerClient.waitContainerCmd(container.getId()).exec( + new WaitContainerResultCallback()); + try { + callback.awaitStatusCode(100, TimeUnit.MILLISECONDS); + fail("Should throw exception on timeout."); + } catch(DockerClientException e){ + LOG.info(e.getMessage()); + } + + dockerClient.killContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); + + assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false))); + } } From a8466ff9fa46d653cafbbc4d4b3ed00fbd683f70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Warcha=C5=82?= Date: Fri, 6 May 2016 12:56:21 +0200 Subject: [PATCH 107/855] Add test for WaitContainerResultCallback timeout in Netty implementation --- .../netty/exec/WaitContainerCmdExecTest.java | 57 +++++++++++++------ 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/src/test/java/com/github/dockerjava/netty/exec/WaitContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/WaitContainerCmdExecTest.java index 527d5f995..20919a934 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/WaitContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/WaitContainerCmdExecTest.java @@ -1,27 +1,25 @@ package com.github.dockerjava.netty.exec; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.isEmptyString; -import static org.hamcrest.Matchers.not; - -import java.lang.reflect.Method; - -import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.api.exception.DockerException; import com.github.dockerjava.api.exception.NotFoundException; import com.github.dockerjava.api.model.WaitResponse; import com.github.dockerjava.core.command.WaitContainerResultCallback; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; @Test(groups = "integration") public class WaitContainerCmdExecTest extends AbstractNettyDockerClientTest { @@ -75,7 +73,7 @@ public void testWaitNonExistingContainer() throws DockerException { WaitContainerResultCallback callback = new WaitContainerResultCallback() { public void onNext(WaitResponse waitResponse) { fail("expected NotFoundException"); - }; + } }; dockerClient.waitContainerCmd("non-existing").exec(callback).awaitStatusCode(); @@ -107,4 +105,31 @@ public void testWaitContainerAbort() throws Exception { assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false))); } + + @Test + public void testWaitContainerTimeout() throws Exception { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + + WaitContainerResultCallback callback = dockerClient.waitContainerCmd(container.getId()).exec( + new WaitContainerResultCallback()); + try { + callback.awaitStatusCode(100, TimeUnit.MILLISECONDS); + fail("Should throw exception on timeout."); + } catch(DockerClientException e){ + LOG.info(e.getMessage()); + } + + dockerClient.killContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); + + assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false))); + } } From f24fc2613d4b9be8ef3619d9cf3827f6e5f780e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Warcha=C5=82?= Date: Fri, 6 May 2016 13:12:57 +0200 Subject: [PATCH 108/855] Polish tests for WaitContainerCmd Reduce containers sleep duration to 10 seconds. Remove unnecessary calls to KillContainerCmd. --- .../core/command/WaitContainerCmdImplTest.java | 9 +-------- .../dockerjava/netty/exec/WaitContainerCmdExecTest.java | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/test/java/com/github/dockerjava/core/command/WaitContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/WaitContainerCmdImplTest.java index 0e69d00f0..b92dcc657 100644 --- a/src/test/java/com/github/dockerjava/core/command/WaitContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/WaitContainerCmdImplTest.java @@ -106,7 +106,7 @@ public void testWaitContainerAbort() throws Exception { @Test public void testWaitContainerTimeout() throws Exception { - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "10").exec(); LOG.info("Created container: {}", container.toString()); assertThat(container.getId(), not(isEmptyString())); @@ -121,12 +121,5 @@ public void testWaitContainerTimeout() throws Exception { } catch(DockerClientException e){ LOG.info(e.getMessage()); } - - dockerClient.killContainerCmd(container.getId()).exec(); - - InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); - LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); - - assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false))); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/WaitContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/WaitContainerCmdExecTest.java index 20919a934..42898974c 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/WaitContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/WaitContainerCmdExecTest.java @@ -109,7 +109,7 @@ public void testWaitContainerAbort() throws Exception { @Test public void testWaitContainerTimeout() throws Exception { - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "10").exec(); LOG.info("Created container: {}", container.toString()); assertThat(container.getId(), not(isEmptyString())); @@ -124,12 +124,5 @@ public void testWaitContainerTimeout() throws Exception { } catch(DockerClientException e){ LOG.info(e.getMessage()); } - - dockerClient.killContainerCmd(container.getId()).exec(); - - InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); - LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); - - assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false))); } } From 4fc98a0d406e000915db5e55ca3d1a6f82e8e1ff Mon Sep 17 00:00:00 2001 From: AE Date: Fri, 6 May 2016 16:39:53 +0200 Subject: [PATCH 109/855] Docker inspect command now shows sizes if request. --- .../dockerjava/api/command/InspectContainerCmd.java | 4 ++++ .../api/command/InspectContainerResponse.java | 7 +++++++ .../core/command/InspectContainerCmdImpl.java | 12 ++++++++++++ .../dockerjava/jaxrs/InspectContainerCmdExec.java | 5 +++-- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java index cb782c64d..c0f666fa3 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java @@ -12,6 +12,10 @@ public interface InspectContainerCmd extends SyncDockerCmd Date: Sun, 1 May 2016 23:44:39 +0200 Subject: [PATCH 110/855] Work on port ranges - change all to strings --- .../dockerjava/api/model/ExposedPort.java | 6 +- .../github/dockerjava/api/model/Ports.java | 76 +++++++++---------- .../command/InspectContainerResponseTest.java | 4 +- .../dockerjava/api/model/BindingTest.java | 7 +- .../dockerjava/api/model/PortBindingTest.java | 12 +-- .../api/model/Ports_SerializingTest.java | 17 ++--- .../api/model/Ports_addBindingsTest.java | 13 ++-- .../core/TestDockerCmdExecFactory.java | 66 ++++++++++++++-- .../core/command/BuildImageCmdImplTest.java | 2 +- .../command/CreateContainerCmdImplTest.java | 12 +-- .../command/RenameContainerCmdImplTest.java | 9 ++- .../command/StartContainerCmdImplTest.java | 71 +++++++++-------- .../core/util/FiltersBuilderTest.java | 5 +- .../netty/exec/BuildImageCmdExecTest.java | 2 +- .../exec/CreateContainerCmdExecTest.java | 67 ++++++++-------- .../exec/RenameContainerCmdExecTest.java | 9 ++- .../netty/exec/StartContainerCmdExecTest.java | 71 +++++++++-------- 17 files changed, 253 insertions(+), 196 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/ExposedPort.java b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java index 25829b8aa..4e30c8df0 100644 --- a/src/main/java/com/github/dockerjava/api/model/ExposedPort.java +++ b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java @@ -65,7 +65,7 @@ public ExposedPort(int port) { * @param scheme * the {@link #getScheme() scheme}, tcp or udp * @param port - * the {@link #getPort() port number} + * the {@link #getPort() port number or port range} * @deprecated use {@link #ExposedPort(int, InternetProtocol)} */ @Deprecated @@ -124,9 +124,9 @@ public static ExposedPort parse(String serialized) throws IllegalArgumentExcepti String[] parts = serialized.split("/"); switch (parts.length) { case 1: - return new ExposedPort(Integer.valueOf(parts[0])); + return new ExposedPort(Integer.parseInt(parts[0])); case 2: - return new ExposedPort(Integer.valueOf(parts[0]), InternetProtocol.parse(parts[1])); + return new ExposedPort(Integer.parseInt(parts[0]), InternetProtocol.parse(parts[1])); default: throw new IllegalArgumentException(); } diff --git a/src/main/java/com/github/dockerjava/api/model/Ports.java b/src/main/java/com/github/dockerjava/api/model/Ports.java index e0250bba1..17b2ad432 100644 --- a/src/main/java/com/github/dockerjava/api/model/Ports.java +++ b/src/main/java/com/github/dockerjava/api/model/Ports.java @@ -1,16 +1,5 @@ package com.github.dockerjava.api.model; -import static org.apache.commons.lang.StringUtils.isEmpty; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Map.Entry; - -import org.apache.commons.lang.ArrayUtils; -import org.apache.commons.lang.builder.EqualsBuilder; - import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; @@ -23,6 +12,16 @@ import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.node.NullNode; +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.builder.EqualsBuilder; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import static org.apache.commons.lang.StringUtils.isEmpty; /** * A container for port bindings, made available as a {@link Map} via its {@link #getBindings()} method. @@ -111,15 +110,15 @@ public Map getBindings() { /** * Creates a {@link Binding} for the given IP address and port number. */ - public static Binding binding(String hostIp, Integer hostPort) { + public static Binding binding(String hostIp, String hostPort) { return new Binding(hostIp, hostPort); } /** * Creates a {@link Binding} for the given port number, leaving the IP address undefined. */ - public static Binding binding(Integer hostPort) { - return new Binding(hostPort); + public static Binding binding(String hostPort) { + return new Binding(null, hostPort); } /** @@ -132,38 +131,38 @@ public static Binding binding(Integer hostPort) { */ public static class Binding { - private final String hostIp; - - private final Integer hostPort; - /** - * Creates a {@link Binding} for the given {@link #getHostIp() IP address} and {@link #getHostPort() port number}. + * Creates a {@link Binding} for the given {@link #getHostPort() port number or range}, leaving the {@link #getHostIp() IP address} + * undefined. * * @see Ports#bind(ExposedPort, Binding) * @see ExposedPort */ - public Binding(String hostIp, Integer hostPort) { - this.hostIp = isEmpty(hostIp) ? null : hostIp; - this.hostPort = hostPort; + public static Binding forPort(String port) { + return new Binding(null, port); } /** - * Creates a {@link Binding} for the given {@link #getHostPort() port number}, leaving the {@link #getHostIp() IP address} + * Creates a {@link Binding} for the given {@link #getHostIp() IP address}, leaving the {@link #getHostPort() port number} * undefined. - * - * @see Ports#bind(ExposedPort, Binding) - * @see ExposedPort */ - public Binding(Integer hostPort) { - this(null, hostPort); + public static Binding forIp(String hostIp) { + return new Binding(hostIp, null); } + private final String hostIp; + + private final String hostPort; + /** - * Creates a {@link Binding} for the given {@link #getHostIp() IP address}, leaving the {@link #getHostPort() port number} - * undefined. + * Creates a {@link Binding} for the given {@link #getHostIp() IP address} and {@link #getHostPort() port number}. + * + * @see Ports#bind(ExposedPort, Binding) + * @see ExposedPort */ - public Binding(String hostIp) { - this(hostIp, null); + public Binding(String hostIp, String hostPort) { + this.hostIp = isEmpty(hostIp) ? null : hostIp; + this.hostPort = hostPort; } /** @@ -184,7 +183,7 @@ public String getHostIp() { /** * @return the port number on the Docker host. May be null, in which case Docker will dynamically assign a port. */ - public Integer getHostPort() { + public String getHostPort() { return hostPort; } @@ -208,10 +207,10 @@ public static Binding parse(String serialized) throws IllegalArgumentException { String[] parts = serialized.split(":"); switch (parts.length) { case 2: { - return new Binding(parts[0], Integer.valueOf(parts[1])); + return new Binding(parts[0], parts[1]); } case 1: { - return parts[0].contains(".") ? new Binding(parts[0]) : new Binding(Integer.valueOf(parts[0])); + return parts[0].contains(".") ? Binding.forIp(parts[0]) : Binding.forPort(parts[0]); } default: { throw new IllegalArgumentException(); @@ -231,7 +230,7 @@ public static Binding parse(String serialized) throws IllegalArgumentException { @Override public String toString() { if (isEmpty(hostIp)) { - return Integer.toString(hostPort); + return hostPort; } else if (hostPort == null) { return hostIp; } else { @@ -270,7 +269,7 @@ public Ports deserialize(JsonParser jsonParser, DeserializationContext deseriali JsonNode bindingNode = bindingsArray.get(i); if (!bindingNode.equals(NullNode.getInstance())) { String hostIp = bindingNode.get("HostIp").textValue(); - int hostPort = bindingNode.get("HostPort").asInt(); + String hostPort = bindingNode.get("HostPort").textValue(); out.bind(ExposedPort.parse(portNode.getKey()), new Binding(hostIp, hostPort)); } } @@ -294,8 +293,7 @@ public void serialize(Ports portBindings, JsonGenerator jsonGen, SerializerProvi for (Binding binding : entry.getValue()) { jsonGen.writeStartObject(); jsonGen.writeStringField("HostIp", binding.getHostIp() == null ? "" : binding.getHostIp()); - jsonGen.writeStringField("HostPort", binding.getHostPort() == null ? "" : binding.getHostPort() - .toString()); + jsonGen.writeStringField("HostPort", binding.getHostPort() == null ? "" : binding.getHostPort()); jsonGen.writeEndObject(); } jsonGen.writeEndArray(); 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 c9d40b65f..f64cf4ead 100644 --- a/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java +++ b/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java @@ -25,7 +25,9 @@ import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.core.IsNot.not; -import static org.testng.Assert.*; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; /** * Tests for {@link InspectContainerResponse}. diff --git a/src/test/java/com/github/dockerjava/api/model/BindingTest.java b/src/test/java/com/github/dockerjava/api/model/BindingTest.java index 23e793cf8..290e66b82 100644 --- a/src/test/java/com/github/dockerjava/api/model/BindingTest.java +++ b/src/test/java/com/github/dockerjava/api/model/BindingTest.java @@ -10,12 +10,12 @@ public class BindingTest { @Test public void parseIpAndPort() { - assertEquals(Binding.parse("127.0.0.1:80"), Ports.binding("127.0.0.1", 80)); + assertEquals(Binding.parse("127.0.0.1:80"), Ports.binding("127.0.0.1", "80")); } @Test public void parsePortOnly() { - assertEquals(Binding.parse("80"), Ports.binding(null, 80)); + assertEquals(Binding.parse("80"), Ports.binding(null, "80")); } @Test @@ -28,7 +28,8 @@ public void parseEmptyString() { assertEquals(Binding.parse(""), Ports.binding(null, null)); } - @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Error parsing Binding 'nonsense'") + // Strings can be used since it can be a range. Let the docker daemon do the validation. + @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Error parsing Binding 'nonsense'", enabled = false) public void parseInvalidInput() { Binding.parse("nonsense"); } diff --git a/src/test/java/com/github/dockerjava/api/model/PortBindingTest.java b/src/test/java/com/github/dockerjava/api/model/PortBindingTest.java index e5f5f4c1b..296148177 100644 --- a/src/test/java/com/github/dockerjava/api/model/PortBindingTest.java +++ b/src/test/java/com/github/dockerjava/api/model/PortBindingTest.java @@ -13,22 +13,22 @@ public class PortBindingTest { @Test public void fullDefinition() { assertEquals(PortBinding.parse("127.0.0.1:80:8080/tcp"), - new PortBinding(new Binding("127.0.0.1", 80), TCP_8080)); + new PortBinding(new Binding("127.0.0.1", "80"), TCP_8080)); } @Test public void noProtocol() { - assertEquals(PortBinding.parse("127.0.0.1:80:8080"), new PortBinding(new Binding("127.0.0.1", 80), TCP_8080)); + assertEquals(PortBinding.parse("127.0.0.1:80:8080"), new PortBinding(new Binding("127.0.0.1", "80"), TCP_8080)); } @Test public void noHostIp() { - assertEquals(PortBinding.parse("80:8080/tcp"), new PortBinding(new Binding(80), TCP_8080)); + assertEquals(PortBinding.parse("80:8080/tcp"), new PortBinding(Binding.forPort("80"), TCP_8080)); } @Test public void portsOnly() { - assertEquals(PortBinding.parse("80:8080"), new PortBinding(new Binding(80), TCP_8080)); + assertEquals(PortBinding.parse("80:8080"), new PortBinding(Binding.forPort("80"), TCP_8080)); } @Test @@ -38,10 +38,10 @@ public void exposedPortOnly() { @Test public void dynamicHostPort() { - assertEquals(PortBinding.parse("127.0.0.1::8080"), new PortBinding(new Binding("127.0.0.1"), TCP_8080)); + assertEquals(PortBinding.parse("127.0.0.1::8080"), new PortBinding(Binding.forIp("127.0.0.1"), TCP_8080)); } - @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Error parsing PortBinding 'nonsense'") + @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Error parsing PortBinding 'nonsense'", enabled = false) public void parseInvalidInput() { PortBinding.parse("nonsense"); } diff --git a/src/test/java/com/github/dockerjava/api/model/Ports_SerializingTest.java b/src/test/java/com/github/dockerjava/api/model/Ports_SerializingTest.java index 8c8d2014f..fb89561e5 100644 --- a/src/test/java/com/github/dockerjava/api/model/Ports_SerializingTest.java +++ b/src/test/java/com/github/dockerjava/api/model/Ports_SerializingTest.java @@ -1,13 +1,12 @@ package com.github.dockerjava.api.model; -import static org.testng.Assert.assertEquals; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.api.model.Ports.Binding; +import org.testng.annotations.Test; import java.util.Map; -import org.testng.annotations.Test; - -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.dockerjava.api.model.Ports.Binding; +import static org.testng.Assert.assertEquals; public class Ports_SerializingTest { private final ObjectMapper objectMapper = new ObjectMapper(); @@ -24,15 +23,15 @@ public void deserializingPortWithMultipleBindings() throws Exception { Binding[] bindings = map.get(ExposedPort.tcp(80)); assertEquals(bindings.length, 2); - assertEquals(bindings[0], new Binding("10.0.0.1", 80)); - assertEquals(bindings[1], new Binding("10.0.0.2", 80)); + assertEquals(bindings[0], new Binding("10.0.0.1", "80")); + assertEquals(bindings[1], new Binding("10.0.0.2", "80")); } @Test public void serializingPortWithMultipleBindings() throws Exception { Ports ports = new Ports(); - ports.bind(ExposedPort.tcp(80), new Binding("10.0.0.1", 80)); - ports.bind(ExposedPort.tcp(80), new Binding("10.0.0.2", 80)); + ports.bind(ExposedPort.tcp(80), new Binding("10.0.0.1", "80")); + ports.bind(ExposedPort.tcp(80), new Binding("10.0.0.2", "80")); assertEquals(objectMapper.writeValueAsString(ports), jsonWithDoubleBindingForOnePort); } diff --git a/src/test/java/com/github/dockerjava/api/model/Ports_addBindingsTest.java b/src/test/java/com/github/dockerjava/api/model/Ports_addBindingsTest.java index a5a8697f5..401ee4b44 100644 --- a/src/test/java/com/github/dockerjava/api/model/Ports_addBindingsTest.java +++ b/src/test/java/com/github/dockerjava/api/model/Ports_addBindingsTest.java @@ -1,13 +1,12 @@ package com.github.dockerjava.api.model; -import static org.testng.Assert.assertEquals; - -import java.util.Map; - +import com.github.dockerjava.api.model.Ports.Binding; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; -import com.github.dockerjava.api.model.Ports.Binding; +import java.util.Map; + +import static org.testng.Assert.assertEquals; /** * As there may be several {@link Binding}s per {@link ExposedPort}, it makes a difference if you add {@link PortBinding}s for the same or @@ -18,9 +17,9 @@ public class Ports_addBindingsTest { private static final ExposedPort TCP_90 = ExposedPort.tcp(90); - private static final Binding BINDING_8080 = Ports.binding(8080); + private static final Binding BINDING_8080 = Ports.binding("8080"); - private static final Binding BINDING_9090 = Ports.binding(9090); + private static final Binding BINDING_9090 = Ports.binding("9090"); private Ports ports; diff --git a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java index ba05ab4e3..aee8a60a8 100644 --- a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java +++ b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java @@ -1,17 +1,69 @@ package com.github.dockerjava.core; +import com.github.dockerjava.api.async.ResultCallback; +import com.github.dockerjava.api.command.AttachContainerCmd; +import com.github.dockerjava.api.command.AuthCmd.Exec; +import com.github.dockerjava.api.command.BuildImageCmd; +import com.github.dockerjava.api.command.CommitCmd; +import com.github.dockerjava.api.command.ConnectToNetworkCmd; +import com.github.dockerjava.api.command.ContainerDiffCmd; +import com.github.dockerjava.api.command.CopyArchiveFromContainerCmd; +import com.github.dockerjava.api.command.CopyArchiveToContainerCmd; +import com.github.dockerjava.api.command.CopyFileFromContainerCmd; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.CreateImageCmd; +import com.github.dockerjava.api.command.CreateImageResponse; +import com.github.dockerjava.api.command.CreateNetworkCmd; +import com.github.dockerjava.api.command.CreateNetworkResponse; +import com.github.dockerjava.api.command.CreateVolumeCmd; +import com.github.dockerjava.api.command.CreateVolumeResponse; +import com.github.dockerjava.api.command.DisconnectFromNetworkCmd; +import com.github.dockerjava.api.command.DockerCmdExecFactory; +import com.github.dockerjava.api.command.EventsCmd; +import com.github.dockerjava.api.command.ExecCreateCmd; +import com.github.dockerjava.api.command.ExecStartCmd; +import com.github.dockerjava.api.command.InfoCmd; +import com.github.dockerjava.api.command.InspectContainerCmd; +import com.github.dockerjava.api.command.InspectExecCmd; +import com.github.dockerjava.api.command.InspectImageCmd; +import com.github.dockerjava.api.command.InspectNetworkCmd; +import com.github.dockerjava.api.command.InspectVolumeCmd; +import com.github.dockerjava.api.command.KillContainerCmd; +import com.github.dockerjava.api.command.ListContainersCmd; +import com.github.dockerjava.api.command.ListImagesCmd; +import com.github.dockerjava.api.command.ListNetworksCmd; +import com.github.dockerjava.api.command.ListVolumesCmd; +import com.github.dockerjava.api.command.LogContainerCmd; +import com.github.dockerjava.api.command.PauseContainerCmd; +import com.github.dockerjava.api.command.PingCmd; +import com.github.dockerjava.api.command.PullImageCmd; +import com.github.dockerjava.api.command.PushImageCmd; +import com.github.dockerjava.api.command.RemoveContainerCmd; +import com.github.dockerjava.api.command.RemoveImageCmd; +import com.github.dockerjava.api.command.RemoveNetworkCmd; +import com.github.dockerjava.api.command.RemoveVolumeCmd; +import com.github.dockerjava.api.command.RenameContainerCmd; +import com.github.dockerjava.api.command.RestartContainerCmd; +import com.github.dockerjava.api.command.SaveImageCmd; +import com.github.dockerjava.api.command.SearchImagesCmd; +import com.github.dockerjava.api.command.StartContainerCmd; +import com.github.dockerjava.api.command.StatsCmd; +import com.github.dockerjava.api.command.StopContainerCmd; +import com.github.dockerjava.api.command.TagImageCmd; +import com.github.dockerjava.api.command.TopContainerCmd; +import com.github.dockerjava.api.command.UnpauseContainerCmd; +import com.github.dockerjava.api.command.UpdateContainerCmd; +import com.github.dockerjava.api.command.VersionCmd; +import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.model.BuildResponseItem; + +import javax.net.ssl.SSLContext; import java.io.IOException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.List; -import javax.net.ssl.SSLContext; - -import com.github.dockerjava.api.async.ResultCallback; -import com.github.dockerjava.api.command.*; -import com.github.dockerjava.api.command.AuthCmd.Exec; -import com.github.dockerjava.api.model.BuildResponseItem; - /** * Special {@link DockerCmdExecFactory} implementation that collects container and image creations while test execution for the purpose of * automatically cleanup. 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 99eefb4de..9ae4e3e98 100644 --- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java @@ -263,7 +263,7 @@ public void testBuildFromPrivateRegistry() throws Exception { CreateContainerResponse testregistry = dockerClient .createContainerCmd("testregistry:2") .withName("registry") - .withPortBindings(new PortBinding(new Ports.Binding(5000), ExposedPort.tcp(5000))) + .withPortBindings(new PortBinding(Ports.Binding.forPort("5000"), ExposedPort.tcp(5000))) .withEnv("REGISTRY_AUTH=htpasswd", "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd", "REGISTRY_LOG_LEVEL=debug", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key") 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 f2fd32b6a..05d2b6d0d 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -361,9 +361,9 @@ public void createContainerWithPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding(11022)); - portBindings.bind(tcp23, Ports.binding(11023)); - portBindings.bind(tcp23, Ports.binding(11024)); + portBindings.bind(tcp22, Ports.binding("11022")); + portBindings.bind(tcp23, Ports.binding("11023")); + portBindings.bind(tcp23, Ports.binding("11024")); CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); @@ -377,13 +377,13 @@ public void createContainerWithPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp22)[0], - is(equalTo(Ports.binding(11022)))); + is(equalTo(Ports.binding("11022")))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[0], - is(equalTo(Ports.binding(11023)))); + is(equalTo(Ports.binding("11023")))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[1], - is(equalTo(Ports.binding(11024)))); + is(equalTo(Ports.binding("11024")))); } diff --git a/src/test/java/com/github/dockerjava/core/command/RenameContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RenameContainerCmdImplTest.java index 9f503a87b..582ab2556 100644 --- a/src/test/java/com/github/dockerjava/core/command/RenameContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/RenameContainerCmdImplTest.java @@ -6,12 +6,17 @@ import com.github.dockerjava.api.exception.NotFoundException; import com.github.dockerjava.client.AbstractDockerClientTest; import org.testng.ITestResult; -import org.testng.annotations.*; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; import java.lang.reflect.Method; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; @Test(groups = "integration") public class RenameContainerCmdImplTest extends AbstractDockerClientTest { diff --git a/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java index a2f1e51d8..4437eaaa7 100644 --- a/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java @@ -1,31 +1,5 @@ package com.github.dockerjava.core.command; -import static com.github.dockerjava.api.model.AccessMode.ro; -import static com.github.dockerjava.api.model.Capability.MKNOD; -import static com.github.dockerjava.api.model.Capability.NET_ADMIN; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.isEmptyString; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.startsWith; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - import com.fasterxml.jackson.databind.ObjectMapper; import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.InspectContainerResponse; @@ -42,6 +16,31 @@ import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.api.model.VolumesFrom; import com.github.dockerjava.client.AbstractDockerClientTest; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static com.github.dockerjava.api.model.AccessMode.ro; +import static com.github.dockerjava.api.model.Capability.MKNOD; +import static com.github.dockerjava.api.model.Capability.NET_ADMIN; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; @Test(groups = "integration") public class StartContainerCmdImplTest extends AbstractDockerClientTest { @@ -189,9 +188,9 @@ public void startContainerWithPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding(11022)); - portBindings.bind(tcp23, Ports.binding(11023)); - portBindings.bind(tcp23, Ports.binding(11024)); + portBindings.bind(tcp22, Ports.binding("11022")); + portBindings.bind(tcp23, Ports.binding("11023")); + portBindings.bind(tcp23, Ports.binding("11024")); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); @@ -209,13 +208,13 @@ public void startContainerWithPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp22)[0], - is(equalTo(Ports.binding(11022)))); + is(equalTo(Ports.binding("11022")))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[0], - is(equalTo(Ports.binding(11023)))); + is(equalTo(Ports.binding("11023")))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[1], - is(equalTo(Ports.binding(11024)))); + is(equalTo(Ports.binding("11024")))); } @@ -243,10 +242,10 @@ public void startContainerWithRandomPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp22)[0].getHostPort(), - is(not(equalTo(tcp22.getPort())))); + is(not(equalTo(String.valueOf(tcp22.getPort()))))); assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp23)[0].getHostPort(), - is(not(equalTo(tcp23.getPort())))); + is(not(equalTo(String.valueOf(tcp23.getPort()))))); } @@ -257,8 +256,8 @@ public void startContainerWithConflictingPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding(11022)); - portBindings.bind(tcp23, Ports.binding(11022)); + portBindings.bind(tcp22, Ports.binding("11022")); + portBindings.bind(tcp23, Ports.binding("11022")); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); diff --git a/src/test/java/com/github/dockerjava/core/util/FiltersBuilderTest.java b/src/test/java/com/github/dockerjava/core/util/FiltersBuilderTest.java index 25027ae76..e70a3b057 100644 --- a/src/test/java/com/github/dockerjava/core/util/FiltersBuilderTest.java +++ b/src/test/java/com/github/dockerjava/core/util/FiltersBuilderTest.java @@ -1,13 +1,12 @@ package com.github.dockerjava.core.util; -import com.github.dockerjava.core.util.FiltersBuilder; import com.google.common.collect.Maps; - import org.testng.annotations.Test; import java.util.Map; -import static org.testng.Assert.*; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotEquals; /** * @author Vincent Latombe 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 1299cf6ae..2f9ac934c 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java @@ -255,7 +255,7 @@ public void testBuildFromPrivateRegistry() throws Exception { CreateContainerResponse testregistry = dockerClient .createContainerCmd("testregistry:2") .withName("registry") - .withPortBindings(new PortBinding(new Ports.Binding(5000), ExposedPort.tcp(5000))) + .withPortBindings(new PortBinding(Ports.Binding.forPort("5000"), ExposedPort.tcp(5000))) .withEnv("REGISTRY_AUTH=htpasswd", "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd", "REGISTRY_LOG_LEVEL=debug", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key") 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 02c5cc54e..0daf4fb46 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java @@ -1,33 +1,5 @@ package com.github.dockerjava.netty.exec; -import static com.github.dockerjava.api.model.Capability.MKNOD; -import static com.github.dockerjava.api.model.Capability.NET_ADMIN; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.containsString; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasItemInArray; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.isEmptyString; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.startsWith; - -import java.lang.reflect.Method; -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; - -import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.exception.ConflictException; @@ -43,6 +15,33 @@ import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.api.model.VolumesFrom; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; +import java.security.SecureRandom; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import static com.github.dockerjava.api.model.Capability.MKNOD; +import static com.github.dockerjava.api.model.Capability.NET_ADMIN; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItemInArray; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; @Test(groups = "integration") public class CreateContainerCmdExecTest extends AbstractNettyDockerClientTest { @@ -352,9 +351,9 @@ public void createContainerWithPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding(11022)); - portBindings.bind(tcp23, Ports.binding(11023)); - portBindings.bind(tcp23, Ports.binding(11024)); + portBindings.bind(tcp22, Ports.binding("11022")); + portBindings.bind(tcp23, Ports.binding("11023")); + portBindings.bind(tcp23, Ports.binding("11024")); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); @@ -368,13 +367,13 @@ public void createContainerWithPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp22)[0], - is(equalTo(Ports.binding(11022)))); + is(equalTo(Ports.binding("11022")))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[0], - is(equalTo(Ports.binding(11023)))); + is(equalTo(Ports.binding("11023")))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[1], - is(equalTo(Ports.binding(11024)))); + is(equalTo(Ports.binding("11024")))); } diff --git a/src/test/java/com/github/dockerjava/netty/exec/RenameContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RenameContainerCmdExecTest.java index c176bc1d6..100a7d772 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/RenameContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/RenameContainerCmdExecTest.java @@ -6,12 +6,17 @@ import com.github.dockerjava.api.exception.NotFoundException; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; import org.testng.ITestResult; -import org.testng.annotations.*; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; import java.lang.reflect.Method; import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.*; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; @Test(groups = "integration") public class RenameContainerCmdExecTest extends AbstractNettyDockerClientTest { diff --git a/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java index 6c70c1f07..844274887 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java @@ -1,31 +1,5 @@ package com.github.dockerjava.netty.exec; -import static com.github.dockerjava.api.model.AccessMode.ro; -import static com.github.dockerjava.api.model.Capability.MKNOD; -import static com.github.dockerjava.api.model.Capability.NET_ADMIN; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.contains; -import static org.hamcrest.Matchers.containsInAnyOrder; -import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.hasSize; -import static org.hamcrest.Matchers.is; -import static org.hamcrest.Matchers.isEmptyString; -import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; -import static org.hamcrest.Matchers.startsWith; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.List; -import java.util.UUID; - -import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - import com.fasterxml.jackson.databind.ObjectMapper; import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.InspectContainerResponse; @@ -43,6 +17,31 @@ import com.github.dockerjava.api.model.VolumesFrom; import com.github.dockerjava.core.command.WaitContainerResultCallback; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static com.github.dockerjava.api.model.AccessMode.ro; +import static com.github.dockerjava.api.model.Capability.MKNOD; +import static com.github.dockerjava.api.model.Capability.NET_ADMIN; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsInAnyOrder; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.startsWith; @Test(groups = "integration") public class StartContainerCmdExecTest extends AbstractNettyDockerClientTest { @@ -192,9 +191,9 @@ public void startContainerWithPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding(11022)); - portBindings.bind(tcp23, Ports.binding(11023)); - portBindings.bind(tcp23, Ports.binding(11024)); + portBindings.bind(tcp22, Ports.binding("11022")); + portBindings.bind(tcp23, Ports.binding("11023")); + portBindings.bind(tcp23, Ports.binding("11024")); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); @@ -212,13 +211,13 @@ public void startContainerWithPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp22)[0], - is(equalTo(Ports.binding(11022)))); + is(equalTo(Ports.binding("11022")))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[0], - is(equalTo(Ports.binding(11023)))); + is(equalTo(Ports.binding("11023")))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[1], - is(equalTo(Ports.binding(11024)))); + is(equalTo(Ports.binding("11024")))); } @@ -246,10 +245,10 @@ public void startContainerWithRandomPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp22)[0].getHostPort(), - is(not(equalTo(tcp22.getPort())))); + is(not(equalTo(String.valueOf(tcp22.getPort()))))); assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp23)[0].getHostPort(), - is(not(equalTo(tcp23.getPort())))); + is(not(equalTo(String.valueOf(tcp23.getPort()))))); } @@ -260,8 +259,8 @@ public void startContainerWithConflictingPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding(11022)); - portBindings.bind(tcp23, Ports.binding(11022)); + portBindings.bind(tcp22, Ports.binding("11022")); + portBindings.bind(tcp23, Ports.binding("11022")); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); From 9641b01d0559aa23299bdf229c07a29e065d4398 Mon Sep 17 00:00:00 2001 From: Lappas Dionysis Date: Sun, 8 May 2016 19:07:39 +0300 Subject: [PATCH 111/855] Fixes copyArchiveToContainerCmdImpl fail when hostResource has an empty dir which gets added as last entry to tar CopyArchiveToContainerCmdImpl FAILS with com.github.dockerjava.api.exception.BadRequestException: Unable to perform tar on host resource /path/to/resource, if the resourceHost is a dir that containes an empty dir which will be added as the last entry to the generated .tar file. --- src/main/java/com/github/dockerjava/core/util/TarDirWalker.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java b/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java index 7c3a9ca29..af263ee9c 100644 --- a/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java +++ b/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java @@ -26,6 +26,7 @@ public TarDirWalker(Path basePath, TarArchiveOutputStream tarArchiveOutputStream public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException { if (!dir.equals(basePath)) { tarArchiveOutputStream.putArchiveEntry(new TarArchiveEntry(FilePathUtil.relativize(basePath, dir))); + tarArchiveOutputStream.closeArchiveEntry(); } return FileVisitResult.CONTINUE; } From 2edfcb0e0aa08feade900dcd3250a991d9458a85 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Sun, 8 May 2016 22:24:06 +0200 Subject: [PATCH 112/855] Polish binding for port ranges --- .../github/dockerjava/api/model/Ports.java | 103 ++++++++++-------- .../dockerjava/api/model/BindingTest.java | 8 +- .../dockerjava/api/model/PortBindingTest.java | 12 +- .../api/model/Ports_addBindingsTest.java | 4 +- .../core/command/BuildImageCmdImplTest.java | 2 +- .../command/CreateContainerCmdImplTest.java | 14 ++- .../command/StartContainerCmdImplTest.java | 26 +++-- .../netty/exec/BuildImageCmdExecTest.java | 3 +- .../exec/CreateContainerCmdExecTest.java | 14 ++- .../netty/exec/StartContainerCmdExecTest.java | 26 +++-- 10 files changed, 119 insertions(+), 93 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/Ports.java b/src/main/java/com/github/dockerjava/api/model/Ports.java index 17b2ad432..904a31c4e 100644 --- a/src/main/java/com/github/dockerjava/api/model/Ports.java +++ b/src/main/java/com/github/dockerjava/api/model/Ports.java @@ -107,24 +107,10 @@ public Map getBindings() { // return bindings.toArray(new PortBinding[bindings.size()]); // } - /** - * Creates a {@link Binding} for the given IP address and port number. - */ - public static Binding binding(String hostIp, String hostPort) { - return new Binding(hostIp, hostPort); - } - - /** - * Creates a {@link Binding} for the given port number, leaving the IP address undefined. - */ - public static Binding binding(String hostPort) { - return new Binding(null, hostPort); - } - /** * A {@link Binding} represents a socket on the Docker host that is used in a {@link PortBinding}. It is characterized by an - * {@link #getHostIp() IP address} and a {@link #getHostPort() port number}. Both properties may be null in order to let - * Docker assign them dynamically/using defaults. + * {@link #getHostIp() IP address} and a {@link #getHostPortSpec() port spec}. Both properties may be null in order to + * let Docker assign them dynamically/using defaults. * * @see Ports#bind(ExposedPort, Binding) * @see ExposedPort @@ -132,44 +118,74 @@ public static Binding binding(String hostPort) { public static class Binding { /** - * Creates a {@link Binding} for the given {@link #getHostPort() port number or range}, leaving the {@link #getHostIp() IP address} + * Creates a {@link Binding} for the given {@link #getHostPortSpec() port spec}, leaving the {@link #getHostIp() IP address} * undefined. * * @see Ports#bind(ExposedPort, Binding) * @see ExposedPort */ - public static Binding forPort(String port) { - return new Binding(null, port); + public static Binding bindPortSpec(String portSpec) { + return new Binding(null, portSpec); } /** - * Creates a {@link Binding} for the given {@link #getHostIp() IP address}, leaving the {@link #getHostPort() port number} + * Creates a {@link Binding} for the given {@link #getHostIp() IP address}, leaving the {@link #getHostPortSpec() port spec} * undefined. */ - public static Binding forIp(String hostIp) { + public static Binding bindIp(String hostIp) { return new Binding(hostIp, null); } + /** + * Creates a {@link Binding} for the given {@link #getHostIp() IP address} and port number. + */ + public static Binding bindIpAndPort(String hostIp, int port) { + return new Binding(hostIp, "" + port); + } + + /** + * Creates a {@link Binding} for the given {@link #getHostIp() IP address} and port range. + */ + public static Binding bindIpAndPortRange(String hostIp, int lowPort, int highPort) { + return new Binding(hostIp, lowPort + "-" + highPort); + } + + /** + * Creates a {@link Binding} for the given port range, leaving the {@link #getHostIp() IP address} + * undefined. + */ + public static Binding bindPortRange(int lowPort, int highPort) { + return bindIpAndPortRange(null, lowPort, highPort); + } + + /** + * Creates a {@link Binding} for the given port leaving the {@link #getHostIp() IP address} + * undefined. + */ + public static Binding bindPort(int port) { + return bindIpAndPort(null, port); + } + + /** + * Creates an empty {@link Binding}. + */ + public static Binding empty() { + return new Binding(null, null); + } + private final String hostIp; - private final String hostPort; + private final String hostPortSpec; /** - * Creates a {@link Binding} for the given {@link #getHostIp() IP address} and {@link #getHostPort() port number}. + * Creates a {@link Binding} for the given {@link #getHostIp() host IP address} and {@link #getHostPortSpec() host port spec}. * * @see Ports#bind(ExposedPort, Binding) * @see ExposedPort */ - public Binding(String hostIp, String hostPort) { + public Binding(String hostIp, String hostPortSpec) { this.hostIp = isEmpty(hostIp) ? null : hostIp; - this.hostPort = hostPort; - } - - /** - * Creates a {@link Binding} with both {@link #getHostIp() IP address} and {@link #getHostPort() port number} undefined. - */ - public Binding() { - this(null, null); + this.hostPortSpec = hostPortSpec; } /** @@ -181,16 +197,17 @@ public String getHostIp() { } /** - * @return the port number on the Docker host. May be null, in which case Docker will dynamically assign a port. + * @return the port spec for the binding on the Docker host. May reference a single port ("1234"), a port range ("1234-2345") or + * null, in which case Docker will dynamically assign a port. */ - public String getHostPort() { - return hostPort; + public String getHostPortSpec() { + return hostPortSpec; } /** * Parses a textual host and port specification (as used by the Docker CLI) to a {@link Binding}. *

- * Legal syntax: IP|IP:port|port + * Legal syntax: IP|IP:portSpec|portSpec where portSpec is either a single port or a port range * * @param serialized * serialized the specification, e.g. 127.0.0.1:80 @@ -201,7 +218,7 @@ public String getHostPort() { public static Binding parse(String serialized) throws IllegalArgumentException { try { if (serialized.isEmpty()) { - return new Binding(); + return Binding.empty(); } String[] parts = serialized.split(":"); @@ -210,7 +227,7 @@ public static Binding parse(String serialized) throws IllegalArgumentException { return new Binding(parts[0], parts[1]); } case 1: { - return parts[0].contains(".") ? Binding.forIp(parts[0]) : Binding.forPort(parts[0]); + return parts[0].contains(".") ? Binding.bindIp(parts[0]) : Binding.bindPortSpec(parts[0]); } default: { throw new IllegalArgumentException(); @@ -230,11 +247,11 @@ public static Binding parse(String serialized) throws IllegalArgumentException { @Override public String toString() { if (isEmpty(hostIp)) { - return hostPort; - } else if (hostPort == null) { + return hostPortSpec; + } else if (hostPortSpec == null) { return hostIp; } else { - return hostIp + ":" + hostPort; + return hostIp + ":" + hostPortSpec; } } @@ -242,7 +259,7 @@ public String toString() { public boolean equals(Object obj) { if (obj instanceof Binding) { Binding other = (Binding) obj; - return new EqualsBuilder().append(hostIp, other.getHostIp()).append(hostPort, other.getHostPort()) + return new EqualsBuilder().append(hostIp, other.getHostIp()).append(hostPortSpec, other.getHostPortSpec()) .isEquals(); } else { return super.equals(obj); @@ -293,7 +310,7 @@ public void serialize(Ports portBindings, JsonGenerator jsonGen, SerializerProvi for (Binding binding : entry.getValue()) { jsonGen.writeStartObject(); jsonGen.writeStringField("HostIp", binding.getHostIp() == null ? "" : binding.getHostIp()); - jsonGen.writeStringField("HostPort", binding.getHostPort() == null ? "" : binding.getHostPort()); + jsonGen.writeStringField("HostPort", binding.getHostPortSpec() == null ? "" : binding.getHostPortSpec()); jsonGen.writeEndObject(); } jsonGen.writeEndArray(); diff --git a/src/test/java/com/github/dockerjava/api/model/BindingTest.java b/src/test/java/com/github/dockerjava/api/model/BindingTest.java index 290e66b82..3b5ea2f6a 100644 --- a/src/test/java/com/github/dockerjava/api/model/BindingTest.java +++ b/src/test/java/com/github/dockerjava/api/model/BindingTest.java @@ -10,22 +10,22 @@ public class BindingTest { @Test public void parseIpAndPort() { - assertEquals(Binding.parse("127.0.0.1:80"), Ports.binding("127.0.0.1", "80")); + assertEquals(Binding.parse("127.0.0.1:80"), Binding.bindIpAndPort("127.0.0.1", 80)); } @Test public void parsePortOnly() { - assertEquals(Binding.parse("80"), Ports.binding(null, "80")); + assertEquals(Binding.parse("80"), Binding.bindPort(80)); } @Test public void parseIPOnly() { - assertEquals(Binding.parse("127.0.0.1"), Ports.binding("127.0.0.1", null)); + assertEquals(Binding.parse("127.0.0.1"), Binding.bindIp("127.0.0.1")); } @Test public void parseEmptyString() { - assertEquals(Binding.parse(""), Ports.binding(null, null)); + assertEquals(Binding.parse(""), Binding.empty()); } // Strings can be used since it can be a range. Let the docker daemon do the validation. diff --git a/src/test/java/com/github/dockerjava/api/model/PortBindingTest.java b/src/test/java/com/github/dockerjava/api/model/PortBindingTest.java index 296148177..7603c3f1b 100644 --- a/src/test/java/com/github/dockerjava/api/model/PortBindingTest.java +++ b/src/test/java/com/github/dockerjava/api/model/PortBindingTest.java @@ -13,32 +13,32 @@ public class PortBindingTest { @Test public void fullDefinition() { assertEquals(PortBinding.parse("127.0.0.1:80:8080/tcp"), - new PortBinding(new Binding("127.0.0.1", "80"), TCP_8080)); + new PortBinding(Binding.bindIpAndPort("127.0.0.1", 80), TCP_8080)); } @Test public void noProtocol() { - assertEquals(PortBinding.parse("127.0.0.1:80:8080"), new PortBinding(new Binding("127.0.0.1", "80"), TCP_8080)); + assertEquals(PortBinding.parse("127.0.0.1:80:8080"), new PortBinding(Binding.bindIpAndPort("127.0.0.1", 80), TCP_8080)); } @Test public void noHostIp() { - assertEquals(PortBinding.parse("80:8080/tcp"), new PortBinding(Binding.forPort("80"), TCP_8080)); + assertEquals(PortBinding.parse("80:8080/tcp"), new PortBinding(Binding.bindPort(80), TCP_8080)); } @Test public void portsOnly() { - assertEquals(PortBinding.parse("80:8080"), new PortBinding(Binding.forPort("80"), TCP_8080)); + assertEquals(PortBinding.parse("80:8080"), new PortBinding(Binding.bindPort(80), TCP_8080)); } @Test public void exposedPortOnly() { - assertEquals(PortBinding.parse("8080"), new PortBinding(new Binding(), TCP_8080)); + assertEquals(PortBinding.parse("8080"), new PortBinding(Binding.empty(), TCP_8080)); } @Test public void dynamicHostPort() { - assertEquals(PortBinding.parse("127.0.0.1::8080"), new PortBinding(Binding.forIp("127.0.0.1"), TCP_8080)); + assertEquals(PortBinding.parse("127.0.0.1::8080"), new PortBinding(Binding.bindIp("127.0.0.1"), TCP_8080)); } @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Error parsing PortBinding 'nonsense'", enabled = false) diff --git a/src/test/java/com/github/dockerjava/api/model/Ports_addBindingsTest.java b/src/test/java/com/github/dockerjava/api/model/Ports_addBindingsTest.java index 401ee4b44..26e815f3b 100644 --- a/src/test/java/com/github/dockerjava/api/model/Ports_addBindingsTest.java +++ b/src/test/java/com/github/dockerjava/api/model/Ports_addBindingsTest.java @@ -17,9 +17,9 @@ public class Ports_addBindingsTest { private static final ExposedPort TCP_90 = ExposedPort.tcp(90); - private static final Binding BINDING_8080 = Ports.binding("8080"); + private static final Binding BINDING_8080 = Binding.bindPort(8080); - private static final Binding BINDING_9090 = Ports.binding("9090"); + private static final Binding BINDING_9090 = Binding.bindPort(9090); private Ports ports; 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 9ae4e3e98..8eea40eec 100644 --- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java @@ -263,7 +263,7 @@ public void testBuildFromPrivateRegistry() throws Exception { CreateContainerResponse testregistry = dockerClient .createContainerCmd("testregistry:2") .withName("registry") - .withPortBindings(new PortBinding(Ports.Binding.forPort("5000"), ExposedPort.tcp(5000))) + .withPortBindings(new PortBinding(Ports.Binding.bindPortSpec("5000"), ExposedPort.tcp(5000))) .withEnv("REGISTRY_AUTH=htpasswd", "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd", "REGISTRY_LOG_LEVEL=debug", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key") 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 05d2b6d0d..bc5a7d940 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -15,7 +15,9 @@ import com.github.dockerjava.api.model.Ulimit; import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.api.model.VolumesFrom; +import com.github.dockerjava.api.model.Ports.Binding; import com.github.dockerjava.client.AbstractDockerClientTest; + import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -361,9 +363,9 @@ public void createContainerWithPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding("11022")); - portBindings.bind(tcp23, Ports.binding("11023")); - portBindings.bind(tcp23, Ports.binding("11024")); + portBindings.bind(tcp22, Binding.bindPort(11022)); + portBindings.bind(tcp23, Binding.bindPort(11023)); + portBindings.bind(tcp23, Binding.bindPort(11024)); CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); @@ -377,13 +379,13 @@ public void createContainerWithPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp22)[0], - is(equalTo(Ports.binding("11022")))); + is(equalTo(Binding.bindPort(11022)))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[0], - is(equalTo(Ports.binding("11023")))); + is(equalTo(Binding.bindPort(11023)))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[1], - is(equalTo(Ports.binding("11024")))); + is(equalTo(Binding.bindPort(11024)))); } diff --git a/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java index 4437eaaa7..2b32e00c5 100644 --- a/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java @@ -15,7 +15,9 @@ import com.github.dockerjava.api.model.RestartPolicy; import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.api.model.VolumesFrom; +import com.github.dockerjava.api.model.Ports.Binding; import com.github.dockerjava.client.AbstractDockerClientTest; + import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -188,9 +190,9 @@ public void startContainerWithPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding("11022")); - portBindings.bind(tcp23, Ports.binding("11023")); - portBindings.bind(tcp23, Ports.binding("11024")); + portBindings.bind(tcp22, Binding.bindPort(11022)); + portBindings.bind(tcp23, Binding.bindPort(11023)); + portBindings.bind(tcp23, Binding.bindPort(11024)); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); @@ -208,13 +210,13 @@ public void startContainerWithPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp22)[0], - is(equalTo(Ports.binding("11022")))); + is(equalTo(Binding.bindPort(11022)))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[0], - is(equalTo(Ports.binding("11023")))); + is(equalTo(Binding.bindPort(11023)))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[1], - is(equalTo(Ports.binding("11024")))); + is(equalTo(Binding.bindPort(11024)))); } @@ -225,8 +227,8 @@ public void startContainerWithRandomPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding(null)); - portBindings.bind(tcp23, Ports.binding(null)); + portBindings.bind(tcp22, Binding.empty()); + portBindings.bind(tcp23, Binding.empty()); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).withPublishAllPorts(true).exec(); @@ -241,10 +243,10 @@ public void startContainerWithRandomPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); - assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp22)[0].getHostPort(), + assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp22)[0].getHostPortSpec(), is(not(equalTo(String.valueOf(tcp22.getPort()))))); - assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp23)[0].getHostPort(), + assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp23)[0].getHostPortSpec(), is(not(equalTo(String.valueOf(tcp23.getPort()))))); } @@ -256,8 +258,8 @@ public void startContainerWithConflictingPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding("11022")); - portBindings.bind(tcp23, Ports.binding("11022")); + portBindings.bind(tcp22, Binding.bindPort(11022)); + portBindings.bind(tcp23, Binding.bindPort(11022)); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); 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 2f9ac934c..92975f38f 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java @@ -34,6 +34,7 @@ import com.github.dockerjava.api.model.ExposedPort; import com.github.dockerjava.api.model.PortBinding; import com.github.dockerjava.api.model.Ports; +import com.github.dockerjava.api.model.Ports.Binding; import com.github.dockerjava.core.command.BuildImageResultCallback; import com.github.dockerjava.core.command.PushImageResultCallback; import com.github.dockerjava.core.command.WaitContainerResultCallback; @@ -255,7 +256,7 @@ public void testBuildFromPrivateRegistry() throws Exception { CreateContainerResponse testregistry = dockerClient .createContainerCmd("testregistry:2") .withName("registry") - .withPortBindings(new PortBinding(Ports.Binding.forPort("5000"), ExposedPort.tcp(5000))) + .withPortBindings(new PortBinding(Binding.bindPort(5000), ExposedPort.tcp(5000))) .withEnv("REGISTRY_AUTH=htpasswd", "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd", "REGISTRY_LOG_LEVEL=debug", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key") 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 0daf4fb46..4231a5f72 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java @@ -10,11 +10,13 @@ import com.github.dockerjava.api.model.Link; import com.github.dockerjava.api.model.LogConfig; import com.github.dockerjava.api.model.Ports; +import com.github.dockerjava.api.model.Ports.Binding; import com.github.dockerjava.api.model.RestartPolicy; import com.github.dockerjava.api.model.Ulimit; import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.api.model.VolumesFrom; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; + import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -351,9 +353,9 @@ public void createContainerWithPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding("11022")); - portBindings.bind(tcp23, Ports.binding("11023")); - portBindings.bind(tcp23, Ports.binding("11024")); + portBindings.bind(tcp22, Binding.bindPort(11022)); + portBindings.bind(tcp23, Binding.bindPort(11023)); + portBindings.bind(tcp23, Binding.bindPort(11024)); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); @@ -367,13 +369,13 @@ public void createContainerWithPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp22)[0], - is(equalTo(Ports.binding("11022")))); + is(equalTo(Binding.bindPort(11022)))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[0], - is(equalTo(Ports.binding("11023")))); + is(equalTo(Binding.bindPort(11023)))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[1], - is(equalTo(Ports.binding("11024")))); + is(equalTo(Binding.bindPort(11024)))); } diff --git a/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java index 844274887..f4a36c2b1 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java @@ -15,8 +15,10 @@ import com.github.dockerjava.api.model.RestartPolicy; import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.api.model.VolumesFrom; +import com.github.dockerjava.api.model.Ports.Binding; import com.github.dockerjava.core.command.WaitContainerResultCallback; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; + import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -191,9 +193,9 @@ public void startContainerWithPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding("11022")); - portBindings.bind(tcp23, Ports.binding("11023")); - portBindings.bind(tcp23, Ports.binding("11024")); + portBindings.bind(tcp22, Binding.bindPort(11022)); + portBindings.bind(tcp23, Binding.bindPort(11023)); + portBindings.bind(tcp23, Binding.bindPort(11024)); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); @@ -211,13 +213,13 @@ public void startContainerWithPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp22)[0], - is(equalTo(Ports.binding("11022")))); + is(equalTo(Binding.bindPort(11022)))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[0], - is(equalTo(Ports.binding("11023")))); + is(equalTo(Binding.bindPort(11023)))); assertThat(inspectContainerResponse.getHostConfig().getPortBindings().getBindings().get(tcp23)[1], - is(equalTo(Ports.binding("11024")))); + is(equalTo(Binding.bindPort(11024)))); } @@ -228,8 +230,8 @@ public void startContainerWithRandomPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding(null)); - portBindings.bind(tcp23, Ports.binding(null)); + portBindings.bind(tcp22, Binding.empty()); + portBindings.bind(tcp23, Binding.empty()); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).withPublishAllPorts(true).exec(); @@ -244,10 +246,10 @@ public void startContainerWithRandomPortBindings() throws DockerException { assertThat(Arrays.asList(inspectContainerResponse.getConfig().getExposedPorts()), contains(tcp22, tcp23)); - assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp22)[0].getHostPort(), + assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp22)[0].getHostPortSpec(), is(not(equalTo(String.valueOf(tcp22.getPort()))))); - assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp23)[0].getHostPort(), + assertThat(inspectContainerResponse.getNetworkSettings().getPorts().getBindings().get(tcp23)[0].getHostPortSpec(), is(not(equalTo(String.valueOf(tcp23.getPort()))))); } @@ -259,8 +261,8 @@ public void startContainerWithConflictingPortBindings() throws DockerException { ExposedPort tcp23 = ExposedPort.tcp(23); Ports portBindings = new Ports(); - portBindings.bind(tcp22, Ports.binding("11022")); - portBindings.bind(tcp23, Ports.binding("11022")); + portBindings.bind(tcp22, Binding.bindPort(11022)); + portBindings.bind(tcp23, Binding.bindPort(11022)); CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("true") .withExposedPorts(tcp22, tcp23).withPortBindings(portBindings).exec(); From 61869c8a75cd9e3e295aadacc74b92471b591d1f Mon Sep 17 00:00:00 2001 From: AE Date: Mon, 9 May 2016 19:33:43 +0200 Subject: [PATCH 113/855] Adds tests for inspect command when size is used. --- .../command/InspectContainerCmdImplTest.java | 17 +++++++++++++++++ .../netty/exec/InspectContainerCmdExecTest.java | 15 +++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java index 47ed11201..2a20edc6e 100644 --- a/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java @@ -63,6 +63,23 @@ public void inspectContainer() throws DockerException { } + @Test() + public void inspectContainerWithSize() throws DockerException { + + String containerName = "generated_" + new SecureRandom().nextInt(); + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("top") + .withName(containerName).exec(); + LOG.info("Created container {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse containerInfo = dockerClient.inspectContainerCmd(container.getId()) + .withSize(true) + .exec(); + assertNotNull(containerInfo.getSizeRootFs()); + assertEquals(containerInfo.getId(), container.getId()); + } + @Test(expectedExceptions = NotFoundException.class) public void inspectNonExistingContainer() throws DockerException { dockerClient.inspectContainerCmd("non-existing").exec(); diff --git a/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java index 87fe3b48b..8f38dde79 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java @@ -63,6 +63,21 @@ public void inspectContainer() throws DockerException { } + @Test() + public void inspectContainerWithSize() throws DockerException { + + String containerName = "generated_" + new SecureRandom().nextInt(); + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("top") + .withName(containerName).exec(); + LOG.info("Created container {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + InspectContainerResponse containerInfo = dockerClient.inspectContainerCmd(container.getId()).exec(); + assertEquals(containerInfo.getId(), container.getId()); + assertNotNull(containerInfo.getSizeRootFs()); + } + @Test(expectedExceptions = NotFoundException.class) public void inspectNonExistingContainer() throws DockerException { dockerClient.inspectContainerCmd("non-existing").exec(); From d2b2a2dde55f367831a749f6246438d08e4522b5 Mon Sep 17 00:00:00 2001 From: Lappas Dionysis Date: Mon, 9 May 2016 20:41:27 +0300 Subject: [PATCH 114/855] Added Test Case that simulates failure on copyArchiveToContainerCmdImpl when last tar entry is an empty dir --- .../CopyArchiveToContainerCmdImplTest.java | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java index 0f8f2164b..06967706f 100644 --- a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java @@ -90,5 +90,32 @@ public void copyToNonExistingContainer() throws Exception { } catch (NotFoundException ignored) { } } + + @Test + public void copyDirWithLastAddedTarEnryEmptyDir() throws Exception{ + // create a temp dir + Path localDir = Files.createTempDirectory(""); + localDir.toFile().deleteOnExit(); + // create sub-dir with name b + Path emptyDir = Files.createTempDirectory(localDir.resolve("b"), ""); + emptyDir.toFile().deleteOnExit(); + // creaet sub-dir with name a + Path dirWithFile = Files.createTempDirectory(localDir.resolve("a"), ""); + dirWithFile.toFile().deleteOnExit(); + // create file in sub-dir b, name or conter are irrelevant + Path file = Files.createTempFile(dirWithFile.resolve("file"), "", ""); + file.toFile().deleteOnExit(); + + // create a test container + CreateContainerResponse container = dockerClient.createContainerCmd("progrium/busybox:latest") + .withCmd("/bin/sh", "-c", "while true; do sleep 9999; done") + .exec(); + // start the container + dockerClient.startContainerCmd(container.getId()).exec(); + // copy data from local dir to container + dockerClient.copyArchiveToContainerCmd(container.getId()) + .withHostResource(localDir.toString()) + .exec(); + } } From 72b2e73a686c39851c177cc440725ef2f888de9d Mon Sep 17 00:00:00 2001 From: AE Date: Mon, 9 May 2016 19:58:00 +0200 Subject: [PATCH 115/855] Strenghten tests for withSize in InspectContainer. --- .../core/command/InspectContainerCmdImplTest.java | 10 ++++++---- .../netty/exec/InspectContainerCmdExecTest.java | 7 ++++++- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java index 2a20edc6e..c0eaab3a6 100644 --- a/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/InspectContainerCmdImplTest.java @@ -8,6 +8,7 @@ import java.lang.reflect.Method; import java.security.SecureRandom; +import com.github.dockerjava.api.command.InspectContainerCmd; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.ITestResult; @@ -73,11 +74,12 @@ public void inspectContainerWithSize() throws DockerException { LOG.info("Created container {}", container.toString()); assertThat(container.getId(), not(isEmptyString())); - InspectContainerResponse containerInfo = dockerClient.inspectContainerCmd(container.getId()) - .withSize(true) - .exec(); - assertNotNull(containerInfo.getSizeRootFs()); + InspectContainerCmd command = dockerClient.inspectContainerCmd(container.getId()).withSize(true); + assertTrue(command.getSize()); + InspectContainerResponse containerInfo = command.exec(); assertEquals(containerInfo.getId(), container.getId()); + assertNotNull(containerInfo.getSizeRootFs()); + assertTrue(containerInfo.getSizeRootFs().intValue() > 0 ); } @Test(expectedExceptions = NotFoundException.class) diff --git a/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java index 8f38dde79..af32cebce 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/InspectContainerCmdExecTest.java @@ -8,6 +8,7 @@ import java.lang.reflect.Method; import java.security.SecureRandom; +import com.github.dockerjava.api.command.InspectContainerCmd; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.ITestResult; @@ -73,9 +74,13 @@ public void inspectContainerWithSize() throws DockerException { LOG.info("Created container {}", container.toString()); assertThat(container.getId(), not(isEmptyString())); - InspectContainerResponse containerInfo = dockerClient.inspectContainerCmd(container.getId()).exec(); + InspectContainerCmd command = dockerClient.inspectContainerCmd(container.getId()) + .withSize(true); + assertTrue(command.getSize()); + InspectContainerResponse containerInfo = command.exec(); assertEquals(containerInfo.getId(), container.getId()); assertNotNull(containerInfo.getSizeRootFs()); + assertTrue(containerInfo.getSizeRootFs().intValue() > 0 ); } @Test(expectedExceptions = NotFoundException.class) From 8af6f2f6437aec20c4ce3501d8843eb4c60d69d7 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Mon, 9 May 2016 21:54:53 +0200 Subject: [PATCH 116/855] Polish test and comment --- src/main/java/com/github/dockerjava/api/model/ExposedPort.java | 2 +- .../github/dockerjava/core/command/BuildImageCmdImplTest.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/model/ExposedPort.java b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java index 4e30c8df0..ec95f6273 100644 --- a/src/main/java/com/github/dockerjava/api/model/ExposedPort.java +++ b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java @@ -65,7 +65,7 @@ public ExposedPort(int port) { * @param scheme * the {@link #getScheme() scheme}, tcp or udp * @param port - * the {@link #getPort() port number or port range} + * the {@link #getPort() port number} * @deprecated use {@link #ExposedPort(int, InternetProtocol)} */ @Deprecated 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 8eea40eec..c0dc967d4 100644 --- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java @@ -34,6 +34,7 @@ import com.github.dockerjava.api.model.ExposedPort; import com.github.dockerjava.api.model.PortBinding; import com.github.dockerjava.api.model.Ports; +import com.github.dockerjava.api.model.Ports.Binding; import com.github.dockerjava.client.AbstractDockerClientTest; import com.github.dockerjava.core.util.CompressArchiveUtil; @@ -263,7 +264,7 @@ public void testBuildFromPrivateRegistry() throws Exception { CreateContainerResponse testregistry = dockerClient .createContainerCmd("testregistry:2") .withName("registry") - .withPortBindings(new PortBinding(Ports.Binding.bindPortSpec("5000"), ExposedPort.tcp(5000))) + .withPortBindings(new PortBinding(Binding.bindPort(5000), ExposedPort.tcp(5000))) .withEnv("REGISTRY_AUTH=htpasswd", "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd", "REGISTRY_LOG_LEVEL=debug", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt", "REGISTRY_HTTP_TLS_KEY=/certs/domain.key") From 8b5badadca35dfb8f96f398aad5aaa942a064fe1 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Mon, 9 May 2016 22:35:55 +0200 Subject: [PATCH 117/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f88303a1c..235b87622 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Notes All changes +* [#575] (https://github.com/docker-java/docker-java/pull/575) Support binding of port ranges * [#563] (https://github.com/docker-java/docker-java/pull/563) Fix memory leak in netty implementation of DockerCmdExecFactory Included in 3.0.0-RC5 From 572a1eafe84397abaf4c93f882e71b6b49c2d27e Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Mon, 9 May 2016 23:27:56 +0200 Subject: [PATCH 118/855] Polish tests --- .../CopyArchiveToContainerCmdImpl.java | 8 ++--- .../CopyArchiveToContainerCmdImplTest.java | 33 ++++++++++--------- .../CopyArchiveToContainerCmdExecTest.java | 28 ++++++++++++++++ 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImpl.java index 3a35b3508..0f734fde9 100644 --- a/src/main/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImpl.java @@ -12,7 +12,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import com.github.dockerjava.api.command.CopyArchiveToContainerCmd; -import com.github.dockerjava.api.exception.BadRequestException; +import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.api.exception.NotFoundException; import com.github.dockerjava.core.util.CompressArchiveUtil; @@ -127,7 +127,7 @@ public Void exec() throws NotFoundException { if (StringUtils.isNotEmpty(this.hostResource)) { // User set host resource and not directly a stream if (this.tarInputStream != null) { - throw new BadRequestException( + throw new DockerClientException( "Only one of host resource or tar input stream should be defined to perform the copy, not both"); } // We compress the given path, call exec so that the stream is consumed and then close it our self @@ -135,10 +135,10 @@ public Void exec() throws NotFoundException { this.tarInputStream = uploadStream; return super.exec(); } catch (IOException e) { - throw new BadRequestException("Unable to perform tar on host resource " + this.hostResource); + throw new DockerClientException("Unable to perform tar on host resource " + this.hostResource, e); } } else if (this.tarInputStream == null) { - throw new BadRequestException( + throw new DockerClientException( "One of host resource or tar input stream must be defined to perform the copy"); } // User set a stream, so we will just consume it and let the user close it by him self diff --git a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java index 06967706f..b8ede3416 100644 --- a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java @@ -11,6 +11,7 @@ import java.nio.file.Path; import java.nio.file.Paths; +import org.apache.commons.io.FileUtils; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -90,32 +91,32 @@ public void copyToNonExistingContainer() throws Exception { } catch (NotFoundException ignored) { } } - - @Test - public void copyDirWithLastAddedTarEnryEmptyDir() throws Exception{ + + @Test + public void copyDirWithLastAddedTarEntryEmptyDir() throws Exception{ // create a temp dir - Path localDir = Files.createTempDirectory(""); + Path localDir = Files.createTempDirectory(null); localDir.toFile().deleteOnExit(); - // create sub-dir with name b - Path emptyDir = Files.createTempDirectory(localDir.resolve("b"), ""); - emptyDir.toFile().deleteOnExit(); - // creaet sub-dir with name a - Path dirWithFile = Files.createTempDirectory(localDir.resolve("a"), ""); - dirWithFile.toFile().deleteOnExit(); + // create empty sub-dir with name b + Files.createDirectory(localDir.resolve("b")); + // create sub-dir with name a + Path dirWithFile = Files.createDirectory(localDir.resolve("a")); // create file in sub-dir b, name or conter are irrelevant - Path file = Files.createTempFile(dirWithFile.resolve("file"), "", ""); - file.toFile().deleteOnExit(); - + Files.createFile(dirWithFile.resolve("file")); + // create a test container - CreateContainerResponse container = dockerClient.createContainerCmd("progrium/busybox:latest") - .withCmd("/bin/sh", "-c", "while true; do sleep 9999; done") + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("sleep", "9999") .exec(); // start the container dockerClient.startContainerCmd(container.getId()).exec(); - // copy data from local dir to container + // copy data from local dir to container dockerClient.copyArchiveToContainerCmd(container.getId()) .withHostResource(localDir.toString()) .exec(); + + // cleanup dir + FileUtils.deleteDirectory(localDir.toFile()); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java index d755dfcba..9e9b0c731 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java @@ -11,6 +11,7 @@ import java.nio.file.Path; import java.nio.file.Paths; +import org.apache.commons.io.FileUtils; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -91,4 +92,31 @@ public void copyToNonExistingContainer() throws Exception { } } + @Test + public void copyDirWithLastAddedTarEntryEmptyDir() throws Exception{ + // create a temp dir + Path localDir = Files.createTempDirectory(null); + localDir.toFile().deleteOnExit(); + // create empty sub-dir with name b + Files.createDirectory(localDir.resolve("b")); + // create sub-dir with name a + Path dirWithFile = Files.createDirectory(localDir.resolve("a")); + // create file in sub-dir b, name or conter are irrelevant + Files.createFile(dirWithFile.resolve("file")); + + // create a test container + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("sleep", "9999") + .exec(); + // start the container + dockerClient.startContainerCmd(container.getId()).exec(); + // copy data from local dir to container + dockerClient.copyArchiveToContainerCmd(container.getId()) + .withHostResource(localDir.toString()) + .exec(); + + // cleanup dir + FileUtils.deleteDirectory(localDir.toFile()); + } + } From 1f85b7dfacc447cfdf5e66df4e142620a6753ce0 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Mon, 9 May 2016 23:30:44 +0200 Subject: [PATCH 119/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 235b87622..4e93dd737 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ Notes All changes * [#575] (https://github.com/docker-java/docker-java/pull/575) Support binding of port ranges +* [#574] (https://github.com/docker-java/docker-java/pull/574) Fix for copyArchiveToContainerCmd bug * [#563] (https://github.com/docker-java/docker-java/pull/563) Fix memory leak in netty implementation of DockerCmdExecFactory Included in 3.0.0-RC5 From 28e11ed2af5ea3ef3dc73a067467d9fb9f8bda19 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Wed, 11 May 2016 21:23:51 +0200 Subject: [PATCH 120/855] Fix issue #551 --- .../core/command/BuildImageCmdImpl.java | 2 +- .../core/dockerfile/Dockerfile.java | 26 ++++++++++++------- .../core/command/BuildImageCmdImplTest.java | 19 ++++++++++++-- .../DockerfileAddMultipleFilesTest.java | 2 +- .../core/dockerfile/DockerfileTest.java | 2 +- .../dockerfileFolder/Dockerfile | 7 +++++ .../testrunFolder/testrun.sh | 3 +++ 7 files changed, 46 insertions(+), 15 deletions(-) create mode 100644 src/test/resources/testDockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile create mode 100755 src/test/resources/testDockerfileNotInBaseDirectory/testrunFolder/testrun.sh 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 58f148cb6..487f0b264 100644 --- a/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java @@ -272,7 +272,7 @@ public BuildImageCmdImpl withDockerfile(File dockerfile) { this.dockerFile = dockerfile; try { - withTarInputStream(new Dockerfile(dockerfile).parse().buildDockerFolderTar(baseDirectory)); + withTarInputStream(new Dockerfile(dockerfile, baseDirectory).parse().buildDockerFolderTar()); } catch (IOException e) { // we just created the file this should never happen. throw new RuntimeException(e); diff --git a/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java b/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java index 8c1c34e2a..c970d6c2d 100644 --- a/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java +++ b/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java @@ -31,8 +31,9 @@ public class Dockerfile { public final File dockerFile; - public Dockerfile(File dockerFile) { + private final File baseDirectory; + public Dockerfile(File dockerFile, File baseDirectory) { if (!dockerFile.exists()) { throw new IllegalStateException(String.format("Dockerfile %s does not exist", dockerFile.getAbsolutePath())); } @@ -43,6 +44,15 @@ public Dockerfile(File dockerFile) { this.dockerFile = dockerFile; + if (!baseDirectory.exists()) { + throw new IllegalStateException(String.format("Base directory %s does not exist", baseDirectory.getAbsolutePath())); + } + + if (!baseDirectory.isDirectory()) { + throw new IllegalStateException(String.format("Base directory %s is not a directory", baseDirectory.getAbsolutePath())); + } + + this.baseDirectory = baseDirectory; } private static class LineTransformer implements Function> { @@ -76,7 +86,7 @@ public Iterable getStatements() throws IOException { public List getIgnores() throws IOException { List ignores = new ArrayList(); - File dockerIgnoreFile = new File(getDockerFolder(), ".dockerignore"); + File dockerIgnoreFile = new File(baseDirectory, ".dockerignore"); if (dockerIgnoreFile.exists()) { int lineNumber = 0; List dockerIgnoreFileContent = FileUtils.readLines(dockerIgnoreFile); @@ -102,10 +112,6 @@ public ScannedResult parse() throws IOException { return new ScannedResult(); } - public File getDockerFolder() { - return dockerFile.getParentFile(); - } - /** * Result of scanning / parsing a docker file. */ @@ -116,7 +122,7 @@ public class ScannedResult { final List filesToAdd = new ArrayList(); public InputStream buildDockerFolderTar() { - return buildDockerFolderTar(getDockerFolder()); + return buildDockerFolderTar(baseDirectory); } public InputStream buildDockerFolderTar(File directory) { @@ -180,7 +186,7 @@ public ScannedResult() throws IOException { "Dockerfile is excluded by pattern '%s' in .dockerignore file", matchingIgnorePattern)); } - Collection filesInBuildContext = FileUtils.listFiles(getDockerFolder(), TrueFileFilter.INSTANCE, + Collection filesInBuildContext = FileUtils.listFiles(baseDirectory, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE); for (File f : filesInBuildContext) { @@ -217,7 +223,7 @@ private List matchingIgnorePatterns(String fileName) { * will be respected. */ private String effectiveMatchingIgnorePattern(File file) { - String relativeFilename = FilePathUtil.relativize(getDockerFolder(), file); + String relativeFilename = FilePathUtil.relativize(baseDirectory, file); List matchingPattern = matchingIgnorePatterns(relativeFilename); @@ -242,6 +248,6 @@ private String effectiveMatchingIgnorePattern(File file) { } return lastMatchingPattern; - } + } } } 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 c0dc967d4..950b80a24 100644 --- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java @@ -24,16 +24,15 @@ import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; -import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.api.command.BuildImageCmd; import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.command.InspectImageResponse; +import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.api.model.AuthConfig; import com.github.dockerjava.api.model.AuthConfigurations; import com.github.dockerjava.api.model.ExposedPort; import com.github.dockerjava.api.model.PortBinding; -import com.github.dockerjava.api.model.Ports; import com.github.dockerjava.api.model.Ports.Binding; import com.github.dockerjava.client.AbstractDockerClientTest; import com.github.dockerjava.core.util.CompressArchiveUtil; @@ -319,4 +318,20 @@ public void testBuildArgs() throws Exception { assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc")); } + + public void testDockerfileNotInBaseDirectory() throws Exception { + File baseDirectory = getResource("testDockerfileNotInBaseDirectory"); + File dockerfile = getResource("testDockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile"); + BuildImageCmd command = dockerClient.buildImageCmd() + .withBaseDirectory(baseDirectory) + .withDockerfile(dockerfile); + + String response = execBuild(command); + + assertThat(response, containsString("Successfully executed testrun.sh")); + } + + private File getResource(String path) { + return new File(Thread.currentThread().getContextClassLoader().getResource(path).getFile()); + } } diff --git a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java index 0752aded5..8997a6d80 100644 --- a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java +++ b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java @@ -29,7 +29,7 @@ public String apply(File file) { public void testAddMultipleFiles() throws IOException { File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddMultipleFiles") .getFile()); - Dockerfile dockerfile = new Dockerfile(new File(baseDir, "Dockerfile")); + Dockerfile dockerfile = new Dockerfile(new File(baseDir, "Dockerfile"), baseDir); Dockerfile.ScannedResult result = dockerfile.parse(); Collection filesToAdd = transform(result.filesToAdd, TO_FILE_NAMES); diff --git a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileTest.java b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileTest.java index ba96ad2eb..390bcf647 100644 --- a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileTest.java +++ b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileTest.java @@ -26,7 +26,7 @@ public void testAllItems() throws IOException { for (File child : root.listFiles()) { if (new File(child, "Dockerfile").exists()) { - Dockerfile dockerfile = new Dockerfile(new File(child, "Dockerfile")); + Dockerfile dockerfile = new Dockerfile(new File(child, "Dockerfile"), baseDir); dockerfiles.put(child.getName(), dockerfile); } } diff --git a/src/test/resources/testDockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile b/src/test/resources/testDockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile new file mode 100644 index 000000000..9bf10088b --- /dev/null +++ b/src/test/resources/testDockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile @@ -0,0 +1,7 @@ +FROM ubuntu:latest + +ADD testrunFolder/testrun.sh /tmp/ + +RUN cp /tmp/testrun.sh /usr/local/bin/ && chmod +x /usr/local/bin/testrun.sh + +CMD ["testrun.sh"] \ No newline at end of file diff --git a/src/test/resources/testDockerfileNotInBaseDirectory/testrunFolder/testrun.sh b/src/test/resources/testDockerfileNotInBaseDirectory/testrunFolder/testrun.sh new file mode 100755 index 000000000..14259aa77 --- /dev/null +++ b/src/test/resources/testDockerfileNotInBaseDirectory/testrunFolder/testrun.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +echo "Successfully executed testrun.sh" \ No newline at end of file From f6edaaad38a3c0451f3c6d923a27e3592fca830f Mon Sep 17 00:00:00 2001 From: "Ciro S. Costa" Date: Thu, 12 May 2016 13:47:10 -0300 Subject: [PATCH 121/855] Adds namefilteer to netty's ListimagesCmdExec Previously just jaxrs had implemented the feature of filtering by image name. Even though the `withFilter` was exposed, netty's implemntation didn't checked for its presence. The commits adds a test for such feature and the correctionn to the mentioned problem. --- .../dockerjava/netty/exec/ListImagesCmdExec.java | 4 ++++ .../dockerjava/netty/exec/ListImagesCmdExecTest.java | 12 ++++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/main/java/com/github/dockerjava/netty/exec/ListImagesCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/ListImagesCmdExec.java index 0d1b81962..a1a38add5 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/ListImagesCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/ListImagesCmdExec.java @@ -33,6 +33,10 @@ protected List execute(ListImagesCmd command) { webTarget = webTarget.queryParam("filters", urlPathSegmentEscaper().escape(FiltersEncoder.jsonEncode(command.getFilters()))); } + if (command.getImageNameFilter() != null) { + webTarget = webTarget.queryParam("filter", urlPathSegmentEscaper().escape(command.getImageNameFilter())); + } + LOGGER.trace("GET: {}", webTarget); List images = webTarget.request().accept(MediaType.APPLICATION_JSON) diff --git a/src/test/java/com/github/dockerjava/netty/exec/ListImagesCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ListImagesCmdExecTest.java index c83fa7ef9..170a8479f 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/ListImagesCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/ListImagesCmdExecTest.java @@ -75,6 +75,18 @@ public void listImagesWithDanglingFilter() throws DockerException { assertTrue(imageInFilteredList); } + @Test + public void listImagesWithNameFilter() throws DockerException { + String imageId = createDanglingImage(); + dockerClient.tagImageCmd(imageId, "test_repository", "latest").exec(); + List images = dockerClient.listImagesCmd().withImageNameFilter("test_repository:latest").exec(); + assertThat(images, notNullValue()); + LOG.info("Images List: {}", images); + assertThat(images.size(), is(equalTo(1))); + Boolean imageInFilteredList = isImageInFilteredList(images, imageId); + assertTrue(imageInFilteredList); + } + private boolean isImageInFilteredList(List images, String expectedImageId) { for (Image image : images) { if (expectedImageId.equals(image.getId())) { From 7ab0418022e9a1591c8c76c2213e946c58914b91 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Thu, 12 May 2016 19:35:25 +0200 Subject: [PATCH 122/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e93dd737..242d575f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Notes All changes +* [#578] (https://github.com/docker-java/docker-java/pull/578) Fix error during image build when Dockerfile in subdirectory of build context * [#575] (https://github.com/docker-java/docker-java/pull/575) Support binding of port ranges * [#574] (https://github.com/docker-java/docker-java/pull/574) Fix for copyArchiveToContainerCmd bug * [#563] (https://github.com/docker-java/docker-java/pull/563) Fix memory leak in netty implementation of DockerCmdExecFactory From 0533459c533bf58ff3fcd66603849f7589d62cf7 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Thu, 12 May 2016 20:13:39 +0200 Subject: [PATCH 123/855] Polish inspect container with rootFS size --- .../com/github/dockerjava/api/command/InspectContainerCmd.java | 2 +- .../dockerjava/core/command/InspectContainerCmdImpl.java | 2 +- .../com/github/dockerjava/jaxrs/InspectContainerCmdExec.java | 3 ++- .../github/dockerjava/netty/exec/InspectContainerCmdExec.java | 2 ++ 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java index c0f666fa3..bbb0159f8 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectContainerCmd.java @@ -14,7 +14,7 @@ public interface InspectContainerCmd extends SyncDockerCmd() { From d4b3be163fc8fc01a2c16d578eda1a7eeebd9fa4 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Thu, 12 May 2016 20:15:32 +0200 Subject: [PATCH 124/855] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 242d575f3..44358e876 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,10 @@ Notes All changes -* [#578] (https://github.com/docker-java/docker-java/pull/578) Fix error during image build when Dockerfile in subdirectory of build context +* [#578] (https://github.com/docker-java/docker-java/pull/578) Fix error during image build when Dockerfile in subdirectory of build context * [#575] (https://github.com/docker-java/docker-java/pull/575) Support binding of port ranges * [#574] (https://github.com/docker-java/docker-java/pull/574) Fix for copyArchiveToContainerCmd bug +* [#572] (https://github.com/docker-java/docker-java/pull/572) Inspect container command now shows sizes if requested * [#563] (https://github.com/docker-java/docker-java/pull/563) Fix memory leak in netty implementation of DockerCmdExecFactory Included in 3.0.0-RC5 From 763559fbfa371d40bc96d3955d4fd8562718c090 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Thu, 12 May 2016 21:04:58 +0200 Subject: [PATCH 125/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 44358e876..ad9ddbba7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ All changes * [#574] (https://github.com/docker-java/docker-java/pull/574) Fix for copyArchiveToContainerCmd bug * [#572] (https://github.com/docker-java/docker-java/pull/572) Inspect container command now shows sizes if requested * [#563] (https://github.com/docker-java/docker-java/pull/563) Fix memory leak in netty implementation of DockerCmdExecFactory +* [#550] (https://github.com/docker-java/docker-java/pull/550) Add ability to configure IPAM config for CreateNetworkCmd Included in 3.0.0-RC5 From e0d418b401308fe24814b249944036be01b4affd Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Thu, 12 May 2016 23:53:57 +0200 Subject: [PATCH 126/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad9ddbba7..75f0f9dc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Notes All changes +* [#579] (https://github.com/docker-java/docker-java/pull/579) Adds missing name filter evaluation to netty version of ListImagesCmdExec * [#578] (https://github.com/docker-java/docker-java/pull/578) Fix error during image build when Dockerfile in subdirectory of build context * [#575] (https://github.com/docker-java/docker-java/pull/575) Support binding of port ranges * [#574] (https://github.com/docker-java/docker-java/pull/574) Fix for copyArchiveToContainerCmd bug From f4dc5637965064c8627137c08511dfc2a84b2aec Mon Sep 17 00:00:00 2001 From: Lappas Dionysis Date: Sat, 14 May 2016 23:58:45 +0300 Subject: [PATCH 127/855] Fixes execute permissions for files inside a dir added to tar using copyArchiveToContainerCmdIml. Files added to tar are stored with 644 permission mode. As a result, execute permissions are discarded. This fix retains permissions for files inside directories copied with copyArchiveToContainerCmdIml. --- .../java/com/github/dockerjava/core/util/TarDirWalker.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java b/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java index af263ee9c..3c5336a28 100644 --- a/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java +++ b/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java @@ -33,8 +33,11 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - CompressArchiveUtil.putTarEntry(tarArchiveOutputStream, - new TarArchiveEntry(FilePathUtil.relativize(basePath, file)), file); + TarArchiveEntry tarEntry = new TarArchiveEntry(FilePathUtil.relativize(basePath, file)); + if (filePath.toFile().canExecute()) { + tarEntry.setMode(tarEntry.getMode() | 0755); + } + CompressArchiveUtil.putTarEntry(tarArchiveOutputStream, tarEntry, file); return FileVisitResult.CONTINUE; } From e229005fd43e9e8d89d52f115ad096947cfd6b14 Mon Sep 17 00:00:00 2001 From: Lappas Dionysis Date: Sun, 15 May 2016 00:02:44 +0300 Subject: [PATCH 128/855] Fixes execute permissions for files not contained in any dir that are added to tar using copyArchiveToContainerCmdIml. --- .../github/dockerjava/core/util/CompressArchiveUtil.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/core/util/CompressArchiveUtil.java b/src/main/java/com/github/dockerjava/core/util/CompressArchiveUtil.java index 5052dda40..a4616514e 100644 --- a/src/main/java/com/github/dockerjava/core/util/CompressArchiveUtil.java +++ b/src/main/java/com/github/dockerjava/core/util/CompressArchiveUtil.java @@ -67,7 +67,11 @@ public static void tar(Path inputPath, Path outputPath, boolean gZipped, boolean try (TarArchiveOutputStream tarArchiveOutputStream = buildTarStream(outputPath, gZipped)) { if (!Files.isDirectory(inputPath)) { - putTarEntry(tarArchiveOutputStream, new TarArchiveEntry(inputPath.getFileName().toString()), inputPath); + TarArchiveEntry tarEntry = new TarArchiveEntry(inputPath.getFileName().toString()); + if (filePath.toFile().canExecute()) { + tarEntry.setMode(tarEntry.getMode() | 0755); + } + putTarEntry(tarArchiveOutputStream, tarEntry, inputPath); } else { Path sourcePath = inputPath; if (!childrenOnly) { From cc93a1fb54bea392cf0c2da5c82ab190a2f921bd Mon Sep 17 00:00:00 2001 From: Lappas Dionysis Date: Sun, 15 May 2016 01:15:58 +0300 Subject: [PATCH 129/855] Added Test Case for CopyArchiveToContainerCmdImpl when copying files with execute permission. Test Case that simulates a scenario where a script file with permission to execute is copied to the containers with CopyArchiveToContainerCmdImpl and then it is executed. --- .../CopyArchiveToContainerCmdImplTest.java | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java index 06967706f..04117aba7 100644 --- a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java @@ -3,6 +3,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.isEmptyOrNullString; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.equalTo; import java.io.IOException; import java.io.InputStream; @@ -117,5 +118,39 @@ public void copyDirWithLastAddedTarEnryEmptyDir() throws Exception{ .withHostResource(localDir.toString()) .exec(); } + + @Test + public void copyFileWithExecutePermission() throws Exception { + // create script file, add permission to execute + scriptPath = Files.createTempFile("run", ".sh"); + boolean executable = scriptPath.toFile().setExecutable(true, false); + if (!executable){ + throw new Exception("Execute permission on file not set!"); + } + String snippet = "Running script with execute permission."; + String scriptTextStr = "#!/bin/sh\necho \"" + snippet + "\""; + // write content for created script + Files.write(scriptPath, scriptTextStr.getBytes()); + // create a test container which starts and waits 3 seconds for the + // script to be copied to the container's home dir and then executes it + String containerCmd = "sleep 3; /home/" + scriptPath.getFileName().toString(); + CreateContainerResponse container = docker.createContainerCmd("busybox") + .withName("test") + .withCmd("/bin/sh", "-c", containerCmd) + .exec(); + // start the container + docker.startContainerCmd(container.getId()).exec(); + // copy script to container home dir + docker.copyArchiveToContainerCmd(container.getId()) + .withRemotePath("/home") + .withHostResource(scriptPath.toString()) + .exec(); + // await exid code + int exitCode = docker.waitContainerCmd(container.getId()) + .exec(new WaitContainerResultCallback()) + .awaitStatusCode(); + // check result + assertThat(exitCode, equalTo(0)); + } } From d3918c3ff3e17dbb4cf3442bae0aa1b22c8ef857 Mon Sep 17 00:00:00 2001 From: Lappas Dionysis Date: Sun, 15 May 2016 01:52:35 +0300 Subject: [PATCH 130/855] Fixed input file name --- .../com/github/dockerjava/core/util/CompressArchiveUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/core/util/CompressArchiveUtil.java b/src/main/java/com/github/dockerjava/core/util/CompressArchiveUtil.java index a4616514e..2e75bcc41 100644 --- a/src/main/java/com/github/dockerjava/core/util/CompressArchiveUtil.java +++ b/src/main/java/com/github/dockerjava/core/util/CompressArchiveUtil.java @@ -68,7 +68,7 @@ public static void tar(Path inputPath, Path outputPath, boolean gZipped, boolean try (TarArchiveOutputStream tarArchiveOutputStream = buildTarStream(outputPath, gZipped)) { if (!Files.isDirectory(inputPath)) { TarArchiveEntry tarEntry = new TarArchiveEntry(inputPath.getFileName().toString()); - if (filePath.toFile().canExecute()) { + if (inputPath.toFile().canExecute()) { tarEntry.setMode(tarEntry.getMode() | 0755); } putTarEntry(tarArchiveOutputStream, tarEntry, inputPath); From c93a1fca4a062a7d90d361c061aa3a6a2edf6057 Mon Sep 17 00:00:00 2001 From: Lappas Dionysis Date: Sun, 15 May 2016 01:55:10 +0300 Subject: [PATCH 131/855] Fixed name for variable --- src/main/java/com/github/dockerjava/core/util/TarDirWalker.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java b/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java index 3c5336a28..bbe834ee6 100644 --- a/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java +++ b/src/main/java/com/github/dockerjava/core/util/TarDirWalker.java @@ -34,7 +34,7 @@ public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) th @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { TarArchiveEntry tarEntry = new TarArchiveEntry(FilePathUtil.relativize(basePath, file)); - if (filePath.toFile().canExecute()) { + if (file.toFile().canExecute()) { tarEntry.setMode(tarEntry.getMode() | 0755); } CompressArchiveUtil.putTarEntry(tarArchiveOutputStream, tarEntry, file); From 7ee187b7ee025ac2a798842f1db06ea198ad6666 Mon Sep 17 00:00:00 2001 From: Lappas Dionysis Date: Sun, 15 May 2016 02:01:14 +0300 Subject: [PATCH 132/855] Added missing variable type declaration --- .../core/command/CopyArchiveToContainerCmdImplTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java index 04117aba7..a1652456e 100644 --- a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java @@ -122,7 +122,7 @@ public void copyDirWithLastAddedTarEnryEmptyDir() throws Exception{ @Test public void copyFileWithExecutePermission() throws Exception { // create script file, add permission to execute - scriptPath = Files.createTempFile("run", ".sh"); + Path scriptPath = Files.createTempFile("run", ".sh"); boolean executable = scriptPath.toFile().setExecutable(true, false); if (!executable){ throw new Exception("Execute permission on file not set!"); From 381b7db28fd1007dea34b491c57fcd2ba8108591 Mon Sep 17 00:00:00 2001 From: Lappas Dionysis Date: Sun, 15 May 2016 02:07:25 +0300 Subject: [PATCH 133/855] Fixed docker client name --- .../core/command/CopyArchiveToContainerCmdImplTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java index a1652456e..d96a6ad25 100644 --- a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java @@ -134,19 +134,19 @@ public void copyFileWithExecutePermission() throws Exception { // create a test container which starts and waits 3 seconds for the // script to be copied to the container's home dir and then executes it String containerCmd = "sleep 3; /home/" + scriptPath.getFileName().toString(); - CreateContainerResponse container = docker.createContainerCmd("busybox") + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") .withName("test") .withCmd("/bin/sh", "-c", containerCmd) .exec(); // start the container - docker.startContainerCmd(container.getId()).exec(); + dockerClient.startContainerCmd(container.getId()).exec(); // copy script to container home dir - docker.copyArchiveToContainerCmd(container.getId()) + dockerClient.copyArchiveToContainerCmd(container.getId()) .withRemotePath("/home") .withHostResource(scriptPath.toString()) .exec(); // await exid code - int exitCode = docker.waitContainerCmd(container.getId()) + int exitCode = dockerClient.waitContainerCmd(container.getId()) .exec(new WaitContainerResultCallback()) .awaitStatusCode(); // check result From 328cd6745af14f57c43b948eaa742d1424ace50a Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Tue, 24 May 2016 20:58:51 +0200 Subject: [PATCH 134/855] Add test for netty impl --- .../CopyArchiveToContainerCmdExecTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java index 9e9b0c731..eb43b54de 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java @@ -1,6 +1,7 @@ package com.github.dockerjava.netty.exec; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.isEmptyOrNullString; import static org.hamcrest.Matchers.not; @@ -21,6 +22,7 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.core.command.WaitContainerResultCallback; import com.github.dockerjava.core.util.CompressArchiveUtil; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; @@ -119,4 +121,38 @@ public void copyDirWithLastAddedTarEntryEmptyDir() throws Exception{ FileUtils.deleteDirectory(localDir.toFile()); } + @Test + public void copyFileWithExecutePermission() throws Exception { + // create script file, add permission to execute + Path scriptPath = Files.createTempFile("run", ".sh"); + boolean executable = scriptPath.toFile().setExecutable(true, false); + if (!executable){ + throw new Exception("Execute permission on file not set!"); + } + String snippet = "Running script with execute permission."; + String scriptTextStr = "#!/bin/sh\necho \"" + snippet + "\""; + // write content for created script + Files.write(scriptPath, scriptTextStr.getBytes()); + // create a test container which starts and waits 3 seconds for the + // script to be copied to the container's home dir and then executes it + String containerCmd = "sleep 3; /home/" + scriptPath.getFileName().toString(); + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withName("test") + .withCmd("/bin/sh", "-c", containerCmd) + .exec(); + // start the container + dockerClient.startContainerCmd(container.getId()).exec(); + // copy script to container home dir + dockerClient.copyArchiveToContainerCmd(container.getId()) + .withRemotePath("/home") + .withHostResource(scriptPath.toString()) + .exec(); + // await exid code + int exitCode = dockerClient.waitContainerCmd(container.getId()) + .exec(new WaitContainerResultCallback()) + .awaitStatusCode(); + // check result + assertThat(exitCode, equalTo(0)); + } + } From 0758623f4763fe4e45618beba5c0233874e2266e Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Tue, 24 May 2016 20:59:41 +0200 Subject: [PATCH 135/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75f0f9dc7..429f4b275 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Notes All changes +* [#580] (https://github.com/docker-java/docker-java/pull/580) Fixes execute permissions for files when copied to container * [#579] (https://github.com/docker-java/docker-java/pull/579) Adds missing name filter evaluation to netty version of ListImagesCmdExec * [#578] (https://github.com/docker-java/docker-java/pull/578) Fix error during image build when Dockerfile in subdirectory of build context * [#575] (https://github.com/docker-java/docker-java/pull/575) Support binding of port ranges From a1d1e3dfda7a2ade9304c990f73d42aa573ef342 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Tue, 24 May 2016 14:19:28 -0600 Subject: [PATCH 136/855] Fixes Issue #584 Adds RootDir property to GraphData. This was seen on a CentOS system without aufs support. --- .../dockerjava/api/command/GraphData.java | 26 ++- .../api/command/InspectImageResponseTest.java | 197 +++++++++--------- 2 files changed, 122 insertions(+), 101 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/GraphData.java b/src/main/java/com/github/dockerjava/api/command/GraphData.java index dc55810ba..a00f44e5d 100644 --- a/src/main/java/com/github/dockerjava/api/command/GraphData.java +++ b/src/main/java/com/github/dockerjava/api/command/GraphData.java @@ -1,17 +1,23 @@ package com.github.dockerjava.api.command; -import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.CheckForNull; + import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; -import javax.annotation.CheckForNull; +import com.fasterxml.jackson.annotation.JsonProperty; /** * part of {@link GraphDriver} + * * @author Kanstantsin Shautsou */ public class GraphData { + + @JsonProperty("RootDir") + private String rootDir; + @JsonProperty("DeviceId") private String deviceId; @@ -21,6 +27,22 @@ public class GraphData { @JsonProperty("DeviceSize") private String deviceSize; + /** + * @see #rootDir + */ + @CheckForNull + public String getRootDir() { + return rootDir; + } + + /** + * @see #deviceId + */ + public GraphData withRootDir(String rootDir) { + this.rootDir = rootDir; + return this; + } + /** * @see #deviceId */ diff --git a/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java b/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java index 410d5b32a..e7cd2aaa8 100644 --- a/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java +++ b/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java @@ -1,13 +1,5 @@ package com.github.dockerjava.api.command; -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.dockerjava.api.model.ContainerConfig; -import org.testng.annotations.Test; - -import java.io.IOException; -import java.util.Collections; - import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_22; import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; import static org.hamcrest.MatcherAssert.assertThat; @@ -21,65 +13,72 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; +import java.io.IOException; +import java.util.Collections; + +import org.testng.annotations.Test; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.api.model.ContainerConfig; + /** * @author Kanstantsin Shautsou */ public class InspectImageResponseTest { + @Test public void serder1_22Json() throws IOException { final ObjectMapper mapper = new ObjectMapper(); final JavaType type = mapper.getTypeFactory().constructType(InspectImageResponse.class); - final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, - "images/image1/inspect1.json", - type - ); - - final ContainerConfig config = new ContainerConfig() - .withAttachStderr(false) - .withAttachStdin(false) - .withAttachStdout(false) - .withCmd(null) - .withDomainName("") - .withEntrypoint(null) - .withEnv(new String[]{"HOME=/", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}) - .withExposedPorts(null) - .withHostName("aee9ba801acc") - .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") - .withLabels(null) - .withMacAddress(null) - .withNetworkDisabled(null) - .withOnBuild(new String[]{}) - .withStdinOpen(false) - .withPortSpecs(null) - .withStdInOnce(false) - .withTty(false) - .withUser("") - .withVolumes(null) - .withWorkingDir(""); - - final ContainerConfig containerConfig = new ContainerConfig() - .withAttachStderr(false) - .withAttachStdin(false) - .withAttachStdout(false) - .withCmd(new String[]{"/bin/sh", "-c", "#(nop) MAINTAINER hack@worldticket.net"}) - .withDomainName("") - .withEntrypoint(null) - .withEnv(new String[]{"HOME=/", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}) - .withExposedPorts(null) - .withHostName("aee9ba801acc") - .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") - .withLabels(null) - .withMacAddress(null) - .withNetworkDisabled(null) - .withOnBuild(new String[]{}) - .withStdinOpen(false) - .withPortSpecs(null) - .withStdInOnce(false) - .withTty(false) - .withUser("") - .withVolumes(null) - .withWorkingDir(""); + final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, "images/image1/inspect1.json", type); + + final ContainerConfig config = new ContainerConfig().withAttachStderr(false) + .withAttachStdin(false) + .withAttachStdout(false) + .withCmd(null) + .withDomainName("") + .withEntrypoint(null) + .withEnv(new String[] { "HOME=/", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" }) + .withExposedPorts(null) + .withHostName("aee9ba801acc") + .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") + .withLabels(null) + .withMacAddress(null) + .withNetworkDisabled(null) + .withOnBuild(new String[] {}) + .withStdinOpen(false) + .withPortSpecs(null) + .withStdInOnce(false) + .withTty(false) + .withUser("") + .withVolumes(null) + .withWorkingDir(""); + + final ContainerConfig containerConfig = new ContainerConfig().withAttachStderr(false) + .withAttachStdin(false) + .withAttachStdout(false) + .withCmd(new String[] { "/bin/sh", "-c", "#(nop) MAINTAINER hack@worldticket.net" }) + .withDomainName("") + .withEntrypoint(null) + .withEnv(new String[] { "HOME=/", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" }) + .withExposedPorts(null) + .withHostName("aee9ba801acc") + .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") + .withLabels(null) + .withMacAddress(null) + .withNetworkDisabled(null) + .withOnBuild(new String[] {}) + .withStdinOpen(false) + .withPortSpecs(null) + .withStdInOnce(false) + .withTty(false) + .withUser("") + .withVolumes(null) + .withWorkingDir(""); assertThat(inspectImage, notNullValue()); assertThat(inspectImage.getArch(), is("amd64")); @@ -113,52 +112,41 @@ public void serder1_22Json() throws IOException { assertThat(inspectImage.getVirtualSize(), is(0L)); - final InspectImageResponse inspectImageResponse = new InspectImageResponse().withArch("amd64") - .withAuthor("hack@worldticket.net") - .withComment("") - .withConfig(config) - .withContainer("aee9ba801acca0e648ffd91df204ba82ae85d97608a4864a019e2004d7e1b133") - .withContainerConfig(containerConfig) - .withCreated("2014-04-29T19:59:10.84997669Z") - .withDockerVersion("0.8.1") - .withId("sha256:ee45fe0d1fcdf1a0f9c2d1e36c6f4b3202bbb2032f14d7c9312b27bfcf6aee24") - .withOs("linux") - .withParent("") - .withSize(0L) - .withRepoTags(Collections.singletonList("hackmann/empty:latest")) - .withRepoDigests(Collections.emptyList()) - .withVirtualSize(0L) - .withGraphDriver(aufsGraphDriver); + .withAuthor("hack@worldticket.net") + .withComment("") + .withConfig(config) + .withContainer("aee9ba801acca0e648ffd91df204ba82ae85d97608a4864a019e2004d7e1b133") + .withContainerConfig(containerConfig) + .withCreated("2014-04-29T19:59:10.84997669Z") + .withDockerVersion("0.8.1") + .withId("sha256:ee45fe0d1fcdf1a0f9c2d1e36c6f4b3202bbb2032f14d7c9312b27bfcf6aee24") + .withOs("linux") + .withParent("") + .withSize(0L) + .withRepoTags(Collections.singletonList("hackmann/empty:latest")) + .withRepoDigests(Collections. emptyList()) + .withVirtualSize(0L) + .withGraphDriver(aufsGraphDriver); assertThat(inspectImage, equalTo(inspectImageResponse)); } - @Test public void serder1_22_doc() throws IOException { final ObjectMapper mapper = new ObjectMapper(); final JavaType type = mapper.getTypeFactory().constructType(InspectImageResponse.class); - final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, - "images/docImage/doc.json", - type - ); + final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, "images/docImage/doc.json", type); assertThat(inspectImage, notNullValue()); assertThat(inspectImage.getRepoDigests(), hasSize(1)); assertThat(inspectImage.getRepoDigests(), - contains("localhost:5000/test/busybox/example@" + - "sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf") - ); + contains("localhost:5000/test/busybox/example@" + "sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf")); assertThat(inspectImage.getRepoTags(), hasSize(3)); - assertThat(inspectImage.getRepoTags(), containsInAnyOrder( - "example:1.0", - "example:latest", - "example:stable" - )); + assertThat(inspectImage.getRepoTags(), containsInAnyOrder("example:1.0", "example:latest", "example:stable")); } @Test @@ -166,15 +154,11 @@ public void serder1_22_inspect_doc() throws IOException { final ObjectMapper mapper = new ObjectMapper(); final JavaType type = mapper.getTypeFactory().constructType(InspectImageResponse.class); - final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, - "images/docImage/inspect_doc.json", - type - ); + final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, "images/docImage/inspect_doc.json", type); - GraphData newGraphData = new GraphData() - .withDeviceId("5") - .withDeviceName("docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47") - .withDeviceSize("171798691840"); + GraphData newGraphData = new GraphData().withDeviceId("5") + .withDeviceName("docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47") + .withDeviceSize("171798691840"); assertThat(inspectImage, notNullValue()); GraphDriver graphDriver = inspectImage.getGraphDriver(); @@ -184,9 +168,24 @@ public void serder1_22_inspect_doc() throws IOException { assertThat(data, is(newGraphData)); assertThat(data.getDeviceId(), is("5")); - assertThat(data.getDeviceName(), - is("docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47")); - assertThat(data.getDeviceSize(), - is("171798691840")); + assertThat(data.getDeviceName(), is("docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47")); + assertThat(data.getDeviceSize(), is("171798691840")); + } + + @Test + private void testOverlayNetworkRootDir() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().constructType(InspectImageResponse.class); + + final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, "images/overlay/inspectOverlay.json", type); + + final GraphData overlayGraphData = new GraphData().withRootDir("/var/lib/docker/overlay/7e8d362d6b78d47eafe4863fd129cbcada35dbd419d7188cc1dbf1233d505576/root"); + final GraphDriver overlayGraphDriver = new GraphDriver().withName("overlay").withData(overlayGraphData); + final GraphDriver graphDriver = inspectImage.getGraphDriver(); + assertThat(graphDriver, notNullValue()); + assertThat(graphDriver, equalTo(overlayGraphDriver)); + assertThat(graphDriver.getName(), is("overlay")); + assertThat(graphDriver.getData(), equalTo(overlayGraphData)); + } } \ No newline at end of file From 3f71f1f165d652ceb044151c9abea2b1707d56c9 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Tue, 24 May 2016 14:19:28 -0600 Subject: [PATCH 137/855] Fixes Issue #584 Adds RootDir property to GraphData. This was seen on a CentOS system without aufs support. --- .../api/command/InspectImageResponseTest.java | 128 +++++++++--------- .../1.22/images/overlay/inspectOverlay.json | 93 +++++++++++++ 2 files changed, 157 insertions(+), 64 deletions(-) create mode 100644 src/test/resources/samples/1.22/images/overlay/inspectOverlay.json diff --git a/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java b/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java index e7cd2aaa8..5bce25a48 100644 --- a/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java +++ b/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java @@ -34,51 +34,49 @@ public void serder1_22Json() throws IOException { final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, "images/image1/inspect1.json", type); - final ContainerConfig config = new ContainerConfig().withAttachStderr(false) - .withAttachStdin(false) - .withAttachStdout(false) - .withCmd(null) - .withDomainName("") - .withEntrypoint(null) - .withEnv(new String[] { "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" }) - .withExposedPorts(null) - .withHostName("aee9ba801acc") - .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") - .withLabels(null) - .withMacAddress(null) - .withNetworkDisabled(null) - .withOnBuild(new String[] {}) - .withStdinOpen(false) - .withPortSpecs(null) - .withStdInOnce(false) - .withTty(false) - .withUser("") - .withVolumes(null) - .withWorkingDir(""); + final ContainerConfig config = new ContainerConfig().withAttachStdout(false) + .withCmd(null) + .withDomainName("") + .withEntrypoint(null) + .withEnv(new String[] {"HOME=/", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}) + .withExposedPorts(null) + .withHostName("aee9ba801acc") + .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") + .withLabels(null) + .withMacAddress(null) + .withNetworkDisabled(null) + .withOnBuild(new String[] {}) + .withStdinOpen(false) + .withPortSpecs(null) + .withStdInOnce(false) + .withTty(false) + .withUser("") + .withVolumes(null) + .withWorkingDir(""); final ContainerConfig containerConfig = new ContainerConfig().withAttachStderr(false) - .withAttachStdin(false) - .withAttachStdout(false) - .withCmd(new String[] { "/bin/sh", "-c", "#(nop) MAINTAINER hack@worldticket.net" }) - .withDomainName("") - .withEntrypoint(null) - .withEnv(new String[] { "HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" }) - .withExposedPorts(null) - .withHostName("aee9ba801acc") - .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") - .withLabels(null) - .withMacAddress(null) - .withNetworkDisabled(null) - .withOnBuild(new String[] {}) - .withStdinOpen(false) - .withPortSpecs(null) - .withStdInOnce(false) - .withTty(false) - .withUser("") - .withVolumes(null) - .withWorkingDir(""); + .withAttachStdin(false) + .withAttachStdout(false) + .withCmd(new String[] {"/bin/sh", "-c", "#(nop) MAINTAINER hack@worldticket.net"}) + .withDomainName("") + .withEntrypoint(null) + .withEnv(new String[] {"HOME=/", + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}) + .withExposedPorts(null) + .withHostName("aee9ba801acc") + .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") + .withLabels(null) + .withMacAddress(null) + .withNetworkDisabled(null) + .withOnBuild(new String[] {}) + .withStdinOpen(false) + .withPortSpecs(null) + .withStdInOnce(false) + .withTty(false) + .withUser("") + .withVolumes(null) + .withWorkingDir(""); assertThat(inspectImage, notNullValue()); assertThat(inspectImage.getArch(), is("amd64")); @@ -113,21 +111,21 @@ public void serder1_22Json() throws IOException { assertThat(inspectImage.getVirtualSize(), is(0L)); final InspectImageResponse inspectImageResponse = new InspectImageResponse().withArch("amd64") - .withAuthor("hack@worldticket.net") - .withComment("") - .withConfig(config) - .withContainer("aee9ba801acca0e648ffd91df204ba82ae85d97608a4864a019e2004d7e1b133") - .withContainerConfig(containerConfig) - .withCreated("2014-04-29T19:59:10.84997669Z") - .withDockerVersion("0.8.1") - .withId("sha256:ee45fe0d1fcdf1a0f9c2d1e36c6f4b3202bbb2032f14d7c9312b27bfcf6aee24") - .withOs("linux") - .withParent("") - .withSize(0L) - .withRepoTags(Collections.singletonList("hackmann/empty:latest")) - .withRepoDigests(Collections. emptyList()) - .withVirtualSize(0L) - .withGraphDriver(aufsGraphDriver); + .withAuthor("hack@worldticket.net") + .withComment("") + .withConfig(config) + .withContainer("aee9ba801acca0e648ffd91df204ba82ae85d97608a4864a019e2004d7e1b133") + .withContainerConfig(containerConfig) + .withCreated("2014-04-29T19:59:10.84997669Z") + .withDockerVersion("0.8.1") + .withId("sha256:ee45fe0d1fcdf1a0f9c2d1e36c6f4b3202bbb2032f14d7c9312b27bfcf6aee24") + .withOs("linux") + .withParent("") + .withSize(0L) + .withRepoTags(Collections.singletonList("hackmann/empty:latest")) + .withRepoDigests(Collections. emptyList()) + .withVirtualSize(0L) + .withGraphDriver(aufsGraphDriver); assertThat(inspectImage, equalTo(inspectImageResponse)); } @@ -143,7 +141,9 @@ public void serder1_22_doc() throws IOException { assertThat(inspectImage.getRepoDigests(), hasSize(1)); assertThat(inspectImage.getRepoDigests(), - contains("localhost:5000/test/busybox/example@" + "sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf")); + + contains("localhost:5000/test/busybox/example@" + + "sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf")); assertThat(inspectImage.getRepoTags(), hasSize(3)); assertThat(inspectImage.getRepoTags(), containsInAnyOrder("example:1.0", "example:latest", "example:stable")); @@ -157,9 +157,8 @@ public void serder1_22_inspect_doc() throws IOException { final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, "images/docImage/inspect_doc.json", type); GraphData newGraphData = new GraphData().withDeviceId("5") - .withDeviceName("docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47") - .withDeviceSize("171798691840"); - + .withDeviceName("docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47") + .withDeviceSize("171798691840"); assertThat(inspectImage, notNullValue()); GraphDriver graphDriver = inspectImage.getGraphDriver(); assertThat(graphDriver, notNullValue()); @@ -179,7 +178,8 @@ private void testOverlayNetworkRootDir() throws IOException { final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, "images/overlay/inspectOverlay.json", type); - final GraphData overlayGraphData = new GraphData().withRootDir("/var/lib/docker/overlay/7e8d362d6b78d47eafe4863fd129cbcada35dbd419d7188cc1dbf1233d505576/root"); + final GraphData overlayGraphData = new GraphData() + .withRootDir("/var/lib/docker/overlay/7e8d362d6b78d47eafe4863fd129cbcada35dbd419d7188cc1dbf1233d505576/root"); final GraphDriver overlayGraphDriver = new GraphDriver().withName("overlay").withData(overlayGraphData); final GraphDriver graphDriver = inspectImage.getGraphDriver(); assertThat(graphDriver, notNullValue()); @@ -188,4 +188,4 @@ private void testOverlayNetworkRootDir() throws IOException { assertThat(graphDriver.getData(), equalTo(overlayGraphData)); } -} \ No newline at end of file +} diff --git a/src/test/resources/samples/1.22/images/overlay/inspectOverlay.json b/src/test/resources/samples/1.22/images/overlay/inspectOverlay.json new file mode 100644 index 000000000..7e3fe0bea --- /dev/null +++ b/src/test/resources/samples/1.22/images/overlay/inspectOverlay.json @@ -0,0 +1,93 @@ +{ + "Id": "sha256:0ac989a7cba2ce7f5fbe5d520b338e780055ec251371ee35f7462ae9944696c5", + "RepoTags": [ + "test-image:latest" + ], + "RepoDigests": [], + "Parent": "", + "Comment": "", + "Created": "2016-05-24T19:25:01.31608131Z", + "Container": "221f000eccdec85b74cd4f4f37c7c0392d0f620bee45e9618cac3e57409a6d2c", + "ContainerConfig": { + "Hostname": "6ea525e7ec5c", + "Domainname": "", + "User": "", + "AttachStdin": false, + "AttachStdout": false, + "AttachStderr": false, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ], + "Cmd": [ + "/bin/sh", + "-c", + "#(nop) ENTRYPOINT [\"bin/run.sh\"]" + ], + "Image": "sha256:f8321fac5b5484874c1c5c02719905ec815c8ad20c2bc66222cfde19cd0491b7", + "Volumes": { + "/var/lib/docker": {} + }, + "WorkingDir": "/opt", + "Entrypoint": [ + "bin/run.sh" + ], + "OnBuild": [], + "Labels": {} + }, + "DockerVersion": "1.11.1", + "Author": "", + "Config": { + "Hostname": "6ea525e7ec5c", + "Domainname": "", + "User": "", + "AttachStdin": false, + "AttachStdout": false, + "AttachStderr": false, + "Tty": false, + "OpenStdin": false, + "StdinOnce": false, + "Env": [ + "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + ], + "Cmd": null, + "Image": "sha256:f8321fac5b5484874c1c5c02719905ec815c8ad20c2bc66222cfde19cd0491b7", + "Volumes": { + "/var/lib/docker": {} + }, + "WorkingDir": "/opt", + "Entrypoint": [ + "bin/run.sh" + ], + "OnBuild": [], + "Labels": {} + }, + "Architecture": "amd64", + "Os": "linux", + "Size": 345943268, + "VirtualSize": 345943268, + "GraphDriver": { + "Name": "overlay", + "Data": { + "RootDir": "/var/lib/docker/overlay/7e8d362d6b78d47eafe4863fd129cbcada35dbd419d7188cc1dbf1233d505576/root" + } + }, + "RootFS": { + "Type": "layers", + "Layers": [ + "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", + "sha256:bd8153423e4131205018c431283e0a08298b291838db9bc6c19620523f5a818c", + "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", + "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", + "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", + "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", + "sha256:bb0716c3f5f5be1e5ee6912f7e9f44193898e0b3ed9031a0416f8ca262e89975", + "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef", + "sha256:58845ae9bfa7659900a9b30abb2c96330eff09bfbc6521ea77937ba60f8cc131", + "sha256:8c22161a61c24eb6f7aa130d45189354fd8dbe9467e5b2debf828908113eacb0", + "sha256:0c0c9045d2542e7845a2bdd8ead0e0fb2722be2c07c5553838dd61ffe051d672" + ] + } +} \ No newline at end of file From 9b8ca72947b771c6fbeda00d17b9382fed2c09a6 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Tue, 24 May 2016 14:19:28 -0600 Subject: [PATCH 138/855] Fixes Issue #584 Adds RootDir property to GraphData. This was seen on a CentOS system without aufs support. --- .../dockerjava/api/command/GraphData.java | 6 +- .../api/command/InspectImageResponseTest.java | 80 ++++++++++++------- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/GraphData.java b/src/main/java/com/github/dockerjava/api/command/GraphData.java index a00f44e5d..1aac8db84 100644 --- a/src/main/java/com/github/dockerjava/api/command/GraphData.java +++ b/src/main/java/com/github/dockerjava/api/command/GraphData.java @@ -1,16 +1,14 @@ package com.github.dockerjava.api.command; -import javax.annotation.CheckForNull; - +import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; -import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.CheckForNull; /** * part of {@link GraphDriver} - * * @author Kanstantsin Shautsou */ public class GraphData { diff --git a/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java b/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java index 5bce25a48..4c604e6a0 100644 --- a/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java +++ b/src/test/java/com/github/dockerjava/api/command/InspectImageResponseTest.java @@ -1,5 +1,13 @@ package com.github.dockerjava.api.command; +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.api.model.ContainerConfig; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.Collections; + import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_22; import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; import static org.hamcrest.MatcherAssert.assertThat; @@ -13,40 +21,35 @@ import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; -import java.io.IOException; -import java.util.Collections; - -import org.testng.annotations.Test; - -import com.fasterxml.jackson.databind.JavaType; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.github.dockerjava.api.model.ContainerConfig; - /** * @author Kanstantsin Shautsou */ public class InspectImageResponseTest { - @Test public void serder1_22Json() throws IOException { final ObjectMapper mapper = new ObjectMapper(); final JavaType type = mapper.getTypeFactory().constructType(InspectImageResponse.class); - final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, "images/image1/inspect1.json", type); + final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, + "images/image1/inspect1.json", + type + ); - final ContainerConfig config = new ContainerConfig().withAttachStdout(false) + final ContainerConfig config = new ContainerConfig() + .withAttachStderr(false) + .withAttachStdin(false) + .withAttachStdout(false) .withCmd(null) .withDomainName("") .withEntrypoint(null) - .withEnv(new String[] {"HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}) + .withEnv(new String[]{"HOME=/", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}) .withExposedPorts(null) .withHostName("aee9ba801acc") .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") .withLabels(null) .withMacAddress(null) .withNetworkDisabled(null) - .withOnBuild(new String[] {}) + .withOnBuild(new String[]{}) .withStdinOpen(false) .withPortSpecs(null) .withStdInOnce(false) @@ -55,21 +58,21 @@ public void serder1_22Json() throws IOException { .withVolumes(null) .withWorkingDir(""); - final ContainerConfig containerConfig = new ContainerConfig().withAttachStderr(false) + final ContainerConfig containerConfig = new ContainerConfig() + .withAttachStderr(false) .withAttachStdin(false) .withAttachStdout(false) - .withCmd(new String[] {"/bin/sh", "-c", "#(nop) MAINTAINER hack@worldticket.net"}) + .withCmd(new String[]{"/bin/sh", "-c", "#(nop) MAINTAINER hack@worldticket.net"}) .withDomainName("") .withEntrypoint(null) - .withEnv(new String[] {"HOME=/", - "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}) + .withEnv(new String[]{"HOME=/", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"}) .withExposedPorts(null) .withHostName("aee9ba801acc") .withImage("511136ea3c5a64f264b78b5433614aec563103b4d4702f3ba7d4d2698e22c158") .withLabels(null) .withMacAddress(null) .withNetworkDisabled(null) - .withOnBuild(new String[] {}) + .withOnBuild(new String[]{}) .withStdinOpen(false) .withPortSpecs(null) .withStdInOnce(false) @@ -110,6 +113,7 @@ public void serder1_22Json() throws IOException { assertThat(inspectImage.getVirtualSize(), is(0L)); + final InspectImageResponse inspectImageResponse = new InspectImageResponse().withArch("amd64") .withAuthor("hack@worldticket.net") .withComment("") @@ -123,30 +127,38 @@ public void serder1_22Json() throws IOException { .withParent("") .withSize(0L) .withRepoTags(Collections.singletonList("hackmann/empty:latest")) - .withRepoDigests(Collections. emptyList()) + .withRepoDigests(Collections.emptyList()) .withVirtualSize(0L) .withGraphDriver(aufsGraphDriver); assertThat(inspectImage, equalTo(inspectImageResponse)); } + @Test public void serder1_22_doc() throws IOException { final ObjectMapper mapper = new ObjectMapper(); final JavaType type = mapper.getTypeFactory().constructType(InspectImageResponse.class); - final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, "images/docImage/doc.json", type); + final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, + "images/docImage/doc.json", + type + ); assertThat(inspectImage, notNullValue()); assertThat(inspectImage.getRepoDigests(), hasSize(1)); assertThat(inspectImage.getRepoDigests(), - - contains("localhost:5000/test/busybox/example@" - + "sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf")); + contains("localhost:5000/test/busybox/example@" + + "sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf") + ); assertThat(inspectImage.getRepoTags(), hasSize(3)); - assertThat(inspectImage.getRepoTags(), containsInAnyOrder("example:1.0", "example:latest", "example:stable")); + assertThat(inspectImage.getRepoTags(), containsInAnyOrder( + "example:1.0", + "example:latest", + "example:stable" + )); } @Test @@ -154,11 +166,16 @@ public void serder1_22_inspect_doc() throws IOException { final ObjectMapper mapper = new ObjectMapper(); final JavaType type = mapper.getTypeFactory().constructType(InspectImageResponse.class); - final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, "images/docImage/inspect_doc.json", type); + final InspectImageResponse inspectImage = testRoundTrip(VERSION_1_22, + "images/docImage/inspect_doc.json", + type + ); - GraphData newGraphData = new GraphData().withDeviceId("5") + GraphData newGraphData = new GraphData() + .withDeviceId("5") .withDeviceName("docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47") .withDeviceSize("171798691840"); + assertThat(inspectImage, notNullValue()); GraphDriver graphDriver = inspectImage.getGraphDriver(); assertThat(graphDriver, notNullValue()); @@ -167,8 +184,10 @@ public void serder1_22_inspect_doc() throws IOException { assertThat(data, is(newGraphData)); assertThat(data.getDeviceId(), is("5")); - assertThat(data.getDeviceName(), is("docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47")); - assertThat(data.getDeviceSize(), is("171798691840")); + assertThat(data.getDeviceName(), + is("docker-253:1-2763198-d2cc496561d6d520cbc0236b4ba88c362c446a7619992123f11c809cded25b47")); + assertThat(data.getDeviceSize(), + is("171798691840")); } @Test @@ -186,6 +205,5 @@ private void testOverlayNetworkRootDir() throws IOException { assertThat(graphDriver, equalTo(overlayGraphDriver)); assertThat(graphDriver.getName(), is("overlay")); assertThat(graphDriver.getData(), equalTo(overlayGraphData)); - } } From d05e38078117c8e1f20ab4ecc20575b64cb801bc Mon Sep 17 00:00:00 2001 From: Jeremy Date: Tue, 24 May 2016 14:19:28 -0600 Subject: [PATCH 139/855] Fixes Issue #584 Adds RootDir property to GraphData. This was seen on a CentOS system without aufs support. --- src/main/java/com/github/dockerjava/api/command/GraphData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/api/command/GraphData.java b/src/main/java/com/github/dockerjava/api/command/GraphData.java index 1aac8db84..5130fafc7 100644 --- a/src/main/java/com/github/dockerjava/api/command/GraphData.java +++ b/src/main/java/com/github/dockerjava/api/command/GraphData.java @@ -34,7 +34,7 @@ public String getRootDir() { } /** - * @see #deviceId + * @see #rootDir */ public GraphData withRootDir(String rootDir) { this.rootDir = rootDir; From 4ac56af0ee3fe02e4e50c30c05e435fbfe7bf9e8 Mon Sep 17 00:00:00 2001 From: Logan O'Sullivan Bruns Date: Tue, 24 May 2016 10:27:27 -0700 Subject: [PATCH 140/855] Always use HTTP to connect to proxy even when proxying HTTPS The intention of the current implementation seems to be to have the normal proxy settings accomplish the same results with docker-java as they would in java in general. I think the one accidental divergence from that is that for the HTTPS case setting https.{proxy,port} would normally still use HTTP but in this case the code is- I think unintentionally- switching to the proxy connection to HTTPS. This change makes it so it corresponds better with how the java proxy properties work as well. Even when proxying HTTPS the connection to the actually proxy is done over HTTP and it makes a CONNECT call to stream the HTTPS over. Most proxies are still used via HTTP and for better or worse this is the assumption built into the java proxy configuration which docker-java is using. The apache client is more flexible and perhaps the docker-java configuration should be too but I'd like to argue that until then that the docker-java match the behavior of java. Also this allows me to use docker-java through the corporate proxy when proxying HTTPS. Otherwise HTTP works but HTTPS fails since the proxy is not configured with HTTPS. --- .../com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index f64cf4e2b..5d489bbc5 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -231,7 +231,7 @@ private void configureProxy(ClientConfig clientConfig, String protocol) { String hostname = address.getHostName(); int port = address.getPort(); - clientConfig.property(ClientProperties.PROXY_URI, protocol + "://" + hostname + ":" + port); + clientConfig.property(ClientProperties.PROXY_URI, "http://" + hostname + ":" + port); String httpProxyUser = System.getProperty(protocol + ".proxyUser"); if (httpProxyUser != null) { From fac1ba22dc904f86774d16c56754a280a7ac4e97 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Thu, 2 Jun 2016 20:22:40 +0200 Subject: [PATCH 141/855] Add ignore unknown properties annotation --- src/main/java/com/github/dockerjava/api/command/GraphData.java | 3 +++ .../java/com/github/dockerjava/api/command/GraphDriver.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/src/main/java/com/github/dockerjava/api/command/GraphData.java b/src/main/java/com/github/dockerjava/api/command/GraphData.java index 5130fafc7..5a2944e0b 100644 --- a/src/main/java/com/github/dockerjava/api/command/GraphData.java +++ b/src/main/java/com/github/dockerjava/api/command/GraphData.java @@ -1,6 +1,8 @@ package com.github.dockerjava.api.command; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; + import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; @@ -11,6 +13,7 @@ * part of {@link GraphDriver} * @author Kanstantsin Shautsou */ +@JsonIgnoreProperties(ignoreUnknown = true) public class GraphData { @JsonProperty("RootDir") diff --git a/src/main/java/com/github/dockerjava/api/command/GraphDriver.java b/src/main/java/com/github/dockerjava/api/command/GraphDriver.java index 0d41364aa..1394e866e 100644 --- a/src/main/java/com/github/dockerjava/api/command/GraphDriver.java +++ b/src/main/java/com/github/dockerjava/api/command/GraphDriver.java @@ -1,6 +1,8 @@ package com.github.dockerjava.api.command; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; + import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; @@ -13,6 +15,7 @@ * @author Kanstantsin Shautsou * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_21} */ +@JsonIgnoreProperties(ignoreUnknown = true) public class GraphDriver { /** * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_21} From ad83c3adc410a901f25e22f20185dea5b0beb0cf Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Thu, 2 Jun 2016 20:24:31 +0200 Subject: [PATCH 142/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 429f4b275..c4a771d25 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Notes All changes +* [#585] (https://github.com/docker-java/docker-java/pull/585) Add RootDir property to GraphData * [#580] (https://github.com/docker-java/docker-java/pull/580) Fixes execute permissions for files when copied to container * [#579] (https://github.com/docker-java/docker-java/pull/579) Adds missing name filter evaluation to netty version of ListImagesCmdExec * [#578] (https://github.com/docker-java/docker-java/pull/578) Fix error during image build when Dockerfile in subdirectory of build context From 0c48b5fe0984388a27a65a3e4fbc2383a3821a30 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Thu, 2 Jun 2016 21:52:06 +0200 Subject: [PATCH 143/855] Add missing tests for netty impl --- .../exec/ConnectToNetworkCmdExecTest.java | 98 +++++++++++++++++++ .../DisconnectFromNetworkCmdExecTest.java | 82 ++++++++++++++++ 2 files changed, 180 insertions(+) create mode 100644 src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java create mode 100644 src/test/java/com/github/dockerjava/netty/exec/DisconnectFromNetworkCmdExecTest.java diff --git a/src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java new file mode 100644 index 000000000..ee1a681b6 --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java @@ -0,0 +1,98 @@ +package com.github.dockerjava.netty.exec; + +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.CreateNetworkResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.model.ContainerNetwork; +import com.github.dockerjava.api.model.Network; +import com.github.dockerjava.netty.AbstractNettyDockerClientTest; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; +import java.util.Collections; + +@Test(groups = "integration") +public class ConnectToNetworkCmdExecTest extends AbstractNettyDockerClientTest { + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void connectToNetwork() throws InterruptedException { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + dockerClient.startContainerCmd(container.getId()).exec(); + + CreateNetworkResponse network = dockerClient.createNetworkCmd().withName("testNetwork").exec(); + + dockerClient.connectToNetworkCmd().withNetworkId(network.getId()).withContainerId(container.getId()).exec(); + + Network updatedNetwork = dockerClient.inspectNetworkCmd().withNetworkId(network.getId()).exec(); + + assertTrue(updatedNetwork.getContainers().containsKey(container.getId())); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + + assertNotNull(inspectContainerResponse.getNetworkSettings().getNetworks().get("testNetwork")); + } + + @Test + public void connectToNetworkWithContainerNetwork() throws InterruptedException { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + dockerClient.startContainerCmd(container.getId()).exec(); + + CreateNetworkResponse network = dockerClient.createNetworkCmd() + .withName("testNetwork") + .withIpam(new Network.Ipam() + .withConfig(new Network.Ipam.Config() + .withSubnet("10.100.100.0/24"))) + .exec(); + + dockerClient.connectToNetworkCmd() + .withNetworkId(network.getId()) + .withContainerId(container.getId()) + .withContainerNetwork(new ContainerNetwork() + .withAliases("testing") + .withIpamConfig(new ContainerNetwork.Ipam() + .withIpv4Address("10.100.100.100"))) + .exec(); + + Network updatedNetwork = dockerClient.inspectNetworkCmd().withNetworkId(network.getId()).exec(); + + Network.ContainerNetworkConfig containerNetworkConfig = updatedNetwork.getContainers().get(container.getId()); + assertNotNull(containerNetworkConfig); + assertEquals(containerNetworkConfig.getIpv4Address(), "10.100.100.100/24"); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + + ContainerNetwork testNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get("testNetwork"); + assertNotNull(testNetwork); + assertEquals(testNetwork.getAliases(), Collections.singletonList("testing")); + assertEquals(testNetwork.getGateway(), "10.100.100.1"); + assertEquals(testNetwork.getIpAddress(), "10.100.100.100"); + } +} diff --git a/src/test/java/com/github/dockerjava/netty/exec/DisconnectFromNetworkCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/DisconnectFromNetworkCmdExecTest.java new file mode 100644 index 000000000..1f2563dec --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/exec/DisconnectFromNetworkCmdExecTest.java @@ -0,0 +1,82 @@ +package com.github.dockerjava.netty.exec; + +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.CreateNetworkResponse; +import com.github.dockerjava.api.model.Network; +import com.github.dockerjava.netty.AbstractNettyDockerClientTest; + +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; + +@Test(groups = "integration") +public class DisconnectFromNetworkCmdExecTest extends AbstractNettyDockerClientTest { + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void disconnectFromNetwork() throws InterruptedException { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + dockerClient.startContainerCmd(container.getId()).exec(); + + CreateNetworkResponse network = dockerClient.createNetworkCmd().withName("testNetwork").exec(); + + dockerClient.connectToNetworkCmd().withNetworkId(network.getId()).withContainerId(container.getId()).exec(); + + Network updatedNetwork = dockerClient.inspectNetworkCmd().withNetworkId(network.getId()).exec(); + + assertTrue(updatedNetwork.getContainers().containsKey(container.getId())); + + dockerClient.disconnectFromNetworkCmd().withNetworkId(network.getId()).withContainerId(container.getId()).exec(); + + updatedNetwork = dockerClient.inspectNetworkCmd().withNetworkId(network.getId()).exec(); + + assertFalse(updatedNetwork.getContainers().containsKey(container.getId())); + } + + @Test + public void forceDisconnectFromNetwork() throws InterruptedException { + + CreateNetworkResponse network = dockerClient.createNetworkCmd().withName("testNetwork").exec(); + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withNetworkMode("testNetwork") + .withCmd("sleep", "9999") + .exec(); + + dockerClient.startContainerCmd(container.getId()).exec(); + + dockerClient.disconnectFromNetworkCmd() + .withNetworkId(network.getId()) + .withContainerId(container.getId()) + .withForce(true) + .exec(); + + Network updatedNetwork = dockerClient.inspectNetworkCmd().withNetworkId(network.getId()).exec(); + assertFalse(updatedNetwork.getContainers().containsKey(container.getId())); + } +} From 19acfcc8496ace6fe52c25d1359c7f891c01a04b Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Thu, 2 Jun 2016 21:54:43 +0200 Subject: [PATCH 144/855] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c4a771d25..7a6bae5af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,8 @@ All changes * [#574] (https://github.com/docker-java/docker-java/pull/574) Fix for copyArchiveToContainerCmd bug * [#572] (https://github.com/docker-java/docker-java/pull/572) Inspect container command now shows sizes if requested * [#563] (https://github.com/docker-java/docker-java/pull/563) Fix memory leak in netty implementation of DockerCmdExecFactory -* [#550] (https://github.com/docker-java/docker-java/pull/550) Add ability to configure IPAM config for CreateNetworkCmd +* [#550] (https://github.com/docker-java/docker-java/pull/550) Add ability to configure IPAM config for CreateNetworkCmd +* [#484] (https://github.com/docker-java/docker-java/pull/484) Implement missing network api options for v1.22 Included in 3.0.0-RC5 From 7d1f64f7678b9857b3605558434c76d140aac172 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Thu, 2 Jun 2016 23:19:50 +0200 Subject: [PATCH 145/855] Fix issue #480 --- .../dockerjava/core/DockerClientConfig.java | 16 ++++++++++------ ...b.dockerjava.api.command.DockerCmdExecFactory | 1 - src/main/resources/docker-java.properties | 12 +++--------- .../dockerjava/core/DockerClientConfigTest.java | 10 +++------- 4 files changed, 16 insertions(+), 23 deletions(-) delete mode 100644 src/main/resources/META-INF/services/com.github.dockerjava.api.command.DockerCmdExecFactory diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java index a03d6e086..31cfc0c58 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java @@ -109,14 +109,16 @@ private String checkDockerCertPath(boolean dockerTlsVerify, String dockerCertPat if (!certPath.exists()) { throw new DockerClientException( - "Certificate path (DOCKER_CERT_PATH) '" + dockerCertPath + "' doesn't exist."); + "Enabled TLS verification (DOCKER_TLS_VERIFY=1) but certificate path (DOCKER_CERT_PATH) '" + dockerCertPath + + "' doesn't exist."); } if (certPath.isDirectory()) { return dockerCertPath; } else { throw new DockerClientException( - "Certificate path (DOCKER_CERT_PATH) '" + dockerCertPath + "' doesn't point to a directory."); + "Enabled TLS verification (DOCKER_TLS_VERIFY=1) but certificate path (DOCKER_CERT_PATH) '" + dockerCertPath + + "' doesn't point to a directory."); } } } else { @@ -375,7 +377,6 @@ public final DockerClientConfigBuilder withDockerHost(String dockerHost) { return this; } - public final DockerClientConfigBuilder withApiVersion(RemoteApiVersion apiVersion) { this.apiVersion = apiVersion.getVersion(); return this; @@ -417,8 +418,12 @@ public final DockerClientConfigBuilder withDockerConfig(String dockerConfig) { } public final DockerClientConfigBuilder withDockerTlsVerify(String dockerTlsVerify) { - String trimmed = dockerTlsVerify.trim(); - this.dockerTlsVerify = "true".equalsIgnoreCase(trimmed) || "1".equals(trimmed); + if (dockerTlsVerify != null) { + String trimmed = dockerTlsVerify.trim(); + this.dockerTlsVerify = "true".equalsIgnoreCase(trimmed) || "1".equals(trimmed); + } else { + this.dockerTlsVerify = false; + } return this; } @@ -433,4 +438,3 @@ public DockerClientConfig build() { } } } - diff --git a/src/main/resources/META-INF/services/com.github.dockerjava.api.command.DockerCmdExecFactory b/src/main/resources/META-INF/services/com.github.dockerjava.api.command.DockerCmdExecFactory deleted file mode 100644 index f0686bc9f..000000000 --- a/src/main/resources/META-INF/services/com.github.dockerjava.api.command.DockerCmdExecFactory +++ /dev/null @@ -1 +0,0 @@ -com.github.dockerjava.jaxrs.DockerCmdExecFactoryImpl \ No newline at end of file diff --git a/src/main/resources/docker-java.properties b/src/main/resources/docker-java.properties index ea85f6c01..fc9209c97 100644 --- a/src/main/resources/docker-java.properties +++ b/src/main/resources/docker-java.properties @@ -1,13 +1,7 @@ -#docker.io.url=https://localhost:2376 -#docker.io.dockerCertPath=${user.home}/.docker -#docker.io.dockerCfgPath=${user.home}/.dockercfg -#docker.io.username=${user.name} -#docker.io.serverAddress=https://index.docker.io/v1/ -# -DOCKER_HOST=tcp://localhost:2376 -DOCKER_TLS_VERIFY=1 +DOCKER_HOST=unix:///var/run/docker.sock DOCKER_CONFIG=${user.home}/.docker -DOCKER_CERT_PATH=${user.home}/.docker/certs +#DOCKER_TLS_VERIFY=1 +#DOCKER_CERT_PATH=${user.home}/.docker/certs api.version= registry.url=https://index.docker.io/v1/ diff --git a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java index a363e12ec..ee679a0af 100644 --- a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java +++ b/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java @@ -4,8 +4,7 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.core.Is.is; import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; +import static org.testng.Assert.assertNull; import java.lang.reflect.Field; import java.net.URI; @@ -54,8 +53,6 @@ public void environmentDockerHost() throws Exception { // and it looks to be SSL disabled env.remove("DOCKER_CERT_PATH"); - - // given default cert path Properties systemProperties = new Properties(); systemProperties.setProperty("user.name", "someUserName"); @@ -82,7 +79,6 @@ public void environment() throws Exception { env.put(DockerClientConfig.DOCKER_CERT_PATH, dockerCertPath()); env.put(DockerClientConfig.DOCKER_TLS_VERIFY, "1"); - // when you build a config DockerClientConfig config = buildConfig(env, new Properties()); @@ -106,12 +102,12 @@ public void defaults() throws Exception { DockerClientConfig config = buildConfig(Collections. emptyMap(), systemProperties); // then the cert path is as expected - assertEquals(config.getDockerHost(), URI.create("tcp://localhost:2376")); + assertEquals(config.getDockerHost(), URI.create("unix:///var/run/docker.sock")); assertEquals(config.getRegistryUsername(), "someUserName"); assertEquals(config.getRegistryUrl(), AuthConfig.DEFAULT_SERVER_ADDRESS); assertEquals(config.getApiVersion(), RemoteApiVersion.unknown()); assertEquals(config.getDockerConfig(), homeDir() + "/.docker"); - assertEquals(config.getDockerCertPath(), homeDir() + "/.docker/certs"); + assertNull(config.getDockerCertPath()); } @Test From 94e860e574d7eebc64ee8e7fa4090d1d4c82d8a7 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Fri, 3 Jun 2016 21:12:42 +0200 Subject: [PATCH 146/855] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a6bae5af..ee0dae776 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,7 @@ Notes * The configuration has been changed to better match the docker CLI configuration options. The properties file was renamed from `docker.io.properties` to `docker-java.properties`. See README.md for details. All changes - +* [#590] (https://github.com/docker-java/docker-java/pull/590) Fix default docker.properties to match with docker CLI defaults * [#585] (https://github.com/docker-java/docker-java/pull/585) Add RootDir property to GraphData * [#580] (https://github.com/docker-java/docker-java/pull/580) Fixes execute permissions for files when copied to container * [#579] (https://github.com/docker-java/docker-java/pull/579) Adds missing name filter evaluation to netty version of ListImagesCmdExec From fc38f319311821f790c1dcb8f1990676cc0e44f3 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Fri, 3 Jun 2016 21:53:02 +0200 Subject: [PATCH 147/855] [maven-release-plugin] prepare release docker-java-3.0.0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 9ee5cad51..3b77e6e98 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-SNAPSHOT + 3.0.0 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 + docker-java-3.0.0 From 37afc15c5baeb5f479a56ca5e858bf230adb1102 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Fri, 3 Jun 2016 21:53:10 +0200 Subject: [PATCH 148/855] [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 3b77e6e98..bee178a6d 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0 + 3.0.1-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 - docker-java-3.0.0 + HEAD From 2f3d90c0a6bd564f8f8c53696198f9d74cdcd045 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Fri, 3 Jun 2016 22:02:41 +0200 Subject: [PATCH 149/855] Update CHANGELOG.md --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee0dae776..f55b2cd75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,11 @@ Change Log === -3.0.0-SNAPSHOT +v3.0.0 --- Notes -* The upcoming release will contain multiple API breaking changes therefore the major version switch. It will support a subset of v.1.22 of the docker remote API. It also includes an experimental netty based implementation of `DockerCmdExecFactory` that probably will replace the current jersey/httpclient based one in a later release. +* The 3.0.0 release contains multiple API breaking changes compared to 2.x therefore the major version switch. It supports a subset of v.1.22 of the docker remote API. It also includes an experimental netty based implementation of `DockerCmdExecFactory` that probably will replace the current jersey/httpclient based one in a later release. Take a look at the [Wiki](https://github.com/docker-java/docker-java/wiki#intialize-docker-client-advanced) how to use it. * The configuration has been changed to better match the docker CLI configuration options. The properties file was renamed from `docker.io.properties` to `docker-java.properties`. See README.md for details. All changes From 9a59b10c5a28e6ae4d29af770f2412b1f88fc7dd Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Fri, 3 Jun 2016 22:54:02 +0200 Subject: [PATCH 150/855] Update README.md --- README.md | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f2135f61b..1b39ebab3 100644 --- a/README.md +++ b/README.md @@ -58,21 +58,12 @@ Run build without integration tests: ## Docker-Java maven dependencies ### Latest release version -Supports a subset of the Docker Remote API [v1.19](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.19.md), Docker Server version 1.7.x - - - com.github.docker-java - docker-java - 2.2.3 - - -### Latest release candidate Supports a subset of the Docker Remote API [v1.22](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.22.md), Docker Server version 1.10.x com.github.docker-java docker-java - 3.0.0-RC5 + 3.0.0 ### Latest development version @@ -83,7 +74,7 @@ You can find the latest development version including javadoc and source files o com.github.docker-java docker-java - 3.0.0-SNAPSHOT + 3.0.1-SNAPSHOT From 0a1b34c3b2a201f82a16821e1f3f6ca0337854ca Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Sat, 4 Jun 2016 00:16:29 +0200 Subject: [PATCH 151/855] Update README.md --- README.md | 44 +++++++++++++++----------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) diff --git a/README.md b/README.md index 1b39ebab3..e47b6e5a4 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ Java API client for [Docker](http://docs.docker.io/ "Docker") Developer forum for [docker-java](https://groups.google.com/forum/?#!forum/docker-java-dev "docker-java") +[Changelog](https://github.com/docker-java/docker-java/blob/master/CHANGELOG.md)
+[Wiki](https://github.com/docker-java/docker-java/wiki) + ## Build with Maven ###### Prerequisites: @@ -15,10 +18,6 @@ Developer forum for [docker-java](https://groups.google.com/forum/?#!forum/docke * Java 1.7 * Maven 3.0.5 -If you need SSL, then you'll need to put your `*.pem` file into `~/.docker/`, if you're using boot2docker, do this: - - $ ln -s /Users/alex.collins/.boot2docker/certs/boot2docker-vm .docker - Build and run integration tests as follows: $ mvn clean install @@ -27,35 +26,22 @@ If you do not have access to a Docker server or just want to execute the build q $ mvn clean install -DskipITs -By default Docker server is using UNIX sockets for communication with the Docker client, however docker-java -client uses TCP/IP to connect to the Docker server by default, so you will need to make sure that your Docker server is -listening on TCP port. To allow Docker server to use TCP add the following line to /etc/default/docker +By default the docker engine is using local UNIX sockets for communication with the docker CLI so docker-java +client also uses UNIX domain sockets to connect to the docker daemon by default. To make the docker daemon listening on a TCP (http/https) port you have to configure it by setting the DOCKER_OPTS environment variable to something like the following: DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock" - -However you can force docker-java to use UNIX socket communication by configure the following (see [Configuration](.#Configuration) for details): - - DOCKER_HOST=unix:///var/run/docker.sock - DOCKER_TLS_VERIFY=0 - + More details about setting up Docker server can be found in official documentation: http://docs.docker.io/en/latest/use/basics/ -Now make sure that docker is up: +To force docker-java to use TCP (http) configure the following (see [Configuration](https://github.com/docker-java/docker-java#configuration) for details): - $ docker -H tcp://127.0.0.1:2375 version - - Client version: 0.8.0 - Go version (client): go1.2 - Git commit (client): cc3a8c8 - Server version: 1.2.0 - Git commit (server): fa7b24f - Go version (server): go1.3.1 - -Run build without integration tests: - - $ mvn clean install -DskipITs + DOCKER_HOST=tcp://127.0.0.1:2375 + +For secure tls (https) communication: -## Docker-Java maven dependencies + DOCKER_HOST=tcp://127.0.0.1:2376 + DOCKER_TLS_VERIFY=1 + DOCKER_CERT_PATH=/Users/marcus/.docker/machine/machines/docker-1.10.2 ### Latest release version Supports a subset of the Docker Remote API [v1.22](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.22.md), Docker Server version 1.10.x @@ -128,11 +114,11 @@ In your application, e.g. ##### System Properties: - java -Dregistry.username=dockeruser pkg.Main + java -DDOCKER_HOST=tcp://localhost:2375 -Dregistry.username=dockeruser pkg.Main ##### System Environment - export DOCKER_URL=tcp://localhost:2376 + export DOCKER_HOST=tcp://localhost:2376 export DOCKER_TLS_VERIFY=1 export DOCKER_CERT_PATH=/home/user/.docker/certs export DOCKER_CONFIG=/home/user/.docker From 3a3318282a4cf5d37b20b7d85ac00ef7549df84d Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Sun, 5 Jun 2016 15:30:00 +0200 Subject: [PATCH 152/855] Reorganize image build tests --- .../client/AbstractDockerClientTest.java | 2 - .../core/command/BuildImageCmdImplTest.java | 144 +++++----------- .../DockerfileAddMultipleFilesTest.java | 14 +- .../core/dockerfile/DockerfileTest.java | 49 ------ .../netty/exec/BuildImageCmdExecTest.java | 159 +++++++----------- .../ADD/file}/Dockerfile | 0 .../ADD/file}/testrun.sh | 0 .../ADD/fileInSubfolder}/Dockerfile | 0 .../ADD/fileInSubfolder}/files/testrun.sh | 0 .../ADD/files}/Dockerfile | 0 .../ADD/files}/src1 | 0 .../ADD/files}/src2 | 0 .../ADD/filesViaWildcard}/Dockerfile | 0 .../ADD/filesViaWildcard}/folder1/testrun.sh | 0 .../filesViaWildcard}/folder2/testinclude1.sh | 0 .../filesViaWildcard}/ignore/testinclude2.sh | 0 .../ADD/folder}/Dockerfile | 0 .../ADD/folder}/folderA/testAddFolder.sh | 0 .../ADD/url}/Dockerfile | 2 +- .../resources/buildTests/ADD/url/testrun.sh | 4 + .../{nginx => buildTests/AUTHOR}/Dockerfile | 2 +- .../ENV}/Dockerfile | 0 .../ENV}/subst-file-2-abc123.txt | 0 .../ENV}/subst-file-abc123.txt | 0 .../ENV}/testrun.sh | 0 .../FROM/privateRegistry}/Dockerfile | 0 .../ONBUILD/child}/Dockerfile | 0 .../ONBUILD/child}/testrun.sh | 0 .../ONBUILD/parent}/Dockerfile | 0 .../buildArgs}/Dockerfile | 0 .../dockerfileFolder/Dockerfile | 0 .../testrunFolder/testrun.sh | 0 .../DockerfileIgnored}/.dockerignore | 0 .../DockerfileIgnored}/Dockerfile | 0 .../DockerfileIgnored}/testrun.sh | 0 .../DockerfileNotIgnored}/.dockerignore | 0 .../DockerfileNotIgnored}/Dockerfile | 0 .../InvalidDockerignorePattern}/.dockerignore | 0 .../InvalidDockerignorePattern}/Dockerfile | 0 .../InvalidDockerignorePattern}/testrun.sh | 0 .../ValidDockerignorePattern}/.dockerignore | 0 .../ValidDockerignorePattern}/Dockerfile | 0 .../ValidDockerignorePattern}/a/a | 0 .../ValidDockerignorePattern}/a/b | 0 .../ValidDockerignorePattern}/a/c | 0 .../ValidDockerignorePattern}/a/d | 0 .../ValidDockerignorePattern}/testrun.sh | 0 src/test/resources/netcat/Dockerfile | 11 -- .../subdirectory/Dockerfile-nonstandard | 12 -- src/test/resources/testAddUrl/testrun.sh | 4 - src/test/resources/testEnv/Dockerfile | 10 -- .../resources/testEnv/subFolder/testrun.sh | 3 - 52 files changed, 111 insertions(+), 305 deletions(-) delete mode 100644 src/test/java/com/github/dockerjava/core/dockerfile/DockerfileTest.java rename src/test/resources/{testAddFile => buildTests/ADD/file}/Dockerfile (100%) rename src/test/resources/{testAddFile => buildTests/ADD/file}/testrun.sh (100%) rename src/test/resources/{testAddFileInSubfolder => buildTests/ADD/fileInSubfolder}/Dockerfile (100%) rename src/test/resources/{testAddFileInSubfolder => buildTests/ADD/fileInSubfolder}/files/testrun.sh (100%) rename src/test/resources/{testAddMultipleFiles => buildTests/ADD/files}/Dockerfile (100%) rename src/test/resources/{testAddMultipleFiles => buildTests/ADD/files}/src1 (100%) rename src/test/resources/{testAddMultipleFiles => buildTests/ADD/files}/src2 (100%) rename src/test/resources/{testAddFilesViaWildcard => buildTests/ADD/filesViaWildcard}/Dockerfile (100%) rename src/test/resources/{testAddFilesViaWildcard => buildTests/ADD/filesViaWildcard}/folder1/testrun.sh (100%) rename src/test/resources/{testAddFilesViaWildcard => buildTests/ADD/filesViaWildcard}/folder2/testinclude1.sh (100%) rename src/test/resources/{testAddFilesViaWildcard => buildTests/ADD/filesViaWildcard}/ignore/testinclude2.sh (100%) rename src/test/resources/{testAddFolder => buildTests/ADD/folder}/Dockerfile (100%) rename src/test/resources/{testAddFolder => buildTests/ADD/folder}/folderA/testAddFolder.sh (100%) rename src/test/resources/{testAddUrl => buildTests/ADD/url}/Dockerfile (71%) create mode 100755 src/test/resources/buildTests/ADD/url/testrun.sh rename src/test/resources/{nginx => buildTests/AUTHOR}/Dockerfile (81%) rename src/test/resources/{testENVSubstitution => buildTests/ENV}/Dockerfile (100%) rename src/test/resources/{testENVSubstitution => buildTests/ENV}/subst-file-2-abc123.txt (100%) rename src/test/resources/{testENVSubstitution => buildTests/ENV}/subst-file-abc123.txt (100%) rename src/test/resources/{testENVSubstitution => buildTests/ENV}/testrun.sh (100%) rename src/test/resources/{testBuildFromPrivateRegistry => buildTests/FROM/privateRegistry}/Dockerfile (100%) rename src/test/resources/{testAddOnBuild/test => buildTests/ONBUILD/child}/Dockerfile (100%) rename src/test/resources/{testAddOnBuild/test => buildTests/ONBUILD/child}/testrun.sh (100%) rename src/test/resources/{testAddOnBuild/onbuild => buildTests/ONBUILD/parent}/Dockerfile (100%) rename src/test/resources/{testBuildArgs => buildTests/buildArgs}/Dockerfile (100%) rename src/test/resources/{testDockerfileNotInBaseDirectory => buildTests/dockerfileNotInBaseDirectory}/dockerfileFolder/Dockerfile (100%) rename src/test/resources/{testDockerfileNotInBaseDirectory => buildTests/dockerfileNotInBaseDirectory}/testrunFolder/testrun.sh (100%) rename src/test/resources/{testDockerfileIgnored => buildTests/dockerignore/DockerfileIgnored}/.dockerignore (100%) rename src/test/resources/{testDockerfileIgnored => buildTests/dockerignore/DockerfileIgnored}/Dockerfile (100%) rename src/test/resources/{testDockerfileIgnored => buildTests/dockerignore/DockerfileIgnored}/testrun.sh (100%) rename src/test/resources/{testDockerfileNotIgnored => buildTests/dockerignore/DockerfileNotIgnored}/.dockerignore (100%) rename src/test/resources/{testDockerfileNotIgnored => buildTests/dockerignore/DockerfileNotIgnored}/Dockerfile (100%) rename src/test/resources/{testInvalidDockerignorePattern => buildTests/dockerignore/InvalidDockerignorePattern}/.dockerignore (100%) rename src/test/resources/{testInvalidDockerignorePattern => buildTests/dockerignore/InvalidDockerignorePattern}/Dockerfile (100%) rename src/test/resources/{testInvalidDockerignorePattern => buildTests/dockerignore/InvalidDockerignorePattern}/testrun.sh (100%) rename src/test/resources/{testDockerignore => buildTests/dockerignore/ValidDockerignorePattern}/.dockerignore (100%) rename src/test/resources/{testDockerignore => buildTests/dockerignore/ValidDockerignorePattern}/Dockerfile (100%) rename src/test/resources/{testDockerignore => buildTests/dockerignore/ValidDockerignorePattern}/a/a (100%) rename src/test/resources/{testDockerignore => buildTests/dockerignore/ValidDockerignorePattern}/a/b (100%) rename src/test/resources/{testDockerignore => buildTests/dockerignore/ValidDockerignorePattern}/a/c (100%) rename src/test/resources/{testDockerignore => buildTests/dockerignore/ValidDockerignorePattern}/a/d (100%) rename src/test/resources/{testDockerignore => buildTests/dockerignore/ValidDockerignorePattern}/testrun.sh (100%) delete mode 100644 src/test/resources/netcat/Dockerfile delete mode 100644 src/test/resources/nonstandard/subdirectory/Dockerfile-nonstandard delete mode 100755 src/test/resources/testAddUrl/testrun.sh delete mode 100644 src/test/resources/testEnv/Dockerfile delete mode 100755 src/test/resources/testEnv/subFolder/testrun.sh diff --git a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java index 4c8750ecc..231e709c1 100644 --- a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java +++ b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java @@ -228,8 +228,6 @@ public static class LogContainerTestCallback extends LogContainerResultCallback @Override public void onNext(Frame frame) { log.append(new String(frame.getPayload())); - System.err.println("LogContainerTestCallback: " + log.toString()); - // super.onNext(frame); } @Override 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 950b80a24..31f3c3045 100644 --- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java @@ -5,7 +5,6 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import java.io.File; @@ -26,7 +25,6 @@ import com.github.dockerjava.api.command.BuildImageCmd; import com.github.dockerjava.api.command.CreateContainerResponse; -import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.command.InspectImageResponse; import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.api.model.AuthConfig; @@ -61,10 +59,9 @@ public void afterMethod(ITestResult result) { } @Test - public void testNginxDockerfileBuilder() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("nginx").getFile()); + public void author() throws Exception { - String imageId = buildImage(baseDir); + String imageId = buildImage(fileFromBuildTestResource("AUTHOR")); InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); assertThat(inspectImageResponse, not(nullValue())); @@ -73,27 +70,9 @@ public void testNginxDockerfileBuilder() throws Exception { assertThat(inspectImageResponse.getAuthor(), equalTo("Guillaume J. Charmes \"guillaume@dotcloud.com\"")); } - @Test(groups = "ignoreInCircleCi") - public void testNonstandard1() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader() - .getResource("nonstandard/subdirectory/Dockerfile-nonstandard").getFile()); - - buildImage(baseDir); - } - - @Test(groups = "ignoreInCircleCi") - public void testNonstandard2() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("nonstandard").getFile()); - File dockerFile = new File(Thread.currentThread().getContextClassLoader() - .getResource("nonstandard/subdirectory/Dockerfile-nonstandard").getFile()); - - dockerClient.buildImageCmd().withBaseDirectory(baseDir).withDockerfile(dockerFile).withNoCache(true) - .exec(new BuildImageResultCallback()).awaitImageId(); - } - @Test - public void testDockerBuilderFromTar() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFile").getFile()); + public void buildImageFromTar() throws Exception { + File baseDir = fileFromBuildTestResource("ADD/file"); Collection files = FileUtils.listFiles(baseDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE); File tarFile = CompressArchiveUtil.archiveTARFiles(baseDir, files, UUID.randomUUID().toString()); String response = dockerfileBuild(new FileInputStream(tarFile)); @@ -101,54 +80,45 @@ public void testDockerBuilderFromTar() throws Exception { } @Test - public void testDockerBuildWithOnBuild() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddOnBuild/onbuild") - .getFile()); + public void onBuild() throws Exception { + File baseDir = fileFromBuildTestResource("ONBUILD/parent"); + dockerClient.buildImageCmd(baseDir).withNoCache(true).withTag("docker-java-onbuild") .exec(new BuildImageResultCallback()).awaitImageId(); - baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddOnBuild/test").getFile()); + baseDir = fileFromBuildTestResource("ONBUILD/child"); String response = dockerfileBuild(baseDir); assertThat(response, containsString("Successfully executed testrun.sh")); } @Test - public void testDockerBuilderAddUrl() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddUrl").getFile()); + public void addUrl() throws Exception { + File baseDir = fileFromBuildTestResource("ADD/url"); String response = dockerfileBuild(baseDir); - assertThat(response, containsString("Docker")); + assertThat(response, containsString("Example Domain")); } @Test - public void testDockerBuilderAddFileInSubfolder() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFileInSubfolder") - .getFile()); + public void addFileInSubfolder() throws Exception { + File baseDir = fileFromBuildTestResource("ADD/fileInSubfolder"); String response = dockerfileBuild(baseDir); assertThat(response, containsString("Successfully executed testrun.sh")); } @Test - public void testDockerBuilderAddFilesViaWildcard() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFilesViaWildcard") - .getFile()); + public void addFilesViaWildcard() throws Exception { + File baseDir = fileFromBuildTestResource("ADD/filesViaWildcard"); String response = dockerfileBuild(baseDir); assertThat(response, containsString("Successfully executed testinclude1.sh")); assertThat(response, not(containsString("Successfully executed testinclude2.sh"))); } @Test - public void testDockerBuilderAddFolder() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFolder").getFile()); + public void addFolder() throws Exception { + File baseDir = fileFromBuildTestResource("ADD/folder"); String response = dockerfileBuild(baseDir); assertThat(response, containsString("Successfully executed testAddFolder.sh")); } - @Test - public void testDockerBuilderEnv() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testEnv").getFile()); - String response = dockerfileBuild(baseDir); - assertThat(response, containsString("Successfully executed testrun.sh")); - } - private String dockerfileBuild(InputStream tarInputStream) throws Exception { return execBuild(dockerClient.buildImageCmd().withTarInputStream(tarInputStream)); @@ -175,80 +145,42 @@ private String execBuild(BuildImageCmd buildImageCmd) throws Exception { } @Test(expectedExceptions = {DockerClientException.class}) - public void testDockerfileIgnored() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerfileIgnored") - .getFile()); + public void dockerignoreDockerfileIgnored() throws Exception { + File baseDir = fileFromBuildTestResource("dockerignore/DockerfileIgnored"); dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId(); } @Test - public void testDockerfileNotIgnored() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerfileNotIgnored") - .getFile()); + public void dockerignoreDockerfileNotIgnored() throws Exception { + File baseDir = fileFromBuildTestResource("dockerignore/DockerfileNotIgnored"); dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId(); } @Test(expectedExceptions = {DockerClientException.class}) - public void testInvalidDockerIgnorePattern() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader() - .getResource("testInvalidDockerignorePattern").getFile()); + public void dockerignoreInvalidDockerIgnorePattern() throws Exception { + File baseDir = fileFromBuildTestResource("dockerignore/InvalidDockerignorePattern"); dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId(); } - @Test(groups = "ignoreInCircleCi") - public void testDockerIgnore() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerignore") - .getFile()); + @Test() + public void dockerignoreValidDockerIgnorePattern() throws Exception { + File baseDir = fileFromBuildTestResource("dockerignore/ValidDockerignorePattern"); String response = dockerfileBuild(baseDir); assertThat(response, containsString("/tmp/a/a /tmp/a/c /tmp/a/d")); } @Test - public void testNetCatDockerfileBuilder() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("netcat").getFile()); - - String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()) - .awaitImageId(); - - assertNotNull(imageId, "Not successful in build"); - - InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); - assertThat(inspectImageResponse, not(nullValue())); - assertThat(inspectImageResponse.getId(), not(nullValue())); - LOG.info("Image Inspect: {}", inspectImageResponse.toString()); - - CreateContainerResponse container = dockerClient.createContainerCmd(inspectImageResponse.getId()).exec(); - assertThat(container.getId(), not(isEmptyString())); - dockerClient.startContainerCmd(container.getId()).exec(); - - InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); - - assertThat(inspectContainerResponse.getId(), notNullValue()); - assertThat(inspectContainerResponse.getNetworkSettings().getPorts(), notNullValue()); - - // No use as such if not running on the server - // for (Ports.Port p : inspectContainerResponse.getNetworkSettings().getPorts().getAllPorts()) { - // int port = Integer.valueOf(p.getHostPort()); - // LOG.info("Checking port {} is open", port); - // assertThat(available(port), is(false)); - // } - dockerClient.stopContainerCmd(container.getId()).withTimeout(0).exec(); - - } - - @Test - public void testAddAndCopySubstitution() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testENVSubstitution") - .getFile()); + public void env() throws Exception { + File baseDir = fileFromBuildTestResource("ENV"); String response = dockerfileBuild(baseDir); assertThat(response, containsString("testENVSubstitution successfully completed")); } @Test - public void testBuildFromPrivateRegistry() throws Exception { + public void fromPrivateRegistry() throws Exception { File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("privateRegistry").getFile()); String imageId = buildImage(baseDir); @@ -289,8 +221,7 @@ public void testBuildFromPrivateRegistry() throws Exception { dockerClient.removeImageCmd("localhost:5000/testuser/busybox").withForce(true).exec(); - baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testBuildFromPrivateRegistry") - .getFile()); + baseDir = fileFromBuildTestResource("FROM/privateRegistry"); AuthConfigurations authConfigurations = new AuthConfigurations(); authConfigurations.addConfig(authConfig); @@ -305,8 +236,8 @@ public void testBuildFromPrivateRegistry() throws Exception { } @Test - public void testBuildArgs() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testBuildArgs").getFile()); + public void buildArgs() throws Exception { + File baseDir = fileFromBuildTestResource("buildArgs"); String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true).withBuildArg("testArg", "abc") .exec(new BuildImageResultCallback()) @@ -319,9 +250,9 @@ public void testBuildArgs() throws Exception { assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc")); } - public void testDockerfileNotInBaseDirectory() throws Exception { - File baseDirectory = getResource("testDockerfileNotInBaseDirectory"); - File dockerfile = getResource("testDockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile"); + public void dockerfileNotInBaseDirectory() throws Exception { + File baseDirectory = fileFromBuildTestResource("dockerfileNotInBaseDirectory"); + File dockerfile = fileFromBuildTestResource("dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile"); BuildImageCmd command = dockerClient.buildImageCmd() .withBaseDirectory(baseDirectory) .withDockerfile(dockerfile); @@ -331,7 +262,8 @@ public void testDockerfileNotInBaseDirectory() throws Exception { assertThat(response, containsString("Successfully executed testrun.sh")); } - private File getResource(String path) { - return new File(Thread.currentThread().getContextClassLoader().getResource(path).getFile()); + private File fileFromBuildTestResource(String resource) { + return new File(Thread.currentThread().getContextClassLoader() + .getResource("buildTests/" + resource).getFile()); } } diff --git a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java index 8997a6d80..164246957 100644 --- a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java +++ b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java @@ -1,7 +1,7 @@ package com.github.dockerjava.core.dockerfile; import com.google.common.base.Function; -import junit.framework.TestCase; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.Test; @@ -14,7 +14,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsInAnyOrder; -public class DockerfileAddMultipleFilesTest extends TestCase { +public class DockerfileAddMultipleFilesTest { private static final Logger log = LoggerFactory.getLogger(DockerfileAddMultipleFilesTest.class); @@ -26,13 +26,17 @@ public String apply(File file) { }; @Test - public void testAddMultipleFiles() throws IOException { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddMultipleFiles") - .getFile()); + public void addFiles() throws IOException { + File baseDir = fileFromBuildTestResource("ADD/files"); Dockerfile dockerfile = new Dockerfile(new File(baseDir, "Dockerfile"), baseDir); Dockerfile.ScannedResult result = dockerfile.parse(); Collection filesToAdd = transform(result.filesToAdd, TO_FILE_NAMES); assertThat(filesToAdd, containsInAnyOrder("Dockerfile", "src1", "src2")); } + + private File fileFromBuildTestResource(String resource) { + return new File(Thread.currentThread().getContextClassLoader() + .getResource("buildTests/" + resource).getFile()); + } } diff --git a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileTest.java b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileTest.java deleted file mode 100644 index 390bcf647..000000000 --- a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.github.dockerjava.core.dockerfile; - -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import junit.framework.TestCase; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.annotations.Test; - -public class DockerfileTest extends TestCase { - - private static final Logger log = LoggerFactory.getLogger(DockerfileTest.class); - - @Test - public void testAllItems() throws IOException { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("netcat").getFile()); - - File root = baseDir.getParentFile(); - - Map dockerfiles = new HashMap(); - Map results = new HashMap(); - - for (File child : root.listFiles()) { - if (new File(child, "Dockerfile").exists()) { - Dockerfile dockerfile = new Dockerfile(new File(child, "Dockerfile"), baseDir); - dockerfiles.put(child.getName(), dockerfile); - } - } - - for (String name : dockerfiles.keySet()) { - log.info("Scanning {}", name); - try { - results.put(name, dockerfiles.get(name).parse()); - } catch (Exception ex) { - log.error("Error in {}", name, ex); - } - - } - - for (String name : results.keySet()) { - log.info("Name: {} = {}", name, results.get(name)); - } - } - -} 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 92975f38f..1474ef25f 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java @@ -5,7 +5,6 @@ import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import java.io.File; @@ -65,10 +64,9 @@ public void afterMethod(ITestResult result) { } @Test - public void testNginxDockerfileBuilder() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("nginx").getFile()); + public void author() throws Exception { - String imageId = buildImage(baseDir); + String imageId = buildImage(fileFromBuildTestResource("AUTHOR")); InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); assertThat(inspectImageResponse, not(nullValue())); @@ -77,27 +75,9 @@ public void testNginxDockerfileBuilder() throws Exception { assertThat(inspectImageResponse.getAuthor(), equalTo("Guillaume J. Charmes \"guillaume@dotcloud.com\"")); } - @Test(groups = "ignoreInCircleCi") - public void testNonstandard1() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader() - .getResource("nonstandard/subdirectory/Dockerfile-nonstandard").getFile()); - - buildImage(baseDir); - } - - @Test(groups = "ignoreInCircleCi") - public void testNonstandard2() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("nonstandard").getFile()); - File dockerFile = new File(Thread.currentThread().getContextClassLoader() - .getResource("nonstandard/subdirectory/Dockerfile-nonstandard").getFile()); - - dockerClient.buildImageCmd().withBaseDirectory(baseDir).withDockerfile(dockerFile).withNoCache(true) - .exec(new BuildImageResultCallback()).awaitImageId(); - } - @Test - public void testDockerBuilderFromTar() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFile").getFile()); + public void buildImageFromTar() throws Exception { + File baseDir = fileFromBuildTestResource("ADD/file"); Collection files = FileUtils.listFiles(baseDir, TrueFileFilter.INSTANCE, TrueFileFilter.INSTANCE); File tarFile = CompressArchiveUtil.archiveTARFiles(baseDir, files, UUID.randomUUID().toString()); String response = dockerfileBuild(new FileInputStream(tarFile)); @@ -105,41 +85,43 @@ public void testDockerBuilderFromTar() throws Exception { } @Test - public void testDockerBuilderAddUrl() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddUrl").getFile()); + public void onBuild() throws Exception { + File baseDir = fileFromBuildTestResource("ONBUILD/parent"); + + dockerClient.buildImageCmd(baseDir).withNoCache(true).withTag("docker-java-onbuild") + .exec(new BuildImageResultCallback()).awaitImageId(); + baseDir = fileFromBuildTestResource("ONBUILD/child"); String response = dockerfileBuild(baseDir); - assertThat(response, containsString("Docker")); + assertThat(response, containsString("Successfully executed testrun.sh")); } @Test - public void testDockerBuilderAddFileInSubfolder() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFileInSubfolder") - .getFile()); + public void addUrl() throws Exception { + File baseDir = fileFromBuildTestResource("ADD/url"); String response = dockerfileBuild(baseDir); - assertThat(response, containsString("Successfully executed testrun.sh")); + assertThat(response, containsString("Example Domain")); } @Test - public void testDockerBuilderAddFilesViaWildcard() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFilesViaWildcard") - .getFile()); + public void addFileInSubfolder() throws Exception { + File baseDir = fileFromBuildTestResource("ADD/fileInSubfolder"); String response = dockerfileBuild(baseDir); - assertThat(response, containsString("Successfully executed testinclude1.sh")); - assertThat(response, not(containsString("Successfully executed testinclude2.sh"))); + assertThat(response, containsString("Successfully executed testrun.sh")); } @Test - public void testDockerBuilderAddFolder() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testAddFolder").getFile()); + public void addFilesViaWildcard() throws Exception { + File baseDir = fileFromBuildTestResource("ADD/filesViaWildcard"); String response = dockerfileBuild(baseDir); - assertThat(response, containsString("Successfully executed testAddFolder.sh")); + assertThat(response, containsString("Successfully executed testinclude1.sh")); + assertThat(response, not(containsString("Successfully executed testinclude2.sh"))); } @Test - public void testDockerBuilderEnv() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testEnv").getFile()); + public void addFolder() throws Exception { + File baseDir = fileFromBuildTestResource("ADD/folder"); String response = dockerfileBuild(baseDir); - assertThat(response, containsString("Successfully executed testrun.sh")); + assertThat(response, containsString("Successfully executed testAddFolder.sh")); } private String dockerfileBuild(InputStream tarInputStream) throws Exception { @@ -168,80 +150,42 @@ private String execBuild(BuildImageCmd buildImageCmd) throws Exception { } @Test(expectedExceptions = {DockerClientException.class}) - public void testDockerfileIgnored() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerfileIgnored") - .getFile()); + public void dockerignoreDockerfileIgnored() throws Exception { + File baseDir = fileFromBuildTestResource("dockerignore/DockerfileIgnored"); dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId(); } @Test - public void testDockerfileNotIgnored() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerfileNotIgnored") - .getFile()); + public void dockerignoreDockerfileNotIgnored() throws Exception { + File baseDir = fileFromBuildTestResource("dockerignore/DockerfileNotIgnored"); dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId(); } @Test(expectedExceptions = {DockerClientException.class}) - public void testInvalidDockerIgnorePattern() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader() - .getResource("testInvalidDockerignorePattern").getFile()); + public void dockerignoreInvalidDockerIgnorePattern() throws Exception { + File baseDir = fileFromBuildTestResource("dockerignore/InvalidDockerignorePattern"); dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()).awaitImageId(); } - @Test(groups = "ignoreInCircleCi") - public void testDockerIgnore() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testDockerignore") - .getFile()); + @Test() + public void dockerignoreValidDockerIgnorePattern() throws Exception { + File baseDir = fileFromBuildTestResource("dockerignore/ValidDockerignorePattern"); String response = dockerfileBuild(baseDir); assertThat(response, containsString("/tmp/a/a /tmp/a/c /tmp/a/d")); } @Test - public void testNetCatDockerfileBuilder() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("netcat").getFile()); - - String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true).exec(new BuildImageResultCallback()) - .awaitImageId(); - - assertNotNull(imageId, "Not successful in build"); - - InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); - assertThat(inspectImageResponse, not(nullValue())); - assertThat(inspectImageResponse.getId(), not(nullValue())); - LOG.info("Image Inspect: {}", inspectImageResponse.toString()); - - CreateContainerResponse container = dockerClient.createContainerCmd(inspectImageResponse.getId()).exec(); - assertThat(container.getId(), not(isEmptyString())); - dockerClient.startContainerCmd(container.getId()).exec(); - - InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); - - assertThat(inspectContainerResponse.getId(), notNullValue()); - assertThat(inspectContainerResponse.getNetworkSettings().getPorts(), notNullValue()); - - // No use as such if not running on the server - // for (Ports.Port p : inspectContainerResponse.getNetworkSettings().getPorts().getAllPorts()) { - // int port = Integer.valueOf(p.getHostPort()); - // LOG.info("Checking port {} is open", port); - // assertThat(available(port), is(false)); - // } - dockerClient.stopContainerCmd(container.getId()).withTimeout(0).exec(); - - } - - @Test - public void testAddAndCopySubstitution() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testENVSubstitution") - .getFile()); + public void env() throws Exception { + File baseDir = fileFromBuildTestResource("ENV"); String response = dockerfileBuild(baseDir); assertThat(response, containsString("testENVSubstitution successfully completed")); } @Test - public void testBuildFromPrivateRegistry() throws Exception { + public void fromPrivateRegistry() throws Exception { File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("privateRegistry").getFile()); String imageId = buildImage(baseDir); @@ -282,17 +226,13 @@ public void testBuildFromPrivateRegistry() throws Exception { dockerClient.removeImageCmd("localhost:5000/testuser/busybox").withForce(true).exec(); - baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testBuildFromPrivateRegistry") - .getFile()); + baseDir = fileFromBuildTestResource("FROM/privateRegistry"); AuthConfigurations authConfigurations = new AuthConfigurations(); authConfigurations.addConfig(authConfig); - imageId = dockerClient.buildImageCmd(baseDir) - .withNoCache(true) - .withBuildAuthConfigs(authConfigurations) - .exec(new BuildImageResultCallback()) - .awaitImageId(); + imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true).withBuildAuthConfigs(authConfigurations) + .exec(new BuildImageResultCallback()).awaitImageId(); inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); assertThat(inspectImageResponse, not(nullValue())); @@ -301,8 +241,8 @@ public void testBuildFromPrivateRegistry() throws Exception { } @Test - public void testBuildArgs() throws Exception { - File baseDir = new File(Thread.currentThread().getContextClassLoader().getResource("testBuildArgs").getFile()); + public void buildArgs() throws Exception { + File baseDir = fileFromBuildTestResource("buildArgs"); String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true).withBuildArg("testArg", "abc") .exec(new BuildImageResultCallback()) @@ -314,4 +254,21 @@ public void testBuildArgs() throws Exception { assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc")); } + + public void dockerfileNotInBaseDirectory() throws Exception { + File baseDirectory = fileFromBuildTestResource("dockerfileNotInBaseDirectory"); + File dockerfile = fileFromBuildTestResource("dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile"); + BuildImageCmd command = dockerClient.buildImageCmd() + .withBaseDirectory(baseDirectory) + .withDockerfile(dockerfile); + + String response = execBuild(command); + + assertThat(response, containsString("Successfully executed testrun.sh")); + } + + private File fileFromBuildTestResource(String resource) { + return new File(Thread.currentThread().getContextClassLoader() + .getResource("buildTests/" + resource).getFile()); + } } diff --git a/src/test/resources/testAddFile/Dockerfile b/src/test/resources/buildTests/ADD/file/Dockerfile similarity index 100% rename from src/test/resources/testAddFile/Dockerfile rename to src/test/resources/buildTests/ADD/file/Dockerfile diff --git a/src/test/resources/testAddFile/testrun.sh b/src/test/resources/buildTests/ADD/file/testrun.sh similarity index 100% rename from src/test/resources/testAddFile/testrun.sh rename to src/test/resources/buildTests/ADD/file/testrun.sh diff --git a/src/test/resources/testAddFileInSubfolder/Dockerfile b/src/test/resources/buildTests/ADD/fileInSubfolder/Dockerfile similarity index 100% rename from src/test/resources/testAddFileInSubfolder/Dockerfile rename to src/test/resources/buildTests/ADD/fileInSubfolder/Dockerfile diff --git a/src/test/resources/testAddFileInSubfolder/files/testrun.sh b/src/test/resources/buildTests/ADD/fileInSubfolder/files/testrun.sh similarity index 100% rename from src/test/resources/testAddFileInSubfolder/files/testrun.sh rename to src/test/resources/buildTests/ADD/fileInSubfolder/files/testrun.sh diff --git a/src/test/resources/testAddMultipleFiles/Dockerfile b/src/test/resources/buildTests/ADD/files/Dockerfile similarity index 100% rename from src/test/resources/testAddMultipleFiles/Dockerfile rename to src/test/resources/buildTests/ADD/files/Dockerfile diff --git a/src/test/resources/testAddMultipleFiles/src1 b/src/test/resources/buildTests/ADD/files/src1 similarity index 100% rename from src/test/resources/testAddMultipleFiles/src1 rename to src/test/resources/buildTests/ADD/files/src1 diff --git a/src/test/resources/testAddMultipleFiles/src2 b/src/test/resources/buildTests/ADD/files/src2 similarity index 100% rename from src/test/resources/testAddMultipleFiles/src2 rename to src/test/resources/buildTests/ADD/files/src2 diff --git a/src/test/resources/testAddFilesViaWildcard/Dockerfile b/src/test/resources/buildTests/ADD/filesViaWildcard/Dockerfile similarity index 100% rename from src/test/resources/testAddFilesViaWildcard/Dockerfile rename to src/test/resources/buildTests/ADD/filesViaWildcard/Dockerfile diff --git a/src/test/resources/testAddFilesViaWildcard/folder1/testrun.sh b/src/test/resources/buildTests/ADD/filesViaWildcard/folder1/testrun.sh similarity index 100% rename from src/test/resources/testAddFilesViaWildcard/folder1/testrun.sh rename to src/test/resources/buildTests/ADD/filesViaWildcard/folder1/testrun.sh diff --git a/src/test/resources/testAddFilesViaWildcard/folder2/testinclude1.sh b/src/test/resources/buildTests/ADD/filesViaWildcard/folder2/testinclude1.sh similarity index 100% rename from src/test/resources/testAddFilesViaWildcard/folder2/testinclude1.sh rename to src/test/resources/buildTests/ADD/filesViaWildcard/folder2/testinclude1.sh diff --git a/src/test/resources/testAddFilesViaWildcard/ignore/testinclude2.sh b/src/test/resources/buildTests/ADD/filesViaWildcard/ignore/testinclude2.sh similarity index 100% rename from src/test/resources/testAddFilesViaWildcard/ignore/testinclude2.sh rename to src/test/resources/buildTests/ADD/filesViaWildcard/ignore/testinclude2.sh diff --git a/src/test/resources/testAddFolder/Dockerfile b/src/test/resources/buildTests/ADD/folder/Dockerfile similarity index 100% rename from src/test/resources/testAddFolder/Dockerfile rename to src/test/resources/buildTests/ADD/folder/Dockerfile diff --git a/src/test/resources/testAddFolder/folderA/testAddFolder.sh b/src/test/resources/buildTests/ADD/folder/folderA/testAddFolder.sh similarity index 100% rename from src/test/resources/testAddFolder/folderA/testAddFolder.sh rename to src/test/resources/buildTests/ADD/folder/folderA/testAddFolder.sh diff --git a/src/test/resources/testAddUrl/Dockerfile b/src/test/resources/buildTests/ADD/url/Dockerfile similarity index 71% rename from src/test/resources/testAddUrl/Dockerfile rename to src/test/resources/buildTests/ADD/url/Dockerfile index d9a0676d4..2b10c34e5 100644 --- a/src/test/resources/testAddUrl/Dockerfile +++ b/src/test/resources/buildTests/ADD/url/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:latest # Copy testrun.sh files into the container -ADD https://hub.docker.com/r/marcuslinke/busybox/ /tmp/docker_home.html +ADD http://www.example.com/index.html /tmp/some.html ADD ./testrun.sh /tmp/ RUN cp /tmp/testrun.sh /usr/local/bin/ && chmod +x /usr/local/bin/testrun.sh diff --git a/src/test/resources/buildTests/ADD/url/testrun.sh b/src/test/resources/buildTests/ADD/url/testrun.sh new file mode 100755 index 000000000..4d240d5ae --- /dev/null +++ b/src/test/resources/buildTests/ADD/url/testrun.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +cat /tmp/some.html + diff --git a/src/test/resources/nginx/Dockerfile b/src/test/resources/buildTests/AUTHOR/Dockerfile similarity index 81% rename from src/test/resources/nginx/Dockerfile rename to src/test/resources/buildTests/AUTHOR/Dockerfile index 2d0fa24cb..32ffcedc7 100644 --- a/src/test/resources/nginx/Dockerfile +++ b/src/test/resources/buildTests/AUTHOR/Dockerfile @@ -9,4 +9,4 @@ MAINTAINER Guillaume J. Charmes "guillaume@dotcloud.com" RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list RUN apt-get update -RUN apt-get install -y inotify-tools nginx apache2 openssh-server \ No newline at end of file +RUN apt-get install -y nginx \ No newline at end of file diff --git a/src/test/resources/testENVSubstitution/Dockerfile b/src/test/resources/buildTests/ENV/Dockerfile similarity index 100% rename from src/test/resources/testENVSubstitution/Dockerfile rename to src/test/resources/buildTests/ENV/Dockerfile diff --git a/src/test/resources/testENVSubstitution/subst-file-2-abc123.txt b/src/test/resources/buildTests/ENV/subst-file-2-abc123.txt similarity index 100% rename from src/test/resources/testENVSubstitution/subst-file-2-abc123.txt rename to src/test/resources/buildTests/ENV/subst-file-2-abc123.txt diff --git a/src/test/resources/testENVSubstitution/subst-file-abc123.txt b/src/test/resources/buildTests/ENV/subst-file-abc123.txt similarity index 100% rename from src/test/resources/testENVSubstitution/subst-file-abc123.txt rename to src/test/resources/buildTests/ENV/subst-file-abc123.txt diff --git a/src/test/resources/testENVSubstitution/testrun.sh b/src/test/resources/buildTests/ENV/testrun.sh similarity index 100% rename from src/test/resources/testENVSubstitution/testrun.sh rename to src/test/resources/buildTests/ENV/testrun.sh diff --git a/src/test/resources/testBuildFromPrivateRegistry/Dockerfile b/src/test/resources/buildTests/FROM/privateRegistry/Dockerfile similarity index 100% rename from src/test/resources/testBuildFromPrivateRegistry/Dockerfile rename to src/test/resources/buildTests/FROM/privateRegistry/Dockerfile diff --git a/src/test/resources/testAddOnBuild/test/Dockerfile b/src/test/resources/buildTests/ONBUILD/child/Dockerfile similarity index 100% rename from src/test/resources/testAddOnBuild/test/Dockerfile rename to src/test/resources/buildTests/ONBUILD/child/Dockerfile diff --git a/src/test/resources/testAddOnBuild/test/testrun.sh b/src/test/resources/buildTests/ONBUILD/child/testrun.sh similarity index 100% rename from src/test/resources/testAddOnBuild/test/testrun.sh rename to src/test/resources/buildTests/ONBUILD/child/testrun.sh diff --git a/src/test/resources/testAddOnBuild/onbuild/Dockerfile b/src/test/resources/buildTests/ONBUILD/parent/Dockerfile similarity index 100% rename from src/test/resources/testAddOnBuild/onbuild/Dockerfile rename to src/test/resources/buildTests/ONBUILD/parent/Dockerfile diff --git a/src/test/resources/testBuildArgs/Dockerfile b/src/test/resources/buildTests/buildArgs/Dockerfile similarity index 100% rename from src/test/resources/testBuildArgs/Dockerfile rename to src/test/resources/buildTests/buildArgs/Dockerfile diff --git a/src/test/resources/testDockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile b/src/test/resources/buildTests/dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile similarity index 100% rename from src/test/resources/testDockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile rename to src/test/resources/buildTests/dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile diff --git a/src/test/resources/testDockerfileNotInBaseDirectory/testrunFolder/testrun.sh b/src/test/resources/buildTests/dockerfileNotInBaseDirectory/testrunFolder/testrun.sh similarity index 100% rename from src/test/resources/testDockerfileNotInBaseDirectory/testrunFolder/testrun.sh rename to src/test/resources/buildTests/dockerfileNotInBaseDirectory/testrunFolder/testrun.sh diff --git a/src/test/resources/testDockerfileIgnored/.dockerignore b/src/test/resources/buildTests/dockerignore/DockerfileIgnored/.dockerignore similarity index 100% rename from src/test/resources/testDockerfileIgnored/.dockerignore rename to src/test/resources/buildTests/dockerignore/DockerfileIgnored/.dockerignore diff --git a/src/test/resources/testDockerfileIgnored/Dockerfile b/src/test/resources/buildTests/dockerignore/DockerfileIgnored/Dockerfile similarity index 100% rename from src/test/resources/testDockerfileIgnored/Dockerfile rename to src/test/resources/buildTests/dockerignore/DockerfileIgnored/Dockerfile diff --git a/src/test/resources/testDockerfileIgnored/testrun.sh b/src/test/resources/buildTests/dockerignore/DockerfileIgnored/testrun.sh similarity index 100% rename from src/test/resources/testDockerfileIgnored/testrun.sh rename to src/test/resources/buildTests/dockerignore/DockerfileIgnored/testrun.sh diff --git a/src/test/resources/testDockerfileNotIgnored/.dockerignore b/src/test/resources/buildTests/dockerignore/DockerfileNotIgnored/.dockerignore similarity index 100% rename from src/test/resources/testDockerfileNotIgnored/.dockerignore rename to src/test/resources/buildTests/dockerignore/DockerfileNotIgnored/.dockerignore diff --git a/src/test/resources/testDockerfileNotIgnored/Dockerfile b/src/test/resources/buildTests/dockerignore/DockerfileNotIgnored/Dockerfile similarity index 100% rename from src/test/resources/testDockerfileNotIgnored/Dockerfile rename to src/test/resources/buildTests/dockerignore/DockerfileNotIgnored/Dockerfile diff --git a/src/test/resources/testInvalidDockerignorePattern/.dockerignore b/src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/.dockerignore similarity index 100% rename from src/test/resources/testInvalidDockerignorePattern/.dockerignore rename to src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/.dockerignore diff --git a/src/test/resources/testInvalidDockerignorePattern/Dockerfile b/src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/Dockerfile similarity index 100% rename from src/test/resources/testInvalidDockerignorePattern/Dockerfile rename to src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/Dockerfile diff --git a/src/test/resources/testInvalidDockerignorePattern/testrun.sh b/src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/testrun.sh similarity index 100% rename from src/test/resources/testInvalidDockerignorePattern/testrun.sh rename to src/test/resources/buildTests/dockerignore/InvalidDockerignorePattern/testrun.sh diff --git a/src/test/resources/testDockerignore/.dockerignore b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/.dockerignore similarity index 100% rename from src/test/resources/testDockerignore/.dockerignore rename to src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/.dockerignore diff --git a/src/test/resources/testDockerignore/Dockerfile b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/Dockerfile similarity index 100% rename from src/test/resources/testDockerignore/Dockerfile rename to src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/Dockerfile diff --git a/src/test/resources/testDockerignore/a/a b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/a similarity index 100% rename from src/test/resources/testDockerignore/a/a rename to src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/a diff --git a/src/test/resources/testDockerignore/a/b b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/b similarity index 100% rename from src/test/resources/testDockerignore/a/b rename to src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/b diff --git a/src/test/resources/testDockerignore/a/c b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/c similarity index 100% rename from src/test/resources/testDockerignore/a/c rename to src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/c diff --git a/src/test/resources/testDockerignore/a/d b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/d similarity index 100% rename from src/test/resources/testDockerignore/a/d rename to src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/a/d diff --git a/src/test/resources/testDockerignore/testrun.sh b/src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/testrun.sh similarity index 100% rename from src/test/resources/testDockerignore/testrun.sh rename to src/test/resources/buildTests/dockerignore/ValidDockerignorePattern/testrun.sh diff --git a/src/test/resources/netcat/Dockerfile b/src/test/resources/netcat/Dockerfile deleted file mode 100644 index 1974f1063..000000000 --- a/src/test/resources/netcat/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -# Firefox over VNC -# -# VERSION 0.3 - -FROM ubuntu:latest - -#install netcat -RUN apt-get install -y netcat - -EXPOSE 6900 -CMD ["nc", "-l", "6900"] \ No newline at end of file diff --git a/src/test/resources/nonstandard/subdirectory/Dockerfile-nonstandard b/src/test/resources/nonstandard/subdirectory/Dockerfile-nonstandard deleted file mode 100644 index 2d0fa24cb..000000000 --- a/src/test/resources/nonstandard/subdirectory/Dockerfile-nonstandard +++ /dev/null @@ -1,12 +0,0 @@ -# Nginx -# -# VERSION 0.0.1 - -FROM ubuntu:latest -MAINTAINER Guillaume J. Charmes "guillaume@dotcloud.com" - -# make sure the package repository is up to date -RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list -RUN apt-get update - -RUN apt-get install -y inotify-tools nginx apache2 openssh-server \ No newline at end of file diff --git a/src/test/resources/testAddUrl/testrun.sh b/src/test/resources/testAddUrl/testrun.sh deleted file mode 100755 index 8eb4630b3..000000000 --- a/src/test/resources/testAddUrl/testrun.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -cat /tmp/docker_home.html - diff --git a/src/test/resources/testEnv/Dockerfile b/src/test/resources/testEnv/Dockerfile deleted file mode 100644 index a0a084633..000000000 --- a/src/test/resources/testEnv/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM ubuntu:latest - -ENV varA ./subFolder -ENV varB $varA/testrun.sh - -ADD $varB /tmp/ - -RUN cp /tmp/testrun.sh /usr/local/bin/ && chmod +x /usr/local/bin/testrun.sh - -CMD ["testrun.sh"] diff --git a/src/test/resources/testEnv/subFolder/testrun.sh b/src/test/resources/testEnv/subFolder/testrun.sh deleted file mode 100755 index 14259aa77..000000000 --- a/src/test/resources/testEnv/subFolder/testrun.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -echo "Successfully executed testrun.sh" \ No newline at end of file From 4280ee7c639605291f8acda039051395055414ae Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Tue, 7 Jun 2016 22:08:41 +0200 Subject: [PATCH 153/855] Use expectExceptions in test annotation --- .../github/dockerjava/netty/exec/AuthCmdExecTest.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) 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 66ac1bce3..690d478f4 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/AuthCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/AuthCmdExecTest.java @@ -44,14 +44,8 @@ public void testAuth() throws Exception { assertEquals(response.getStatus(), "Login Succeeded"); } - @Test() + @Test(expectedExceptions = UnauthorizedException.class) public void testAuthInvalid() throws Exception { - - try { - DockerClientBuilder.getInstance(config("garbage")).build().authCmd().exec(); - fail("Expected a UnauthorizedException caused by a bad password."); - } catch (UnauthorizedException e) { - assertEquals(e.getMessage(), "Wrong login/password, please try again\n"); - } + DockerClientBuilder.getInstance(config("garbage")).build().authCmd().exec(); } } From 84cf070278343867bf2a984a6fa18839a5a635e5 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Tue, 7 Jun 2016 22:09:59 +0200 Subject: [PATCH 154/855] Fix test for v.1.23 --- .../netty/exec/ExecStartCmdExecTest.java | 60 +++++++++++++------ 1 file changed, 43 insertions(+), 17 deletions(-) diff --git a/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java index 2938ac8c0..e87c56d74 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java @@ -46,7 +46,7 @@ public void afterMethod(ITestResult result) { super.afterMethod(result); } - @Test(groups = "ignoreInCircleCi") + @Test() public void execStart() throws Exception { String containerName = "generated_" + new SecureRandom().nextInt(); @@ -58,9 +58,14 @@ public void execStart() throws Exception { dockerClient.startContainerCmd(container.getId()).exec(); ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId()) - .withAttachStdout(true).withCmd("touch", "/execStartTest.log").exec(); - dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false) - .exec(new ExecStartResultCallback(System.out, System.err)).awaitCompletion(); + .withAttachStdout(true) + .withCmd("touch", "/execStartTest.log") + .exec(); + + dockerClient.execStartCmd(execCreateCmdResponse.getId()) + .withDetach(false) + .exec(new ExecStartResultCallback(System.out, System.err)) + .awaitCompletion(); InputStream response = dockerClient.copyArchiveFromContainerCmd(container.getId(), "/execStartTest.log").exec(); @@ -73,7 +78,7 @@ public void execStart() throws Exception { assertTrue(responseAsString.length() > 0); } - @Test(groups = "ignoreInCircleCi") + @Test() public void execStartAttached() throws Exception { String containerName = "generated_" + new SecureRandom().nextInt(); @@ -85,9 +90,14 @@ public void execStartAttached() throws Exception { dockerClient.startContainerCmd(container.getId()).exec(); ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId()) - .withAttachStdout(true).withCmd("touch", "/execStartTest.log").exec(); - dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false) - .exec(new ExecStartResultCallback(System.out, System.err)).awaitCompletion(); + .withAttachStdout(true) + .withCmd("touch", "/execStartTest.log") + .exec(); + + dockerClient.execStartCmd(execCreateCmdResponse.getId()) + .withDetach(false) + .exec(new ExecStartResultCallback(System.out, System.err)) + .awaitCompletion(); InputStream response = dockerClient.copyArchiveFromContainerCmd(container.getId(), "/execStartTest.log").exec(); Boolean bytesAvailable = response.available() > 0; @@ -99,7 +109,7 @@ public void execStartAttached() throws Exception { assertTrue(responseAsString.length() > 0); } - @Test(groups = "ignoreInCircleCi") + @Test() public void execStartAttachStdin() throws Exception { String containerName = "generated_" + new SecureRandom().nextInt(); @@ -115,14 +125,23 @@ public void execStartAttachStdin() throws Exception { ByteArrayOutputStream stdout = new ByteArrayOutputStream(); ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId()) - .withAttachStdout(true).withAttachStdin(true).withCmd("cat").exec(); - boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withTty(true).withStdIn(stdin) - .exec(new ExecStartResultCallback(stdout, System.err)).awaitCompletion(5, TimeUnit.SECONDS); + .withAttachStdout(true) + .withAttachStdin(true) + .withCmd("cat") + .exec(); + + boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId()) + .withDetach(false) + .withTty(true) + .withStdIn(stdin) + .exec(new ExecStartResultCallback(stdout, System.err)) + .awaitCompletion(5, TimeUnit.SECONDS); assertTrue(completed, "The process was not finished."); assertEquals(stdout.toString("UTF-8"), "STDIN\n"); } + @Test() public void execStartAttachStdinToShell() throws Exception { String containerName = "generated_" + new SecureRandom().nextInt(); @@ -156,7 +175,7 @@ public void execStartAttachStdinToShell() throws Exception { assertThat(stdout.toString(), containsString("etc\n")); } - @Test(groups = "ignoreInCircleCi") + @Test() public void execStartNotAttachedStdin() throws Exception { String containerName = "generated_" + new SecureRandom().nextInt(); @@ -172,11 +191,18 @@ public void execStartNotAttachedStdin() throws Exception { ByteArrayOutputStream stdout = new ByteArrayOutputStream(); ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId()) - .withAttachStdout(true).withAttachStdin(false).withCmd("/bin/sh").exec(); - boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withStdIn(stdin) - .exec(new ExecStartResultCallback(stdout, System.err)).awaitCompletion(5, TimeUnit.SECONDS); + .withAttachStdout(true) + .withAttachStdin(false) + .withCmd("/bin/sh").exec(); - assertTrue(completed, "The process was not finished."); + boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId()) + .withDetach(false) + .withStdIn(stdin) + .exec(new ExecStartResultCallback(stdout, System.err)) + .awaitCompletion(5, TimeUnit.SECONDS); + + // with v1.22 of the remote api the server closed the connection when no stdin was attached while exec create, so completed was true + assertFalse(completed, "The process was not finished."); assertEquals(stdout.toString(), ""); } } From 63f276a99c0f5245e47e869431d6c2b11a2dd101 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Tue, 7 Jun 2016 23:36:25 +0200 Subject: [PATCH 155/855] Fix load certs from file system --- .../dockerjava/core/LocalDirectorySSLConfig.java | 15 +++++++++++++-- .../dockerjava/core/util/CertificateUtils.java | 10 +--------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/LocalDirectorySSLConfig.java b/src/main/java/com/github/dockerjava/core/LocalDirectorySSLConfig.java index e39a2bc40..961c282de 100644 --- a/src/main/java/com/github/dockerjava/core/LocalDirectorySSLConfig.java +++ b/src/main/java/com/github/dockerjava/core/LocalDirectorySSLConfig.java @@ -2,7 +2,10 @@ import static com.google.common.base.Preconditions.checkNotNull; +import java.io.File; import java.io.Serializable; +import java.nio.file.Files; +import java.nio.file.Paths; import java.security.Security; import javax.net.ssl.SSLContext; @@ -50,9 +53,17 @@ public SSLContext getSSLContext() { System.setProperty("https.protocols", httpProtocols); } - sslConfig.keyStore(CertificateUtils.createKeyStore(dockerCertPath)); + String caPemPath = dockerCertPath + File.separator + "ca.pem"; + String keyPemPath = dockerCertPath + File.separator + "key.pem"; + String certPemPath = dockerCertPath + File.separator + "cert.pem"; + + String keypem = new String(Files.readAllBytes(Paths.get(keyPemPath))); + String certpem = new String(Files.readAllBytes(Paths.get(certPemPath))); + String capem = new String(Files.readAllBytes(Paths.get(caPemPath))); + + sslConfig.keyStore(CertificateUtils.createKeyStore(keypem, certpem)); sslConfig.keyStorePassword("docker"); - sslConfig.trustStore(CertificateUtils.createTrustStore(dockerCertPath)); + sslConfig.trustStore(CertificateUtils.createTrustStore(capem)); return sslConfig.createSSLContext(); 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 6e1925630..c760331d6 100644 --- a/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java +++ b/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java @@ -18,6 +18,7 @@ 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; @@ -49,15 +50,6 @@ public static boolean verifyCertificatesExist(String dockerCertPath) { return result; } - /** - * @param dockerCertPath with standard named files. - */ - public static KeyStore createKeyStore(final String dockerCertPath) throws NoSuchAlgorithmException, - InvalidKeySpecException, IOException, CertificateException, KeyStoreException { - return createKeyStore("key.pem", "cert.pem"); - } - - @SuppressFBWarnings(value = "NP_NULL_ON_SOME_PATH_FROM_RETURN_VALUE") public static KeyStore createKeyStore(final String keypem, final String certpem) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException, CertificateException, KeyStoreException { From fefd16017d70b29e1d1f337bf9338ce0cb9543a3 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Tue, 7 Jun 2016 23:38:37 +0200 Subject: [PATCH 156/855] Update CHANGELOG.md --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f55b2cd75..6125ab5b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ Change Log === +3.0.0-SNAPSHOT +--- + +All changes +* [#529] (https://github.com/docker-java/docker-java/pull/529) Refactor CertUtils. Support ECDSA and PrivateKey + v3.0.0 --- Notes From 605815651521f3270e01b67b0e89b183e10cedbe Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Tue, 7 Jun 2016 23:39:22 +0200 Subject: [PATCH 157/855] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6125ab5b7..1f3b7e9b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ Change Log === -3.0.0-SNAPSHOT +3.0.1-SNAPSHOT --- All changes From 3a2dcc490879d345c6c96b215f1e47c995d293f5 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 8 Jun 2016 21:59:57 +0300 Subject: [PATCH 158/855] Implemented Device parser (#593) * Implement Device parser Signed-off-by: Kanstantsin Shautsou * Add more tests, fix. --- .../github/dockerjava/api/model/Device.java | 76 +++++++++++++++ .../dockerjava/api/model/DeviceTest.java | 95 +++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 src/test/java/com/github/dockerjava/api/model/DeviceTest.java diff --git a/src/main/java/com/github/dockerjava/api/model/Device.java b/src/main/java/com/github/dockerjava/api/model/Device.java index 9240239b1..f2b75e3f5 100644 --- a/src/main/java/com/github/dockerjava/api/model/Device.java +++ b/src/main/java/com/github/dockerjava/api/model/Device.java @@ -1,6 +1,8 @@ package com.github.dockerjava.api.model; import static com.google.common.base.Preconditions.checkNotNull; +import static org.apache.commons.lang.BooleanUtils.isNotTrue; +import static org.apache.commons.lang.StringUtils.isEmpty; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; @@ -9,6 +11,11 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import javax.annotation.Nonnull; +import java.util.HashMap; +import java.util.Map; +import java.util.StringTokenizer; + @JsonInclude(Include.NON_NULL) public class Device { @@ -45,6 +52,75 @@ public String getPathOnHost() { return pathOnHost; } + /** + * @link https://github.com/docker/docker/blob/6b4a46f28266031ce1a1315f17fb69113a06efe1/runconfig/opts/parse_test.go#L468 + */ + @Nonnull + public static Device parse(@Nonnull String deviceStr) { + String src = ""; + String dst = ""; + String permissions = "rwm"; + final String[] arr = deviceStr.trim().split(":"); + // java String.split() returns wrong length, use tokenizer instead + switch (new StringTokenizer(deviceStr, ":").countTokens()) { + case 3: { + // Mismatches docker code logic. While there is no validations after parsing, checking heregit + if (validDeviceMode(arr[2])) { + permissions = arr[2]; + } else { + throw new IllegalArgumentException("Invalid device specification: " + deviceStr); + } + } + case 2: { + if (validDeviceMode(arr[1])) { + permissions = arr[1]; + } else { + dst = arr[1]; + } + } + case 1: { + src = arr[0]; + break; + } + default: { + throw new IllegalArgumentException("Invalid device specification: " + deviceStr); + } + } + + if (isEmpty(dst)) { + dst = src; + } + + return new Device(permissions, dst, src); + } + + /** + * ValidDeviceMode checks if the mode for device is valid or not. + * Valid mode is a composition of r (read), w (write), and m (mknod). + * + * @link https://github.com/docker/docker/blob/6b4a46f28266031ce1a1315f17fb69113a06efe1/runconfig/opts/parse.go#L796 + */ + private static boolean validDeviceMode(String deviceMode) { + Map validModes = new HashMap<>(3); + validModes.put("r", true); + validModes.put("w", true); + validModes.put("m", true); + + if (isEmpty(deviceMode)) { + return false; + } + + for (char ch : deviceMode.toCharArray()) { + final String mode = String.valueOf(ch); + if (isNotTrue(validModes.get(mode))) { + return false; // wrong mode + } + validModes.put(mode, false); + } + + return true; + } + @Override public boolean equals(Object obj) { if (obj instanceof Device) { diff --git a/src/test/java/com/github/dockerjava/api/model/DeviceTest.java b/src/test/java/com/github/dockerjava/api/model/DeviceTest.java new file mode 100644 index 000000000..5c48c4886 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/DeviceTest.java @@ -0,0 +1,95 @@ +package com.github.dockerjava.api.model; + +import org.testng.annotations.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static junit.framework.Assert.fail; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.contains; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; + +/** + * @author Kanstantsin Shautsou + */ +public class DeviceTest { + + public static List validPaths = Arrays.asList( + "/home", + "/home:/home", + "/home:/something/else", + "/with space", + "/home:/with space", + "relative:/absolute-path", + "hostPath:/containerPath:r", + "/hostPath:/containerPath:rw", + "/hostPath:/containerPath:mrw" + ); + + public static HashMap badPaths = new LinkedHashMap() {{ + put("", "bad format for path: "); + // TODO implement ValidatePath +// put("./", "./ is not an absolute path"); +// put("../", "../ is not an absolute path"); +// put("/:../", "../ is not an absolute path"); +// put("/:path", "path is not an absolute path"); +// put(":", "bad format for path: :"); +// put("/tmp:", " is not an absolute path"); +// put(":test", "bad format for path: :test"); +// put(":/test", "bad format for path: :/test"); +// put("tmp:", " is not an absolute path"); +// put(":test:", "bad format for path: :test:"); +// put("::", "bad format for path: ::"); +// put(":::", "bad format for path: :::"); +// put("/tmp:::", "bad format for path: /tmp:::"); +// put(":/tmp::", "bad format for path: :/tmp::"); +// put("path:ro", "ro is not an absolute path"); +// put("path:rr", "rr is not an absolute path"); + put("a:/b:ro", "bad mode specified: ro"); + put("a:/b:rr", "bad mode specified: rr"); + }}; + + @Test + public void testParse() throws Exception { + assertThat(Device.parse("/dev/sda:/dev/xvdc:r"), + equalTo(new Device("r", "/dev/xvdc", "/dev/sda"))); + + assertThat(Device.parse("/dev/snd:rw"), + equalTo(new Device("rw", "/dev/snd", "/dev/snd"))); + + assertThat(Device.parse("/dev/snd:/something"), + equalTo(new Device("rwm", "/something", "/dev/snd"))); + + assertThat(Device.parse("/dev/snd:/something:rw"), + equalTo(new Device("rw", "/something", "/dev/snd"))); + + } + + @Test + public void testParseBadPaths() { + for (Map.Entry entry : badPaths.entrySet()) { + final String deviceStr = entry.getKey(); + try { + Device.parse(deviceStr); + fail("Should fail because: " + entry.getValue() + " '" + deviceStr + "'"); + } catch (IllegalArgumentException ex) { + assertThat(ex.getMessage(), containsString("Invalid device specification:")); + } + } + } + + @Test + public void testParseValidPaths() { + for (String path : validPaths) { + Device.parse(path); + } + } +} From 72597d723e56d84890d3821d734a46cc2e0a9441 Mon Sep 17 00:00:00 2001 From: Marcus Linke Date: Thu, 9 Jun 2016 23:44:04 +0200 Subject: [PATCH 159/855] Complement logging tests --- .../client/AbstractDockerClientTest.java | 18 ++++ .../core/command/LogContainerCmdImplTest.java | 93 ++++++++++++++----- .../netty/exec/LogContainerCmdExecTest.java | 93 ++++++++++++++----- 3 files changed, 162 insertions(+), 42 deletions(-) diff --git a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java index 231e709c1..1a52bbd3f 100644 --- a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java +++ b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java @@ -225,8 +225,21 @@ protected String containerLog(String containerId) throws Exception { public static class LogContainerTestCallback extends LogContainerResultCallback { protected final StringBuffer log = new StringBuffer(); + List collectedFrames = new ArrayList(); + + boolean collectFrames = false; + + public LogContainerTestCallback() { + this(false); + } + + public LogContainerTestCallback(boolean collectFrames) { + this.collectFrames = collectFrames; + } + @Override public void onNext(Frame frame) { + if(collectFrames) collectedFrames.add(frame); log.append(new String(frame.getPayload())); } @@ -234,6 +247,11 @@ public void onNext(Frame frame) { public String toString() { return log.toString(); } + + + public List getCollectedFrames() { + return collectedFrames; + } } protected String buildImage(File baseDir) throws Exception { diff --git a/src/test/java/com/github/dockerjava/core/command/LogContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/LogContainerCmdImplTest.java index 817179eb2..869bcbb1a 100644 --- a/src/test/java/com/github/dockerjava/core/command/LogContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/LogContainerCmdImplTest.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; @@ -17,6 +18,7 @@ import org.testng.annotations.Test; import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.api.model.StreamType; import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.client.AbstractDockerClientTest; @@ -44,31 +46,65 @@ public void afterMethod(ITestResult result) { } @Test - public void asyncLogContainer() throws Exception { + public void asyncLogContainerWithTtyEnabled() throws Exception { - String snippet = "hello world"; - - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet) + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("/bin/sh", "-c", "while true; do echo hello; sleep 1; done") + .withTty(true) .exec(); LOG.info("Created container: {}", container.toString()); assertThat(container.getId(), not(isEmptyString())); - dockerClient.startContainerCmd(container.getId()).exec(); + dockerClient.startContainerCmd(container.getId()) + .exec(); - int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback()) - .awaitStatusCode(); + LogContainerTestCallback loggingCallback = new LogContainerTestCallback(true); - assertThat(exitCode, equalTo(0)); + // this essentially test the since=0 case + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .withFollowStream(true) + .withTailAll() + .exec(loggingCallback); - LogContainerTestCallback loggingCallback = new LogContainerTestCallback(); + loggingCallback.awaitCompletion(3, TimeUnit.SECONDS); + + assertTrue(loggingCallback.toString().contains("hello")); + + assertEquals(loggingCallback.getCollectedFrames().get(0).getStreamType(), StreamType.RAW); + } + + @Test + public void asyncLogContainerWithTtyDisabled() throws Exception { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("/bin/sh", "-c", "while true; do echo hello; sleep 1; done") + .withTty(false) + .exec(); + + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()) + .exec(); + + LogContainerTestCallback loggingCallback = new LogContainerTestCallback(true); // this essentially test the since=0 case - dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback); + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .withFollowStream(true) + .withTailAll() + .exec(loggingCallback); - loggingCallback.awaitCompletion(); + loggingCallback.awaitCompletion(3, TimeUnit.SECONDS); - assertTrue(loggingCallback.toString().contains(snippet)); + assertTrue(loggingCallback.toString().contains("hello")); + + assertEquals(loggingCallback.getCollectedFrames().get(0).getStreamType(), StreamType.STDOUT); } @Test @@ -105,7 +141,8 @@ public void asyncMultipleLogContainer() throws Exception { String snippet = "hello world"; - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet) + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("/bin/echo", snippet) .exec(); LOG.info("Created container: {}", container.toString()); @@ -113,26 +150,36 @@ public void asyncMultipleLogContainer() throws Exception { dockerClient.startContainerCmd(container.getId()).exec(); - int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback()) + int exitCode = dockerClient.waitContainerCmd(container.getId()) + .exec(new WaitContainerResultCallback()) .awaitStatusCode(); assertThat(exitCode, equalTo(0)); LogContainerTestCallback loggingCallback = new LogContainerTestCallback(); - dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback); + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .exec(loggingCallback); loggingCallback.close(); loggingCallback = new LogContainerTestCallback(); - dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback); + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .exec(loggingCallback); loggingCallback.close(); loggingCallback = new LogContainerTestCallback(); - dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback); + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .exec(loggingCallback); loggingCallback.awaitCompletion(); @@ -143,7 +190,8 @@ public void asyncMultipleLogContainer() throws Exception { public void asyncLogContainerWithSince() throws Exception { String snippet = "hello world"; - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet) + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("/bin/echo", snippet) .exec(); LOG.info("Created container: {}", container.toString()); @@ -153,19 +201,22 @@ public void asyncLogContainerWithSince() throws Exception { dockerClient.startContainerCmd(container.getId()).exec(); - int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback()) + int exitCode = dockerClient.waitContainerCmd(container.getId()) + .exec(new WaitContainerResultCallback()) .awaitStatusCode(); assertThat(exitCode, equalTo(0)); LogContainerTestCallback loggingCallback = new LogContainerTestCallback(); - dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withSince(timestamp) + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .withSince(timestamp) .exec(loggingCallback); loggingCallback.awaitCompletion(); assertThat(loggingCallback.toString(), containsString(snippet)); } - } diff --git a/src/test/java/com/github/dockerjava/netty/exec/LogContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/LogContainerCmdExecTest.java index 310994755..fe408ac18 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/LogContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/LogContainerCmdExecTest.java @@ -8,6 +8,7 @@ import java.io.IOException; import java.lang.reflect.Method; +import java.util.concurrent.TimeUnit; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; @@ -18,6 +19,7 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.api.model.StreamType; import com.github.dockerjava.core.command.WaitContainerResultCallback; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; @@ -45,31 +47,65 @@ public void afterMethod(ITestResult result) { } @Test - public void asyncLogContainer() throws Exception { + public void asyncLogContainerWithTtyEnabled() throws Exception { - String snippet = "hello world"; - - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet) + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("/bin/sh", "-c", "while true; do echo hello; sleep 1; done") + .withTty(true) .exec(); LOG.info("Created container: {}", container.toString()); assertThat(container.getId(), not(isEmptyString())); - dockerClient.startContainerCmd(container.getId()).exec(); + dockerClient.startContainerCmd(container.getId()) + .exec(); - int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback()) - .awaitStatusCode(); + LogContainerTestCallback loggingCallback = new LogContainerTestCallback(true); - assertThat(exitCode, equalTo(0)); + // this essentially test the since=0 case + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .withFollowStream(true) + .withTailAll() + .exec(loggingCallback); - LogContainerTestCallback loggingCallback = new LogContainerTestCallback(); + loggingCallback.awaitCompletion(3, TimeUnit.SECONDS); + + assertTrue(loggingCallback.toString().contains("hello")); + + assertEquals(loggingCallback.getCollectedFrames().get(0).getStreamType(), StreamType.RAW); + } + + @Test + public void asyncLogContainerWithTtyDisabled() throws Exception { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("/bin/sh", "-c", "while true; do echo hello; sleep 1; done") + .withTty(false) + .exec(); + + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()) + .exec(); + + LogContainerTestCallback loggingCallback = new LogContainerTestCallback(true); // this essentially test the since=0 case - dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback); + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .withFollowStream(true) + .withTailAll() + .exec(loggingCallback); - loggingCallback.awaitCompletion(); + loggingCallback.awaitCompletion(3, TimeUnit.SECONDS); - assertTrue(loggingCallback.toString().contains(snippet)); + assertTrue(loggingCallback.toString().contains("hello")); + + assertEquals(loggingCallback.getCollectedFrames().get(0).getStreamType(), StreamType.STDOUT); } @Test @@ -106,7 +142,8 @@ public void asyncMultipleLogContainer() throws Exception { String snippet = "hello world"; - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet) + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("/bin/echo", snippet) .exec(); LOG.info("Created container: {}", container.toString()); @@ -114,26 +151,36 @@ public void asyncMultipleLogContainer() throws Exception { dockerClient.startContainerCmd(container.getId()).exec(); - int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback()) + int exitCode = dockerClient.waitContainerCmd(container.getId()) + .exec(new WaitContainerResultCallback()) .awaitStatusCode(); assertThat(exitCode, equalTo(0)); LogContainerTestCallback loggingCallback = new LogContainerTestCallback(); - dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback); + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .exec(loggingCallback); loggingCallback.close(); loggingCallback = new LogContainerTestCallback(); - dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback); + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .exec(loggingCallback); loggingCallback.close(); loggingCallback = new LogContainerTestCallback(); - dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).exec(loggingCallback); + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .exec(loggingCallback); loggingCallback.awaitCompletion(); @@ -144,7 +191,8 @@ public void asyncMultipleLogContainer() throws Exception { public void asyncLogContainerWithSince() throws Exception { String snippet = "hello world"; - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/echo", snippet) + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("/bin/echo", snippet) .exec(); LOG.info("Created container: {}", container.toString()); @@ -154,19 +202,22 @@ public void asyncLogContainerWithSince() throws Exception { dockerClient.startContainerCmd(container.getId()).exec(); - int exitCode = dockerClient.waitContainerCmd(container.getId()).exec(new WaitContainerResultCallback()) + int exitCode = dockerClient.waitContainerCmd(container.getId()) + .exec(new WaitContainerResultCallback()) .awaitStatusCode(); assertThat(exitCode, equalTo(0)); LogContainerTestCallback loggingCallback = new LogContainerTestCallback(); - dockerClient.logContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withSince(timestamp) + dockerClient.logContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .withSince(timestamp) .exec(loggingCallback); loggingCallback.awaitCompletion(); assertThat(loggingCallback.toString(), containsString(snippet)); } - } From 9ae14cb9567b8257be26f41423f94cf61391969c Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Mon, 13 Jun 2016 22:56:48 +0200 Subject: [PATCH 160/855] Refactor configuration of SSL to allow override with custom config (#596) * Refactor configuration of SSL to allow override with custom config * Store SSLConfig instead SSLContext * avoid NPE * prepare release * Coding style changes --- pom.xml | 2 +- .../api/command/DockerCmdExecFactory.java | 4 - .../core/DefaultDockerClientConfig.java | 455 ++++++++++++++++++ .../dockerjava/core/DockerClientBuilder.java | 4 +- .../dockerjava/core/DockerClientConfig.java | 436 +---------------- .../dockerjava/core/DockerClientImpl.java | 4 +- .../jaxrs/DockerCmdExecFactoryImpl.java | 28 +- .../netty/DockerCmdExecFactoryImpl.java | 38 +- .../client/AbstractDockerClientTest.java | 8 +- ...ava => DefaultDockerClientConfigTest.java} | 96 ++-- .../dockerjava/core/DockerClientImplTest.java | 2 +- .../core/TestDockerCmdExecFactory.java | 6 - 12 files changed, 552 insertions(+), 531 deletions(-) create mode 100644 src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java rename src/test/java/com/github/dockerjava/core/{DockerClientConfigTest.java => DefaultDockerClientConfigTest.java} (54%) diff --git a/pom.xml b/pom.xml index bee178a6d..3f9caa55a 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.1-SNAPSHOT + 3.0.0-kostyasha-3 docker-java https://github.com/docker-java/docker-java diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java index ae090e434..0de3afe38 100644 --- a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java @@ -3,8 +3,6 @@ import java.io.Closeable; import java.io.IOException; -import javax.net.ssl.SSLContext; - import com.github.dockerjava.core.DockerClientConfig; import com.github.dockerjava.core.RemoteApiVersion; @@ -117,8 +115,6 @@ public interface DockerCmdExecFactory extends Closeable { DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec(); - DockerCmdExecFactory withSSLContext(SSLContext sslContext); - @Override void close() throws IOException; diff --git a/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java new file mode 100644 index 000000000..4641f9d3c --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -0,0 +1,455 @@ +package com.github.dockerjava.core; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.Serializable; +import java.net.URI; +import java.util.HashSet; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; +import org.apache.commons.lang.builder.ToStringStyle; + +import com.github.dockerjava.api.exception.DockerClientException; +import com.github.dockerjava.api.model.AuthConfig; +import com.github.dockerjava.api.model.AuthConfigurations; +import com.github.dockerjava.core.NameParser.HostnameReposName; +import com.github.dockerjava.core.NameParser.ReposTag; + +/** + * Respects some of the docker CLI options. See https://docs.docker.com/engine/reference/commandline/cli/#environment-variables + */ +public class DefaultDockerClientConfig implements Serializable, DockerClientConfig { + + private static final long serialVersionUID = -4307357472441531489L; + + public static final String DOCKER_HOST = "DOCKER_HOST"; + + public static final String DOCKER_TLS_VERIFY = "DOCKER_TLS_VERIFY"; + + public static final String DOCKER_CONFIG = "DOCKER_CONFIG"; + + public static final String DOCKER_CERT_PATH = "DOCKER_CERT_PATH"; + + public static final String API_VERSION = "api.version"; + + public static final String REGISTRY_USERNAME = "registry.username"; + + public static final String REGISTRY_PASSWORD = "registry.password"; + + public static final String REGISTRY_EMAIL = "registry.email"; + + public static final String REGISTRY_URL = "registry.url"; + + private static final String DOCKER_JAVA_PROPERTIES = "docker-java.properties"; + + private static final String DOCKER_CFG = ".dockercfg"; + + private static final Set CONFIG_KEYS = new HashSet(); + + static { + CONFIG_KEYS.add(DOCKER_HOST); + CONFIG_KEYS.add(DOCKER_TLS_VERIFY); + CONFIG_KEYS.add(DOCKER_CONFIG); + CONFIG_KEYS.add(DOCKER_CERT_PATH); + CONFIG_KEYS.add(API_VERSION); + CONFIG_KEYS.add(REGISTRY_USERNAME); + CONFIG_KEYS.add(REGISTRY_PASSWORD); + CONFIG_KEYS.add(REGISTRY_EMAIL); + CONFIG_KEYS.add(REGISTRY_URL); + } + + private final URI dockerHost; + + private final String registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig; + + private final SSLConfig sslConfig; + + private final RemoteApiVersion apiVersion; + + DefaultDockerClientConfig(URI dockerHost, String dockerConfig, String apiVersion, String registryUrl, + String registryUsername, String registryPassword, String registryEmail, SSLConfig sslConfig) { + this.dockerHost = checkDockerHostScheme(dockerHost); + this.dockerConfig = dockerConfig; + this.apiVersion = RemoteApiVersion.parseConfigWithDefault(apiVersion); + this.sslConfig = sslConfig; + this.registryUsername = registryUsername; + this.registryPassword = registryPassword; + this.registryEmail = registryEmail; + this.registryUrl = registryUrl; + } + + private URI checkDockerHostScheme(URI dockerHost) { + if ("tcp".equals(dockerHost.getScheme()) || "unix".equals(dockerHost.getScheme())) { + return dockerHost; + } else { + throw new DockerClientException("Unsupported protocol scheme found: '" + dockerHost + + "'. Only 'tcp://' or 'unix://' supported."); + } + } + + private static Properties loadIncludedDockerProperties(Properties systemProperties) { + try (InputStream is = DefaultDockerClientConfig.class.getResourceAsStream("/" + DOCKER_JAVA_PROPERTIES)) { + Properties p = new Properties(); + p.load(is); + replaceProperties(p, systemProperties); + return p; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static void replaceProperties(Properties properties, Properties replacements) { + for (Object objectKey : properties.keySet()) { + String key = objectKey.toString(); + properties.setProperty(key, replaceProperties(properties.getProperty(key), replacements)); + } + } + + private static String replaceProperties(String s, Properties replacements) { + for (Map.Entry entry : replacements.entrySet()) { + String key = "${" + entry.getKey() + "}"; + while (s.contains(key)) { + s = s.replace(key, String.valueOf(entry.getValue())); + } + } + return s; + } + + /** + * Creates a new Properties object containing values overridden from ${user.home}/.docker.io.properties + * + * @param p + * The original set of properties to override + * @return A copy of the original Properties with overridden values + */ + private static Properties overrideDockerPropertiesWithSettingsFromUserHome(Properties p, Properties systemProperties) { + Properties overriddenProperties = new Properties(); + overriddenProperties.putAll(p); + + final File usersDockerPropertiesFile = new File(systemProperties.getProperty("user.home"), + "." + DOCKER_JAVA_PROPERTIES); + if (usersDockerPropertiesFile.isFile()) { + try (FileInputStream in = new FileInputStream(usersDockerPropertiesFile)) { + overriddenProperties.load(in); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + return overriddenProperties; + } + + private static Properties overrideDockerPropertiesWithEnv(Properties properties, Map env) { + Properties overriddenProperties = new Properties(); + overriddenProperties.putAll(properties); + + // special case which is a sensible default + if (env.containsKey(DOCKER_HOST)) { + overriddenProperties.setProperty(DOCKER_HOST, env.get(DOCKER_HOST)); + } + + for (Map.Entry envEntry : env.entrySet()) { + String envKey = envEntry.getKey(); + if (CONFIG_KEYS.contains(envKey)) { + overriddenProperties.setProperty(envKey, envEntry.getValue()); + } + } + + return overriddenProperties; + } + + /** + * Creates a new Properties object containing values overridden from the System properties + * + * @param p + * The original set of properties to override + * @return A copy of the original Properties with overridden values + */ + private static Properties overrideDockerPropertiesWithSystemProperties(Properties p, Properties systemProperties) { + Properties overriddenProperties = new Properties(); + overriddenProperties.putAll(p); + + for (String key : CONFIG_KEYS) { + if (systemProperties.containsKey(key)) { + overriddenProperties.setProperty(key, systemProperties.getProperty(key)); + } + } + return overriddenProperties; + } + + public static Builder createDefaultConfigBuilder() { + return createDefaultConfigBuilder(System.getenv(), System.getProperties()); + } + + /** + * Allows you to build the config without system environment interfering for more robust testing + */ + static Builder createDefaultConfigBuilder(Map env, Properties systemProperties) { + Properties properties = loadIncludedDockerProperties(systemProperties); + properties = overrideDockerPropertiesWithSettingsFromUserHome(properties, systemProperties); + properties = overrideDockerPropertiesWithEnv(properties, env); + properties = overrideDockerPropertiesWithSystemProperties(properties, systemProperties); + return new Builder().withProperties(properties); + } + + @Override + public URI getDockerHost() { + return dockerHost; + } + + @Override + public RemoteApiVersion getApiVersion() { + return apiVersion; + } + + @Override + public String getRegistryUsername() { + return registryUsername; + } + + @Override + public String getRegistryPassword() { + return registryPassword; + } + + @Override + public String getRegistryEmail() { + return registryEmail; + } + + @Override + public String getRegistryUrl() { + return registryUrl; + } + + public String getDockerConfig() { + return dockerConfig; + } + + private AuthConfig getAuthConfig() { + AuthConfig authConfig = null; + if (getRegistryUsername() != null && getRegistryPassword() != null && getRegistryEmail() != null + && getRegistryUrl() != null) { + authConfig = new AuthConfig() + .withUsername(getRegistryUsername()) + .withPassword(getRegistryPassword()) + .withEmail(getRegistryEmail()) + .withRegistryAddress(getRegistryUrl()); + } + return authConfig; + } + + @Override + public AuthConfig effectiveAuthConfig(String imageName) { + AuthConfig authConfig = null; + + File dockerCfgFile = new File(getDockerConfig() + File.separator + DOCKER_CFG); + + if (dockerCfgFile.exists() && dockerCfgFile.isFile() && imageName != null) { + AuthConfigFile authConfigFile; + try { + authConfigFile = AuthConfigFile.loadConfig(dockerCfgFile); + } catch (IOException e) { + throw new DockerClientException("Failed to parse dockerCfgFile", e); + } + ReposTag reposTag = NameParser.parseRepositoryTag(imageName); + HostnameReposName hostnameReposName = NameParser.resolveRepositoryName(reposTag.repos); + + authConfig = authConfigFile.resolveAuthConfig(hostnameReposName.hostname); + } + + AuthConfig otherAuthConfig = getAuthConfig(); + + if (otherAuthConfig != null) { + authConfig = otherAuthConfig; + } + + return authConfig; + } + + @Override + public AuthConfigurations getAuthConfigurations() { + File dockerCfgFile = new File(getDockerConfig() + File.separator + DOCKER_CFG); + if (dockerCfgFile.exists() && dockerCfgFile.isFile()) { + AuthConfigFile authConfigFile; + try { + authConfigFile = AuthConfigFile.loadConfig(dockerCfgFile); + } catch (IOException e) { + throw new DockerClientException("Failed to parse dockerCfgFile", e); + } + + return authConfigFile.getAuthConfigurations(); + } + + return new AuthConfigurations(); + } + + @Override + public SSLConfig getSSLConfig() { + return sslConfig; + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); + } + + public static class Builder { + private URI dockerHost; + + private String apiVersion, registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig, + dockerCertPath; + + private boolean dockerTlsVerify; + + private SSLConfig customSslConfig = null; + + /** + * This will set all fields in the builder to those contained in the Properties object. The Properties object should contain the + * following docker-java configuration keys: DOCKER_HOST, DOCKER_TLS_VERIFY, api.version, registry.username, registry.password, + * registry.email, DOCKER_CERT_PATH, and DOCKER_CONFIG. + */ + public Builder withProperties(Properties p) { + return withDockerHost(p.getProperty(DOCKER_HOST)) + .withDockerTlsVerify(p.getProperty(DOCKER_TLS_VERIFY)) + .withDockerConfig(p.getProperty(DOCKER_CONFIG)) + .withDockerCertPath(p.getProperty(DOCKER_CERT_PATH)) + .withApiVersion(p.getProperty(API_VERSION)) + .withRegistryUsername(p.getProperty(REGISTRY_USERNAME)) + .withRegistryPassword(p.getProperty(REGISTRY_PASSWORD)) + .withRegistryEmail(p.getProperty(REGISTRY_EMAIL)) + .withRegistryUrl(p.getProperty(REGISTRY_URL)); + } + + /** + * configure DOCKER_HOST + */ + public final Builder withDockerHost(String dockerHost) { + checkNotNull(dockerHost, "uri was not specified"); + this.dockerHost = URI.create(dockerHost); + return this; + } + + public final Builder withApiVersion(RemoteApiVersion apiVersion) { + this.apiVersion = apiVersion.getVersion(); + return this; + } + + public final Builder withApiVersion(String apiVersion) { + this.apiVersion = apiVersion; + return this; + } + + public final Builder withRegistryUsername(String registryUsername) { + this.registryUsername = registryUsername; + return this; + } + + public final Builder withRegistryPassword(String registryPassword) { + this.registryPassword = registryPassword; + return this; + } + + public final Builder withRegistryEmail(String registryEmail) { + this.registryEmail = registryEmail; + return this; + } + + public Builder withRegistryUrl(String registryUrl) { + this.registryUrl = registryUrl; + return this; + } + + public final Builder withDockerCertPath(String dockerCertPath) { + this.dockerCertPath = dockerCertPath; + return this; + } + + public final Builder withDockerConfig(String dockerConfig) { + this.dockerConfig = dockerConfig; + return this; + } + + public final Builder withDockerTlsVerify(String dockerTlsVerify) { + if (dockerTlsVerify != null) { + String trimmed = dockerTlsVerify.trim(); + this.dockerTlsVerify = "true".equalsIgnoreCase(trimmed) || "1".equals(trimmed); + } else { + this.dockerTlsVerify = false; + } + return this; + } + + public final Builder withDockerTlsVerify(Boolean dockerTlsVerify) { + this.dockerTlsVerify = dockerTlsVerify; + return this; + } + + /** + * Overrides the default {@link SSLConfig} that is used when calling {@link Builder#withDockerTlsVerify(java.lang.Boolean)} and + * {@link Builder#withDockerCertPath(String)}. This way it is possible to pass a custom {@link SSLConfig} to the resulting + * {@link DockerClientConfig} that may be created by other means than the local file system. + */ + public final Builder withCustomSslConfig(SSLConfig customSslConfig) { + this.customSslConfig = customSslConfig; + return this; + } + + public DefaultDockerClientConfig build() { + + SSLConfig sslConfig = null; + + if (customSslConfig == null) { + if (dockerTlsVerify) { + dockerCertPath = checkDockerCertPath(dockerCertPath); + sslConfig = new LocalDirectorySSLConfig(dockerCertPath); + } + } else { + sslConfig = customSslConfig; + } + + return new DefaultDockerClientConfig(dockerHost, dockerConfig, apiVersion, registryUrl, registryUsername, + registryPassword, registryEmail, sslConfig); + } + + private String checkDockerCertPath(String dockerCertPath) { + if (StringUtils.isEmpty(dockerCertPath)) { + throw new DockerClientException( + "Enabled TLS verification (DOCKER_TLS_VERIFY=1) but certifate path (DOCKER_CERT_PATH) is not defined."); + } + + File certPath = new File(dockerCertPath); + + if (!certPath.exists()) { + throw new DockerClientException( + "Enabled TLS verification (DOCKER_TLS_VERIFY=1) but certificate path (DOCKER_CERT_PATH) '" + + dockerCertPath + "' doesn't exist."); + } else if (!certPath.isDirectory()) { + throw new DockerClientException( + "Enabled TLS verification (DOCKER_TLS_VERIFY=1) but certificate path (DOCKER_CERT_PATH) '" + + dockerCertPath + "' doesn't point to a directory."); + } + + return dockerCertPath; + } + } +} diff --git a/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java b/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java index 6aed6c358..743b8c2ef 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java @@ -2,7 +2,7 @@ import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.DockerCmdExecFactory; -import com.github.dockerjava.core.DockerClientConfig.DockerClientConfigBuilder; +import com.github.dockerjava.core.DefaultDockerClientConfig.Builder; import com.github.dockerjava.jaxrs.DockerCmdExecFactoryImpl; public class DockerClientBuilder { @@ -19,7 +19,7 @@ public static DockerClientBuilder getInstance() { return new DockerClientBuilder(DockerClientImpl.getInstance()); } - public static DockerClientBuilder getInstance(DockerClientConfigBuilder dockerClientConfigBuilder) { + public static DockerClientBuilder getInstance(Builder dockerClientConfigBuilder) { return getInstance(dockerClientConfigBuilder.build()); } diff --git a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java index 31cfc0c58..532fe6b43 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientConfig.java @@ -1,440 +1,40 @@ +/* + * Created on 08.06.2016 + */ package com.github.dockerjava.core; -import static com.google.common.base.Preconditions.checkNotNull; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.Serializable; import java.net.URI; -import java.util.HashSet; -import java.util.Map; -import java.util.Properties; -import java.util.Set; - -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; -import org.apache.commons.lang.builder.ToStringStyle; -import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.api.model.AuthConfig; import com.github.dockerjava.api.model.AuthConfigurations; -import com.github.dockerjava.core.NameParser.HostnameReposName; -import com.github.dockerjava.core.NameParser.ReposTag; /** - * Respects some of the docker CLI options. See https://docs.docker.com/engine/reference/commandline/cli/#environment-variables + * Interface that describes the docker client configuration. + * + * @author Marcus Linke + * */ -public class DockerClientConfig implements Serializable { - - private static final long serialVersionUID = -4307357472441531489L; - - public static final String DOCKER_HOST = "DOCKER_HOST"; - - public static final String DOCKER_TLS_VERIFY = "DOCKER_TLS_VERIFY"; - - public static final String DOCKER_CONFIG = "DOCKER_CONFIG"; - - public static final String DOCKER_CERT_PATH = "DOCKER_CERT_PATH"; - - public static final String API_VERSION = "api.version"; - - public static final String REGISTRY_USERNAME = "registry.username"; - - public static final String REGISTRY_PASSWORD = "registry.password"; - - public static final String REGISTRY_EMAIL = "registry.email"; - - public static final String REGISTRY_URL = "registry.url"; - - private static final String DOCKER_JAVA_PROPERTIES = "docker-java.properties"; - - private static final String DOCKER_CFG = ".dockercfg"; - - private static final Set CONFIG_KEYS = new HashSet(); - - static { - CONFIG_KEYS.add(DOCKER_HOST); - CONFIG_KEYS.add(DOCKER_TLS_VERIFY); - CONFIG_KEYS.add(DOCKER_CONFIG); - CONFIG_KEYS.add(DOCKER_CERT_PATH); - CONFIG_KEYS.add(API_VERSION); - CONFIG_KEYS.add(REGISTRY_USERNAME); - CONFIG_KEYS.add(REGISTRY_PASSWORD); - CONFIG_KEYS.add(REGISTRY_EMAIL); - CONFIG_KEYS.add(REGISTRY_URL); - } - - private final URI dockerHost; - - private final String registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig, dockerCertPath; +public interface DockerClientConfig { - private final boolean dockerTlsVerify; + URI getDockerHost(); - private final RemoteApiVersion apiVersion; + RemoteApiVersion getApiVersion(); - DockerClientConfig(URI dockerHost, String dockerConfig, String apiVersion, String registryUrl, - String registryUsername, String registryPassword, String registryEmail, String dockerCertPath, - boolean dockerTslVerify) { - this.dockerHost = checkDockerHostScheme(dockerHost); - this.dockerTlsVerify = dockerTslVerify; - this.dockerCertPath = checkDockerCertPath(dockerTslVerify, dockerCertPath); - this.dockerConfig = dockerConfig; - this.apiVersion = RemoteApiVersion.parseConfigWithDefault(apiVersion); - this.registryUsername = registryUsername; - this.registryPassword = registryPassword; - this.registryEmail = registryEmail; - this.registryUrl = registryUrl; - } + String getRegistryUsername(); - private URI checkDockerHostScheme(URI dockerHost) { - if ("tcp".equals(dockerHost.getScheme()) || "unix".equals(dockerHost.getScheme())) { - return dockerHost; - } else { - throw new DockerClientException("Unsupported protocol scheme found: '" + dockerHost - + "'. Only 'tcp://' or 'unix://' supported."); - } - } + String getRegistryPassword(); - private String checkDockerCertPath(boolean dockerTlsVerify, String dockerCertPath) { - if (dockerTlsVerify) { - if (StringUtils.isEmpty(dockerCertPath)) { - throw new DockerClientException( - "Enabled TLS verification (DOCKER_TLS_VERIFY=1) but certifate path (DOCKER_CERT_PATH) is not defined."); - } else { - File certPath = new File(dockerCertPath); + String getRegistryEmail(); - if (!certPath.exists()) { - throw new DockerClientException( - "Enabled TLS verification (DOCKER_TLS_VERIFY=1) but certificate path (DOCKER_CERT_PATH) '" + dockerCertPath - + "' doesn't exist."); - } + String getRegistryUrl(); - if (certPath.isDirectory()) { - return dockerCertPath; - } else { - throw new DockerClientException( - "Enabled TLS verification (DOCKER_TLS_VERIFY=1) but certificate path (DOCKER_CERT_PATH) '" + dockerCertPath - + "' doesn't point to a directory."); - } - } - } else { - return dockerCertPath; - } - } + AuthConfig effectiveAuthConfig(String imageName); - private static Properties loadIncludedDockerProperties(Properties systemProperties) { - try (InputStream is = DockerClientConfig.class.getResourceAsStream("/" + DOCKER_JAVA_PROPERTIES)) { - Properties p = new Properties(); - p.load(is); - replaceProperties(p, systemProperties); - return p; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private static void replaceProperties(Properties properties, Properties replacements) { - for (Object objectKey : properties.keySet()) { - String key = objectKey.toString(); - properties.setProperty(key, replaceProperties(properties.getProperty(key), replacements)); - } - } - - private static String replaceProperties(String s, Properties replacements) { - for (Map.Entry entry : replacements.entrySet()) { - String key = "${" + entry.getKey() + "}"; - while (s.contains(key)) { - s = s.replace(key, String.valueOf(entry.getValue())); - } - } - return s; - } - - /** - * Creates a new Properties object containing values overridden from ${user.home}/.docker.io.properties - * - * @param p - * The original set of properties to override - * @return A copy of the original Properties with overridden values - */ - private static Properties overrideDockerPropertiesWithSettingsFromUserHome(Properties p, Properties systemProperties) { - Properties overriddenProperties = new Properties(); - overriddenProperties.putAll(p); - - final File usersDockerPropertiesFile = new File(systemProperties.getProperty("user.home"), - "." + DOCKER_JAVA_PROPERTIES); - if (usersDockerPropertiesFile.isFile()) { - try (FileInputStream in = new FileInputStream(usersDockerPropertiesFile)) { - overriddenProperties.load(in); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - return overriddenProperties; - } - - private static Properties overrideDockerPropertiesWithEnv(Properties properties, Map env) { - Properties overriddenProperties = new Properties(); - overriddenProperties.putAll(properties); - - // special case which is a sensible default - if (env.containsKey(DOCKER_HOST)) { - overriddenProperties.setProperty(DOCKER_HOST, env.get(DOCKER_HOST)); - } - - for (Map.Entry envEntry : env.entrySet()) { - String envKey = envEntry.getKey(); - if (CONFIG_KEYS.contains(envKey)) { - overriddenProperties.setProperty(envKey, envEntry.getValue()); - } - } - - return overriddenProperties; - } + AuthConfigurations getAuthConfigurations(); /** - * Creates a new Properties object containing values overridden from the System properties - * - * @param p - * The original set of properties to override - * @return A copy of the original Properties with overridden values + * Returns an {@link SSLConfig} when secure connection is configured or null if not. */ - private static Properties overrideDockerPropertiesWithSystemProperties(Properties p, Properties systemProperties) { - Properties overriddenProperties = new Properties(); - overriddenProperties.putAll(p); - - for (String key : CONFIG_KEYS) { - if (systemProperties.containsKey(key)) { - overriddenProperties.setProperty(key, systemProperties.getProperty(key)); - } - } - return overriddenProperties; - } - - public static DockerClientConfigBuilder createDefaultConfigBuilder() { - return createDefaultConfigBuilder(System.getenv(), System.getProperties()); - } - - /** - * Allows you to build the config without system environment interfering for more robust testing - */ - static DockerClientConfigBuilder createDefaultConfigBuilder(Map env, Properties systemProperties) { - Properties properties = loadIncludedDockerProperties(systemProperties); - properties = overrideDockerPropertiesWithSettingsFromUserHome(properties, systemProperties); - properties = overrideDockerPropertiesWithEnv(properties, env); - properties = overrideDockerPropertiesWithSystemProperties(properties, systemProperties); - return new DockerClientConfigBuilder().withProperties(properties); - } - - public URI getDockerHost() { - return dockerHost; - } - - public RemoteApiVersion getApiVersion() { - return apiVersion; - } - - public String getRegistryUsername() { - return registryUsername; - } - - public String getRegistryPassword() { - return registryPassword; - } - - public String getRegistryEmail() { - return registryEmail; - } - - public String getRegistryUrl() { - return registryUrl; - } - - public String getDockerConfig() { - return dockerConfig; - } - - public String getDockerCertPath() { - return dockerCertPath; - } - - public boolean getDockerTlsVerify() { - return dockerTlsVerify; - } - - private AuthConfig getAuthConfig() { - AuthConfig authConfig = null; - if (getRegistryUsername() != null && getRegistryPassword() != null && getRegistryEmail() != null - && getRegistryUrl() != null) { - authConfig = new AuthConfig() - .withUsername(getRegistryUsername()) - .withPassword(getRegistryPassword()) - .withEmail(getRegistryEmail()) - .withRegistryAddress(getRegistryUrl()); - } - return authConfig; - } - - public AuthConfig effectiveAuthConfig(String imageName) { - AuthConfig authConfig = null; - - File dockerCfgFile = new File(getDockerConfig() + File.separator + DOCKER_CFG); - - if (dockerCfgFile.exists() && dockerCfgFile.isFile() && imageName != null) { - AuthConfigFile authConfigFile; - try { - authConfigFile = AuthConfigFile.loadConfig(dockerCfgFile); - } catch (IOException e) { - throw new DockerClientException("Failed to parse dockerCfgFile", e); - } - ReposTag reposTag = NameParser.parseRepositoryTag(imageName); - HostnameReposName hostnameReposName = NameParser.resolveRepositoryName(reposTag.repos); - - authConfig = authConfigFile.resolveAuthConfig(hostnameReposName.hostname); - } - - AuthConfig otherAuthConfig = getAuthConfig(); - - if (otherAuthConfig != null) { - authConfig = otherAuthConfig; - } - - return authConfig; - } - - public AuthConfigurations getAuthConfigurations() { - File dockerCfgFile = new File(getDockerConfig() + File.separator + DOCKER_CFG); - if (dockerCfgFile.exists() && dockerCfgFile.isFile()) { - AuthConfigFile authConfigFile; - try { - authConfigFile = AuthConfigFile.loadConfig(dockerCfgFile); - } catch (IOException e) { - throw new DockerClientException("Failed to parse dockerCfgFile", e); - } - - return authConfigFile.getAuthConfigurations(); - } - - return new AuthConfigurations(); - } - - // CHECKSTYLE:OFF - @Override - public boolean equals(Object o) { - if (this == o) - return true; - if (o == null || getClass() != o.getClass()) - return false; - - DockerClientConfig that = (DockerClientConfig) o; - - return EqualsBuilder.reflectionEquals(this, that); - } - - @Override - public int hashCode() { - return HashCodeBuilder.reflectionHashCode(this); - } - - // CHECKSTYLE:ON - - @Override - public String toString() { - return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE); - } - - public static class DockerClientConfigBuilder { - private URI dockerHost; - - private String apiVersion, registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig, - dockerCertPath; - - private boolean dockerTlsVerify; - - /** - * This will set all fields in the builder to those contained in the Properties object. The Properties object should contain the - * following docker-java configuration keys: DOCKER_HOST, DOCKER_TLS_VERIFY, api.version, registry.username, registry.password, - * registry.email, DOCKER_CERT_PATH, and DOCKER_CONFIG. - */ - public DockerClientConfigBuilder withProperties(Properties p) { - return withDockerHost(p.getProperty(DOCKER_HOST)).withDockerTlsVerify(p.getProperty(DOCKER_TLS_VERIFY)) - .withDockerConfig(p.getProperty(DOCKER_CONFIG)).withDockerCertPath(p.getProperty(DOCKER_CERT_PATH)) - .withApiVersion(p.getProperty(API_VERSION)).withRegistryUsername(p.getProperty(REGISTRY_USERNAME)) - .withRegistryPassword(p.getProperty(REGISTRY_PASSWORD)) - .withRegistryEmail(p.getProperty(REGISTRY_EMAIL)).withRegistryUrl(p.getProperty(REGISTRY_URL)); - } - - /** - * configure DOCKER_HOST - */ - public final DockerClientConfigBuilder withDockerHost(String dockerHost) { - checkNotNull(dockerHost, "uri was not specified"); - this.dockerHost = URI.create(dockerHost); - return this; - } - - public final DockerClientConfigBuilder withApiVersion(RemoteApiVersion apiVersion) { - this.apiVersion = apiVersion.getVersion(); - return this; - } - - public final DockerClientConfigBuilder withApiVersion(String apiVersion) { - this.apiVersion = apiVersion; - return this; - } - - public final DockerClientConfigBuilder withRegistryUsername(String registryUsername) { - this.registryUsername = registryUsername; - return this; - } - - public final DockerClientConfigBuilder withRegistryPassword(String registryPassword) { - this.registryPassword = registryPassword; - return this; - } - - public final DockerClientConfigBuilder withRegistryEmail(String registryEmail) { - this.registryEmail = registryEmail; - return this; - } - - public DockerClientConfigBuilder withRegistryUrl(String registryUrl) { - this.registryUrl = registryUrl; - return this; - } - - public final DockerClientConfigBuilder withDockerCertPath(String dockerCertPath) { - this.dockerCertPath = dockerCertPath; - return this; - } - - public final DockerClientConfigBuilder withDockerConfig(String dockerConfig) { - this.dockerConfig = dockerConfig; - return this; - } - - public final DockerClientConfigBuilder withDockerTlsVerify(String dockerTlsVerify) { - if (dockerTlsVerify != null) { - String trimmed = dockerTlsVerify.trim(); - this.dockerTlsVerify = "true".equalsIgnoreCase(trimmed) || "1".equals(trimmed); - } else { - this.dockerTlsVerify = false; - } - return this; - } - - public final DockerClientConfigBuilder withDockerTlsVerify(Boolean dockerTlsVerify) { - this.dockerTlsVerify = dockerTlsVerify; - return this; - } + SSLConfig getSSLConfig(); - public DockerClientConfig build() { - return new DockerClientConfig(dockerHost, dockerConfig, apiVersion, registryUrl, registryUsername, - registryPassword, registryEmail, dockerCertPath, dockerTlsVerify); - } - } } diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java index 765f562bd..e11ca4f30 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -125,7 +125,7 @@ public class DockerClientImpl implements Closeable, DockerClient { private DockerCmdExecFactory dockerCmdExecFactory; private DockerClientImpl() { - this(DockerClientConfig.createDefaultConfigBuilder().build()); + this(DefaultDockerClientConfig.createDefaultConfigBuilder().build()); } private DockerClientImpl(String serverUrl) { @@ -138,7 +138,7 @@ private DockerClientImpl(DockerClientConfig dockerClientConfig) { } private static DockerClientConfig configWithServerUrl(String serverUrl) { - return DockerClientConfig.createDefaultConfigBuilder().withDockerHost(serverUrl).build(); + return DefaultDockerClientConfig.createDefaultConfigBuilder().withDockerHost(serverUrl).build(); } public static DockerClientImpl getInstance() { diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index 5d489bbc5..d71cc33ae 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -18,6 +18,7 @@ import javax.ws.rs.client.WebTarget; import com.github.dockerjava.api.command.UpdateContainerCmd; + import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; @@ -83,7 +84,6 @@ import com.github.dockerjava.api.command.RenameContainerCmd; import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.core.DockerClientConfig; -import com.github.dockerjava.core.LocalDirectorySSLConfig; import com.github.dockerjava.jaxrs.connector.ApacheConnectorProvider; import com.github.dockerjava.jaxrs.filter.JsonClientFilter; import com.github.dockerjava.jaxrs.filter.ResponseStatusExceptionFilter; @@ -114,8 +114,6 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { private DockerClientConfig dockerClientConfig; - SSLContext sslContext = null; - @Override public void init(DockerClientConfig dockerClientConfig) { checkNotNull(dockerClientConfig, "config was not specified"); @@ -160,18 +158,16 @@ public void init(DockerClientConfig dockerClientConfig) { String protocol = null; - if (dockerClientConfig.getDockerTlsVerify()) { - protocol = "https"; + SSLContext sslContext = null; - try { - - if (sslContext == null) { - sslContext = new LocalDirectorySSLConfig(dockerClientConfig.getDockerCertPath()).getSSLContext(); - } + try { + sslContext = dockerClientConfig.getSSLConfig().getSSLContext(); + } catch (Exception ex) { + throw new DockerClientException("Error in SSL Configuration", ex); + } - } catch (Exception ex) { - throw new DockerClientException("Error in SSL Configuration", ex); - } + if (sslContext != null) { + protocol = "https"; } else { protocol = "http"; } @@ -529,12 +525,6 @@ public void close() throws IOException { client.close(); } - @Override - public DockerCmdExecFactoryImpl withSSLContext(SSLContext sslContext) { - this.sslContext = sslContext; - return this; - } - public DockerCmdExecFactoryImpl withReadTimeout(Integer readTimeout) { this.readTimeout = readTimeout; return this; diff --git a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java index 8f704c7af..1f55c61a8 100644 --- a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java @@ -53,7 +53,7 @@ import com.github.dockerjava.api.command.RenameContainerCmd; import com.github.dockerjava.core.DockerClientConfig; import com.github.dockerjava.core.DockerClientImpl; -import com.github.dockerjava.core.LocalDirectorySSLConfig; +import com.github.dockerjava.core.SSLConfig; import com.github.dockerjava.netty.exec.AttachContainerCmdExec; import com.github.dockerjava.netty.exec.AuthCmdExec; import com.github.dockerjava.netty.exec.BuildImageCmdExec; @@ -123,7 +123,6 @@ import org.bouncycastle.jce.provider.BouncyCastleProvider; -import javax.net.ssl.SSLContext; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLParameters; @@ -168,8 +167,6 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { private NettyInitializer nettyInitializer; - private SSLContext sslContext = null; - private ChannelProvider channelProvider = new ChannelProvider() { @Override public DuplexChannel getChannel() { @@ -270,12 +267,10 @@ public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException { DuplexChannel channel = (DuplexChannel) bootstrap.connect(host, port).sync().channel(); - if (dockerClientConfig.getDockerTlsVerify()) { - final SslHandler ssl = initSsl(dockerClientConfig); + final SslHandler ssl = initSsl(dockerClientConfig); - if (ssl != null) { - channel.pipeline().addFirst(ssl); - } + if (ssl != null) { + channel.pipeline().addFirst(ssl); } return channel; @@ -288,18 +283,19 @@ private SslHandler initSsl(DockerClientConfig dockerClientConfig) { String host = dockerClientConfig.getDockerHost().getHost(); int port = dockerClientConfig.getDockerHost().getPort(); - if (sslContext == null) { - sslContext = new LocalDirectorySSLConfig(dockerClientConfig.getDockerCertPath()).getSSLContext(); - } + final SSLConfig sslConfig = dockerClientConfig.getSSLConfig(); + + if (sslConfig != null && sslConfig.getSSLContext() != null) { - SSLEngine engine = sslContext.createSSLEngine(host, port); - engine.setUseClientMode(true); - engine.setSSLParameters(enableHostNameVerification(engine.getSSLParameters())); + SSLEngine engine = sslConfig.getSSLContext().createSSLEngine(host, port); + engine.setUseClientMode(true); + engine.setSSLParameters(enableHostNameVerification(engine.getSSLParameters())); - // in the future we may use HostnameVerifier like here: - // https://github.com/AsyncHttpClient/async-http-client/blob/1.8.x/src/main/java/com/ning/http/client/providers/netty/NettyConnectListener.java#L76 + // in the future we may use HostnameVerifier like here: + // https://github.com/AsyncHttpClient/async-http-client/blob/1.8.x/src/main/java/com/ning/http/client/providers/netty/NettyConnectListener.java#L76 - ssl = new SslHandler(engine); + ssl = new SslHandler(engine); + } } catch (Exception e) { throw new RuntimeException(e); @@ -577,12 +573,6 @@ public void close() throws IOException { eventLoopGroup.shutdownGracefully(); } - @Override - public DockerCmdExecFactory withSSLContext(SSLContext sslContext) { - this.sslContext = sslContext; - return this; - } - private WebTarget getBaseResource() { return new WebTarget(channelProvider); } diff --git a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java index 1a52bbd3f..e6cc00ac0 100644 --- a/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java +++ b/src/test/java/com/github/dockerjava/client/AbstractDockerClientTest.java @@ -29,7 +29,7 @@ import com.github.dockerjava.api.model.Network; import com.github.dockerjava.api.model.Volume; import com.github.dockerjava.core.DockerClientBuilder; -import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.DefaultDockerClientConfig; import com.github.dockerjava.core.TestDockerCmdExecFactory; import com.github.dockerjava.core.command.BuildImageResultCallback; import com.github.dockerjava.core.command.LogContainerResultCallback; @@ -68,12 +68,12 @@ public void beforeTest() throws Exception { LOG.info("======================= END OF BEFORETEST =======================\n\n"); } - private DockerClientConfig config() { + private DefaultDockerClientConfig config() { return config(null); } - protected DockerClientConfig config(String password) { - DockerClientConfig.DockerClientConfigBuilder builder = DockerClientConfig.createDefaultConfigBuilder() + protected DefaultDockerClientConfig config(String password) { + DefaultDockerClientConfig.Builder builder = DefaultDockerClientConfig.createDefaultConfigBuilder() .withRegistryUrl("https://index.docker.io/v1/"); if (password != null) { builder = builder.withRegistryPassword(password); diff --git a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java b/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java similarity index 54% rename from src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java rename to src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java index ee679a0af..55ec38015 100644 --- a/src/test/java/com/github/dockerjava/core/DockerClientConfigTest.java +++ b/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java @@ -19,16 +19,16 @@ import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.api.model.AuthConfig; -public class DockerClientConfigTest { +public class DefaultDockerClientConfigTest { - public static final DockerClientConfig EXAMPLE_CONFIG = newExampleConfig(); + public static final DefaultDockerClientConfig EXAMPLE_CONFIG = newExampleConfig(); - private static DockerClientConfig newExampleConfig() { + private static DefaultDockerClientConfig newExampleConfig() { String dockerCertPath = dockerCertPath(); - return new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", - dockerCertPath, true); + return new DefaultDockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + new LocalDirectorySSLConfig(dockerCertPath)); } private static String homeDir() { @@ -49,7 +49,7 @@ public void environmentDockerHost() throws Exception { // given docker host in env Map env = new HashMap(); - env.put(DockerClientConfig.DOCKER_HOST, "tcp://baz:8768"); + env.put(DefaultDockerClientConfig.DOCKER_HOST, "tcp://baz:8768"); // and it looks to be SSL disabled env.remove("DOCKER_CERT_PATH"); @@ -59,7 +59,7 @@ public void environmentDockerHost() throws Exception { systemProperties.setProperty("user.home", homeDir()); // when you build a config - DockerClientConfig config = buildConfig(env, systemProperties); + DefaultDockerClientConfig config = buildConfig(env, systemProperties); assertEquals(config.getDockerHost(), URI.create("tcp://baz:8768")); } @@ -69,25 +69,25 @@ public void environment() throws Exception { // given a default config in env properties Map env = new HashMap(); - env.put(DockerClientConfig.DOCKER_HOST, "tcp://foo"); - env.put(DockerClientConfig.API_VERSION, "apiVersion"); - env.put(DockerClientConfig.REGISTRY_USERNAME, "registryUsername"); - env.put(DockerClientConfig.REGISTRY_PASSWORD, "registryPassword"); - env.put(DockerClientConfig.REGISTRY_EMAIL, "registryEmail"); - env.put(DockerClientConfig.REGISTRY_URL, "registryUrl"); - env.put(DockerClientConfig.DOCKER_CONFIG, "dockerConfig"); - env.put(DockerClientConfig.DOCKER_CERT_PATH, dockerCertPath()); - env.put(DockerClientConfig.DOCKER_TLS_VERIFY, "1"); + env.put(DefaultDockerClientConfig.DOCKER_HOST, "tcp://foo"); + env.put(DefaultDockerClientConfig.API_VERSION, "apiVersion"); + env.put(DefaultDockerClientConfig.REGISTRY_USERNAME, "registryUsername"); + env.put(DefaultDockerClientConfig.REGISTRY_PASSWORD, "registryPassword"); + env.put(DefaultDockerClientConfig.REGISTRY_EMAIL, "registryEmail"); + env.put(DefaultDockerClientConfig.REGISTRY_URL, "registryUrl"); + env.put(DefaultDockerClientConfig.DOCKER_CONFIG, "dockerConfig"); + env.put(DefaultDockerClientConfig.DOCKER_CERT_PATH, dockerCertPath()); + env.put(DefaultDockerClientConfig.DOCKER_TLS_VERIFY, "1"); // when you build a config - DockerClientConfig config = buildConfig(env, new Properties()); + DefaultDockerClientConfig config = buildConfig(env, new Properties()); // then we get the example object assertEquals(config, EXAMPLE_CONFIG); } - private DockerClientConfig buildConfig(Map env, Properties systemProperties) { - return DockerClientConfig.createDefaultConfigBuilder(env, systemProperties).build(); + private DefaultDockerClientConfig buildConfig(Map env, Properties systemProperties) { + return DefaultDockerClientConfig.createDefaultConfigBuilder(env, systemProperties).build(); } @Test @@ -99,7 +99,7 @@ public void defaults() throws Exception { systemProperties.setProperty("user.home", homeDir()); // when you build config - DockerClientConfig config = buildConfig(Collections. emptyMap(), systemProperties); + DefaultDockerClientConfig config = buildConfig(Collections. emptyMap(), systemProperties); // then the cert path is as expected assertEquals(config.getDockerHost(), URI.create("unix:///var/run/docker.sock")); @@ -107,7 +107,7 @@ public void defaults() throws Exception { assertEquals(config.getRegistryUrl(), AuthConfig.DEFAULT_SERVER_ADDRESS); assertEquals(config.getApiVersion(), RemoteApiVersion.unknown()); assertEquals(config.getDockerConfig(), homeDir() + "/.docker"); - assertNull(config.getDockerCertPath()); + assertNull(config.getSSLConfig()); } @Test @@ -115,18 +115,18 @@ public void systemProperties() throws Exception { // given system properties based on the example Properties systemProperties = new Properties(); - systemProperties.put(DockerClientConfig.DOCKER_HOST, "tcp://foo"); - systemProperties.put(DockerClientConfig.API_VERSION, "apiVersion"); - systemProperties.put(DockerClientConfig.REGISTRY_USERNAME, "registryUsername"); - systemProperties.put(DockerClientConfig.REGISTRY_PASSWORD, "registryPassword"); - systemProperties.put(DockerClientConfig.REGISTRY_EMAIL, "registryEmail"); - systemProperties.put(DockerClientConfig.REGISTRY_URL, "registryUrl"); - systemProperties.put(DockerClientConfig.DOCKER_CONFIG, "dockerConfig"); - systemProperties.put(DockerClientConfig.DOCKER_CERT_PATH, dockerCertPath()); - systemProperties.put(DockerClientConfig.DOCKER_TLS_VERIFY, "1"); + systemProperties.put(DefaultDockerClientConfig.DOCKER_HOST, "tcp://foo"); + systemProperties.put(DefaultDockerClientConfig.API_VERSION, "apiVersion"); + systemProperties.put(DefaultDockerClientConfig.REGISTRY_USERNAME, "registryUsername"); + systemProperties.put(DefaultDockerClientConfig.REGISTRY_PASSWORD, "registryPassword"); + systemProperties.put(DefaultDockerClientConfig.REGISTRY_EMAIL, "registryEmail"); + systemProperties.put(DefaultDockerClientConfig.REGISTRY_URL, "registryUrl"); + systemProperties.put(DefaultDockerClientConfig.DOCKER_CONFIG, "dockerConfig"); + systemProperties.put(DefaultDockerClientConfig.DOCKER_CERT_PATH, dockerCertPath()); + systemProperties.put(DefaultDockerClientConfig.DOCKER_TLS_VERIFY, "1"); // when you build new config - DockerClientConfig config = buildConfig(Collections. emptyMap(), systemProperties); + DefaultDockerClientConfig config = buildConfig(Collections. emptyMap(), systemProperties); // then it is the same as the example assertEquals(config, EXAMPLE_CONFIG); @@ -136,50 +136,46 @@ public void systemProperties() throws Exception { @Test public void serializableTest() { final byte[] serialized = SerializationUtils.serialize(EXAMPLE_CONFIG); - final DockerClientConfig deserialized = (DockerClientConfig) SerializationUtils.deserialize(serialized); + final DefaultDockerClientConfig deserialized = (DefaultDockerClientConfig) SerializationUtils.deserialize(serialized); assertThat("Deserialized object mush match source object", deserialized, equalTo(EXAMPLE_CONFIG)); } - @Test(expectedExceptions = DockerClientException.class) - public void testTlsVerifyAndCertPathNull() throws Exception { - new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", - null, true); + @Test() + public void testSslContextEmpty() throws Exception { + new DefaultDockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + null); } - @Test(expectedExceptions = DockerClientException.class) - public void testTlsVerifyAndCertPathEmpty() throws Exception { - new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", - "", true); - } + @Test() public void testTlsVerifyAndCertPath() throws Exception { - new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", - dockerCertPath(), true); + new DefaultDockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + new LocalDirectorySSLConfig(dockerCertPath())); } @Test(expectedExceptions = DockerClientException.class) public void testWrongHostScheme() throws Exception { - new DockerClientConfig(URI.create("http://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", - null, false); + new DefaultDockerClientConfig(URI.create("http://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + null); } @Test() public void testTcpHostScheme() throws Exception { - new DockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", - null, false); + new DefaultDockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + null); } @Test() public void testUnixHostScheme() throws Exception { - new DockerClientConfig(URI.create("unix://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", - null, false); + new DefaultDockerClientConfig(URI.create("unix://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + null); } @Test public void withDockerTlsVerify() throws Exception { - DockerClientConfig.DockerClientConfigBuilder builder = new DockerClientConfig.DockerClientConfigBuilder(); + DefaultDockerClientConfig.Builder builder = new DefaultDockerClientConfig.Builder(); Field field = builder.getClass().getDeclaredField("dockerTlsVerify"); field.setAccessible(true); diff --git a/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java b/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java index 7ea8bace5..1df4636ba 100644 --- a/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java +++ b/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java @@ -12,7 +12,7 @@ public class DockerClientImplTest { @Test public void configuredInstanceAuthConfig() throws Exception { // given a config with null serverAddress - DockerClientConfig dockerClientConfig = new DockerClientConfig(URI.create("tcp://foo"), null, null, null, "", "", "", null, false); + DefaultDockerClientConfig dockerClientConfig = new DefaultDockerClientConfig(URI.create("tcp://foo"), null, null, null, "", "", "", null); DockerClientImpl dockerClient = DockerClientImpl.getInstance(dockerClientConfig); // when we get the auth config diff --git a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java index aee8a60a8..48ea1e164 100644 --- a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java +++ b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java @@ -58,7 +58,6 @@ import com.github.dockerjava.api.command.WaitContainerCmd; import com.github.dockerjava.api.model.BuildResponseItem; -import javax.net.ssl.SSLContext; import java.io.IOException; import java.security.SecureRandom; import java.util.ArrayList; @@ -431,9 +430,4 @@ public List getVolumeNames() { public List getNetworkIds() { return new ArrayList<>(networkIds); } - - @Override - public DockerCmdExecFactory withSSLContext(SSLContext sslContext) { - return delegate.withSSLContext(sslContext); - } } From 006fd9b061066ba76c7412009292ec2e644417a4 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Mon, 13 Jun 2016 23:00:05 +0200 Subject: [PATCH 161/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f3b7e9b9..ad5885775 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Change Log --- All changes +* [#596] (https://github.com/docker-java/docker-java/pull/596) Refactor configuration of SSL to allow override with custom config * [#529] (https://github.com/docker-java/docker-java/pull/529) Refactor CertUtils. Support ECDSA and PrivateKey v3.0.0 From 2f8d317585c0d4b4e9fc45d122a3a02ad31a1d72 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 14 Jun 2016 00:02:15 +0300 Subject: [PATCH 162/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad5885775..10065afad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Change Log All changes * [#596] (https://github.com/docker-java/docker-java/pull/596) Refactor configuration of SSL to allow override with custom config * [#529] (https://github.com/docker-java/docker-java/pull/529) Refactor CertUtils. Support ECDSA and PrivateKey +* [#593] (https://github.com/docker-java/docker-java/pull/593) Added Device.parse() method with simple verification. v3.0.0 --- From efb424523971ddb50488bc3b03a52f32d8bcc5b9 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 15 Jun 2016 23:43:44 +0300 Subject: [PATCH 163/855] Allow null value. boolean <-> Boolean error --- .../github/dockerjava/core/DefaultDockerClientConfig.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java index 4641f9d3c..b21e227ec 100644 --- a/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -1,6 +1,7 @@ package com.github.dockerjava.core; import static com.google.common.base.Preconditions.checkNotNull; +import static org.apache.commons.lang.BooleanUtils.isTrue; import java.io.File; import java.io.FileInputStream; @@ -319,7 +320,7 @@ public static class Builder { private String apiVersion, registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig, dockerCertPath; - private boolean dockerTlsVerify; + private Boolean dockerTlsVerify; private SSLConfig customSslConfig = null; @@ -419,7 +420,7 @@ public DefaultDockerClientConfig build() { SSLConfig sslConfig = null; if (customSslConfig == null) { - if (dockerTlsVerify) { + if (isTrue(dockerTlsVerify)) { dockerCertPath = checkDockerCertPath(dockerCertPath); sslConfig = new LocalDirectorySSLConfig(dockerCertPath); } From 019770cc8dda7fcdcbede13fa7cefcdb072589ed Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 16 Jun 2016 09:53:49 +0300 Subject: [PATCH 164/855] Fix tests --- .../core/DefaultDockerClientConfigTest.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java b/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java index 55ec38015..54e70c511 100644 --- a/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java +++ b/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java @@ -180,25 +180,25 @@ public void withDockerTlsVerify() throws Exception { field.setAccessible(true); builder.withDockerTlsVerify(""); - assertThat(field.getBoolean(builder), is(false)); + assertThat((Boolean) field.get(builder), is(false)); builder.withDockerTlsVerify("false"); - assertThat(field.getBoolean(builder), is(false)); + assertThat((Boolean) field.get(builder), is(false)); builder.withDockerTlsVerify("FALSE"); - assertThat(field.getBoolean(builder), is(false)); + assertThat((Boolean) field.get(builder), is(false)); builder.withDockerTlsVerify("true"); - assertThat(field.getBoolean(builder), is(true)); + assertThat((Boolean) field.get(builder), is(true)); builder.withDockerTlsVerify("TRUE"); - assertThat(field.getBoolean(builder), is(true)); + assertThat((Boolean) field.get(builder), is(true)); builder.withDockerTlsVerify("0"); - assertThat(field.getBoolean(builder), is(false)); + assertThat((Boolean) field.get(builder), is(false)); builder.withDockerTlsVerify("1"); - assertThat(field.getBoolean(builder), is(true)); + assertThat((Boolean) field.get(builder), is(true)); } } From 2116ae00f5ca5e5630491bc68a4208adc969b1dc Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sat, 18 Jun 2016 00:12:52 +0300 Subject: [PATCH 165/855] Docker travis for ITs (#606) Fast build - without integration tests. ITs - against different docker versions. --- .travis.yml | 37 ++- get-docker-com.sh | 313 ++++++++++++++++++ .../jaxrs/DockerCmdExecFactoryImpl.java | 6 +- src/test/resources/travis-logback.xml | 19 ++ travis-after-success.sh | 5 +- travis-before-install.sh | 43 +++ 6 files changed, 418 insertions(+), 5 deletions(-) create mode 100755 get-docker-com.sh create mode 100644 src/test/resources/travis-logback.xml create mode 100755 travis-before-install.sh diff --git a/.travis.yml b/.travis.yml index 1d78b3bb9..4e980294e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,40 @@ +sudo: required +dist: trusty language: java + +services: + - docker + jdk: - oraclejdk7 + +env: + global: + - DOCKER_TLS_VERIFY="" + + matrix: + - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" FAST_BUILD=true + - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" + - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.11.2-0~trusty" DEPLOY=true + - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.10.3-0~trusty" + - repo="testing" DOCKER_HOST="tcp://127.0.0.1:2375" + - repo="testing" DOCKER_HOST="unix:///var/run/docker.sock" + - repo="experimental" DOCKER_HOST="tcp://127.0.0.1:2375" + - repo="experimental" DOCKER_HOST="unix:///var/run/docker.sock" + +cache: + directories: + - $HOME/.travis_cache +# - $HOME/.m2 install would pollute it + before_install: - - pip install --user codecov + - pip install --user codecov + - ./travis-before-install.sh + +script: if [ "${FAST_BUILD}" == true ]; then mvn package ; else mvn verify; fi + after_success: - - ./travis-after-success.sh + - ./travis-after-success.sh + +after_script: + - sudo cat /var/log/upstart/docker.log diff --git a/get-docker-com.sh b/get-docker-com.sh new file mode 100755 index 000000000..66ca4aefc --- /dev/null +++ b/get-docker-com.sh @@ -0,0 +1,313 @@ +#!/bin/sh +set -e +# +# This script is meant for quick & easy install via: +# 'curl -sSL https://get.docker.com/ | sh' +# or: +# 'wget -qO- https://get.docker.com/ | sh' +# +# For test builds (ie. release candidates): +# 'curl -fsSL https://test.docker.com/ | sh' +# or: +# 'wget -qO- https://test.docker.com/ | sh' +# +# For experimental builds: +# 'curl -fsSL https://experimental.docker.com/ | sh' +# or: +# 'wget -qO- https://experimental.docker.com/ | sh' +# +# Docker Maintainers: +# To update this script on https://get.docker.com, +# use hack/release.sh during a normal release, +# or the following one-liner for script hotfixes: +# aws s3 cp --acl public-read hack/install.sh s3://get.docker.com/index +# + +url="https://get.docker.com/" +apt_url="https://apt.dockerproject.org" +yum_url="https://yum.dockerproject.org" +gpg_fingerprint="58118E89F3A912897C070ADBF76221572C52609D" + +key_servers=" +ha.pool.sks-keyservers.net +pgp.mit.edu +keyserver.ubuntu.com +" + +command_exists() { + command -v "$@" > /dev/null 2>&1 +} + +semverParse() { + major="${1%%.*}" + minor="${1#$major.}" + minor="${minor%%.*}" + patch="${1#$major.$minor.}" + patch="${patch%%[-.]*}" +} + +do_install() { + case "$(uname -m)" in + *64) + ;; + *) + cat >&2 <<-'EOF' + Error: you are not using a 64bit platform. + Docker currently only supports 64bit platforms. + EOF + exit 1 + ;; + esac + + user="$(id -un 2>/dev/null || true)" + + sh_c='sh -c' + if [ "$user" != 'root' ]; then + if command_exists sudo; then + sh_c='sudo -E sh -c' + elif command_exists su; then + sh_c='su -c' + else + cat >&2 <<-'EOF' + Error: this installer needs the ability to run commands as root. + We are unable to find either "sudo" or "su" available to make this happen. + EOF + exit 1 + fi + fi + + curl='' + if command_exists curl; then + curl='curl -sSL' + elif command_exists wget; then + curl='wget -qO-' + elif command_exists busybox && busybox --list-modules | grep -q wget; then + curl='busybox wget -qO-' + fi + + # check to see which repo they are trying to install from + if [ -z "$repo" ]; then + repo='main' + if [ "https://test.docker.com/" = "$url" ]; then + repo='testing' + elif [ "https://experimental.docker.com/" = "$url" ]; then + repo='experimental' + fi + fi + + # perform some very rudimentary platform detection + lsb_dist='' + dist_version='' + if command_exists lsb_release; then + lsb_dist="$(lsb_release -si)" + fi + if [ -z "$lsb_dist" ] && [ -r /etc/lsb-release ]; then + lsb_dist="$(. /etc/lsb-release && echo "$DISTRIB_ID")" + fi + if [ -z "$lsb_dist" ] && [ -r /etc/debian_version ]; then + lsb_dist='debian' + fi + if [ -z "$lsb_dist" ] && [ -r /etc/fedora-release ]; then + lsb_dist='fedora' + fi + if [ -z "$lsb_dist" ] && [ -r /etc/oracle-release ]; then + lsb_dist='oracleserver' + fi + if [ -z "$lsb_dist" ]; then + if [ -r /etc/centos-release ] || [ -r /etc/redhat-release ]; then + lsb_dist='centos' + fi + fi + if [ -z "$lsb_dist" ] && [ -r /etc/os-release ]; then + lsb_dist="$(. /etc/os-release && echo "$ID")" + fi + + lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')" + + case "$lsb_dist" in + + ubuntu) + if command_exists lsb_release; then + dist_version="$(lsb_release --codename | cut -f2)" + fi + if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then + dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")" + fi + ;; + + debian) + dist_version="$(cat /etc/debian_version | sed 's/\/.*//' | sed 's/\..*//')" + case "$dist_version" in + 8) + dist_version="jessie" + ;; + 7) + dist_version="wheezy" + ;; + esac + ;; + + oracleserver) + # need to switch lsb_dist to match yum repo URL + lsb_dist="oraclelinux" + dist_version="$(rpm -q --whatprovides redhat-release --queryformat "%{VERSION}\n" | sed 's/\/.*//' | sed 's/\..*//' | sed 's/Server*//')" + ;; + + fedora|centos) + dist_version="$(rpm -q --whatprovides redhat-release --queryformat "%{VERSION}\n" | sed 's/\/.*//' | sed 's/\..*//' | sed 's/Server*//')" + ;; + + *) + if command_exists lsb_release; then + dist_version="$(lsb_release --codename | cut -f2)" + fi + if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then + dist_version="$(. /etc/os-release && echo "$VERSION_ID")" + fi + ;; + + + esac + + + # Run setup for each distro accordingly + case "$lsb_dist" in + ubuntu|debian) + export DEBIAN_FRONTEND=noninteractive + + did_apt_get_update= + apt_get_update() { + if [ -z "$did_apt_get_update" ]; then + ( set -x; $sh_c 'sleep 3; apt-get update' ) + did_apt_get_update=1 + fi + } + + # aufs is preferred over devicemapper; try to ensure the driver is available. + if ! grep -q aufs /proc/filesystems && ! $sh_c 'modprobe aufs'; then + if uname -r | grep -q -- '-generic' && dpkg -l 'linux-image-*-generic' | grep -qE '^ii|^hi' 2>/dev/null; then + kern_extras="linux-image-extra-$(uname -r) linux-image-extra-virtual" + + apt_get_update + ( set -x; $sh_c 'sleep 3; apt-get install -y -q '"$kern_extras" ) || true + + if ! grep -q aufs /proc/filesystems && ! $sh_c 'modprobe aufs'; then + echo >&2 'Warning: tried to install '"$kern_extras"' (for AUFS)' + echo >&2 ' but we still have no AUFS. Docker may not work. Proceeding anyways!' + ( set -x; sleep 10 ) + fi + else + echo >&2 'Warning: current kernel is not supported by the linux-image-extra-virtual' + echo >&2 ' package. We have no AUFS support. Consider installing the packages' + echo >&2 ' linux-image-virtual kernel and linux-image-extra-virtual for AUFS support.' + ( set -x; sleep 10 ) + fi + fi + + # install apparmor utils if they're missing and apparmor is enabled in the kernel + # otherwise Docker will fail to start + if [ "$(cat /sys/module/apparmor/parameters/enabled 2>/dev/null)" = 'Y' ]; then + if command -v apparmor_parser >/dev/null 2>&1; then + echo 'apparmor is enabled in the kernel and apparmor utils were already installed' + else + echo 'apparmor is enabled in the kernel, but apparmor_parser missing' + apt_get_update + ( set -x; $sh_c 'sleep 3; apt-get install -y -q apparmor' ) + fi + fi + + if [ ! -e /usr/lib/apt/methods/https ]; then + apt_get_update + ( set -x; $sh_c 'sleep 3; apt-get install -y -q apt-transport-https ca-certificates' ) + fi + if [ -z "$curl" ]; then + apt_get_update + ( set -x; $sh_c 'sleep 3; apt-get install -y -q curl ca-certificates' ) + curl='curl -sSL' + fi + ( + set -x + for key_server in $key_servers ; do + $sh_c "apt-key adv --keyserver hkp://${key_server}:80 --recv-keys ${gpg_fingerprint}" && break + done + $sh_c "apt-key adv -k ${gpg_fingerprint} >/dev/null" + $sh_c "mkdir -p /etc/apt/sources.list.d" + $sh_c "echo deb [arch=$(dpkg --print-architecture)] ${apt_url}/repo ${lsb_dist}-${dist_version} ${repo} > /etc/apt/sources.list.d/docker.list" + $sh_c 'sleep 3; apt-get update' + if [ -z "$DOCKER_VERSION" ]; then + $sh_c 'apt-get -o Dpkg::Options::="--force-confnew" install -y -q docker-engine' + else + $sh_c "apt-get -o Dpkg::Options::=\"--force-confnew\" install -y -q docker-engine=$DOCKER_VERSION" + fi + ) + exit 0 + ;; + + fedora|centos|oraclelinux) + $sh_c "cat >/etc/yum.repos.d/docker-${repo}.repo" <<-EOF + [docker-${repo}-repo] + name=Docker ${repo} Repository + baseurl=${yum_url}/repo/${repo}/${lsb_dist}/${dist_version} + enabled=1 + gpgcheck=1 + gpgkey=${yum_url}/gpg + EOF + if [ "$lsb_dist" = "fedora" ] && [ "$dist_version" -ge "22" ]; then + ( + set -x + $sh_c 'sleep 3; dnf -y -q install docker-engine' + ) + else + ( + set -x + $sh_c 'sleep 3; yum -y -q install docker-engine' + ) + fi + exit 0 + ;; + gentoo) + if [ "$url" = "https://test.docker.com/" ]; then + # intentionally mixed spaces and tabs here -- tabs are stripped by "<<-'EOF'", spaces are kept in the output + cat >&2 <<-'EOF' + + You appear to be trying to install the latest nightly build in Gentoo.' + The portage tree should contain the latest stable release of Docker, but' + if you want something more recent, you can always use the live ebuild' + provided in the "docker" overlay available via layman. For more' + instructions, please see the following URL:' + + https://github.com/tianon/docker-overlay#using-this-overlay' + + After adding the "docker" overlay, you should be able to:' + + emerge -av =app-emulation/docker-9999' + + EOF + exit 1 + fi + + ( + set -x + $sh_c 'sleep 3; emerge app-emulation/docker' + ) + exit 0 + ;; + esac + + # intentionally mixed spaces and tabs here -- tabs are stripped by "<<-'EOF'", spaces are kept in the output + cat >&2 <<-'EOF' + + Either your platform is not easily detectable, is not supported by this + installer script (yet - PRs welcome! [hack/install.sh]), or does not yet have + a package for Docker. Please visit the following URL for more detailed + installation instructions: + + https://docs.docker.com/engine/installation/ + + EOF + exit 1 +} + +# wrapped up in a function so that we have some protection against only getting +# half the file during "curl | sh" +do_install \ No newline at end of file diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index d71cc33ae..fc74e1fde 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -19,6 +19,7 @@ import com.github.dockerjava.api.command.UpdateContainerCmd; +import com.github.dockerjava.core.SSLConfig; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; @@ -161,7 +162,10 @@ public void init(DockerClientConfig dockerClientConfig) { SSLContext sslContext = null; try { - sslContext = dockerClientConfig.getSSLConfig().getSSLContext(); + final SSLConfig sslConfig = dockerClientConfig.getSSLConfig(); + if (sslConfig != null) { + sslContext = sslConfig.getSSLContext(); + } } catch (Exception ex) { throw new DockerClientException("Error in SSL Configuration", ex); } diff --git a/src/test/resources/travis-logback.xml b/src/test/resources/travis-logback.xml new file mode 100644 index 000000000..250cbd335 --- /dev/null +++ b/src/test/resources/travis-logback.xml @@ -0,0 +1,19 @@ + + + + + %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n + + + + + + + + + + + + + + diff --git a/travis-after-success.sh b/travis-after-success.sh index aeb3c12c7..6d198daf5 100755 --- a/travis-after-success.sh +++ b/travis-after-success.sh @@ -1,9 +1,10 @@ #!/usr/bin/env bash + codecov -if [[ $TRAVIS_BRANCH == "master" ]] && [[ $TRAVIS_PULL_REQUEST == "false" ]]; +if [[ $TRAVIS_BRANCH == "master" ]] && [[ $TRAVIS_PULL_REQUEST == "false" ]] && [[ $DEPLOY == "true" ]]; then - cat << EOF >> ~/settings.xml + cat <> ~/settings.xml diff --git a/travis-before-install.sh b/travis-before-install.sh new file mode 100755 index 000000000..0253ce6bf --- /dev/null +++ b/travis-before-install.sh @@ -0,0 +1,43 @@ +#!/usr/bin/env bash + + +if [ "$FAST_BUILD" == true ]; then + echo "Fast build, skipping docker installations." + exit 0 +fi + +set -exu + +docker info +docker version + +sudo -E apt-get update +sudo -E apt-get install -q -y wget +sudo -E apt-get -q -y --purge remove docker-engine +sudo -E apt-cache policy docker-engine + +./get-docker-com.sh +#mkdir "${HOME}/.cache" || : +#pushd "${HOME}/.cache" +# wget -N "https://apt.dockerproject.org/repo/pool/main/d/docker-engine/docker-engine_${DOCKER_VERSION}_amd64.deb" +# sudo apt-get -f install +# sudo dpkg -i "$(ls *${DOCKER_VERSION}*)" +#popd +#rm -f "src/test/resources/logback.xml" +mv "src/test/resources/travis-logback.xml" "src/test/resources/logback.xml" + +echo 'DOCKER_OPTS="-H=unix:///var/run/docker.sock -H=tcp://127.0.0.1:2375"' | sudo tee -a /etc/default/docker +sudo -E restart docker +sleep 10 +docker version +docker info + +set +u + +cat < "${HOME}/.docker-java.properties" +registry.username=${registry_username} +registry.password=${registry_password} +registry.email=${registry_email} +registry.url=https://index.docker.io/v1/ + +EOF From 2bd837f0187edbb85888f4d2a43c05b487d1858b Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 20 Jun 2016 10:54:50 +0300 Subject: [PATCH 166/855] Coverity (#613) - more badges - coverity verification on master on main (fast/successful) build. --- .travis.yml | 15 ++++++++++++--- README.md | 2 ++ travis-before-install.sh | 5 +++++ travis-script.sh | 22 ++++++++++++++++++++++ 4 files changed, 41 insertions(+), 3 deletions(-) create mode 100755 travis-script.sh diff --git a/.travis.yml b/.travis.yml index 4e980294e..b99125afc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,14 +8,22 @@ services: jdk: - oraclejdk7 +install: true + env: global: - DOCKER_TLS_VERIFY="" + # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created + # via the "travis encrypt" command using the project repo's public key + - secure: "GonzmzvnXsTNQV+6sKtBSSPiwbpMZjxumNt5LFp1g77/afLxw9kl2EQOXbUe308vFOwRVqeY7drBvNJa8aJkTUClfMaGRjfZ9DUwm6doMKMUYrdEkYoQTcH7yDX5K5w9MT6m+Izj+BK2gB7nK3yFlYG6COeXCdFbQ4/cf3/xfRc=" + - COVERITY_SCAN_PROJECT_NAME="docker-java/docker-java" + - COVERITY_SCAN_BRANCH_PATTERN="master" + - COVERITY_SCAN_NOTIFICATION_EMAIL="kanstantsin.sha@gmail.com" matrix: - - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" FAST_BUILD=true + - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" DEPLOY=true FAST_BUILD=true COVERITY=true - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" - - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.11.2-0~trusty" DEPLOY=true + - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.11.2-0~trusty" - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.10.3-0~trusty" - repo="testing" DOCKER_HOST="tcp://127.0.0.1:2375" - repo="testing" DOCKER_HOST="unix:///var/run/docker.sock" @@ -31,7 +39,8 @@ before_install: - pip install --user codecov - ./travis-before-install.sh -script: if [ "${FAST_BUILD}" == true ]; then mvn package ; else mvn verify; fi +script: + - ./travis-script.sh after_success: - ./travis-after-success.sh diff --git a/README.md b/README.md index e47b6e5a4..71fbaa11e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ [![Build Status](https://travis-ci.org/docker-java/docker-java.svg?branch=master)](https://travis-ci.org/docker-java/docker-java) +[![Coverity Scan Build Status](https://scan.coverity.com/projects/9177/badge.svg?flat=1)](https://scan.coverity.com/projects/9177) +[![codecov.io](http://codecov.io/github/docker-java/docker-java/coverage.svg?branch=master)](http://codecov.io/github/docker-java/docker-java?branch=master) # docker-java diff --git a/travis-before-install.sh b/travis-before-install.sh index 0253ce6bf..13034fc74 100755 --- a/travis-before-install.sh +++ b/travis-before-install.sh @@ -1,6 +1,11 @@ #!/usr/bin/env bash +sudo apt-get install -y -q ca-certificates + +echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-certificates.crt + + if [ "$FAST_BUILD" == true ]; then echo "Fast build, skipping docker installations." exit 0 diff --git a/travis-script.sh b/travis-script.sh new file mode 100755 index 000000000..0a5fdd38c --- /dev/null +++ b/travis-script.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + +set -ex + +IS_COVERITY_SCAN_BRANCH=`ruby -e "puts '${TRAVIS_BRANCH}' =~ /\\A$COVERITY_SCAN_BRANCH_PATTERN\\z/ ? 1 : 0"` + + +if [ "${FAST_BUILD}" == "true" ]; then + if [ "$COVERITY" == "true" ] && [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then + export COVERITY_SCAN_BUILD_COMMAND="mvn package" + curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash + else + mvn package + fi +else + if [ "$COVERITY" == "true" ] && [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then + COVERITY_SCAN_BUILD_COMMAND="mvn verify" + curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash + else + mvn verify + fi +fi From 197e72c268d3c0a555b78095987864565f23f5c9 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 29 Jun 2016 23:58:33 +0300 Subject: [PATCH 167/855] Versioneye references. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 71fbaa11e..47873ccfe 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ [![Build Status](https://travis-ci.org/docker-java/docker-java.svg?branch=master)](https://travis-ci.org/docker-java/docker-java) [![Coverity Scan Build Status](https://scan.coverity.com/projects/9177/badge.svg?flat=1)](https://scan.coverity.com/projects/9177) [![codecov.io](http://codecov.io/github/docker-java/docker-java/coverage.svg?branch=master)](http://codecov.io/github/docker-java/docker-java?branch=master) +[![Reference Status](https://www.versioneye.com/java/com.github.docker-java:docker-java/reference_badge.svg?style=flat-square)](https://www.versioneye.com/java/com.github.docker-java:docker-java/references) # docker-java From 2e79af92672df2d5b722dad5857ed43eebb16b77 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 4 Jul 2016 10:30:51 +0300 Subject: [PATCH 168/855] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 47873ccfe..5fb385387 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ [![Coverity Scan Build Status](https://scan.coverity.com/projects/9177/badge.svg?flat=1)](https://scan.coverity.com/projects/9177) [![codecov.io](http://codecov.io/github/docker-java/docker-java/coverage.svg?branch=master)](http://codecov.io/github/docker-java/docker-java?branch=master) [![Reference Status](https://www.versioneye.com/java/com.github.docker-java:docker-java/reference_badge.svg?style=flat-square)](https://www.versioneye.com/java/com.github.docker-java:docker-java/references) +![License](http://img.shields.io/:license-apache-blue.svg?style=flat-square)](https://github.com/docker-java/docker-java/blob/master/LICENSE) + # docker-java From 4b2ffe244493639b8fef0622ef2405cd95942cba Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 4 Jul 2016 10:31:26 +0300 Subject: [PATCH 169/855] Typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5fb385387..d50624c0d 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Coverity Scan Build Status](https://scan.coverity.com/projects/9177/badge.svg?flat=1)](https://scan.coverity.com/projects/9177) [![codecov.io](http://codecov.io/github/docker-java/docker-java/coverage.svg?branch=master)](http://codecov.io/github/docker-java/docker-java?branch=master) [![Reference Status](https://www.versioneye.com/java/com.github.docker-java:docker-java/reference_badge.svg?style=flat-square)](https://www.versioneye.com/java/com.github.docker-java:docker-java/references) -![License](http://img.shields.io/:license-apache-blue.svg?style=flat-square)](https://github.com/docker-java/docker-java/blob/master/LICENSE) +[![License](http://img.shields.io/:license-apache-blue.svg?style=flat-square)](https://github.com/docker-java/docker-java/blob/master/LICENSE) # docker-java From 04fa7e86584ad0d6a8d8bb4d7b8712bd193aa7cd Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 4 Jul 2016 22:04:35 +0300 Subject: [PATCH 170/855] Fix it2 (#621) * Fix hasItem in test * Disable toolbox only tests --- .../core/command/CreateContainerCmdImplTest.java | 12 ++++++++---- .../core/command/UpdateContainerCmdImplTest.java | 8 ++++---- .../netty/exec/CreateContainerCmdExecTest.java | 12 ++++++++---- .../netty/exec/UpdateContainerCmdExecTest.java | 8 ++++---- 4 files changed, 24 insertions(+), 16 deletions(-) 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 a93e100c6..a9c0acb8c 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -45,6 +45,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItemInArray; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isEmptyString; @@ -191,9 +192,12 @@ public void createContainerWithVolumesFrom() throws DockerException { @Test public void createContainerWithEnv() throws Exception { + final String testVariable = "VARIABLE=success"; - CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withEnv("VARIABLE=success") - .withCmd("env").exec(); + CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE) + .withEnv(testVariable) + .withCmd("env") + .exec(); LOG.info("Created container {}", container.toString()); @@ -201,11 +205,11 @@ public void createContainerWithEnv() throws Exception { InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); - assertThat(Arrays.asList(inspectContainerResponse.getConfig().getEnv()), containsInAnyOrder("VARIABLE=success")); + assertThat(Arrays.asList(inspectContainerResponse.getConfig().getEnv()), hasItem(testVariable)); dockerClient.startContainerCmd(container.getId()).exec(); - assertThat(containerLog(container.getId()), containsString("VARIABLE=success")); + assertThat(containerLog(container.getId()), containsString(testVariable)); } @Test diff --git a/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java index c230fbb02..3c7a9fd47 100644 --- a/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java @@ -84,10 +84,10 @@ public void updateContainer() throws DockerException, IOException { // .withKernelMemory(52428800) Can not update kernel memory to a running container, please stop it first. .exec(); - // docker toolbox 1.10.1 - assertThat(updateResponse.getWarnings(), hasSize(1)); - assertThat(updateResponse.getWarnings().get(0), - is("Your kernel does not support Block I/O weight. Weight discarded.")); + // true only on docker toolbox (1.10.1) +// assertThat(updateResponse.getWarnings(), hasSize(1)); +// assertThat(updateResponse.getWarnings().get(0), +// is("Your kernel does not support Block I/O weight. Weight discarded.")); InspectContainerResponse inspectAfter = dockerClient.inspectContainerCmd(containerId).exec(); final HostConfig afterHostConfig = inspectAfter.getHostConfig(); 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 3dbe21f16..ec35f930a 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java @@ -43,6 +43,7 @@ import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItemInArray; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isEmptyString; @@ -189,9 +190,12 @@ public void createContainerWithVolumesFrom() throws DockerException { @Test public void createContainerWithEnv() throws Exception { + final String testVariable = "VARIABLE=success"; - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withEnv("VARIABLE=success") - .withCmd("env").exec(); + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withEnv(testVariable) + .withCmd("env") + .exec(); LOG.info("Created container {}", container.toString()); @@ -199,11 +203,11 @@ public void createContainerWithEnv() throws Exception { InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); - assertThat(Arrays.asList(inspectContainerResponse.getConfig().getEnv()), containsInAnyOrder("VARIABLE=success")); + assertThat(Arrays.asList(inspectContainerResponse.getConfig().getEnv()), hasItem(testVariable)); dockerClient.startContainerCmd(container.getId()).exec(); - assertThat(containerLog(container.getId()), containsString("VARIABLE=success")); + assertThat(containerLog(container.getId()), containsString(testVariable)); } @Test diff --git a/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java index e2907dc8a..1134afd6d 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java @@ -83,10 +83,10 @@ public void updateContainer() throws DockerException, IOException { // .withKernelMemory(52428800) Can not update kernel memory to a running container, please stop it first. .exec(); - // docker toolbox 1.10.1 - assertThat(updateResponse.getWarnings(), hasSize(1)); - assertThat(updateResponse.getWarnings().get(0), - is("Your kernel does not support Block I/O weight. Weight discarded.")); + // found only on docker toolbox (1.10.1) +// assertThat(updateResponse.getWarnings(), hasSize(1)); +// assertThat(updateResponse.getWarnings().get(0), +// is("Your kernel does not support Block I/O weight. Weight discarded.")); InspectContainerResponse inspectAfter = dockerClient.inspectContainerCmd(containerId).exec(); final HostConfig afterHostConfig = inspectAfter.getHostConfig(); From 0890ec30cdf8d33c639eabc23bd158323fb83966 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 4 Jul 2016 22:09:11 +0300 Subject: [PATCH 171/855] [CID-125822] Fix resource leak --- .../dockerjava/jaxrs/async/AbstractCallbackNotifier.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java b/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java index 86f528af6..bd80a2d66 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java +++ b/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java @@ -60,9 +60,7 @@ public Void call() throws Exception { return null; } - try { - InputStream inputStream = new WrappedResponseInputStream(response); - + try (InputStream inputStream = new WrappedResponseInputStream(response)) { if (resultCallback != null) { responseStreamProcessor.processResponseStream(inputStream, resultCallback); } From f74fc3dd51d454e561c66c6a0667525ce9d250de Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 4 Jul 2016 22:49:41 +0300 Subject: [PATCH 172/855] Don't upload coverity for PRs --- travis-script.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/travis-script.sh b/travis-script.sh index 0a5fdd38c..e40de7f73 100755 --- a/travis-script.sh +++ b/travis-script.sh @@ -6,14 +6,14 @@ IS_COVERITY_SCAN_BRANCH=`ruby -e "puts '${TRAVIS_BRANCH}' =~ /\\A$COVERITY_SCAN_ if [ "${FAST_BUILD}" == "true" ]; then - if [ "$COVERITY" == "true" ] && [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then + if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$COVERITY" == "true" ] && [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then export COVERITY_SCAN_BUILD_COMMAND="mvn package" curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash else mvn package fi else - if [ "$COVERITY" == "true" ] && [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then + if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$COVERITY" == "true" ] && [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then COVERITY_SCAN_BUILD_COMMAND="mvn verify" curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash else From ada726bbdb79bf850d571e8f184be1ad454892db Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 4 Jul 2016 22:54:30 +0300 Subject: [PATCH 173/855] Update badges --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d50624c0d..159108dd8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ +[![Maven Central](https://img.shields.io/maven-central/v/com.github.docker-java/docker-java.svg?maxAge=2592000)]() +[![Reference Status](https://www.versioneye.com/java/com.github.docker-java:docker-java/reference_badge.svg?style=flat)](https://www.versioneye.com/java/com.github.docker-java:docker-java/references) [![Build Status](https://travis-ci.org/docker-java/docker-java.svg?branch=master)](https://travis-ci.org/docker-java/docker-java) [![Coverity Scan Build Status](https://scan.coverity.com/projects/9177/badge.svg?flat=1)](https://scan.coverity.com/projects/9177) [![codecov.io](http://codecov.io/github/docker-java/docker-java/coverage.svg?branch=master)](http://codecov.io/github/docker-java/docker-java?branch=master) -[![Reference Status](https://www.versioneye.com/java/com.github.docker-java:docker-java/reference_badge.svg?style=flat-square)](https://www.versioneye.com/java/com.github.docker-java:docker-java/references) -[![License](http://img.shields.io/:license-apache-blue.svg?style=flat-square)](https://github.com/docker-java/docker-java/blob/master/LICENSE) +[![License](http://img.shields.io/:license-apache-blue.svg?style=flat)](https://github.com/docker-java/docker-java/blob/master/LICENSE) # docker-java From 199e27db662da73fe51c2af8f66ad595bd91b1cc Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 4 Jul 2016 23:32:13 +0300 Subject: [PATCH 174/855] Move scripts to dir. Fix coverity skip. --- .travis.yml | 6 +- .../travis-after-success.sh | 0 .../travis-before-install.sh | 0 travis-script.sh => .travis/travis-script.sh | 6 +- .travis/travisci_build_coverity_scan.sh | 100 ++++++++++++++++++ 5 files changed, 107 insertions(+), 5 deletions(-) rename travis-after-success.sh => .travis/travis-after-success.sh (100%) rename travis-before-install.sh => .travis/travis-before-install.sh (100%) rename travis-script.sh => .travis/travis-script.sh (68%) create mode 100644 .travis/travisci_build_coverity_scan.sh diff --git a/.travis.yml b/.travis.yml index b99125afc..b6e6f953b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,13 +37,13 @@ cache: before_install: - pip install --user codecov - - ./travis-before-install.sh + - ./.travis/travis-before-install.sh script: - - ./travis-script.sh + - ./.travis/travis-script.sh after_success: - - ./travis-after-success.sh + - ./.travis/travis-after-success.sh after_script: - sudo cat /var/log/upstart/docker.log diff --git a/travis-after-success.sh b/.travis/travis-after-success.sh similarity index 100% rename from travis-after-success.sh rename to .travis/travis-after-success.sh diff --git a/travis-before-install.sh b/.travis/travis-before-install.sh similarity index 100% rename from travis-before-install.sh rename to .travis/travis-before-install.sh diff --git a/travis-script.sh b/.travis/travis-script.sh similarity index 68% rename from travis-script.sh rename to .travis/travis-script.sh index e40de7f73..7046940ff 100755 --- a/travis-script.sh +++ b/.travis/travis-script.sh @@ -8,14 +8,16 @@ IS_COVERITY_SCAN_BRANCH=`ruby -e "puts '${TRAVIS_BRANCH}' =~ /\\A$COVERITY_SCAN_ if [ "${FAST_BUILD}" == "true" ]; then if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$COVERITY" == "true" ] && [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then export COVERITY_SCAN_BUILD_COMMAND="mvn package" - curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash + #curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash + ./.travis/travisci_build_coverity_scan.sh else mvn package fi else if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$COVERITY" == "true" ] && [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then COVERITY_SCAN_BUILD_COMMAND="mvn verify" - curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash + #curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash + ./.travis/travisci_build_coverity_scan.sh else mvn verify fi diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh new file mode 100644 index 000000000..2679384b9 --- /dev/null +++ b/.travis/travisci_build_coverity_scan.sh @@ -0,0 +1,100 @@ +#!/bin/sh + +set -e + +# Environment check +echo -e "\033[33;1mNote: COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN are available on Project Settings page on scan.coverity.com\033[0m" +[ -z "$COVERITY_SCAN_PROJECT_NAME" ] && echo "ERROR: COVERITY_SCAN_PROJECT_NAME must be set" && exit 1 +[ -z "$COVERITY_SCAN_NOTIFICATION_EMAIL" ] && echo "ERROR: COVERITY_SCAN_NOTIFICATION_EMAIL must be set" && exit 1 +[ -z "$COVERITY_SCAN_BRANCH_PATTERN" ] && echo "ERROR: COVERITY_SCAN_BRANCH_PATTERN must be set" && exit 1 +[ -z "$COVERITY_SCAN_BUILD_COMMAND" ] && echo "ERROR: COVERITY_SCAN_BUILD_COMMAND must be set" && exit 1 +[ -z "$COVERITY_SCAN_TOKEN" ] && echo "ERROR: COVERITY_SCAN_TOKEN must be set" && exit 1 + +PLATFORM=`uname` +TOOL_ARCHIVE=/tmp/cov-analysis-${PLATFORM}.tgz +TOOL_URL=https://scan.coverity.com/download/${PLATFORM} +TOOL_BASE=/tmp/coverity-scan-analysis +UPLOAD_URL="https://scan.coverity.com/builds" +SCAN_URL="https://scan.coverity.com" + +# Do not run on pull requests +if [ "${TRAVIS_PULL_REQUEST}" = "true" ]; then + echo -e "\033[33;1mINFO: Skipping Coverity Analysis: branch is a pull request.\033[0m" + exit 0 +fi + +# Verify this branch should run +IS_COVERITY_SCAN_BRANCH=`ruby -e "puts '${TRAVIS_BRANCH}' =~ /\\A$COVERITY_SCAN_BRANCH_PATTERN\\z/ ? 1 : 0"` +if [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then + echo -e "\033[33;1mCoverity Scan configured to run on branch ${TRAVIS_BRANCH}\033[0m" +else + echo -e "\033[33;1mCoverity Scan NOT configured to run on branch ${TRAVIS_BRANCH}\033[0m" + exit 1 +fi + +# Verify upload is permitted +AUTH_RES=`curl -s --form project="$COVERITY_SCAN_PROJECT_NAME" --form token="$COVERITY_SCAN_TOKEN" $SCAN_URL/api/upload_permitted` +if [ "$AUTH_RES" = "Access denied" ]; then + echo -e "\033[33;1mCoverity Scan API access denied. Check COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN.\033[0m" + exit 1 +else + AUTH=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['upload_permitted']"` + if [ "$AUTH" = "true" ]; then + echo -e "\033[33;1mCoverity Scan analysis authorized per quota.\033[0m" + else + WHEN=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['next_upload_permitted_at']"` + echo -e "\033[33;1mCoverity Scan analysis NOT authorized until $WHEN.\033[0m" + + exit 1 + fi +fi + +if [ ! -d $TOOL_BASE ]; then + # Download Coverity Scan Analysis Tool + if [ ! -e $TOOL_ARCHIVE ]; then + echo -e "\033[33;1mDownloading Coverity Scan Analysis Tool...\033[0m" + wget -nv -O $TOOL_ARCHIVE $TOOL_URL --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN" + fi + + # Extract Coverity Scan Analysis Tool + echo -e "\033[33;1mExtracting Coverity Scan Analysis Tool...\033[0m" + mkdir -p $TOOL_BASE + pushd $TOOL_BASE + tar xzf $TOOL_ARCHIVE + popd +fi + +TOOL_DIR=`find $TOOL_BASE -type d -name 'cov-analysis*'` +export PATH=$TOOL_DIR/bin:$PATH + +# Build +echo -e "\033[33;1mRunning Coverity Scan Analysis Tool...\033[0m" +COV_BUILD_OPTIONS="" +#COV_BUILD_OPTIONS="--return-emit-failures 8 --parse-error-threshold 85" +RESULTS_DIR="cov-int" +eval "${COVERITY_SCAN_BUILD_COMMAND_PREPEND}" +COVERITY_UNSUPPORTED=1 cov-build --dir $RESULTS_DIR $COV_BUILD_OPTIONS $COVERITY_SCAN_BUILD_COMMAND +cov-import-scm --dir $RESULTS_DIR --scm git --log $RESULTS_DIR/scm_log.txt 2>&1 + +# Upload results +echo -e "\033[33;1mTarring Coverity Scan Analysis results...\033[0m" +RESULTS_ARCHIVE=analysis-results.tgz +tar czf $RESULTS_ARCHIVE $RESULTS_DIR +SHA=`git rev-parse --short HEAD` + +echo -e "\033[33;1mUploading Coverity Scan Analysis results...\033[0m" +response=$(curl \ + --silent --write-out "\n%{http_code}\n" \ + --form project=$COVERITY_SCAN_PROJECT_NAME \ + --form token=$COVERITY_SCAN_TOKEN \ + --form email=$COVERITY_SCAN_NOTIFICATION_EMAIL \ + --form file=@$RESULTS_ARCHIVE \ + --form version=$SHA \ + --form description="Travis CI build" \ + $UPLOAD_URL) +status_code=$(echo "$response" | sed -n '$p') +if [ "$status_code" != "201" ]; then + TEXT=$(echo "$response" | sed '$d') + echo -e "\033[33;1mCoverity Scan upload failed: $TEXT.\033[0m" + exit 1 +fi From a4d5d85d28e6ccb70c33215515b8ef75352c4bb9 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 5 Jul 2016 21:24:07 +0300 Subject: [PATCH 175/855] Fix file perm. --- .travis/travisci_build_coverity_scan.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 .travis/travisci_build_coverity_scan.sh diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh old mode 100644 new mode 100755 From 898d6fa3c7dd7367327f21ed3f3088e0f1f9e691 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 5 Jul 2016 21:49:10 +0300 Subject: [PATCH 176/855] require bash? --- .travis/travisci_build_coverity_scan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh index 2679384b9..13af2c275 100755 --- a/.travis/travisci_build_coverity_scan.sh +++ b/.travis/travisci_build_coverity_scan.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash set -e From fba96397576f2e9f9c56eb0aad7eb5713eefddc0 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 20 Jun 2016 14:55:12 +0300 Subject: [PATCH 177/855] Update deps. Fix IT. - remove custom jersey connector - update all deps - httpclient latest fails, stay on working version --- pom.xml | 77 +- .../jaxrs/DockerCmdExecFactoryImpl.java | 25 +- .../jaxrs/UnixConnectionSocketFactory.java | 5 +- .../jaxrs/async/AbstractCallbackNotifier.java | 1 + .../jaxrs/connector/ApacheConnector.java | 663 ------------------ .../ApacheConnectorClientResponse.java | 48 -- .../connector/ApacheConnectorProvider.java | 146 ---- .../dockerjava/jaxrs/connector/README.txt | 3 - .../command/AttachContainerCmdImplTest.java | 26 +- .../exec/AttachContainerCmdExecTest.java | 8 +- 10 files changed, 101 insertions(+), 901 deletions(-) delete mode 100644 src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnector.java delete mode 100644 src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnectorClientResponse.java delete mode 100644 src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnectorProvider.java delete mode 100644 src/main/java/com/github/dockerjava/jaxrs/connector/README.txt diff --git a/pom.xml b/pom.xml index 3f9caa55a..cb43f2897 100644 --- a/pom.xml +++ b/pom.xml @@ -47,35 +47,35 @@ 1.7 1.7 - 2.11 + 2.23.1 2.6.4 - 4.3.1 - 1.5 - 1.8 - 2.3 + 4.5 + 1.12 + 1.10 + 2.5 2.6 - 1.7.5 + 1.7.21 - 1.51 - 2015-01-27T15-02-14 - 18.0 + 1.54 + 2016-04-06T22-21-19 + 19.0 - 1.1.0 - 6.1.1 - 4.1.0.CR3 + 1.1.7 + 6.9.10 + 4.1.1.Final 1.3 - 1.6 + 1.8 2.3.3 1.10.19 - 2.2 - 2.3.1 - 2.3.1 + 3.0.2 + 3.5.1 + 2.5.3 2.19.1 2.19.1 - 1.7 + 1.8 @@ -89,6 +89,11 @@ jersey-apache-connector ${jersey.version} + + org.apache.httpcomponents + httpcore + 4.4.5 + org.apache.httpcomponents httpclient @@ -99,10 +104,20 @@ jersey-client ${jersey.version} + + + + + + + com.kohlschutter.junixsocket + junixsocket-common + 2.0.4 + - de.gesellix - unix-socket-factory - ${unix-socket-factory.version} + com.kohlschutter.junixsocket + junixsocket-native-common + 2.0.4 @@ -133,7 +148,7 @@ org.slf4j jcl-over-slf4j - 1.7.12 + 1.7.21 @@ -206,7 +221,7 @@ com.google.code.findbugs annotations - 3.0.0 + 3.0.1 provided @@ -231,6 +246,12 @@ ${netty.version} linux-x86_64 + + junit + junit + 4.12 + test + @@ -321,7 +342,7 @@ org.apache.maven.plugins maven-source-plugin - 2.2.1 + 3.0.1 attach-sources @@ -334,7 +355,7 @@ org.apache.maven.plugins maven-javadoc-plugin - 2.9.1 + 2.10.4 attach-javadocs @@ -350,7 +371,7 @@ org.sonatype.plugins nexus-staging-maven-plugin - 1.6.2 + 1.6.7 true ossrh @@ -362,7 +383,7 @@ org.apache.maven.plugins maven-release-plugin - 2.5 + ${maven-release-plugin.version} true false @@ -465,7 +486,7 @@ org.codehaus.mojo findbugs-maven-plugin - 3.0.2 + 3.0.3 Max Low @@ -484,7 +505,7 @@ org.jacoco jacoco-maven-plugin - 0.7.6.201602180812 + 0.7.7.201606060606 diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index fc74e1fde..4800f22ae 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -18,8 +18,8 @@ import javax.ws.rs.client.WebTarget; import com.github.dockerjava.api.command.UpdateContainerCmd; - import com.github.dockerjava.core.SSLConfig; + import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; @@ -27,6 +27,7 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.glassfish.jersey.CommonProperties; import org.glassfish.jersey.apache.connector.ApacheClientProperties; +import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; import org.glassfish.jersey.client.ClientConfig; import org.glassfish.jersey.client.ClientProperties; import org.slf4j.Logger; @@ -85,7 +86,6 @@ import com.github.dockerjava.api.command.RenameContainerCmd; import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.core.DockerClientConfig; -import com.github.dockerjava.jaxrs.connector.ApacheConnectorProvider; import com.github.dockerjava.jaxrs.filter.JsonClientFilter; import com.github.dockerjava.jaxrs.filter.ResponseStatusExceptionFilter; import com.github.dockerjava.jaxrs.filter.SelectiveLoggingFilter; @@ -115,6 +115,8 @@ public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { private DockerClientConfig dockerClientConfig; + private PoolingHttpClientConnectionManager connManager = null; + @Override public void init(DockerClientConfig dockerClientConfig) { checkNotNull(dockerClientConfig, "config was not specified"); @@ -187,8 +189,21 @@ public void init(DockerClientConfig dockerClientConfig) { configureProxy(clientConfig, protocol); } - PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(getSchemeRegistry( - originalUri, sslContext)); + connManager = new PoolingHttpClientConnectionManager(getSchemeRegistry( + originalUri, sslContext)) { + + @Override + public void close() { + super.shutdown(); + } + + @Override + public void shutdown() { + // Disable shutdown of the pool. This will be done later, when this factory is closed + // This is a workaround for finalize method on jerseys ClientRuntime which + // closes the client and shuts down the connection pool when it is garbage collected + } + }; if (maxTotalConnections != null) { connManager.setMaxTotal(maxTotalConnections); @@ -412,7 +427,6 @@ public KillContainerCmd.Exec createKillContainerCmdExec() { return new KillContainerCmdExec(getBaseResource(), getDockerClientConfig()); } - @Override public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig()); @@ -527,6 +541,7 @@ public DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec() { public void close() throws IOException { checkNotNull(client, "Factory not initialized. You probably forgot to call init()!"); client.close(); + connManager.close(); } public DockerCmdExecFactoryImpl withReadTimeout(Integer readTimeout) { diff --git a/src/main/java/com/github/dockerjava/jaxrs/UnixConnectionSocketFactory.java b/src/main/java/com/github/dockerjava/jaxrs/UnixConnectionSocketFactory.java index 870e2fd04..0c5400ecd 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/UnixConnectionSocketFactory.java +++ b/src/main/java/com/github/dockerjava/jaxrs/UnixConnectionSocketFactory.java @@ -29,7 +29,8 @@ import java.net.URI; import org.apache.http.HttpHost; -import org.apache.http.annotation.Immutable; +import org.apache.http.annotation.Contract; +import org.apache.http.annotation.ThreadingBehavior; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.protocol.HttpContext; @@ -38,7 +39,7 @@ /** * Provides a ConnectionSocketFactory for connecting Apache HTTP clients to Unix sockets. */ -@Immutable +@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL) public class UnixConnectionSocketFactory implements ConnectionSocketFactory { private File socketFile; diff --git a/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java b/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java index bd80a2d66..cd7a7f809 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java +++ b/src/main/java/com/github/dockerjava/jaxrs/async/AbstractCallbackNotifier.java @@ -61,6 +61,7 @@ public Void call() throws Exception { } try (InputStream inputStream = new WrappedResponseInputStream(response)) { + if (resultCallback != null) { responseStreamProcessor.processResponseStream(inputStream, resultCallback); } diff --git a/src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnector.java b/src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnector.java deleted file mode 100644 index 68b47bfa8..000000000 --- a/src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnector.java +++ /dev/null @@ -1,663 +0,0 @@ -package com.github.dockerjava.jaxrs.connector; - -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) 2010-2014 Oracle and/or its affiliates. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can - * obtain a copy of the License at - * http://glassfish.java.net/public/CDDL+GPL_1_1.html - * or packager/legal/LICENSE.txt. See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at packager/legal/LICENSE.txt. - * - * GPL Classpath Exception: - * Oracle designates this particular file as subject to the "Classpath" - * exception as provided by Oracle in the GPL Version 2 section of the License - * file that accompanied this code. - * - * Modifications: - * If applicable, add the following below the License Header, with the fields - * enclosed by brackets [] replaced by your own identifying information: - * "Portions Copyright [year] [name of copyright owner]" - * - * Contributor(s): - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ - -import java.io.BufferedInputStream; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.FilterInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.Future; -import java.util.concurrent.atomic.AtomicLong; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import javax.ws.rs.ProcessingException; -import javax.ws.rs.core.Configuration; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; - -import jersey.repackaged.com.google.common.util.concurrent.MoreExecutors; - -import org.apache.http.Header; -import org.apache.http.HttpEntity; -import org.apache.http.HttpHost; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.AuthCache; -import org.apache.http.client.CookieStore; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.client.HttpClient; -import org.apache.http.client.config.CookieSpecs; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpUriRequest; -import org.apache.http.client.methods.RequestBuilder; -import org.apache.http.client.protocol.HttpClientContext; -import org.apache.http.config.ConnectionConfig; -import org.apache.http.config.Registry; -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.HttpClientConnectionManager; -import org.apache.http.conn.ManagedHttpClientConnection; -import org.apache.http.conn.routing.HttpRoute; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.conn.socket.LayeredConnectionSocketFactory; -import org.apache.http.conn.socket.PlainConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLContexts; -import org.apache.http.conn.ssl.X509HostnameVerifier; -import org.apache.http.entity.AbstractHttpEntity; -import org.apache.http.entity.BufferedHttpEntity; -import org.apache.http.entity.ContentLengthStrategy; -import org.apache.http.impl.auth.BasicScheme; -import org.apache.http.impl.client.BasicAuthCache; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.impl.conn.DefaultManagedHttpClientConnection; -import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.apache.http.impl.io.ChunkedOutputStream; -import org.apache.http.io.SessionOutputBuffer; -import org.apache.http.util.TextUtils; -import org.apache.http.util.VersionInfo; -import org.glassfish.jersey.SslConfigurator; -import org.glassfish.jersey.apache.connector.ApacheClientProperties; -import org.glassfish.jersey.apache.connector.LocalizationMessages; -import org.glassfish.jersey.client.ClientProperties; -import org.glassfish.jersey.client.ClientRequest; -import org.glassfish.jersey.client.ClientResponse; -import org.glassfish.jersey.client.RequestEntityProcessing; -import org.glassfish.jersey.client.spi.AsyncConnectorCallback; -import org.glassfish.jersey.client.spi.Connector; -import org.glassfish.jersey.internal.util.PropertiesHelper; -import org.glassfish.jersey.message.internal.HeaderUtils; -import org.glassfish.jersey.message.internal.OutboundMessageContext; -import org.glassfish.jersey.message.internal.ReaderWriter; -import org.glassfish.jersey.message.internal.Statuses; - -/** - * A {@link Connector} that utilizes the Apache HTTP Client to send and receive HTTP request and responses. - *

- * The following properties are only supported at construction of this class: - *

    - *
  • {@link ApacheClientProperties#CONNECTION_MANAGER}
  • - *
  • {@link ApacheClientProperties#REQUEST_CONFIG}
  • - *
  • {@link ApacheClientProperties#CREDENTIALS_PROVIDER}
  • - *
  • {@link ApacheClientProperties#DISABLE_COOKIES}
  • - *
  • {@link ClientProperties#PROXY_URI}
  • - *
  • {@link ClientProperties#PROXY_USERNAME}
  • - *
  • {@link ClientProperties#PROXY_PASSWORD}
  • - *
  • {@link ClientProperties#REQUEST_ENTITY_PROCESSING} - default value is {@link RequestEntityProcessing#CHUNKED}
  • - *
  • {@link ApacheClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}
  • - *
  • {@link ApacheClientProperties#SSL_CONFIG}
  • - *
- *

- * This connector uses {@link RequestEntityProcessing#CHUNKED chunked encoding} as a default setting. This can be overridden by the - * {@link ClientProperties#REQUEST_ENTITY_PROCESSING}. By default the {@link ClientProperties#CHUNKED_ENCODING_SIZE} property is only - * supported by using default connection manager. If custom connection manager needs to be used then chunked encoding size can be set by - * providing a custom {@link org.apache.http.HttpClientConnection} (via custom - * {@link org.apache.http.impl.conn.ManagedHttpClientConnectionFactory}) and overriding {@code createOutputStream} method. - *

- *

- * Using of authorization is dependent on the chunk encoding setting. If the entity buffering is enabled, the entity is buffered and - * authorization can be performed automatically in response to a 401 by sending the request again. When entity buffering is disabled - * (chunked encoding is used) then the property - * {@link org.glassfish.jersey.apache.connector.ApacheClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION} must be set to {@code true}. - *

- *

- * If a {@link org.glassfish.jersey.client.ClientResponse} is obtained and an entity is not read from the response then - * {@link org.glassfish.jersey.client.ClientResponse#close()} MUST be called after processing the response to release connection-based - * resources. - *

- *

- * Client operations are thread safe, the HTTP connection may be shared between different threads. - *

- *

- * If a response entity is obtained that is an instance of {@link Closeable} then the instance MUST be closed after processing the entity to - * release connection-based resources. - *

- *

- * The following methods are currently supported: HEAD, GET, POST, PUT, DELETE, OPTIONS, PATCH and TRACE. - *

- * - * @author jorgeluisw@mac.com - * @author Paul Sandoz (paul.sandoz at oracle.com) - * @author Pavel Bucek (pavel.bucek at oracle.com) - * @author Arul Dhesiaseelan (aruld at acm.org) - * @see ApacheClientProperties#CONNECTION_MANAGER - */ -@SuppressWarnings("deprecation") -class ApacheConnector implements Connector { - - private static final Logger LOGGER = Logger.getLogger(ApacheConnector.class.getName()); - - private static final VersionInfo VERSION_INFO; - - private static final String RELEASE; - - static { - VERSION_INFO = VersionInfo.loadVersionInfo("org.apache.http.client", HttpClientBuilder.class.getClassLoader()); - RELEASE = (VERSION_INFO != null) ? VERSION_INFO.getRelease() : VersionInfo.UNAVAILABLE; - } - - private final CloseableHttpClient client; - - private final CookieStore cookieStore; - - private final boolean preemptiveBasicAuth; - - private final RequestConfig requestConfig; - - /** - * Create the new Apache HTTP Client connector. - * - * @param config - * client configuration. - */ - ApacheConnector(Configuration config) { - Object reqConfig = null; - - if (config != null) { - final Object connectionManager = config.getProperties().get(ApacheClientProperties.CONNECTION_MANAGER); - - if (connectionManager != null && !(connectionManager instanceof HttpClientConnectionManager)) { - LOGGER.log(Level.WARNING, LocalizationMessages.IGNORING_VALUE_OF_PROPERTY( - ApacheClientProperties.CONNECTION_MANAGER, connectionManager.getClass().getName(), - HttpClientConnectionManager.class.getName())); - } - - reqConfig = config.getProperties().get(ApacheClientProperties.REQUEST_CONFIG); - if (reqConfig != null) { - if (!(reqConfig instanceof RequestConfig)) { - LOGGER.log(Level.WARNING, LocalizationMessages.IGNORING_VALUE_OF_PROPERTY( - ApacheClientProperties.REQUEST_CONFIG, reqConfig.getClass().getName(), - RequestConfig.class.getName())); - reqConfig = null; - } - } - } - - final SSLContext sslContext = getSslContext(config); - final HttpClientBuilder clientBuilder = HttpClientBuilder.create(); - - clientBuilder.setConnectionManager(getConnectionManager(config, sslContext)); - clientBuilder.setSslcontext(sslContext); - - final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); - - int connectTimeout = 0; - int socketTimeout = 0; - boolean ignoreCookies = false; - if (config != null) { - connectTimeout = ClientProperties.getValue(config.getProperties(), ClientProperties.CONNECT_TIMEOUT, 0); - socketTimeout = ClientProperties.getValue(config.getProperties(), ClientProperties.READ_TIMEOUT, 0); - ignoreCookies = PropertiesHelper.isProperty(config.getProperties(), ApacheClientProperties.DISABLE_COOKIES); - - final Object credentialsProvider = config.getProperty(ApacheClientProperties.CREDENTIALS_PROVIDER); - if (credentialsProvider != null && (credentialsProvider instanceof CredentialsProvider)) { - clientBuilder.setDefaultCredentialsProvider((CredentialsProvider) credentialsProvider); - } - - Object proxyUri; - proxyUri = config.getProperty(ClientProperties.PROXY_URI); - if (proxyUri != null) { - final URI u = getProxyUri(proxyUri); - final HttpHost proxy = new HttpHost(u.getHost(), u.getPort(), u.getScheme()); - String userName; - userName = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_USERNAME, - String.class); - if (userName != null) { - String password; - password = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_PASSWORD, - String.class); - - if (password != null) { - final CredentialsProvider credsProvider = new BasicCredentialsProvider(); - credsProvider.setCredentials(new AuthScope(u.getHost(), u.getPort()), - new UsernamePasswordCredentials(userName, password)); - clientBuilder.setDefaultCredentialsProvider(credsProvider); - } - } - clientBuilder.setProxy(proxy); - } - - final Boolean preemptiveBasicAuthProperty = (Boolean) config.getProperties().get( - ApacheClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION); - this.preemptiveBasicAuth = (preemptiveBasicAuthProperty != null) ? preemptiveBasicAuthProperty : false; - } else { - this.preemptiveBasicAuth = false; - } - - if (reqConfig != null) { - RequestConfig.Builder reqConfigBuilder = RequestConfig.copy((RequestConfig) reqConfig); - if (connectTimeout > 0) { - reqConfigBuilder.setConnectTimeout(connectTimeout); - } - if (socketTimeout > 0) { - reqConfigBuilder.setSocketTimeout(socketTimeout); - } - if (ignoreCookies) { - reqConfigBuilder.setCookieSpec(CookieSpecs.IGNORE_COOKIES); - } - requestConfig = reqConfigBuilder.build(); - } else { - requestConfigBuilder.setConnectTimeout(connectTimeout); - requestConfigBuilder.setSocketTimeout(socketTimeout); - if (ignoreCookies) { - requestConfigBuilder.setCookieSpec(CookieSpecs.IGNORE_COOKIES); - } - requestConfig = requestConfigBuilder.build(); - } - - if (requestConfig.getCookieSpec() == null || !requestConfig.getCookieSpec().equals(CookieSpecs.IGNORE_COOKIES)) { - this.cookieStore = new BasicCookieStore(); - clientBuilder.setDefaultCookieStore(cookieStore); - } else { - this.cookieStore = null; - } - clientBuilder.setDefaultRequestConfig(requestConfig); - this.client = clientBuilder.build(); - } - - private SSLContext getSslContext(final Configuration config) { - final SslConfigurator sslConfigurator = ApacheClientProperties.getValue(config.getProperties(), - ApacheClientProperties.SSL_CONFIG, SslConfigurator.class); - - return sslConfigurator != null ? sslConfigurator.createSSLContext() : null; - } - - HttpClientConnectionManager getConnectionManager(final Configuration config, final SSLContext sslContext) { - final Object cmObject = config.getProperties().get(ApacheClientProperties.CONNECTION_MANAGER); - - // Connection manager from configuration. - if (cmObject != null) { - if (cmObject instanceof HttpClientConnectionManager) { - return (HttpClientConnectionManager) cmObject; - } else { - LOGGER.log(Level.WARNING, LocalizationMessages.IGNORING_VALUE_OF_PROPERTY( - ApacheClientProperties.CONNECTION_MANAGER, cmObject.getClass().getName(), - HttpClientConnectionManager.class.getName())); - } - } - - // Create custom connection manager. - return createConnectionManager(config, sslContext, null, false); - } - - private HttpClientConnectionManager createConnectionManager(final Configuration config, - final SSLContext sslContext, X509HostnameVerifier hostnameVerifier, final boolean useSystemProperties) { - - final String[] supportedProtocols = useSystemProperties ? split(System.getProperty("https.protocols")) : null; - final String[] supportedCipherSuites = useSystemProperties ? split(System.getProperty("https.cipherSuites")) - : null; - - if (hostnameVerifier == null) { - hostnameVerifier = SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER; - } - - final LayeredConnectionSocketFactory sslSocketFactory; - if (sslContext != null) { - sslSocketFactory = new SSLConnectionSocketFactory(sslContext, supportedProtocols, supportedCipherSuites, - hostnameVerifier); - } else { - if (useSystemProperties) { - sslSocketFactory = new SSLConnectionSocketFactory((SSLSocketFactory) SSLSocketFactory.getDefault(), - supportedProtocols, supportedCipherSuites, hostnameVerifier); - } else { - sslSocketFactory = new SSLConnectionSocketFactory(SSLContexts.createDefault(), hostnameVerifier); - } - } - - final Registry registry = RegistryBuilder. create() - .register("http", PlainConnectionSocketFactory.getSocketFactory()).register("https", sslSocketFactory) - .build(); - - final Integer chunkSize = ClientProperties.getValue(config.getProperties(), - ClientProperties.CHUNKED_ENCODING_SIZE, 4096, Integer.class); - - final PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry, - new ConnectionFactory(chunkSize)); - - if (useSystemProperties) { - String s = System.getProperty("http.keepAlive", "true"); - if ("true".equalsIgnoreCase(s)) { - s = System.getProperty("http.maxConnections", "5"); - final int max = Integer.parseInt(s); - connectionManager.setDefaultMaxPerRoute(max); - connectionManager.setMaxTotal(2 * max); - } - } - - return connectionManager; - } - - private static String[] split(final String s) { - if (TextUtils.isBlank(s)) { - return null; - } - return s.split(" *, *"); - } - - /** - * Get the {@link HttpClient}. - * - * @return the {@link HttpClient}. - */ - @SuppressWarnings("UnusedDeclaration") - public HttpClient getHttpClient() { - return client; - } - - /** - * Get the {@link CookieStore}. - * - * @return the {@link CookieStore} instance or {@code null} when {@value ApacheClientProperties#DISABLE_COOKIES} set to {@code true}. - */ - public CookieStore getCookieStore() { - return cookieStore; - } - - private static URI getProxyUri(final Object proxy) { - if (proxy instanceof URI) { - return (URI) proxy; - } else if (proxy instanceof String) { - return URI.create((String) proxy); - } else { - throw new ProcessingException(LocalizationMessages.WRONG_PROXY_URI_TYPE(ClientProperties.PROXY_URI)); - } - } - - @Override - public ClientResponse apply(final ClientRequest clientRequest) throws ProcessingException { - final HttpUriRequest request = getUriHttpRequest(clientRequest); - final Map clientHeadersSnapshot = writeOutBoundHeaders(clientRequest.getHeaders(), request); - - try { - final CloseableHttpResponse response; - final HttpClientContext context = HttpClientContext.create(); - if (preemptiveBasicAuth) { - final AuthCache authCache = new BasicAuthCache(); - final BasicScheme basicScheme = new BasicScheme(); - authCache.put(getHost(request), basicScheme); - context.setAuthCache(authCache); - } - - // context.setRequestConfig(RequestConfig.custom().setConnectionRequestTimeout(10).build()); - - response = client.execute(getHost(request), request, context); - HeaderUtils - .checkHeaderChanges(clientHeadersSnapshot, clientRequest.getHeaders(), this.getClass().getName()); - - final Response.StatusType status = response.getStatusLine().getReasonPhrase() == null ? Statuses - .from(response.getStatusLine().getStatusCode()) : Statuses.from(response.getStatusLine() - .getStatusCode(), response.getStatusLine().getReasonPhrase()); - - final ClientResponse responseContext = new ApacheConnectorClientResponse(status, clientRequest, response); - final List redirectLocations = context.getRedirectLocations(); - if (redirectLocations != null && !redirectLocations.isEmpty()) { - responseContext.setResolvedRequestUri(redirectLocations.get(redirectLocations.size() - 1)); - } - - final Header[] respHeaders = response.getAllHeaders(); - final MultivaluedMap headers = responseContext.getHeaders(); - for (final Header header : respHeaders) { - final String headerName = header.getName(); - List list = headers.get(headerName); - if (list == null) { - list = new ArrayList(); - } - list.add(header.getValue()); - headers.put(headerName, list); - } - - final HttpEntity entity = response.getEntity(); - - if (entity != null) { - if (headers.get(HttpHeaders.CONTENT_LENGTH) == null) { - headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(entity.getContentLength())); - } - - final Header contentEncoding = entity.getContentEncoding(); - if (headers.get(HttpHeaders.CONTENT_ENCODING) == null && contentEncoding != null) { - headers.add(HttpHeaders.CONTENT_ENCODING, contentEncoding.getValue()); - } - } - - try { - responseContext.setEntityStream(new HttpClientResponseInputStream(response)); - } catch (final IOException e) { - LOGGER.log(Level.SEVERE, null, e); - } - - return responseContext; - } catch (final Exception e) { - throw new ProcessingException(e); - } - } - - @Override - public Future apply(final ClientRequest request, final AsyncConnectorCallback callback) { - return MoreExecutors.sameThreadExecutor().submit(new Runnable() { - @Override - public void run() { - try { - callback.response(apply(request)); - } catch (final ProcessingException ex) { - callback.failure(ex); - } catch (final Throwable t) { - callback.failure(t); - } - } - }); - } - - @Override - public String getName() { - return "Apache HttpClient " + RELEASE; - } - - @Override - public void close() { - try { - client.close(); - } catch (final IOException e) { - throw new ProcessingException(LocalizationMessages.FAILED_TO_STOP_CLIENT(), e); - } - } - - private HttpHost getHost(final HttpUriRequest request) { - return new HttpHost(request.getURI().getHost(), request.getURI().getPort(), request.getURI().getScheme()); - } - - private HttpUriRequest getUriHttpRequest(final ClientRequest clientRequest) { - final Boolean redirectsEnabled = clientRequest.resolveProperty(ClientProperties.FOLLOW_REDIRECTS, - requestConfig.isRedirectsEnabled()); - final RequestConfig config = RequestConfig.copy(requestConfig).setRedirectsEnabled(redirectsEnabled).build(); - - final Boolean bufferingEnabled = clientRequest.resolveProperty(ClientProperties.REQUEST_ENTITY_PROCESSING, - RequestEntityProcessing.class) == RequestEntityProcessing.BUFFERED; - final HttpEntity entity = getHttpEntity(clientRequest, bufferingEnabled); - - return RequestBuilder.create(clientRequest.getMethod()).setUri(clientRequest.getUri()).setConfig(config) - .setEntity(entity).build(); - } - - private HttpEntity getHttpEntity(final ClientRequest clientRequest, final boolean bufferingEnabled) { - final Object entity = clientRequest.getEntity(); - - if (entity == null) { - return null; - } - - final AbstractHttpEntity httpEntity = new AbstractHttpEntity() { - @Override - public boolean isRepeatable() { - return false; - } - - @Override - public long getContentLength() { - return -1; - } - - @Override - public InputStream getContent() throws IOException, IllegalStateException { - if (bufferingEnabled) { - final ByteArrayOutputStream buffer = new ByteArrayOutputStream(512); - writeTo(buffer); - return new ByteArrayInputStream(buffer.toByteArray()); - } else { - return null; - } - } - - @Override - public void writeTo(final OutputStream outputStream) throws IOException { - clientRequest.setStreamProvider(new OutboundMessageContext.StreamProvider() { - @Override - public OutputStream getOutputStream(final int contentLength) throws IOException { - return outputStream; - } - }); - clientRequest.writeEntity(); - } - - @Override - public boolean isStreaming() { - return false; - } - }; - - if (bufferingEnabled) { - try { - return new BufferedHttpEntity(httpEntity); - } catch (final IOException e) { - throw new ProcessingException(LocalizationMessages.ERROR_BUFFERING_ENTITY(), e); - } - } else { - return httpEntity; - } - } - - private static Map writeOutBoundHeaders(final MultivaluedMap headers, - final HttpUriRequest request) { - Map stringHeaders = HeaderUtils.asStringHeadersSingleValue(headers); - - for (Map.Entry e : stringHeaders.entrySet()) { - request.addHeader(e.getKey(), e.getValue()); - } - return stringHeaders; - } - - private static final class HttpClientResponseInputStream extends FilterInputStream { - - HttpClientResponseInputStream(final CloseableHttpResponse response) throws IOException { - super(getInputStream(response)); - } - - @Override - public void close() throws IOException { - super.close(); - } - } - - private static InputStream getInputStream(final CloseableHttpResponse response) throws IOException { - - if (response.getEntity() == null) { - return new ByteArrayInputStream(new byte[0]); - } else { - final InputStream i = response.getEntity().getContent(); - if (i.markSupported()) { - return i; - } - return new BufferedInputStream(i, ReaderWriter.BUFFER_SIZE); - } - } - - private static class ConnectionFactory extends ManagedHttpClientConnectionFactory { - - private static final AtomicLong COUNTER = new AtomicLong(); - - private final int chunkSize; - - private ConnectionFactory(final int chunkSize) { - this.chunkSize = chunkSize; - } - - @Override - public ManagedHttpClientConnection create(final HttpRoute route, final ConnectionConfig config) { - final String id = "http-outgoing-" + Long.toString(COUNTER.getAndIncrement()); - - return new HttpClientConnection(id, config.getBufferSize(), chunkSize); - } - } - - private static class HttpClientConnection extends DefaultManagedHttpClientConnection { - - private final int chunkSize; - - private HttpClientConnection(final String id, final int buffersize, final int chunkSize) { - super(id, buffersize); - - this.chunkSize = chunkSize; - } - - @Override - protected OutputStream createOutputStream(final long len, final SessionOutputBuffer outbuffer) { - if (len == ContentLengthStrategy.CHUNKED) { - return new ChunkedOutputStream(chunkSize, outbuffer); - } - return super.createOutputStream(len, outbuffer); - } - } -} diff --git a/src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnectorClientResponse.java b/src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnectorClientResponse.java deleted file mode 100644 index fead3575c..000000000 --- a/src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnectorClientResponse.java +++ /dev/null @@ -1,48 +0,0 @@ -package com.github.dockerjava.jaxrs.connector; - -import java.io.IOException; - -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.StatusType; - -import org.apache.http.client.methods.CloseableHttpResponse; -import org.glassfish.jersey.client.ClientRequest; -import org.glassfish.jersey.client.ClientResponse; - -/** - * Fix for https://github.com/docker-java/docker-java/issues/196 - * - * https://java.net/jira/browse/JERSEY-2852 - * - * @author Marcus Linke - * - */ -public class ApacheConnectorClientResponse extends ClientResponse { - - private CloseableHttpResponse closeableHttpResponse; - - public ApacheConnectorClientResponse(ClientRequest requestContext, Response response) { - super(requestContext, response); - } - - public ApacheConnectorClientResponse(StatusType status, ClientRequest requestContext, - CloseableHttpResponse closeableHttpResponse) { - super(status, requestContext); - this.closeableHttpResponse = closeableHttpResponse; - } - - public ApacheConnectorClientResponse(StatusType status, ClientRequest requestContext) { - super(status, requestContext); - } - - @Override - public void close() { - try { - closeableHttpResponse.close(); - } catch (IOException e) { - throw new RuntimeException(e); - } - super.close(); - } - -} diff --git a/src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnectorProvider.java b/src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnectorProvider.java deleted file mode 100644 index eafb55c29..000000000 --- a/src/main/java/com/github/dockerjava/jaxrs/connector/ApacheConnectorProvider.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.github.dockerjava.jaxrs.connector; - -/* - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. - * - * Copyright (c) 2013-2014 Oracle and/or its affiliates. All rights reserved. - * - * The contents of this file are subject to the terms of either the GNU - * General Public License Version 2 only ("GPL") or the Common Development - * and Distribution License("CDDL") (collectively, the "License"). You - * may not use this file except in compliance with the License. You can - * obtain a copy of the License at - * http://glassfish.java.net/public/CDDL+GPL_1_1.html - * or packager/legal/LICENSE.txt. See the License for the specific - * language governing permissions and limitations under the License. - * - * When distributing the software, include this License Header Notice in each - * file and include the License file at packager/legal/LICENSE.txt. - * - * GPL Classpath Exception: - * Oracle designates this particular file as subject to the "Classpath" - * exception as provided by Oracle in the GPL Version 2 section of the License - * file that accompanied this code. - * - * Modifications: - * If applicable, add the following below the License Header, with the fields - * enclosed by brackets [] replaced by your own identifying information: - * "Portions Copyright [year] [name of copyright owner]" - * - * Contributor(s): - * If you wish your version of this file to be governed by only the CDDL or - * only the GPL Version 2, indicate your decision by adding "[Contributor] - * elects to include this software in this distribution under the [CDDL or GPL - * Version 2] license." If you don't indicate a single choice of license, a - * recipient has the option to distribute your version of this file under - * either the CDDL, the GPL Version 2 or to extend the choice of license to - * its licensees as provided above. However, if you add GPL Version 2 code - * and therefore, elected the GPL Version 2 license, then the option applies - * only if the new code is made subject to such option by the copyright - * holder. - */ -import javax.ws.rs.client.Client; -import javax.ws.rs.core.Configurable; -import javax.ws.rs.core.Configuration; - -import org.apache.http.client.HttpClient; -import org.glassfish.jersey.apache.connector.ApacheClientProperties; -import org.glassfish.jersey.apache.connector.LocalizationMessages; -import org.glassfish.jersey.client.Initializable; -import org.glassfish.jersey.client.spi.Connector; -import org.glassfish.jersey.client.spi.ConnectorProvider; - -/** - * Connector provider for Jersey {@link Connector connectors} that utilize Apache HTTP Client to send and receive HTTP request and - * responses. - *

- * The following connector configuration properties are supported: - *

    - *
  • {@link ApacheClientProperties#CONNECTION_MANAGER}
  • - *
  • {@link ApacheClientProperties#REQUEST_CONFIG}
  • - *
  • {@link ApacheClientProperties#CREDENTIALS_PROVIDER}
  • - *
  • {@link ApacheClientProperties#DISABLE_COOKIES}
  • - *
  • {@link org.glassfish.jersey.client.ClientProperties#PROXY_URI}
  • - *
  • {@link org.glassfish.jersey.client.ClientProperties#PROXY_USERNAME}
  • - *
  • {@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}
  • - *
  • {@link org.glassfish.jersey.client.ClientProperties#REQUEST_ENTITY_PROCESSING} - default value is - * {@link org.glassfish.jersey.client.RequestEntityProcessing#CHUNKED}
  • - *
  • {@link ApacheClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}
  • - *
  • {@link ApacheClientProperties#SSL_CONFIG}
  • - *
- *

- *

- * Connector instances created via this connector provider use {@link org.glassfish.jersey.client.RequestEntityProcessing#CHUNKED chunked - * encoding} as a default setting. This can be overridden by the - * {@link org.glassfish.jersey.client.ClientProperties#REQUEST_ENTITY_PROCESSING}. By default the - * {@link org.glassfish.jersey.client.ClientProperties#CHUNKED_ENCODING_SIZE} property is only supported when using the default - * {@code org.apache.http.conn.HttpClientConnectionManager} instance. If custom connection manager is used, then chunked encoding size can - * be set by providing a custom {@code org.apache.http.HttpClientConnection} (via custom - * {@code org.apache.http.impl.conn.ManagedHttpClientConnectionFactory}) and overriding it's {@code createOutputStream} method. - *

- *

- * Use of authorization by the AHC-based connectors is dependent on the chunk encoding setting. If the entity buffering is enabled, the - * entity is buffered and authorization can be performed automatically in response to a 401 by sending the request again. When entity - * buffering is disabled (chunked encoding is used) then the property - * {@link org.glassfish.jersey.apache.connector.ApacheClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION} must be set to {@code true}. - *

- *

- * If a {@link org.glassfish.jersey.client.ClientResponse} is obtained and an entity is not read from the response then - * {@link org.glassfish.jersey.client.ClientResponse#close()} MUST be called after processing the response to release connection-based - * resources. - *

- *

- * If a response entity is obtained that is an instance of {@link java.io.Closeable} then the instance MUST be closed after processing the - * entity to release connection-based resources. - *

- *

- * The following methods are currently supported: HEAD, GET, POST, PUT, DELETE, OPTIONS, PATCH and TRACE. - *

- * - * @author Pavel Bucek (pavel.bucek at oracle.com) - * @author Arul Dhesiaseelan (aruld at acm.org) - * @author jorgeluisw at mac.com - * @author Marek Potociar (marek.potociar at oracle.com) - * @author Paul Sandoz (paul.sandoz at oracle.com) - * @since 2.5 - */ -public class ApacheConnectorProvider implements ConnectorProvider { - - @Override - public Connector getConnector(Client client, Configuration runtimeConfig) { - return new ApacheConnector(runtimeConfig); - } - - /** - * Retrieve the underlying Apache {@link HttpClient} instance from {@link org.glassfish.jersey.client.JerseyClient} or - * {@link org.glassfish.jersey.client.JerseyWebTarget} configured to use {@code ApacheConnectorProvider}. - * - * @param component - * {@code JerseyClient} or {@code JerseyWebTarget} instance that is configured to use {@code ApacheConnectorProvider}. - * @return underlying Apache {@code HttpClient} instance. - * - * @throws java.lang.IllegalArgumentException - * in case the {@code component} is neither {@code JerseyClient} nor {@code JerseyWebTarget} instance or in case the - * component is not configured to use a {@code ApacheConnectorProvider}. - * @since 2.8 - */ - public static HttpClient getHttpClient(Configurable component) { - if (!(component instanceof Initializable)) { - throw new IllegalArgumentException(LocalizationMessages.INVALID_CONFIGURABLE_COMPONENT_TYPE(component - .getClass().getName())); - } - - final Initializable initializable = (Initializable) component; - Connector connector = initializable.getConfiguration().getConnector(); - if (connector == null) { - initializable.preInitialize(); - connector = initializable.getConfiguration().getConnector(); - } - - if (connector instanceof ApacheConnector) { - return ((ApacheConnector) connector).getHttpClient(); - } - - throw new IllegalArgumentException(LocalizationMessages.EXPECTED_CONNECTOR_PROVIDER_NOT_USED()); - } -} diff --git a/src/main/java/com/github/dockerjava/jaxrs/connector/README.txt b/src/main/java/com/github/dockerjava/jaxrs/connector/README.txt deleted file mode 100644 index c3c1415f1..000000000 --- a/src/main/java/com/github/dockerjava/jaxrs/connector/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -This package exists as a workaround to https://java.net/jira/browse/JERSEY-2852. -It introduces ApacheConnectorClientResponse which extends ClientResponse and closes -the underlying CloseableHttpResponse when close() is called. \ No newline at end of file diff --git a/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java index 21507e44e..f8bf33fef 100644 --- a/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java @@ -1,5 +1,6 @@ package com.github.dockerjava.core.command; +import static org.apache.commons.lang.StringUtils.isEmpty; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.isEmptyString; @@ -11,7 +12,9 @@ import java.lang.reflect.Method; import java.util.concurrent.TimeUnit; +import org.apache.commons.codec.binary.StringUtils; import org.testng.ITestResult; +import org.testng.SkipException; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeMethod; @@ -74,7 +77,7 @@ public void onNext(Frame frame) { assertThat(callback.toString(), containsString(snippet)); } - @Test + @Test(groups = "badTests", enabled = false) public void attachContainerWithTTY() throws Exception { File baseDir = new File(Thread.currentThread().getContextClassLoader() @@ -97,14 +100,24 @@ public void onNext(Frame frame) { }; }; - dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true) - .exec(callback).awaitCompletion(15, TimeUnit.SECONDS); + dockerClient.attachContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .withFollowStream(true) + .exec(callback) + .awaitCompletion(); +// .awaitCompletion(15, TimeUnit.SECONDS); callback.close(); + dockerClient.close(); + System.out.println("log: " + callback.toString()); // HexDump.dump(collectFramesCallback.toString().getBytes(), 0, System.out, 0); - + RuntimeException firstError = callback.getFirstError(); + if (isEmpty(callback.toString())) { + throw new SkipException("com.github.dockerjava.api.exception.InternalServerErrorException: http: Hijack is incompatible with use of CloseNotifier"); + } assertThat(callback.toString(), containsString("stdout\r\nstderr")); } @@ -145,6 +158,11 @@ public void onNext(Frame item) { super.onNext(item); } + @Override + public RuntimeException getFirstError() { + return super.getFirstError(); + } + @Override public String toString() { return log.toString(); diff --git a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java index 7f8e66609..ba3d5a9ca 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java @@ -134,8 +134,12 @@ public void onNext(Frame frame) { }; }; - dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true) - .exec(callback).awaitCompletion(10, TimeUnit.SECONDS); + dockerClient.attachContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .withFollowStream(true) + .exec(callback) + .awaitCompletion(10, TimeUnit.SECONDS); callback.close(); // HexDump.dump(collectFramesCallback.toString().getBytes(), 0, System.out, 0); From 52ff6d82952a4b1ff2426a24e239547e32f38314 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 8 Jul 2016 00:31:26 +0300 Subject: [PATCH 178/855] revert dep and test --- pom.xml | 18 ++++-------------- .../command/AttachContainerCmdImplTest.java | 11 ++--------- 2 files changed, 6 insertions(+), 23 deletions(-) diff --git a/pom.xml b/pom.xml index cb43f2897..a13ac1fc0 100644 --- a/pom.xml +++ b/pom.xml @@ -57,7 +57,7 @@ 1.7.21 1.54 - 2016-04-06T22-21-19 + 2015-01-27T15-02-14 19.0 @@ -104,20 +104,10 @@ jersey-client ${jersey.version} - - - - - - com.kohlschutter.junixsocket - junixsocket-common - 2.0.4 - - - com.kohlschutter.junixsocket - junixsocket-native-common - 2.0.4 + de.gesellix + unix-socket-factory + ${unix-socket-factory.version} diff --git a/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java index f8bf33fef..ef69984f3 100644 --- a/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/AttachContainerCmdImplTest.java @@ -77,7 +77,7 @@ public void onNext(Frame frame) { assertThat(callback.toString(), containsString(snippet)); } - @Test(groups = "badTests", enabled = false) + @Test public void attachContainerWithTTY() throws Exception { File baseDir = new File(Thread.currentThread().getContextClassLoader() @@ -105,19 +105,12 @@ public void onNext(Frame frame) { .withStdOut(true) .withFollowStream(true) .exec(callback) - .awaitCompletion(); -// .awaitCompletion(15, TimeUnit.SECONDS); + .awaitCompletion(15, TimeUnit.SECONDS); callback.close(); - dockerClient.close(); - System.out.println("log: " + callback.toString()); // HexDump.dump(collectFramesCallback.toString().getBytes(), 0, System.out, 0); - RuntimeException firstError = callback.getFirstError(); - if (isEmpty(callback.toString())) { - throw new SkipException("com.github.dockerjava.api.exception.InternalServerErrorException: http: Hijack is incompatible with use of CloseNotifier"); - } assertThat(callback.toString(), containsString("stdout\r\nstderr")); } From 19d5f84c0bfe9494d558f991e073680195989371 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 8 Jul 2016 00:44:37 +0300 Subject: [PATCH 179/855] Fix version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3f9caa55a..bee178a6d 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.0-kostyasha-3 + 3.0.1-SNAPSHOT docker-java https://github.com/docker-java/docker-java From 1a148f2e51ac908cfa9a23e0f847a07b2c155797 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 8 Jul 2016 01:14:28 +0300 Subject: [PATCH 180/855] Skip auth tests --- pom.xml | 3 ++- .../github/dockerjava/core/command/PushImageCmdImplTest.java | 2 +- .../com/github/dockerjava/netty/exec/PushImageCmdExecTest.java | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index a13ac1fc0..2437baa22 100644 --- a/pom.xml +++ b/pom.xml @@ -388,6 +388,7 @@ ${maven-surefire-plugin.version} integration + integration-auth @@ -403,7 +404,7 @@ integration - + integration-auth **/*Test.java diff --git a/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java index e89a071b8..a48750bd1 100644 --- a/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java @@ -19,7 +19,7 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.client.AbstractDockerClientTest; -@Test(groups = "integration") +@Test(groups = "integration-auth") public class PushImageCmdImplTest extends AbstractDockerClientTest { public static final Logger LOG = LoggerFactory.getLogger(PushImageCmdImplTest.class); diff --git a/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java index 777cc8eed..5e77a6765 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java @@ -21,7 +21,7 @@ import com.github.dockerjava.core.command.PushImageResultCallback; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; -@Test(groups = "integration") +@Test(groups = "integration-auth") public class PushImageCmdExecTest extends AbstractNettyDockerClientTest { public static final Logger LOG = LoggerFactory.getLogger(PushImageCmdExecTest.class); From 3a782a9834449f78368c54356d5dd3412ae89917 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 8 Jul 2016 01:26:19 +0300 Subject: [PATCH 181/855] Enable cache --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b6e6f953b..4491de529 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,7 +33,7 @@ env: cache: directories: - $HOME/.travis_cache -# - $HOME/.m2 install would pollute it + - $HOME/.m2 # install will pollute it before_install: - pip install --user codecov From 31d5627be8dad851941f126a5af0aa5385e002b4 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 8 Jul 2016 01:45:09 +0300 Subject: [PATCH 182/855] Disable experimental/testing --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 4491de529..9c96c5abd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,10 +25,10 @@ env: - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.11.2-0~trusty" - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.10.3-0~trusty" - - repo="testing" DOCKER_HOST="tcp://127.0.0.1:2375" - - repo="testing" DOCKER_HOST="unix:///var/run/docker.sock" - - repo="experimental" DOCKER_HOST="tcp://127.0.0.1:2375" - - repo="experimental" DOCKER_HOST="unix:///var/run/docker.sock" +# - repo="testing" DOCKER_HOST="tcp://127.0.0.1:2375" +# - repo="testing" DOCKER_HOST="unix:///var/run/docker.sock" +# - repo="experimental" DOCKER_HOST="tcp://127.0.0.1:2375" +# - repo="experimental" DOCKER_HOST="unix:///var/run/docker.sock" cache: directories: From 007f66899f9a84bde102f4740631816973e2fb9a Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 8 Jul 2016 02:12:48 +0300 Subject: [PATCH 183/855] run codecov only on one run --- .travis.yml | 3 +-- .travis/travis-after-success.sh | 4 +++- .travis/travis-before-install.sh | 3 +-- .../github/dockerjava/core/command/PushImageCmdImplTest.java | 2 +- .../github/dockerjava/netty/exec/PushImageCmdExecTest.java | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9c96c5abd..bb559fd93 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,7 @@ env: - COVERITY_SCAN_NOTIFICATION_EMAIL="kanstantsin.sha@gmail.com" matrix: - - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" DEPLOY=true FAST_BUILD=true COVERITY=true - - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" + - 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" - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.10.3-0~trusty" # - repo="testing" DOCKER_HOST="tcp://127.0.0.1:2375" diff --git a/.travis/travis-after-success.sh b/.travis/travis-after-success.sh index 6d198daf5..695358122 100755 --- a/.travis/travis-after-success.sh +++ b/.travis/travis-after-success.sh @@ -1,7 +1,9 @@ #!/usr/bin/env bash +if [[ $CODECOV == "true" ]]; then + codecov +fi -codecov if [[ $TRAVIS_BRANCH == "master" ]] && [[ $TRAVIS_PULL_REQUEST == "false" ]] && [[ $DEPLOY == "true" ]]; then cat <> ~/settings.xml diff --git a/.travis/travis-before-install.sh b/.travis/travis-before-install.sh index 13034fc74..970425f63 100755 --- a/.travis/travis-before-install.sh +++ b/.travis/travis-before-install.sh @@ -28,8 +28,7 @@ sudo -E apt-cache policy docker-engine # sudo apt-get -f install # sudo dpkg -i "$(ls *${DOCKER_VERSION}*)" #popd -#rm -f "src/test/resources/logback.xml" -mv "src/test/resources/travis-logback.xml" "src/test/resources/logback.xml" + echo 'DOCKER_OPTS="-H=unix:///var/run/docker.sock -H=tcp://127.0.0.1:2375"' | sudo tee -a /etc/default/docker sudo -E restart docker diff --git a/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java index a48750bd1..0fb32c311 100644 --- a/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/PushImageCmdImplTest.java @@ -19,7 +19,7 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.client.AbstractDockerClientTest; -@Test(groups = "integration-auth") +@Test(groups = {"integration-auth", "integration"}) public class PushImageCmdImplTest extends AbstractDockerClientTest { public static final Logger LOG = LoggerFactory.getLogger(PushImageCmdImplTest.class); diff --git a/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java index 5e77a6765..73e99af6d 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/PushImageCmdExecTest.java @@ -21,7 +21,7 @@ import com.github.dockerjava.core.command.PushImageResultCallback; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; -@Test(groups = "integration-auth") +@Test(groups = {"integration", "integration-auth"}) public class PushImageCmdExecTest extends AbstractNettyDockerClientTest { public static final Logger LOG = LoggerFactory.getLogger(PushImageCmdExecTest.class); From 3854e2efd477ae4cba4e0d1c85302ccc2d085c41 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 8 Jul 2016 02:15:44 +0300 Subject: [PATCH 184/855] revert typo --- .travis/travis-before-install.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis/travis-before-install.sh b/.travis/travis-before-install.sh index 970425f63..13034fc74 100755 --- a/.travis/travis-before-install.sh +++ b/.travis/travis-before-install.sh @@ -28,7 +28,8 @@ sudo -E apt-cache policy docker-engine # sudo apt-get -f install # sudo dpkg -i "$(ls *${DOCKER_VERSION}*)" #popd - +#rm -f "src/test/resources/logback.xml" +mv "src/test/resources/travis-logback.xml" "src/test/resources/logback.xml" echo 'DOCKER_OPTS="-H=unix:///var/run/docker.sock -H=tcp://127.0.0.1:2375"' | sudo tee -a /etc/default/docker sudo -E restart docker From 24d3a15001da56083a5c83f47a1f5076e1468195 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 8 Jul 2016 02:31:08 +0300 Subject: [PATCH 185/855] tune timeout --- .../dockerjava/netty/exec/AttachContainerCmdExecTest.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java index ba3d5a9ca..675c11177 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java @@ -105,7 +105,9 @@ public void onNext(Frame frame) { InputStream stdin = new ByteArrayInputStream((snippet + "\n").getBytes()); dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true) - .withStdIn(stdin).exec(callback).awaitCompletion(2, TimeUnit.SECONDS); + .withStdIn(stdin) + .exec(callback) + .awaitCompletion(5, TimeUnit.SECONDS); callback.close(); assertThat(callback.toString(), containsString(snippet)); From 8837ac38a9a6b820ea292a8afc82a658cb24d883 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 8 Jul 2016 10:50:27 +0300 Subject: [PATCH 186/855] Fix shell scripting --- .travis/travis-script.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/travis-script.sh b/.travis/travis-script.sh index 7046940ff..aeae555ef 100755 --- a/.travis/travis-script.sh +++ b/.travis/travis-script.sh @@ -15,7 +15,7 @@ if [ "${FAST_BUILD}" == "true" ]; then fi else if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$COVERITY" == "true" ] && [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then - COVERITY_SCAN_BUILD_COMMAND="mvn verify" + export COVERITY_SCAN_BUILD_COMMAND="mvn verify" #curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash ./.travis/travisci_build_coverity_scan.sh else From 1c14bc3cf04f22a0768e47431a0124425f53e787 Mon Sep 17 00:00:00 2001 From: tejksat Date: Sat, 9 Jul 2016 11:19:43 +0300 Subject: [PATCH 187/855] Fix for #625 (#630) * Fix for #625 * Checkstyle errors fixed --- .../github/dockerjava/netty/WebTarget.java | 63 +++++++++++++++---- .../dockerjava/netty/WebTargetTest.java | 39 ++++++++++++ 2 files changed, 89 insertions(+), 13 deletions(-) create mode 100644 src/test/java/com/github/dockerjava/netty/WebTargetTest.java diff --git a/src/main/java/com/github/dockerjava/netty/WebTarget.java b/src/main/java/com/github/dockerjava/netty/WebTarget.java index 090fea67c..ef1510f5c 100644 --- a/src/main/java/com/github/dockerjava/netty/WebTarget.java +++ b/src/main/java/com/github/dockerjava/netty/WebTarget.java @@ -2,12 +2,14 @@ import java.util.ArrayList; import java.util.Arrays; -import java.util.HashMap; import java.util.List; import java.util.Map; 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 * implementation. @@ -16,32 +18,40 @@ */ public class WebTarget { - private ChannelProvider channelProvider; + private final ChannelProvider channelProvider; - private List path = new ArrayList(); + private final ImmutableList path; - private Map queryParams = new HashMap(); + private final ImmutableMap queryParams; private static final String PATH_SEPARATOR = "/"; public WebTarget(ChannelProvider channelProvider) { + this(channelProvider, ImmutableList.of(), ImmutableMap.of()); + } + + private WebTarget(ChannelProvider channelProvider, + ImmutableList path, + ImmutableMap queryParams) { this.channelProvider = channelProvider; + this.path = path; + this.queryParams = queryParams; } public WebTarget path(String... components) { + ImmutableList.Builder newPath = ImmutableList.builder().addAll(this.path); for (String component : components) { - - path.addAll(Arrays.asList(StringUtils.split(component, PATH_SEPARATOR))); + newPath.addAll(Arrays.asList(StringUtils.split(component, PATH_SEPARATOR))); } - return this; + return new WebTarget(channelProvider, newPath.build(), queryParams); } public InvocationBuilder request() { String resource = PATH_SEPARATOR + StringUtils.join(path, PATH_SEPARATOR); - List params = new ArrayList(); + List params = new ArrayList<>(); for (Map.Entry entry : queryParams.entrySet()) { params.add(entry.getKey() + "=" + entry.getValue()); } @@ -54,20 +64,47 @@ public InvocationBuilder request() { } public WebTarget resolveTemplate(String name, Object value) { - List newPath = new ArrayList(); + ImmutableList.Builder newPath = ImmutableList.builder(); for (String component : path) { component = component.replaceAll("\\{" + name + "\\}", value.toString()); newPath.add(component); } - path = newPath; - return this; + return new WebTarget(channelProvider, newPath.build(), queryParams); } public WebTarget queryParam(String name, Object value) { + ImmutableMap.Builder builder = ImmutableMap.builder().putAll(queryParams); if (value != null) { - queryParams.put(name, value.toString()); + builder.put(name, value.toString()); } - return this; + return new WebTarget(channelProvider, path, builder.build()); } + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + WebTarget webTarget = (WebTarget) o; + + if (channelProvider != null ? !channelProvider.equals(webTarget.channelProvider) : webTarget.channelProvider != null) { + return false; + } + if (path != null ? !path.equals(webTarget.path) : webTarget.path != null) { + return false; + } + return queryParams != null ? queryParams.equals(webTarget.queryParams) : webTarget.queryParams == null; + } + + @Override + 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); + return result; + } } diff --git a/src/test/java/com/github/dockerjava/netty/WebTargetTest.java b/src/test/java/com/github/dockerjava/netty/WebTargetTest.java new file mode 100644 index 000000000..a462eb8b5 --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/WebTargetTest.java @@ -0,0 +1,39 @@ +package com.github.dockerjava.netty; + +import static org.testng.Assert.assertEquals; + +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +/** + * @author Alexander Koshevoy + */ +public class WebTargetTest { + @Mock private ChannelProvider channelProvider; + + @BeforeMethod + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + } + + @Test + public void verifyImmutability() throws Exception { + WebTarget emptyWebTarget = new WebTarget(channelProvider); + + WebTarget initWebTarget = emptyWebTarget.path("/containers/{id}/attach").resolveTemplate("id", "d03da378b592") + .queryParam("logs", "true"); + + WebTarget anotherWebTarget = emptyWebTarget.path("/containers/{id}/attach") + .resolveTemplate("id", "2cfada4e3c07").queryParam("stdin", "true"); + + assertEquals(new WebTarget(channelProvider), emptyWebTarget); + + assertEquals(new WebTarget(channelProvider).path("/containers/d03da378b592/attach") + .queryParam("logs", "true"), initWebTarget); + + assertEquals(new WebTarget(channelProvider).path("/containers/2cfada4e3c07/attach") + .queryParam("stdin", "true"), anotherWebTarget); + } +} From 1923e7e5866374dc4cb771ef9d7d3317aba2704b Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Sat, 9 Jul 2016 10:22:03 +0200 Subject: [PATCH 188/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 10065afad..e1f16ec14 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ Change Log --- All changes +* [#630 ] (https://github.com/docker-java/docker-java/pull/630) Fix: Second execution of a docker command in Netty implementation always fails * [#596] (https://github.com/docker-java/docker-java/pull/596) Refactor configuration of SSL to allow override with custom config * [#529] (https://github.com/docker-java/docker-java/pull/529) Refactor CertUtils. Support ECDSA and PrivateKey * [#593] (https://github.com/docker-java/docker-java/pull/593) Added Device.parse() method with simple verification. From 5f9e2bfe2f840467394152cb18695002302e0767 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 12 Jul 2016 11:28:35 +0300 Subject: [PATCH 189/855] Change serial until we didn't ship release --- .../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 b21e227ec..a9a15bb36 100644 --- a/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java +++ b/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -31,7 +31,7 @@ */ public class DefaultDockerClientConfig implements Serializable, DockerClientConfig { - private static final long serialVersionUID = -4307357472441531489L; + private static final long serialVersionUID = 1L; public static final String DOCKER_HOST = "DOCKER_HOST"; From 2f50240329e336d097239b7813949d1ba29d607e Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 12 Jul 2016 11:29:28 +0300 Subject: [PATCH 190/855] Test also on 1.10 --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index bb559fd93..31a062e79 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,6 +23,7 @@ env: matrix: - 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" + - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.10.3-0~trusty" - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.10.3-0~trusty" # - repo="testing" DOCKER_HOST="tcp://127.0.0.1:2375" # - repo="testing" DOCKER_HOST="unix:///var/run/docker.sock" From d803c4692efc51bf0e8c138ca3a396947274391d Mon Sep 17 00:00:00 2001 From: Leonid Rudenko Date: Thu, 14 Jul 2016 23:42:54 +0400 Subject: [PATCH 191/855] Implement POST /images/load endpoint (#627) --- .../github/dockerjava/api/DockerClient.java | 13 +++ .../api/command/DockerCmdExecFactory.java | 2 + .../dockerjava/api/command/LoadImageCmd.java | 21 +++++ .../dockerjava/core/DockerClientImpl.java | 7 ++ .../dockerjava/core/RemoteApiVersion.java | 5 ++ .../core/command/LoadImageCmdImpl.java | 39 +++++++++ .../jaxrs/DockerCmdExecFactoryImpl.java | 6 ++ .../dockerjava/jaxrs/LoadImageCmdExec.java | 31 +++++++ .../netty/DockerCmdExecFactoryImpl.java | 7 ++ .../netty/exec/LoadImageCmdExec.java | 29 +++++++ .../core/TestDockerCmdExecFactory.java | 12 +++ .../core/command/LoadImageCmdImplTest.java | 76 ++++++++++++++++++ .../netty/exec/LoadImageCmdExecTest.java | 76 ++++++++++++++++++ .../dockerjava/utils/TestResources.java | 14 ++++ src/test/resources/api/images/load/image.tar | Bin 0 -> 11264 bytes 15 files changed, 338 insertions(+) create mode 100644 src/main/java/com/github/dockerjava/api/command/LoadImageCmd.java create mode 100644 src/main/java/com/github/dockerjava/core/command/LoadImageCmdImpl.java create mode 100644 src/main/java/com/github/dockerjava/jaxrs/LoadImageCmdExec.java create mode 100644 src/main/java/com/github/dockerjava/netty/exec/LoadImageCmdExec.java create mode 100644 src/test/java/com/github/dockerjava/core/command/LoadImageCmdImplTest.java create mode 100644 src/test/java/com/github/dockerjava/netty/exec/LoadImageCmdExecTest.java create mode 100644 src/test/java/com/github/dockerjava/utils/TestResources.java create mode 100644 src/test/resources/api/images/load/image.tar diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java index 4c0e2ed56..491c11ac8 100644 --- a/src/main/java/com/github/dockerjava/api/DockerClient.java +++ b/src/main/java/com/github/dockerjava/api/DockerClient.java @@ -35,6 +35,7 @@ import com.github.dockerjava.api.command.ListImagesCmd; import com.github.dockerjava.api.command.ListNetworksCmd; import com.github.dockerjava.api.command.ListVolumesCmd; +import com.github.dockerjava.api.command.LoadImageCmd; import com.github.dockerjava.api.command.LogContainerCmd; import com.github.dockerjava.api.command.PauseContainerCmd; import com.github.dockerjava.api.command.PingCmd; @@ -90,6 +91,18 @@ public interface DockerClient extends Closeable { CreateImageCmd createImageCmd(@Nonnull String repository, @Nonnull InputStream imageStream); + /** + * Loads a tarball with a set of images and tags into a Docker repository. + * + * Corresponds to POST /images/load API endpoint. + * + * @param imageStream + * stream of the tarball file + * @return created command + * @since {@link RemoteApiVersion#VERSION_1_7} + */ + LoadImageCmd loadImageCmd(@Nonnull InputStream imageStream); + SearchImagesCmd searchImagesCmd(@Nonnull String term); RemoveImageCmd removeImageCmd(@Nonnull String imageId); diff --git a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java index 0de3afe38..671c0d535 100644 --- a/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/api/command/DockerCmdExecFactory.java @@ -28,6 +28,8 @@ public interface DockerCmdExecFactory extends Closeable { CreateImageCmd.Exec createCreateImageCmdExec(); + LoadImageCmd.Exec createLoadImageCmdExec(); + SearchImagesCmd.Exec createSearchImagesCmdExec(); RemoveImageCmd.Exec createRemoveImageCmdExec(); diff --git a/src/main/java/com/github/dockerjava/api/command/LoadImageCmd.java b/src/main/java/com/github/dockerjava/api/command/LoadImageCmd.java new file mode 100644 index 000000000..184b7ef33 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/command/LoadImageCmd.java @@ -0,0 +1,21 @@ +package com.github.dockerjava.api.command; + +import java.io.InputStream; + +import javax.annotation.CheckForNull; +import javax.annotation.Nonnull; + +public interface LoadImageCmd extends SyncDockerCmd { + + @CheckForNull + InputStream getImageStream(); + + /** + * @param imageStream + * the InputStream of the tar file + */ + LoadImageCmd withImageStream(@Nonnull InputStream imageStream); + + interface Exec extends DockerCmdSyncExec { + } +} diff --git a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java index e11ca4f30..2d0b5caab 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientImpl.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientImpl.java @@ -37,6 +37,7 @@ import com.github.dockerjava.api.command.ListImagesCmd; import com.github.dockerjava.api.command.ListNetworksCmd; import com.github.dockerjava.api.command.ListVolumesCmd; +import com.github.dockerjava.api.command.LoadImageCmd; import com.github.dockerjava.api.command.LogContainerCmd; import com.github.dockerjava.api.command.PauseContainerCmd; import com.github.dockerjava.api.command.PingCmd; @@ -89,6 +90,7 @@ import com.github.dockerjava.core.command.ListImagesCmdImpl; import com.github.dockerjava.core.command.ListNetworksCmdImpl; import com.github.dockerjava.core.command.ListVolumesCmdImpl; +import com.github.dockerjava.core.command.LoadImageCmdImpl; import com.github.dockerjava.core.command.LogContainerCmdImpl; import com.github.dockerjava.core.command.PauseContainerCmdImpl; import com.github.dockerjava.core.command.PingCmdImpl; @@ -249,6 +251,11 @@ public CreateImageCmd createImageCmd(String repository, InputStream imageStream) return new CreateImageCmdImpl(getDockerCmdExecFactory().createCreateImageCmdExec(), repository, imageStream); } + @Override + public LoadImageCmd loadImageCmd(@Nonnull InputStream imageStream) { + return new LoadImageCmdImpl(getDockerCmdExecFactory().createLoadImageCmdExec(), imageStream); + } + @Override public SearchImagesCmd searchImagesCmd(String term) { return new SearchImagesCmdImpl(getDockerCmdExecFactory().createSearchImagesCmdExec(), term); diff --git a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java index 992125414..954ed9971 100644 --- a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java +++ b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java @@ -22,6 +22,11 @@ public class RemoteApiVersion implements Serializable { private static final Pattern VERSION_REGEX = Pattern.compile("v?(\\d+)\\.(\\d+)"); + /** + * Online documentation is not available anymore. + */ + public static final RemoteApiVersion VERSION_1_7 = RemoteApiVersion.create(1, 7); + /** * @see Docker API 1.16 */ diff --git a/src/main/java/com/github/dockerjava/core/command/LoadImageCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/LoadImageCmdImpl.java new file mode 100644 index 000000000..496ea3176 --- /dev/null +++ b/src/main/java/com/github/dockerjava/core/command/LoadImageCmdImpl.java @@ -0,0 +1,39 @@ +package com.github.dockerjava.core.command; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.InputStream; + +import com.github.dockerjava.api.command.LoadImageCmd; + +import javax.annotation.Nonnull; + +public class LoadImageCmdImpl extends AbstrDockerCmd implements LoadImageCmd { + + private InputStream imageStream; + + /** + * @param imageStream + * the InputStream of the tar file + */ + public LoadImageCmdImpl(LoadImageCmd.Exec exec, InputStream imageStream) { + super(exec); + withImageStream(imageStream); + } + + @Override + public InputStream getImageStream() { + return imageStream; + } + + /** + * @param imageStream + * the InputStream of the tar file + */ + @Override + public LoadImageCmdImpl withImageStream(@Nonnull InputStream imageStream) { + checkNotNull(imageStream, "imageStream was not specified"); + this.imageStream = imageStream; + return this; + } +} diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index 4800f22ae..7e573a123 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -63,6 +63,7 @@ import com.github.dockerjava.api.command.ListImagesCmd; import com.github.dockerjava.api.command.ListNetworksCmd; import com.github.dockerjava.api.command.ListVolumesCmd; +import com.github.dockerjava.api.command.LoadImageCmd; import com.github.dockerjava.api.command.LogContainerCmd; import com.github.dockerjava.api.command.PauseContainerCmd; import com.github.dockerjava.api.command.PingCmd; @@ -322,6 +323,11 @@ public CreateImageCmd.Exec createCreateImageCmdExec() { return new CreateImageCmdExec(getBaseResource(), getDockerClientConfig()); } + @Override + public LoadImageCmd.Exec createLoadImageCmdExec() { + return new LoadImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + @Override public SearchImagesCmd.Exec createSearchImagesCmdExec() { return new SearchImagesCmdExec(getBaseResource(), getDockerClientConfig()); diff --git a/src/main/java/com/github/dockerjava/jaxrs/LoadImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/LoadImageCmdExec.java new file mode 100644 index 000000000..23d6c493a --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/LoadImageCmdExec.java @@ -0,0 +1,31 @@ +package com.github.dockerjava.jaxrs; + +import static javax.ws.rs.client.Entity.entity; + +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.github.dockerjava.api.command.LoadImageCmd; +import com.github.dockerjava.core.DockerClientConfig; + +public class LoadImageCmdExec extends AbstrSyncDockerCmdExec implements LoadImageCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(LoadImageCmdExec.class); + + public LoadImageCmdExec(WebTarget baseResource, DockerClientConfig dockerClientConfig) { + super(baseResource, dockerClientConfig); + } + + @Override + protected Void execute(LoadImageCmd command) { + WebTarget webTarget = getBaseResource().path("/images/load"); + + LOGGER.trace("POST: {}", webTarget); + webTarget.request().post(entity(command.getImageStream(), MediaType.APPLICATION_OCTET_STREAM)); + + return null; + } +} diff --git a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java index 1f55c61a8..dff69a228 100644 --- a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java @@ -29,6 +29,7 @@ import com.github.dockerjava.api.command.ListImagesCmd; import com.github.dockerjava.api.command.ListNetworksCmd; import com.github.dockerjava.api.command.ListVolumesCmd; +import com.github.dockerjava.api.command.LoadImageCmd; import com.github.dockerjava.api.command.LogContainerCmd; import com.github.dockerjava.api.command.PauseContainerCmd; import com.github.dockerjava.api.command.PingCmd; @@ -82,6 +83,7 @@ import com.github.dockerjava.netty.exec.ListImagesCmdExec; import com.github.dockerjava.netty.exec.ListNetworksCmdExec; import com.github.dockerjava.netty.exec.ListVolumesCmdExec; +import com.github.dockerjava.netty.exec.LoadImageCmdExec; import com.github.dockerjava.netty.exec.LogContainerCmdExec; import com.github.dockerjava.netty.exec.PauseContainerCmdExec; import com.github.dockerjava.netty.exec.PingCmdExec; @@ -366,6 +368,11 @@ public CreateImageCmd.Exec createCreateImageCmdExec() { return new CreateImageCmdExec(getBaseResource(), getDockerClientConfig()); } + @Override + public LoadImageCmd.Exec createLoadImageCmdExec() { + return new LoadImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + @Override public SearchImagesCmd.Exec createSearchImagesCmdExec() { return new SearchImagesCmdExec(getBaseResource(), getDockerClientConfig()); diff --git a/src/main/java/com/github/dockerjava/netty/exec/LoadImageCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/LoadImageCmdExec.java new file mode 100644 index 000000000..23581119f --- /dev/null +++ b/src/main/java/com/github/dockerjava/netty/exec/LoadImageCmdExec.java @@ -0,0 +1,29 @@ +package com.github.dockerjava.netty.exec; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.github.dockerjava.api.command.LoadImageCmd; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.netty.WebTarget; + +public class LoadImageCmdExec extends AbstrSyncDockerCmdExec implements + LoadImageCmd.Exec { + + private static final Logger LOGGER = LoggerFactory.getLogger(LoadImageCmdExec.class); + + public LoadImageCmdExec(WebTarget baseResource, DockerClientConfig dockerClientConfig) { + super(baseResource, dockerClientConfig); + } + + @Override + protected Void execute(LoadImageCmd command) { + WebTarget webResource = getBaseResource().path("/images/load"); + + LOGGER.trace("POST: {}", webResource); + return webResource.request() + .post(new TypeReference() { + }, command.getImageStream()); + } +} diff --git a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java index 48ea1e164..46d6d4dcc 100644 --- a/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java +++ b/src/test/java/com/github/dockerjava/core/TestDockerCmdExecFactory.java @@ -34,6 +34,7 @@ import com.github.dockerjava.api.command.ListImagesCmd; import com.github.dockerjava.api.command.ListNetworksCmd; import com.github.dockerjava.api.command.ListVolumesCmd; +import com.github.dockerjava.api.command.LoadImageCmd; import com.github.dockerjava.api.command.LogContainerCmd; import com.github.dockerjava.api.command.PauseContainerCmd; import com.github.dockerjava.api.command.PingCmd; @@ -131,6 +132,17 @@ public CreateImageResponse exec(CreateImageCmd command) { }; } + @Override + public LoadImageCmd.Exec createLoadImageCmdExec() { + return new LoadImageCmd.Exec() { + @Override + public Void exec(LoadImageCmd command) { + delegate.createLoadImageCmdExec().exec(command); + return null; + } + }; + } + @Override public RemoveImageCmd.Exec createRemoveImageCmdExec() { return new RemoveImageCmd.Exec() { diff --git a/src/test/java/com/github/dockerjava/core/command/LoadImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/LoadImageCmdImplTest.java new file mode 100644 index 000000000..7cecf7334 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/LoadImageCmdImplTest.java @@ -0,0 +1,76 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.model.Image; +import com.github.dockerjava.client.AbstractDockerClientTest; + +import com.github.dockerjava.utils.TestResources; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.io.InputStream; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.util.List; + +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNull.notNullValue; +import static org.hamcrest.core.IsEqual.equalTo; + +@Test(groups = "integration") +public class LoadImageCmdImplTest extends AbstractDockerClientTest { + + private String expectedImageId; + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + expectedImageId = "sha256:56031f66eb0cef2e2e5cb2d1dabafaa0ebcd0a18a507d313b5bdb8c0472c5eba"; + if (findImageWithId(expectedImageId, dockerClient.listImagesCmd().exec()) != null) { + dockerClient.removeImageCmd(expectedImageId).exec(); + } + } + + @AfterMethod + public void afterMethod(ITestResult result) { + dockerClient.removeImageCmd(expectedImageId).exec(); + super.afterMethod(result); + } + + @Test + public void loadImageFromTar() throws Exception { + try (InputStream uploadStream = Files.newInputStream(TestResources.getApiImagesLoadTestTarball())) { + dockerClient.loadImageCmd(uploadStream).exec(); + } + + final Image image = findImageWithId(expectedImageId, dockerClient.listImagesCmd().exec()); + + assertThat("Can't find expected image after loading from a tar archive!", image, notNullValue()); + assertThat("Image after loading from a tar archive has wrong tags!", + asList(image.getRepoTags()), equalTo(singletonList("docker-java/load:1.0"))); + } + + private Image findImageWithId(final String id, final List images) { + for (Image image : images) { + if (id.equals(image.getId())) { + return image; + } + } + return null; + } +} diff --git a/src/test/java/com/github/dockerjava/netty/exec/LoadImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/LoadImageCmdExecTest.java new file mode 100644 index 000000000..d978f5662 --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/exec/LoadImageCmdExecTest.java @@ -0,0 +1,76 @@ +package com.github.dockerjava.netty.exec; + +import com.github.dockerjava.api.model.Image; + +import com.github.dockerjava.netty.AbstractNettyDockerClientTest; +import com.github.dockerjava.utils.TestResources; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.io.InputStream; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.util.List; + +import static java.util.Arrays.asList; +import static java.util.Collections.singletonList; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.IsNull.notNullValue; +import static org.hamcrest.core.IsEqual.equalTo; + +@Test(groups = "integration") +public class LoadImageCmdExecTest extends AbstractNettyDockerClientTest { + + private String expectedImageId; + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + expectedImageId = "sha256:56031f66eb0cef2e2e5cb2d1dabafaa0ebcd0a18a507d313b5bdb8c0472c5eba"; + if (findImageWithId(expectedImageId, dockerClient.listImagesCmd().exec()) != null) { + dockerClient.removeImageCmd(expectedImageId).exec(); + } + } + + @AfterMethod + public void afterMethod(ITestResult result) { + dockerClient.removeImageCmd(expectedImageId).exec(); + super.afterMethod(result); + } + + @Test + public void loadImageFromTar() throws Exception { + try (InputStream uploadStream = Files.newInputStream(TestResources.getApiImagesLoadTestTarball())) { + dockerClient.loadImageCmd(uploadStream).exec(); + } + + final Image image = findImageWithId(expectedImageId, dockerClient.listImagesCmd().exec()); + + assertThat("Can't find expected image after loading from a tar archive!", image, notNullValue()); + assertThat("Image after loading from a tar archive has wrong tags!", + asList(image.getRepoTags()), equalTo(singletonList("docker-java/load:1.0"))); + } + + private Image findImageWithId(final String id, final List images) { + for (Image image : images) { + if (id.equals(image.getId())) { + return image; + } + } + return null; + } +} diff --git a/src/test/java/com/github/dockerjava/utils/TestResources.java b/src/test/java/com/github/dockerjava/utils/TestResources.java new file mode 100644 index 000000000..35ece680f --- /dev/null +++ b/src/test/java/com/github/dockerjava/utils/TestResources.java @@ -0,0 +1,14 @@ +package com.github.dockerjava.utils; + +import java.nio.file.Path; +import java.nio.file.Paths; + +public class TestResources { + + private TestResources() { + } + + public static Path getApiImagesLoadTestTarball() { + return Paths.get("src/test/resources/api/images/load/image.tar"); + } +} diff --git a/src/test/resources/api/images/load/image.tar b/src/test/resources/api/images/load/image.tar new file mode 100644 index 0000000000000000000000000000000000000000..6f2f08f9e945811249c0027eec3a0de531ead521 GIT binary patch literal 11264 zcmeHNU2oeq6!r6dg~7dSfMfHUl7KyQX@C|e=Az9ybU_eM{7BTwQXt7e1H=D)SGJQl zZc`_<5_AalV2kACC3%i6DISUw%9s-|cByxSTE>L%Owu^wR>{~?N(lB&lGIZk5$z(u zm`oMJ80$#kQE&T&F~>@X9#mJE6eGJe5nab(LwazFe zau2ILEDs4!h)gIO#)?WQW5)h%P0OOuS>Y-$_Hi0x?&FvlDJ&;mOD!~IX+#+Dm@DpL ztWzs36A|a|mLRZnOgax4g3xt$C*as;rzn}BS7qH4dg3-(0PC0K1lnGeLHh4{(GR$L z(KOney>Dz*pv3FEc58X%wD~&IRWO8=u*JQ{(FCa z{PtttXSqv+RVtq}P++db5s*Ov94w|m0d@BaiQsj&Xv3227} zi|M>Wf8TPog@2%*-tbQ;?Ef)gBJlq$EW6IrzjW;}_zMUG1Ofs9f&T*nLSoovOX*T< zoTrXDVNz;|)v5Mc!?A#|Sd&N#tSloe6{$@l1N(AngiH0X1O12NP5p-`9M=CQd3J?Ynf@b+ ziE~gB*Hoqfs>-tQAUn-ab9vrsQ45iw1~JNJ-k)R^%8pQdrm2vLW1M;d$Jf#*2WQj~ z7cm7T*~Lz!B-TVyr5#Cyj%}<(Y?x&auat%)u&@9O40>-di@NZa=R zjFPppVE8_O!1^EbpC5($LG@sA*k2u*pibTeAxPi3^YT!iE`oG9Kka?e7a9&Yv`yf^ zxjj92)5?Ymi|!Oih~(oSXFQ1hUIkp$87vf;s~=YL{?^;#pYZE%g4(ZW+W40u#Q*&P m-obLVI&Hg&(018vgS3M~;rTp-;||<}ssVw3KtSLz5%>?llNJ&H literal 0 HcmV?d00001 From 8be5180513b65be8da2444a71de62f7dba5106c3 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 14 Jul 2016 22:44:12 +0300 Subject: [PATCH 192/855] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e1f16ec14..4d28a9319 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,8 @@ Change Log --- All changes -* [#630 ] (https://github.com/docker-java/docker-java/pull/630) Fix: Second execution of a docker command in Netty implementation always fails +* [#627] (https://github.com/docker-java/docker-java/pull/627) Implementation of POST /images/load endpoint +* [#630] (https://github.com/docker-java/docker-java/pull/630) Fix: Second execution of a docker command in Netty implementation always fails * [#596] (https://github.com/docker-java/docker-java/pull/596) Refactor configuration of SSL to allow override with custom config * [#529] (https://github.com/docker-java/docker-java/pull/529) Refactor CertUtils. Support ECDSA and PrivateKey * [#593] (https://github.com/docker-java/docker-java/pull/593) Added Device.parse() method with simple verification. From 369a12e410cd4c1fe7d58dde8b5a49920330c4e4 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 15 Jul 2016 14:27:25 +0300 Subject: [PATCH 193/855] Try cache coverity (#636) --- .travis.yml | 1 + .travis/travisci_build_coverity_scan.sh | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 31a062e79..bb93f49b5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,6 +33,7 @@ env: cache: directories: - $HOME/.travis_cache + - /tmp/coverity-cache - $HOME/.m2 # install will pollute it before_install: diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh index 13af2c275..160945f40 100755 --- a/.travis/travisci_build_coverity_scan.sh +++ b/.travis/travisci_build_coverity_scan.sh @@ -11,7 +11,7 @@ echo -e "\033[33;1mNote: COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN are [ -z "$COVERITY_SCAN_TOKEN" ] && echo "ERROR: COVERITY_SCAN_TOKEN must be set" && exit 1 PLATFORM=`uname` -TOOL_ARCHIVE=/tmp/cov-analysis-${PLATFORM}.tgz +TOOL_ARCHIVE=/tmp/coverity-cache/cov-analysis-${PLATFORM}.tgz TOOL_URL=https://scan.coverity.com/download/${PLATFORM} TOOL_BASE=/tmp/coverity-scan-analysis UPLOAD_URL="https://scan.coverity.com/builds" @@ -49,18 +49,20 @@ else fi fi +mkdir -p /tmp/coverity-cache || : + if [ ! -d $TOOL_BASE ]; then # Download Coverity Scan Analysis Tool if [ ! -e $TOOL_ARCHIVE ]; then echo -e "\033[33;1mDownloading Coverity Scan Analysis Tool...\033[0m" - wget -nv -O $TOOL_ARCHIVE $TOOL_URL --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN" + wget -nvN -O $TOOL_ARCHIVE $TOOL_URL --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN" fi # Extract Coverity Scan Analysis Tool echo -e "\033[33;1mExtracting Coverity Scan Analysis Tool...\033[0m" mkdir -p $TOOL_BASE pushd $TOOL_BASE - tar xzf $TOOL_ARCHIVE + tar -xf $TOOL_ARCHIVE popd fi From a87b7894272ff3cb9ffecadd6848fdb45ad777a7 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 15 Jul 2016 14:34:19 +0300 Subject: [PATCH 194/855] Update travisci_build_coverity_scan.sh --- .travis/travisci_build_coverity_scan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh index 160945f40..a4d978e22 100755 --- a/.travis/travisci_build_coverity_scan.sh +++ b/.travis/travisci_build_coverity_scan.sh @@ -55,7 +55,7 @@ if [ ! -d $TOOL_BASE ]; then # Download Coverity Scan Analysis Tool if [ ! -e $TOOL_ARCHIVE ]; then echo -e "\033[33;1mDownloading Coverity Scan Analysis Tool...\033[0m" - wget -nvN -O $TOOL_ARCHIVE $TOOL_URL --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN" + wget -nv -N -O $TOOL_ARCHIVE $TOOL_URL --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN" fi # Extract Coverity Scan Analysis Tool From 7bcf6fbe2f561e51d45727b4dac9773f4d162f2f Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 15 Jul 2016 14:52:36 +0300 Subject: [PATCH 195/855] Update travisci_build_coverity_scan.sh --- .travis/travisci_build_coverity_scan.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh index a4d978e22..8d0fff04b 100755 --- a/.travis/travisci_build_coverity_scan.sh +++ b/.travis/travisci_build_coverity_scan.sh @@ -62,6 +62,9 @@ if [ ! -d $TOOL_BASE ]; then echo -e "\033[33;1mExtracting Coverity Scan Analysis Tool...\033[0m" mkdir -p $TOOL_BASE pushd $TOOL_BASE + du -sh $TOOL_ARCHIVE + file $TOOL_ARCHIVE + ls -la $TOOL_ARCHIVE tar -xf $TOOL_ARCHIVE popd fi From a57fec6f7fa10645589b3b5b9d5e5ea7d2590254 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 15 Jul 2016 17:25:34 +0300 Subject: [PATCH 196/855] Add second run that should be successfull @coverity fails without any clear reason. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index bb93f49b5..a8cbe29e2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,6 +21,7 @@ env: - COVERITY_SCAN_NOTIFICATION_EMAIL="kanstantsin.sha@gmail.com" matrix: + - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" DEPLOY=true 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" - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.10.3-0~trusty" From 236e1be53547f86bf279fbbc4ec8daef6e8cf83e Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 22 Jul 2016 00:56:00 +0300 Subject: [PATCH 197/855] Try debug bad travis download --- .travis/travisci_build_coverity_scan.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh index 8d0fff04b..6bf9a9b1f 100755 --- a/.travis/travisci_build_coverity_scan.sh +++ b/.travis/travisci_build_coverity_scan.sh @@ -64,6 +64,7 @@ if [ ! -d $TOOL_BASE ]; then pushd $TOOL_BASE du -sh $TOOL_ARCHIVE file $TOOL_ARCHIVE + file $TOOL_ARCHIVE | grep HTML && cat $TOOL_ARCHIVE || : ls -la $TOOL_ARCHIVE tar -xf $TOOL_ARCHIVE popd From 5dbde940d32b02c57b6c55e87be455846d511eac Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 22 Jul 2016 00:59:46 +0300 Subject: [PATCH 198/855] Fix IT run when it shouldn't CSV and not list. --- pom.xml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 5842ac320..130977ba3 100644 --- a/pom.xml +++ b/pom.xml @@ -387,8 +387,7 @@ maven-surefire-plugin ${maven-surefire-plugin.version} - integration - integration-auth + integration,integration-auth From 4db9bee87c58e564479ed55a4929f3e1fa4662a1 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 22 Jul 2016 02:08:13 +0300 Subject: [PATCH 199/855] fix concurrency issue --- .../exec/AttachContainerCmdExecTest.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java index 675c11177..7daa59b25 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java @@ -1,5 +1,6 @@ package com.github.dockerjava.netty.exec; +import static java.util.concurrent.TimeUnit.SECONDS; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.isEmptyString; @@ -70,7 +71,7 @@ public void onNext(Frame frame) { }; dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true) - .withLogs(true).exec(callback).awaitCompletion(10, TimeUnit.SECONDS); + .withLogs(true).exec(callback).awaitCompletion(10, SECONDS); callback.close(); assertThat(callback.toString(), containsString(snippet)); @@ -81,33 +82,40 @@ public void attachContainerWithStdin() throws Exception { String snippet = "hello world"; - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("/bin/sh", "-c", "read line && echo $line") - .withTty(false).withStdinOpen(true).exec(); + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("/bin/sh", "-c", "sleep 1 && read line && echo $line") + .withTty(false) + .withStdinOpen(true) + .exec(); LOG.info("Created container: {}", container.toString()); assertThat(container.getId(), not(isEmptyString())); dockerClient.startContainerCmd(container.getId()).exec(); + Thread.sleep(SECONDS.toMillis(3)); //wait bash initialisation + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); assertTrue(inspectContainerResponse.getState().getRunning()); AttachContainerTestCallback callback = new AttachContainerTestCallback() { - @Override public void onNext(Frame frame) { assertEquals(frame.getStreamType(), StreamType.STDOUT); super.onNext(frame); - }; + } }; InputStream stdin = new ByteArrayInputStream((snippet + "\n").getBytes()); - dockerClient.attachContainerCmd(container.getId()).withStdErr(true).withStdOut(true).withFollowStream(true) + dockerClient.attachContainerCmd(container.getId()) + .withStdErr(true) + .withStdOut(true) + .withFollowStream(true) .withStdIn(stdin) .exec(callback) - .awaitCompletion(5, TimeUnit.SECONDS); + .awaitCompletion(15, SECONDS); callback.close(); assertThat(callback.toString(), containsString(snippet)); @@ -141,7 +149,7 @@ public void onNext(Frame frame) { .withStdOut(true) .withFollowStream(true) .exec(callback) - .awaitCompletion(10, TimeUnit.SECONDS); + .awaitCompletion(10, SECONDS); callback.close(); // HexDump.dump(collectFramesCallback.toString().getBytes(), 0, System.out, 0); From 582331a85ad9bc529b4d8a37d1d80d286bd57b25 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 22 Jul 2016 02:48:09 +0300 Subject: [PATCH 200/855] Verify coverity before not downloading it --- .travis/travisci_build_coverity_scan.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh index 6bf9a9b1f..a73c66536 100755 --- a/.travis/travisci_build_coverity_scan.sh +++ b/.travis/travisci_build_coverity_scan.sh @@ -52,6 +52,13 @@ fi mkdir -p /tmp/coverity-cache || : if [ ! -d $TOOL_BASE ]; then + + # verify that binary is right + if file $TOOL_ARCHIVE | grep HTML ; then + echo "Removing $TOOL_ARCHIVE" + rm -f $TOOL_ARCHIVE + fi + # Download Coverity Scan Analysis Tool if [ ! -e $TOOL_ARCHIVE ]; then echo -e "\033[33;1mDownloading Coverity Scan Analysis Tool...\033[0m" From eacea85d70e689e03407572ff982983ecea0c640 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 22 Jul 2016 03:23:56 +0300 Subject: [PATCH 201/855] Don't spam with warnings @coverity using bsd tar?? --- .travis/travisci_build_coverity_scan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh index a73c66536..7f30638e1 100755 --- a/.travis/travisci_build_coverity_scan.sh +++ b/.travis/travisci_build_coverity_scan.sh @@ -73,7 +73,7 @@ if [ ! -d $TOOL_BASE ]; then file $TOOL_ARCHIVE file $TOOL_ARCHIVE | grep HTML && cat $TOOL_ARCHIVE || : ls -la $TOOL_ARCHIVE - tar -xf $TOOL_ARCHIVE + tar -xf $TOOL_ARCHIVE | grep -v "Ignoring unknown extended header keyword" popd fi From 59db6da8f40f7559c9e33968f5ba5a8283df3673 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 22 Jul 2016 03:26:10 +0300 Subject: [PATCH 202/855] Try limit threadCount Default is parallel test, when there are many tests they become slow and fails. --- pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pom.xml b/pom.xml index 130977ba3..7f51e9d99 100644 --- a/pom.xml +++ b/pom.xml @@ -402,6 +402,9 @@ verify + true + true + 1 integration integration-auth From 51fe92d8400541afb7fdeb170b55bfa91538920e Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 22 Jul 2016 03:54:24 +0300 Subject: [PATCH 203/855] Update travisci_build_coverity_scan.sh --- .travis/travisci_build_coverity_scan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh index 7f30638e1..933ddae37 100755 --- a/.travis/travisci_build_coverity_scan.sh +++ b/.travis/travisci_build_coverity_scan.sh @@ -73,7 +73,7 @@ if [ ! -d $TOOL_BASE ]; then file $TOOL_ARCHIVE file $TOOL_ARCHIVE | grep HTML && cat $TOOL_ARCHIVE || : ls -la $TOOL_ARCHIVE - tar -xf $TOOL_ARCHIVE | grep -v "Ignoring unknown extended header keyword" + tar -xf $TOOL_ARCHIVE |& grep -v "Ignoring unknown extended header keyword" popd fi From 9578981d860478f0c8bda9d1da5b481bdd960c5d Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 22 Jul 2016 03:57:44 +0300 Subject: [PATCH 204/855] Update netty Try fix #632 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7f51e9d99..1d4328f9b 100644 --- a/pom.xml +++ b/pom.xml @@ -63,7 +63,7 @@ 1.1.7 6.9.10 - 4.1.1.Final + 4.1.3.Final 1.3 1.8 2.3.3 From 22fe7a6794c91f6a73988099eaf7e2f3e91bf25b Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 22 Jul 2016 04:18:14 +0300 Subject: [PATCH 205/855] Update travisci_build_coverity_scan.sh --- .travis/travisci_build_coverity_scan.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis/travisci_build_coverity_scan.sh b/.travis/travisci_build_coverity_scan.sh index 933ddae37..074d0a46f 100755 --- a/.travis/travisci_build_coverity_scan.sh +++ b/.travis/travisci_build_coverity_scan.sh @@ -73,7 +73,7 @@ if [ ! -d $TOOL_BASE ]; then file $TOOL_ARCHIVE file $TOOL_ARCHIVE | grep HTML && cat $TOOL_ARCHIVE || : ls -la $TOOL_ARCHIVE - tar -xf $TOOL_ARCHIVE |& grep -v "Ignoring unknown extended header keyword" + tar -xf $TOOL_ARCHIVE #|& grep -v "Ignoring unknown extended header keyword" popd fi From 83ac192b85614c0263aebfcb5ef298d9a9cf0b52 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 22 Jul 2016 11:10:09 +0300 Subject: [PATCH 206/855] Name classes normally (#639) * Name classes normally --- .../dockerjava/core/DockerClientBuilder.java | 4 +- .../jaxrs/DockerCmdExecFactoryImpl.java | 586 +----------------- .../jaxrs/JerseyDockerCmdExecFactory.java | 583 +++++++++++++++++ .../netty/DockerCmdExecFactoryImpl.java | 585 +---------------- .../netty/NettyDockerCmdExecFactory.java | 586 ++++++++++++++++++ .../netty/AbstractNettyDockerClientTest.java | 2 +- 6 files changed, 1182 insertions(+), 1164 deletions(-) create mode 100644 src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java create mode 100644 src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java diff --git a/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java b/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java index 743b8c2ef..991bdbb86 100644 --- a/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java +++ b/src/main/java/com/github/dockerjava/core/DockerClientBuilder.java @@ -3,7 +3,7 @@ import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.DockerCmdExecFactory; import com.github.dockerjava.core.DefaultDockerClientConfig.Builder; -import com.github.dockerjava.jaxrs.DockerCmdExecFactoryImpl; +import com.github.dockerjava.jaxrs.JerseyDockerCmdExecFactory; public class DockerClientBuilder { @@ -32,7 +32,7 @@ public static DockerClientBuilder getInstance(String serverUrl) { } public static DockerCmdExecFactory getDefaultDockerCmdExecFactory() { - return new DockerCmdExecFactoryImpl(); + return new JerseyDockerCmdExecFactory(); } public DockerClientBuilder withDockerCmdExecFactory(DockerCmdExecFactory dockerCmdExecFactory) { diff --git a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java index 7e573a123..1d407e233 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/jaxrs/DockerCmdExecFactoryImpl.java @@ -1,583 +1,9 @@ package com.github.dockerjava.jaxrs; -import static com.google.common.base.Preconditions.checkNotNull; - -import java.io.IOException; -import java.net.InetSocketAddress; -import java.net.Proxy; -import java.net.ProxySelector; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.List; - -import javax.net.ssl.SSLContext; -import javax.ws.rs.client.Client; -import javax.ws.rs.client.ClientBuilder; -import javax.ws.rs.client.ClientRequestFilter; -import javax.ws.rs.client.ClientResponseFilter; -import javax.ws.rs.client.WebTarget; - -import com.github.dockerjava.api.command.UpdateContainerCmd; -import com.github.dockerjava.core.SSLConfig; - -import org.apache.http.config.RegistryBuilder; -import org.apache.http.conn.socket.ConnectionSocketFactory; -import org.apache.http.conn.socket.PlainConnectionSocketFactory; -import org.apache.http.conn.ssl.SSLConnectionSocketFactory; -import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; -import org.glassfish.jersey.CommonProperties; -import org.glassfish.jersey.apache.connector.ApacheClientProperties; -import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; -import org.glassfish.jersey.client.ClientConfig; -import org.glassfish.jersey.client.ClientProperties; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; -import com.github.dockerjava.api.command.AttachContainerCmd; -import com.github.dockerjava.api.command.AuthCmd; -import com.github.dockerjava.api.command.BuildImageCmd; -import com.github.dockerjava.api.command.CommitCmd; -import com.github.dockerjava.api.command.ConnectToNetworkCmd; -import com.github.dockerjava.api.command.ContainerDiffCmd; -import com.github.dockerjava.api.command.CopyArchiveFromContainerCmd; -import com.github.dockerjava.api.command.CopyArchiveToContainerCmd; -import com.github.dockerjava.api.command.CopyFileFromContainerCmd; -import com.github.dockerjava.api.command.CreateContainerCmd; -import com.github.dockerjava.api.command.CreateImageCmd; -import com.github.dockerjava.api.command.CreateNetworkCmd; -import com.github.dockerjava.api.command.CreateVolumeCmd; -import com.github.dockerjava.api.command.DisconnectFromNetworkCmd; -import com.github.dockerjava.api.command.DockerCmdExecFactory; -import com.github.dockerjava.api.command.EventsCmd; -import com.github.dockerjava.api.command.ExecCreateCmd; -import com.github.dockerjava.api.command.ExecStartCmd; -import com.github.dockerjava.api.command.InfoCmd; -import com.github.dockerjava.api.command.InspectContainerCmd; -import com.github.dockerjava.api.command.InspectExecCmd; -import com.github.dockerjava.api.command.InspectImageCmd; -import com.github.dockerjava.api.command.InspectNetworkCmd; -import com.github.dockerjava.api.command.InspectVolumeCmd; -import com.github.dockerjava.api.command.KillContainerCmd; -import com.github.dockerjava.api.command.ListContainersCmd; -import com.github.dockerjava.api.command.ListImagesCmd; -import com.github.dockerjava.api.command.ListNetworksCmd; -import com.github.dockerjava.api.command.ListVolumesCmd; -import com.github.dockerjava.api.command.LoadImageCmd; -import com.github.dockerjava.api.command.LogContainerCmd; -import com.github.dockerjava.api.command.PauseContainerCmd; -import com.github.dockerjava.api.command.PingCmd; -import com.github.dockerjava.api.command.PullImageCmd; -import com.github.dockerjava.api.command.PushImageCmd; -import com.github.dockerjava.api.command.RemoveContainerCmd; -import com.github.dockerjava.api.command.RemoveImageCmd; -import com.github.dockerjava.api.command.RemoveNetworkCmd; -import com.github.dockerjava.api.command.RemoveVolumeCmd; -import com.github.dockerjava.api.command.RestartContainerCmd; -import com.github.dockerjava.api.command.SaveImageCmd; -import com.github.dockerjava.api.command.SearchImagesCmd; -import com.github.dockerjava.api.command.StartContainerCmd; -import com.github.dockerjava.api.command.StatsCmd; -import com.github.dockerjava.api.command.StopContainerCmd; -import com.github.dockerjava.api.command.TagImageCmd; -import com.github.dockerjava.api.command.TopContainerCmd; -import com.github.dockerjava.api.command.UnpauseContainerCmd; -import com.github.dockerjava.api.command.VersionCmd; -import com.github.dockerjava.api.command.WaitContainerCmd; -import com.github.dockerjava.api.command.RenameContainerCmd; -import com.github.dockerjava.api.exception.DockerClientException; -import com.github.dockerjava.core.DockerClientConfig; -import com.github.dockerjava.jaxrs.filter.JsonClientFilter; -import com.github.dockerjava.jaxrs.filter.ResponseStatusExceptionFilter; -import com.github.dockerjava.jaxrs.filter.SelectiveLoggingFilter; - -//import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; -// see https://github.com/docker-java/docker-java/issues/196 - -public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { - - private static final Logger LOGGER = LoggerFactory.getLogger(DockerCmdExecFactoryImpl.class.getName()); - - private Client client; - - private WebTarget baseResource; - - private Integer readTimeout = null; - - private Integer connectTimeout = null; - - private Integer maxTotalConnections = null; - - private Integer maxPerRouteConnections = null; - - private ClientRequestFilter[] clientRequestFilters = null; - - private ClientResponseFilter[] clientResponseFilters = null; - - private DockerClientConfig dockerClientConfig; - - private PoolingHttpClientConnectionManager connManager = null; - - @Override - public void init(DockerClientConfig dockerClientConfig) { - checkNotNull(dockerClientConfig, "config was not specified"); - this.dockerClientConfig = dockerClientConfig; - - ClientConfig clientConfig = new ClientConfig(); - clientConfig.connectorProvider(new ApacheConnectorProvider()); - clientConfig.property(CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true); - - clientConfig.register(ResponseStatusExceptionFilter.class); - clientConfig.register(JsonClientFilter.class); - clientConfig.register(JacksonJsonProvider.class); - - // logging may disabled via log level - clientConfig.register(new SelectiveLoggingFilter(LOGGER, true)); - - if (readTimeout != null) { - clientConfig.property(ClientProperties.READ_TIMEOUT, readTimeout); - } - - if (connectTimeout != null) { - clientConfig.property(ClientProperties.CONNECT_TIMEOUT, connectTimeout); - } - - if (clientResponseFilters != null) { - for (ClientResponseFilter clientResponseFilter : clientResponseFilters) { - if (clientResponseFilter != null) { - clientConfig.register(clientResponseFilter); - } - } - } - - if (clientRequestFilters != null) { - for (ClientRequestFilter clientRequestFilter : clientRequestFilters) { - if (clientRequestFilter != null) { - clientConfig.register(clientRequestFilter); - } - } - } - - URI originalUri = dockerClientConfig.getDockerHost(); - - String protocol = null; - - SSLContext sslContext = null; - - try { - final SSLConfig sslConfig = dockerClientConfig.getSSLConfig(); - if (sslConfig != null) { - sslContext = sslConfig.getSSLContext(); - } - } catch (Exception ex) { - throw new DockerClientException("Error in SSL Configuration", ex); - } - - if (sslContext != null) { - protocol = "https"; - } else { - protocol = "http"; - } - - if (!originalUri.getScheme().equals("unix")) { - - try { - originalUri = new URI(originalUri.toString().replaceFirst("tcp", protocol)); - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } - - configureProxy(clientConfig, protocol); - } - - connManager = new PoolingHttpClientConnectionManager(getSchemeRegistry( - originalUri, sslContext)) { - - @Override - public void close() { - super.shutdown(); - } - - @Override - public void shutdown() { - // Disable shutdown of the pool. This will be done later, when this factory is closed - // This is a workaround for finalize method on jerseys ClientRuntime which - // closes the client and shuts down the connection pool when it is garbage collected - } - }; - - if (maxTotalConnections != null) { - connManager.setMaxTotal(maxTotalConnections); - } - if (maxPerRouteConnections != null) { - connManager.setDefaultMaxPerRoute(maxPerRouteConnections); - } - - clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connManager); - - // Configure connection pool timeout - // clientConfig.property(ApacheClientProperties.REQUEST_CONFIG, RequestConfig.custom() - // .setConnectionRequestTimeout(1000).build()); - - ClientBuilder clientBuilder = ClientBuilder.newBuilder().withConfig(clientConfig); - - if (sslContext != null) { - clientBuilder.sslContext(sslContext); - } - - client = clientBuilder.build(); - - baseResource = client.target(sanitizeUrl(originalUri).toString()).path(dockerClientConfig.getApiVersion().asWebPathPart()); - } - - private URI sanitizeUrl(URI originalUri) { - if (originalUri.getScheme().equals("unix")) { - return UnixConnectionSocketFactory.sanitizeUri(originalUri); - } - return originalUri; - } - - private void configureProxy(ClientConfig clientConfig, String protocol) { - - List proxies = ProxySelector.getDefault().select(dockerClientConfig.getDockerHost()); - - for (Proxy proxy : proxies) { - InetSocketAddress address = (InetSocketAddress) proxy.address(); - if (address != null) { - String hostname = address.getHostName(); - int port = address.getPort(); - - clientConfig.property(ClientProperties.PROXY_URI, "http://" + hostname + ":" + port); - - String httpProxyUser = System.getProperty(protocol + ".proxyUser"); - if (httpProxyUser != null) { - clientConfig.property(ClientProperties.PROXY_USERNAME, httpProxyUser); - String httpProxyPassword = System.getProperty(protocol + ".proxyPassword"); - if (httpProxyPassword != null) { - clientConfig.property(ClientProperties.PROXY_PASSWORD, httpProxyPassword); - } - } - } - } - } - - private org.apache.http.config.Registry getSchemeRegistry(final URI originalUri, - SSLContext sslContext) { - RegistryBuilder registryBuilder = RegistryBuilder.create(); - registryBuilder.register("http", PlainConnectionSocketFactory.getSocketFactory()); - if (sslContext != null) { - registryBuilder.register("https", new SSLConnectionSocketFactory(sslContext)); - } - registryBuilder.register("unix", new UnixConnectionSocketFactory(originalUri)); - return registryBuilder.build(); - } - - protected WebTarget getBaseResource() { - checkNotNull(baseResource, "Factory not initialized, baseResource not set. You probably forgot to call init()!"); - return baseResource; - } - - protected DockerClientConfig getDockerClientConfig() { - checkNotNull(dockerClientConfig, - "Factor not initialized, dockerClientConfig not set. You probably forgot to call init()!"); - return dockerClientConfig; - } - - @Override - public AuthCmd.Exec createAuthCmdExec() { - return new AuthCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InfoCmd.Exec createInfoCmdExec() { - return new InfoCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public PingCmd.Exec createPingCmdExec() { - return new PingCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public VersionCmd.Exec createVersionCmdExec() { - return new VersionCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public PullImageCmd.Exec createPullImageCmdExec() { - return new PullImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public PushImageCmd.Exec createPushImageCmdExec() { - return new PushImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public SaveImageCmd.Exec createSaveImageCmdExec() { - return new SaveImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CreateImageCmd.Exec createCreateImageCmdExec() { - return new CreateImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public LoadImageCmd.Exec createLoadImageCmdExec() { - return new LoadImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public SearchImagesCmd.Exec createSearchImagesCmdExec() { - return new SearchImagesCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RemoveImageCmd.Exec createRemoveImageCmdExec() { - return new RemoveImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ListImagesCmd.Exec createListImagesCmdExec() { - return new ListImagesCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InspectImageCmd.Exec createInspectImageCmdExec() { - return new InspectImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ListContainersCmd.Exec createListContainersCmdExec() { - return new ListContainersCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CreateContainerCmd.Exec createCreateContainerCmdExec() { - return new CreateContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public StartContainerCmd.Exec createStartContainerCmdExec() { - return new StartContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InspectContainerCmd.Exec createInspectContainerCmdExec() { - return new InspectContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ExecCreateCmd.Exec createExecCmdExec() { - return new ExecCreateCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RemoveContainerCmd.Exec createRemoveContainerCmdExec() { - return new RemoveContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public WaitContainerCmd.Exec createWaitContainerCmdExec() { - return new WaitContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public AttachContainerCmd.Exec createAttachContainerCmdExec() { - return new AttachContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ExecStartCmd.Exec createExecStartCmdExec() { - return new ExecStartCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InspectExecCmd.Exec createInspectExecCmdExec() { - return new InspectExecCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public LogContainerCmd.Exec createLogContainerCmdExec() { - return new LogContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CopyArchiveFromContainerCmd.Exec createCopyArchiveFromContainerCmdExec() { - return new CopyArchiveFromContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec() { - return new CopyFileFromContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CopyArchiveToContainerCmd.Exec createCopyArchiveToContainerCmdExec() { - return new CopyArchiveToContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public StopContainerCmd.Exec createStopContainerCmdExec() { - return new StopContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ContainerDiffCmd.Exec createContainerDiffCmdExec() { - return new ContainerDiffCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public KillContainerCmd.Exec createKillContainerCmdExec() { - return new KillContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { - return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RenameContainerCmd.Exec createRenameContainerCmdExec() { - return new RenameContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RestartContainerCmd.Exec createRestartContainerCmdExec() { - return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CommitCmd.Exec createCommitCmdExec() { - return new CommitCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public BuildImageCmd.Exec createBuildImageCmdExec() { - return new BuildImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public TopContainerCmd.Exec createTopContainerCmdExec() { - return new TopContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public TagImageCmd.Exec createTagImageCmdExec() { - return new TagImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public PauseContainerCmd.Exec createPauseContainerCmdExec() { - return new PauseContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec() { - return new UnpauseContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public EventsCmd.Exec createEventsCmdExec() { - return new EventsCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public StatsCmd.Exec createStatsCmdExec() { - return new StatsCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CreateVolumeCmd.Exec createCreateVolumeCmdExec() { - return new CreateVolumeCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InspectVolumeCmd.Exec createInspectVolumeCmdExec() { - return new InspectVolumeCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RemoveVolumeCmd.Exec createRemoveVolumeCmdExec() { - return new RemoveVolumeCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ListVolumesCmd.Exec createListVolumesCmdExec() { - return new ListVolumesCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ListNetworksCmd.Exec createListNetworksCmdExec() { - return new ListNetworksCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InspectNetworkCmd.Exec createInspectNetworkCmdExec() { - - return new InspectNetworkCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CreateNetworkCmd.Exec createCreateNetworkCmdExec() { - - return new CreateNetworkCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RemoveNetworkCmd.Exec createRemoveNetworkCmdExec() { - - return new RemoveNetworkCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ConnectToNetworkCmd.Exec createConnectToNetworkCmdExec() { - - return new ConnectToNetworkCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec() { - - return new DisconnectFromNetworkCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public void close() throws IOException { - checkNotNull(client, "Factory not initialized. You probably forgot to call init()!"); - client.close(); - connManager.close(); - } - - public DockerCmdExecFactoryImpl withReadTimeout(Integer readTimeout) { - this.readTimeout = readTimeout; - return this; - } - - public DockerCmdExecFactoryImpl withConnectTimeout(Integer connectTimeout) { - this.connectTimeout = connectTimeout; - return this; - } - - public DockerCmdExecFactoryImpl withMaxTotalConnections(Integer maxTotalConnections) { - this.maxTotalConnections = maxTotalConnections; - return this; - } - - public DockerCmdExecFactoryImpl withMaxPerRouteConnections(Integer maxPerRouteConnections) { - this.maxPerRouteConnections = maxPerRouteConnections; - return this; - } - - public DockerCmdExecFactoryImpl withClientResponseFilters(ClientResponseFilter... clientResponseFilter) { - this.clientResponseFilters = clientResponseFilter; - return this; - } - - public DockerCmdExecFactoryImpl withClientRequestFilters(ClientRequestFilter... clientRequestFilters) { - this.clientRequestFilters = clientRequestFilters; - return this; - } - +/** + * @author Kanstantsin Shautsou + * @deprecated clashes with netty impl. + */ +@Deprecated +public class DockerCmdExecFactoryImpl extends JerseyDockerCmdExecFactory { } diff --git a/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java new file mode 100644 index 000000000..3339a2696 --- /dev/null +++ b/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java @@ -0,0 +1,583 @@ +package com.github.dockerjava.jaxrs; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; + +import javax.net.ssl.SSLContext; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.ClientRequestFilter; +import javax.ws.rs.client.ClientResponseFilter; +import javax.ws.rs.client.WebTarget; + +import com.github.dockerjava.api.command.UpdateContainerCmd; +import com.github.dockerjava.core.SSLConfig; + +import org.apache.http.config.RegistryBuilder; +import org.apache.http.conn.socket.ConnectionSocketFactory; +import org.apache.http.conn.socket.PlainConnectionSocketFactory; +import org.apache.http.conn.ssl.SSLConnectionSocketFactory; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.glassfish.jersey.CommonProperties; +import org.glassfish.jersey.apache.connector.ApacheClientProperties; +import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; +import org.glassfish.jersey.client.ClientConfig; +import org.glassfish.jersey.client.ClientProperties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; +import com.github.dockerjava.api.command.AttachContainerCmd; +import com.github.dockerjava.api.command.AuthCmd; +import com.github.dockerjava.api.command.BuildImageCmd; +import com.github.dockerjava.api.command.CommitCmd; +import com.github.dockerjava.api.command.ConnectToNetworkCmd; +import com.github.dockerjava.api.command.ContainerDiffCmd; +import com.github.dockerjava.api.command.CopyArchiveFromContainerCmd; +import com.github.dockerjava.api.command.CopyArchiveToContainerCmd; +import com.github.dockerjava.api.command.CopyFileFromContainerCmd; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateImageCmd; +import com.github.dockerjava.api.command.CreateNetworkCmd; +import com.github.dockerjava.api.command.CreateVolumeCmd; +import com.github.dockerjava.api.command.DisconnectFromNetworkCmd; +import com.github.dockerjava.api.command.DockerCmdExecFactory; +import com.github.dockerjava.api.command.EventsCmd; +import com.github.dockerjava.api.command.ExecCreateCmd; +import com.github.dockerjava.api.command.ExecStartCmd; +import com.github.dockerjava.api.command.InfoCmd; +import com.github.dockerjava.api.command.InspectContainerCmd; +import com.github.dockerjava.api.command.InspectExecCmd; +import com.github.dockerjava.api.command.InspectImageCmd; +import com.github.dockerjava.api.command.InspectNetworkCmd; +import com.github.dockerjava.api.command.InspectVolumeCmd; +import com.github.dockerjava.api.command.KillContainerCmd; +import com.github.dockerjava.api.command.ListContainersCmd; +import com.github.dockerjava.api.command.ListImagesCmd; +import com.github.dockerjava.api.command.ListNetworksCmd; +import com.github.dockerjava.api.command.ListVolumesCmd; +import com.github.dockerjava.api.command.LoadImageCmd; +import com.github.dockerjava.api.command.LogContainerCmd; +import com.github.dockerjava.api.command.PauseContainerCmd; +import com.github.dockerjava.api.command.PingCmd; +import com.github.dockerjava.api.command.PullImageCmd; +import com.github.dockerjava.api.command.PushImageCmd; +import com.github.dockerjava.api.command.RemoveContainerCmd; +import com.github.dockerjava.api.command.RemoveImageCmd; +import com.github.dockerjava.api.command.RemoveNetworkCmd; +import com.github.dockerjava.api.command.RemoveVolumeCmd; +import com.github.dockerjava.api.command.RestartContainerCmd; +import com.github.dockerjava.api.command.SaveImageCmd; +import com.github.dockerjava.api.command.SearchImagesCmd; +import com.github.dockerjava.api.command.StartContainerCmd; +import com.github.dockerjava.api.command.StatsCmd; +import com.github.dockerjava.api.command.StopContainerCmd; +import com.github.dockerjava.api.command.TagImageCmd; +import com.github.dockerjava.api.command.TopContainerCmd; +import com.github.dockerjava.api.command.UnpauseContainerCmd; +import com.github.dockerjava.api.command.VersionCmd; +import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.command.RenameContainerCmd; +import com.github.dockerjava.api.exception.DockerClientException; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.jaxrs.filter.JsonClientFilter; +import com.github.dockerjava.jaxrs.filter.ResponseStatusExceptionFilter; +import com.github.dockerjava.jaxrs.filter.SelectiveLoggingFilter; + +//import org.glassfish.jersey.apache.connector.ApacheConnectorProvider; +// see https://github.com/docker-java/docker-java/issues/196 + +public class JerseyDockerCmdExecFactory implements DockerCmdExecFactory { + + private static final Logger LOGGER = LoggerFactory.getLogger(JerseyDockerCmdExecFactory.class.getName()); + + private Client client; + + private WebTarget baseResource; + + private Integer readTimeout = null; + + private Integer connectTimeout = null; + + private Integer maxTotalConnections = null; + + private Integer maxPerRouteConnections = null; + + private ClientRequestFilter[] clientRequestFilters = null; + + private ClientResponseFilter[] clientResponseFilters = null; + + private DockerClientConfig dockerClientConfig; + + private PoolingHttpClientConnectionManager connManager = null; + + @Override + public void init(DockerClientConfig dockerClientConfig) { + checkNotNull(dockerClientConfig, "config was not specified"); + this.dockerClientConfig = dockerClientConfig; + + ClientConfig clientConfig = new ClientConfig(); + clientConfig.connectorProvider(new ApacheConnectorProvider()); + clientConfig.property(CommonProperties.FEATURE_AUTO_DISCOVERY_DISABLE, true); + + clientConfig.register(ResponseStatusExceptionFilter.class); + clientConfig.register(JsonClientFilter.class); + clientConfig.register(JacksonJsonProvider.class); + + // logging may disabled via log level + clientConfig.register(new SelectiveLoggingFilter(LOGGER, true)); + + if (readTimeout != null) { + clientConfig.property(ClientProperties.READ_TIMEOUT, readTimeout); + } + + if (connectTimeout != null) { + clientConfig.property(ClientProperties.CONNECT_TIMEOUT, connectTimeout); + } + + if (clientResponseFilters != null) { + for (ClientResponseFilter clientResponseFilter : clientResponseFilters) { + if (clientResponseFilter != null) { + clientConfig.register(clientResponseFilter); + } + } + } + + if (clientRequestFilters != null) { + for (ClientRequestFilter clientRequestFilter : clientRequestFilters) { + if (clientRequestFilter != null) { + clientConfig.register(clientRequestFilter); + } + } + } + + URI originalUri = dockerClientConfig.getDockerHost(); + + String protocol = null; + + SSLContext sslContext = null; + + try { + final SSLConfig sslConfig = dockerClientConfig.getSSLConfig(); + if (sslConfig != null) { + sslContext = sslConfig.getSSLContext(); + } + } catch (Exception ex) { + throw new DockerClientException("Error in SSL Configuration", ex); + } + + if (sslContext != null) { + protocol = "https"; + } else { + protocol = "http"; + } + + if (!originalUri.getScheme().equals("unix")) { + + try { + originalUri = new URI(originalUri.toString().replaceFirst("tcp", protocol)); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + + configureProxy(clientConfig, protocol); + } + + connManager = new PoolingHttpClientConnectionManager(getSchemeRegistry( + originalUri, sslContext)) { + + @Override + public void close() { + super.shutdown(); + } + + @Override + public void shutdown() { + // Disable shutdown of the pool. This will be done later, when this factory is closed + // This is a workaround for finalize method on jerseys ClientRuntime which + // closes the client and shuts down the connection pool when it is garbage collected + } + }; + + if (maxTotalConnections != null) { + connManager.setMaxTotal(maxTotalConnections); + } + if (maxPerRouteConnections != null) { + connManager.setDefaultMaxPerRoute(maxPerRouteConnections); + } + + clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connManager); + + // Configure connection pool timeout + // clientConfig.property(ApacheClientProperties.REQUEST_CONFIG, RequestConfig.custom() + // .setConnectionRequestTimeout(1000).build()); + + ClientBuilder clientBuilder = ClientBuilder.newBuilder().withConfig(clientConfig); + + if (sslContext != null) { + clientBuilder.sslContext(sslContext); + } + + client = clientBuilder.build(); + + baseResource = client.target(sanitizeUrl(originalUri).toString()).path(dockerClientConfig.getApiVersion().asWebPathPart()); + } + + private URI sanitizeUrl(URI originalUri) { + if (originalUri.getScheme().equals("unix")) { + return UnixConnectionSocketFactory.sanitizeUri(originalUri); + } + return originalUri; + } + + private void configureProxy(ClientConfig clientConfig, String protocol) { + + List proxies = ProxySelector.getDefault().select(dockerClientConfig.getDockerHost()); + + for (Proxy proxy : proxies) { + InetSocketAddress address = (InetSocketAddress) proxy.address(); + if (address != null) { + String hostname = address.getHostName(); + int port = address.getPort(); + + clientConfig.property(ClientProperties.PROXY_URI, "http://" + hostname + ":" + port); + + String httpProxyUser = System.getProperty(protocol + ".proxyUser"); + if (httpProxyUser != null) { + clientConfig.property(ClientProperties.PROXY_USERNAME, httpProxyUser); + String httpProxyPassword = System.getProperty(protocol + ".proxyPassword"); + if (httpProxyPassword != null) { + clientConfig.property(ClientProperties.PROXY_PASSWORD, httpProxyPassword); + } + } + } + } + } + + private org.apache.http.config.Registry getSchemeRegistry(final URI originalUri, + SSLContext sslContext) { + RegistryBuilder registryBuilder = RegistryBuilder.create(); + registryBuilder.register("http", PlainConnectionSocketFactory.getSocketFactory()); + if (sslContext != null) { + registryBuilder.register("https", new SSLConnectionSocketFactory(sslContext)); + } + registryBuilder.register("unix", new UnixConnectionSocketFactory(originalUri)); + return registryBuilder.build(); + } + + protected WebTarget getBaseResource() { + checkNotNull(baseResource, "Factory not initialized, baseResource not set. You probably forgot to call init()!"); + return baseResource; + } + + protected DockerClientConfig getDockerClientConfig() { + checkNotNull(dockerClientConfig, + "Factor not initialized, dockerClientConfig not set. You probably forgot to call init()!"); + return dockerClientConfig; + } + + @Override + public AuthCmd.Exec createAuthCmdExec() { + return new AuthCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InfoCmd.Exec createInfoCmdExec() { + return new InfoCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public PingCmd.Exec createPingCmdExec() { + return new PingCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public VersionCmd.Exec createVersionCmdExec() { + return new VersionCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public PullImageCmd.Exec createPullImageCmdExec() { + return new PullImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public PushImageCmd.Exec createPushImageCmdExec() { + return new PushImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public SaveImageCmd.Exec createSaveImageCmdExec() { + return new SaveImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CreateImageCmd.Exec createCreateImageCmdExec() { + return new CreateImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public LoadImageCmd.Exec createLoadImageCmdExec() { + return new LoadImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public SearchImagesCmd.Exec createSearchImagesCmdExec() { + return new SearchImagesCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RemoveImageCmd.Exec createRemoveImageCmdExec() { + return new RemoveImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ListImagesCmd.Exec createListImagesCmdExec() { + return new ListImagesCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InspectImageCmd.Exec createInspectImageCmdExec() { + return new InspectImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ListContainersCmd.Exec createListContainersCmdExec() { + return new ListContainersCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CreateContainerCmd.Exec createCreateContainerCmdExec() { + return new CreateContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public StartContainerCmd.Exec createStartContainerCmdExec() { + return new StartContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InspectContainerCmd.Exec createInspectContainerCmdExec() { + return new InspectContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ExecCreateCmd.Exec createExecCmdExec() { + return new ExecCreateCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RemoveContainerCmd.Exec createRemoveContainerCmdExec() { + return new RemoveContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public WaitContainerCmd.Exec createWaitContainerCmdExec() { + return new WaitContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public AttachContainerCmd.Exec createAttachContainerCmdExec() { + return new AttachContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ExecStartCmd.Exec createExecStartCmdExec() { + return new ExecStartCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InspectExecCmd.Exec createInspectExecCmdExec() { + return new InspectExecCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public LogContainerCmd.Exec createLogContainerCmdExec() { + return new LogContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CopyArchiveFromContainerCmd.Exec createCopyArchiveFromContainerCmdExec() { + return new CopyArchiveFromContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec() { + return new CopyFileFromContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CopyArchiveToContainerCmd.Exec createCopyArchiveToContainerCmdExec() { + return new CopyArchiveToContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public StopContainerCmd.Exec createStopContainerCmdExec() { + return new StopContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ContainerDiffCmd.Exec createContainerDiffCmdExec() { + return new ContainerDiffCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public KillContainerCmd.Exec createKillContainerCmdExec() { + return new KillContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { + return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RenameContainerCmd.Exec createRenameContainerCmdExec() { + return new RenameContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RestartContainerCmd.Exec createRestartContainerCmdExec() { + return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CommitCmd.Exec createCommitCmdExec() { + return new CommitCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public BuildImageCmd.Exec createBuildImageCmdExec() { + return new BuildImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public TopContainerCmd.Exec createTopContainerCmdExec() { + return new TopContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public TagImageCmd.Exec createTagImageCmdExec() { + return new TagImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public PauseContainerCmd.Exec createPauseContainerCmdExec() { + return new PauseContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec() { + return new UnpauseContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public EventsCmd.Exec createEventsCmdExec() { + return new EventsCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public StatsCmd.Exec createStatsCmdExec() { + return new StatsCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CreateVolumeCmd.Exec createCreateVolumeCmdExec() { + return new CreateVolumeCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InspectVolumeCmd.Exec createInspectVolumeCmdExec() { + return new InspectVolumeCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RemoveVolumeCmd.Exec createRemoveVolumeCmdExec() { + return new RemoveVolumeCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ListVolumesCmd.Exec createListVolumesCmdExec() { + return new ListVolumesCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ListNetworksCmd.Exec createListNetworksCmdExec() { + return new ListNetworksCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InspectNetworkCmd.Exec createInspectNetworkCmdExec() { + + return new InspectNetworkCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CreateNetworkCmd.Exec createCreateNetworkCmdExec() { + + return new CreateNetworkCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RemoveNetworkCmd.Exec createRemoveNetworkCmdExec() { + + return new RemoveNetworkCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ConnectToNetworkCmd.Exec createConnectToNetworkCmdExec() { + + return new ConnectToNetworkCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec() { + + return new DisconnectFromNetworkCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public void close() throws IOException { + checkNotNull(client, "Factory not initialized. You probably forgot to call init()!"); + client.close(); + connManager.close(); + } + + public JerseyDockerCmdExecFactory withReadTimeout(Integer readTimeout) { + this.readTimeout = readTimeout; + return this; + } + + public JerseyDockerCmdExecFactory withConnectTimeout(Integer connectTimeout) { + this.connectTimeout = connectTimeout; + return this; + } + + public JerseyDockerCmdExecFactory withMaxTotalConnections(Integer maxTotalConnections) { + this.maxTotalConnections = maxTotalConnections; + return this; + } + + public JerseyDockerCmdExecFactory withMaxPerRouteConnections(Integer maxPerRouteConnections) { + this.maxPerRouteConnections = maxPerRouteConnections; + return this; + } + + public JerseyDockerCmdExecFactory withClientResponseFilters(ClientResponseFilter... clientResponseFilter) { + this.clientResponseFilters = clientResponseFilter; + return this; + } + + public JerseyDockerCmdExecFactory withClientRequestFilters(ClientRequestFilter... clientRequestFilters) { + this.clientRequestFilters = clientRequestFilters; + return this; + } + +} diff --git a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java index dff69a228..25825d169 100644 --- a/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java +++ b/src/main/java/com/github/dockerjava/netty/DockerCmdExecFactoryImpl.java @@ -1,586 +1,9 @@ package com.github.dockerjava.netty; -import com.github.dockerjava.api.command.AttachContainerCmd; -import com.github.dockerjava.api.command.AuthCmd; -import com.github.dockerjava.api.command.BuildImageCmd; -import com.github.dockerjava.api.command.CommitCmd; -import com.github.dockerjava.api.command.ConnectToNetworkCmd; -import com.github.dockerjava.api.command.ContainerDiffCmd; -import com.github.dockerjava.api.command.CopyArchiveFromContainerCmd; -import com.github.dockerjava.api.command.CopyArchiveToContainerCmd; -import com.github.dockerjava.api.command.CopyFileFromContainerCmd; -import com.github.dockerjava.api.command.CreateContainerCmd; -import com.github.dockerjava.api.command.CreateImageCmd; -import com.github.dockerjava.api.command.CreateNetworkCmd; -import com.github.dockerjava.api.command.CreateVolumeCmd; -import com.github.dockerjava.api.command.DisconnectFromNetworkCmd; -import com.github.dockerjava.api.command.DockerCmdExecFactory; -import com.github.dockerjava.api.command.EventsCmd; -import com.github.dockerjava.api.command.ExecCreateCmd; -import com.github.dockerjava.api.command.ExecStartCmd; -import com.github.dockerjava.api.command.InfoCmd; -import com.github.dockerjava.api.command.InspectContainerCmd; -import com.github.dockerjava.api.command.InspectExecCmd; -import com.github.dockerjava.api.command.InspectImageCmd; -import com.github.dockerjava.api.command.InspectNetworkCmd; -import com.github.dockerjava.api.command.InspectVolumeCmd; -import com.github.dockerjava.api.command.KillContainerCmd; -import com.github.dockerjava.api.command.ListContainersCmd; -import com.github.dockerjava.api.command.ListImagesCmd; -import com.github.dockerjava.api.command.ListNetworksCmd; -import com.github.dockerjava.api.command.ListVolumesCmd; -import com.github.dockerjava.api.command.LoadImageCmd; -import com.github.dockerjava.api.command.LogContainerCmd; -import com.github.dockerjava.api.command.PauseContainerCmd; -import com.github.dockerjava.api.command.PingCmd; -import com.github.dockerjava.api.command.PullImageCmd; -import com.github.dockerjava.api.command.PushImageCmd; -import com.github.dockerjava.api.command.RemoveContainerCmd; -import com.github.dockerjava.api.command.RemoveImageCmd; -import com.github.dockerjava.api.command.RemoveNetworkCmd; -import com.github.dockerjava.api.command.RemoveVolumeCmd; -import com.github.dockerjava.api.command.RestartContainerCmd; -import com.github.dockerjava.api.command.SaveImageCmd; -import com.github.dockerjava.api.command.SearchImagesCmd; -import com.github.dockerjava.api.command.StartContainerCmd; -import com.github.dockerjava.api.command.StatsCmd; -import com.github.dockerjava.api.command.StopContainerCmd; -import com.github.dockerjava.api.command.TagImageCmd; -import com.github.dockerjava.api.command.TopContainerCmd; -import com.github.dockerjava.api.command.UnpauseContainerCmd; -import com.github.dockerjava.api.command.UpdateContainerCmd; -import com.github.dockerjava.api.command.VersionCmd; -import com.github.dockerjava.api.command.WaitContainerCmd; -import com.github.dockerjava.api.command.RenameContainerCmd; -import com.github.dockerjava.core.DockerClientConfig; -import com.github.dockerjava.core.DockerClientImpl; -import com.github.dockerjava.core.SSLConfig; -import com.github.dockerjava.netty.exec.AttachContainerCmdExec; -import com.github.dockerjava.netty.exec.AuthCmdExec; -import com.github.dockerjava.netty.exec.BuildImageCmdExec; -import com.github.dockerjava.netty.exec.CommitCmdExec; -import com.github.dockerjava.netty.exec.ConnectToNetworkCmdExec; -import com.github.dockerjava.netty.exec.ContainerDiffCmdExec; -import com.github.dockerjava.netty.exec.CopyArchiveFromContainerCmdExec; -import com.github.dockerjava.netty.exec.CopyArchiveToContainerCmdExec; -import com.github.dockerjava.netty.exec.CopyFileFromContainerCmdExec; -import com.github.dockerjava.netty.exec.CreateContainerCmdExec; -import com.github.dockerjava.netty.exec.CreateImageCmdExec; -import com.github.dockerjava.netty.exec.CreateNetworkCmdExec; -import com.github.dockerjava.netty.exec.CreateVolumeCmdExec; -import com.github.dockerjava.netty.exec.DisconnectFromNetworkCmdExec; -import com.github.dockerjava.netty.exec.EventsCmdExec; -import com.github.dockerjava.netty.exec.ExecCreateCmdExec; -import com.github.dockerjava.netty.exec.ExecStartCmdExec; -import com.github.dockerjava.netty.exec.InfoCmdExec; -import com.github.dockerjava.netty.exec.InspectContainerCmdExec; -import com.github.dockerjava.netty.exec.InspectExecCmdExec; -import com.github.dockerjava.netty.exec.InspectImageCmdExec; -import com.github.dockerjava.netty.exec.InspectNetworkCmdExec; -import com.github.dockerjava.netty.exec.InspectVolumeCmdExec; -import com.github.dockerjava.netty.exec.KillContainerCmdExec; -import com.github.dockerjava.netty.exec.ListContainersCmdExec; -import com.github.dockerjava.netty.exec.ListImagesCmdExec; -import com.github.dockerjava.netty.exec.ListNetworksCmdExec; -import com.github.dockerjava.netty.exec.ListVolumesCmdExec; -import com.github.dockerjava.netty.exec.LoadImageCmdExec; -import com.github.dockerjava.netty.exec.LogContainerCmdExec; -import com.github.dockerjava.netty.exec.PauseContainerCmdExec; -import com.github.dockerjava.netty.exec.PingCmdExec; -import com.github.dockerjava.netty.exec.PullImageCmdExec; -import com.github.dockerjava.netty.exec.PushImageCmdExec; -import com.github.dockerjava.netty.exec.RemoveContainerCmdExec; -import com.github.dockerjava.netty.exec.RemoveImageCmdExec; -import com.github.dockerjava.netty.exec.RemoveNetworkCmdExec; -import com.github.dockerjava.netty.exec.RemoveVolumeCmdExec; -import com.github.dockerjava.netty.exec.RestartContainerCmdExec; -import com.github.dockerjava.netty.exec.SaveImageCmdExec; -import com.github.dockerjava.netty.exec.SearchImagesCmdExec; -import com.github.dockerjava.netty.exec.StartContainerCmdExec; -import com.github.dockerjava.netty.exec.StatsCmdExec; -import com.github.dockerjava.netty.exec.StopContainerCmdExec; -import com.github.dockerjava.netty.exec.TagImageCmdExec; -import com.github.dockerjava.netty.exec.TopContainerCmdExec; -import com.github.dockerjava.netty.exec.UnpauseContainerCmdExec; -import com.github.dockerjava.netty.exec.UpdateContainerCmdExec; -import com.github.dockerjava.netty.exec.VersionCmdExec; -import com.github.dockerjava.netty.exec.WaitContainerCmdExec; -import com.github.dockerjava.netty.exec.RenameContainerCmdExec; - -import io.netty.bootstrap.Bootstrap; -import io.netty.channel.ChannelInitializer; -import io.netty.channel.EventLoopGroup; -import io.netty.channel.epoll.EpollDomainSocketChannel; -import io.netty.channel.epoll.EpollEventLoopGroup; -import io.netty.channel.nio.NioEventLoopGroup; -import io.netty.channel.socket.DuplexChannel; -import io.netty.channel.socket.SocketChannel; -import io.netty.channel.socket.nio.NioSocketChannel; -import io.netty.channel.unix.DomainSocketAddress; -import io.netty.channel.unix.UnixChannel; -import io.netty.handler.codec.http.HttpClientCodec; -import io.netty.handler.logging.LoggingHandler; -import io.netty.handler.ssl.SslHandler; -import io.netty.util.concurrent.DefaultThreadFactory; - -import org.bouncycastle.jce.provider.BouncyCastleProvider; - -import javax.net.ssl.SSLEngine; -import javax.net.ssl.SSLParameters; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketAddress; -import java.security.Security; - -import static com.google.common.base.Preconditions.checkNotNull; - /** - * Experimental implementation of {@link DockerCmdExecFactory} that supports http connection hijacking that is needed to pass STDIN to the - * container. - * - * To use it just pass an instance via {@link DockerClientImpl#withDockerCmdExecFactory(DockerCmdExecFactory)} - * - * @see https://docs.docker.com/engine/reference/api/docker_remote_api_v1.21/#attach-to-a-container - * @see https://docs.docker.com/engine/reference/api/docker_remote_api_v1.21/#exec-start - * - * - * @author Marcus Linke + * @author Kanstantsin Shautsou + * @deprecated old clashing name */ -public class DockerCmdExecFactoryImpl implements DockerCmdExecFactory { - - private static String threadPrefix = "dockerjava-netty"; - - /* - * useful links: - * - * http://stackoverflow.com/questions/33296749/netty-connect-to-unix-domain-socket-failed - * http://netty.io/wiki/native-transports.html - * https://github.com/netty/netty/blob/master/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java - * https://github.com/slandelle/netty-request-chunking/blob/master/src/test/java/slandelle/ChunkingTest.java - */ - - private DockerClientConfig dockerClientConfig; - - private Bootstrap bootstrap; - - private EventLoopGroup eventLoopGroup; - - private NettyInitializer nettyInitializer; - - private ChannelProvider channelProvider = new ChannelProvider() { - @Override - public DuplexChannel getChannel() { - DuplexChannel channel = connect(); - channel.pipeline().addLast(new LoggingHandler(getClass())); - return channel; - } - }; - - @Override - public void init(DockerClientConfig dockerClientConfig) { - checkNotNull(dockerClientConfig, "config was not specified"); - this.dockerClientConfig = dockerClientConfig; - - bootstrap = new Bootstrap(); - - String scheme = dockerClientConfig.getDockerHost().getScheme(); - - if ("unix".equals(scheme)) { - nettyInitializer = new UnixDomainSocketInitializer(); - } else if ("tcp".equals(scheme)) { - nettyInitializer = new InetSocketInitializer(); - } - - eventLoopGroup = nettyInitializer.init(bootstrap, dockerClientConfig); - } - - private DuplexChannel connect() { - try { - return connect(bootstrap); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - private DuplexChannel connect(final Bootstrap bootstrap) throws InterruptedException { - return nettyInitializer.connect(bootstrap); - } - - private interface NettyInitializer { - EventLoopGroup init(final Bootstrap bootstrap, DockerClientConfig dockerClientConfig); - - DuplexChannel connect(final Bootstrap bootstrap) throws InterruptedException; - } - - 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) - .handler(new ChannelInitializer() { - @Override - protected void initChannel(final UnixChannel channel) throws Exception { - channel.pipeline().addLast(new HttpClientCodec()); - } - }); - return epollEventLoopGroup; - } - - @Override - public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException { - return (DuplexChannel) bootstrap.connect(new DomainSocketAddress("/var/run/docker.sock")).sync().channel(); - } - } - - private class InetSocketInitializer implements NettyInitializer { - @Override - public EventLoopGroup init(Bootstrap bootstrap, final DockerClientConfig dockerClientConfig) { - EventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(0, new DefaultThreadFactory(threadPrefix)); - - InetAddress addr = InetAddress.getLoopbackAddress(); - - final SocketAddress proxyAddress = new InetSocketAddress(addr, 8008); - - Security.addProvider(new BouncyCastleProvider()); - - bootstrap.group(nioEventLoopGroup).channel(NioSocketChannel.class) - .handler(new ChannelInitializer() { - @Override - protected void initChannel(final SocketChannel channel) throws Exception { - // channel.pipeline().addLast(new - // HttpProxyHandler(proxyAddress)); - channel.pipeline().addLast(new HttpClientCodec()); - } - }); - - return nioEventLoopGroup; - } - - @Override - public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException { - String host = dockerClientConfig.getDockerHost().getHost(); - int port = dockerClientConfig.getDockerHost().getPort(); - - if (port == -1) { - throw new RuntimeException("no port configured for " + host); - } - - DuplexChannel channel = (DuplexChannel) bootstrap.connect(host, port).sync().channel(); - - final SslHandler ssl = initSsl(dockerClientConfig); - - if (ssl != null) { - channel.pipeline().addFirst(ssl); - } - - return channel; - } - - private SslHandler initSsl(DockerClientConfig dockerClientConfig) { - SslHandler ssl = null; - - try { - String host = dockerClientConfig.getDockerHost().getHost(); - int port = dockerClientConfig.getDockerHost().getPort(); - - final SSLConfig sslConfig = dockerClientConfig.getSSLConfig(); - - if (sslConfig != null && sslConfig.getSSLContext() != null) { - - SSLEngine engine = sslConfig.getSSLContext().createSSLEngine(host, port); - engine.setUseClientMode(true); - engine.setSSLParameters(enableHostNameVerification(engine.getSSLParameters())); - - // in the future we may use HostnameVerifier like here: - // https://github.com/AsyncHttpClient/async-http-client/blob/1.8.x/src/main/java/com/ning/http/client/providers/netty/NettyConnectListener.java#L76 - - ssl = new SslHandler(engine); - } - - } catch (Exception e) { - throw new RuntimeException(e); - } - - return ssl; - } - } - - protected DockerClientConfig getDockerClientConfig() { - checkNotNull(dockerClientConfig, - "Factor not initialized, dockerClientConfig not set. You probably forgot to call init()!"); - return dockerClientConfig; - } - - public SSLParameters enableHostNameVerification(SSLParameters sslParameters) { - sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); - return sslParameters; - } - - @Override - public CopyArchiveFromContainerCmd.Exec createCopyArchiveFromContainerCmdExec() { - return new CopyArchiveFromContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CopyArchiveToContainerCmd.Exec createCopyArchiveToContainerCmdExec() { - return new CopyArchiveToContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public AuthCmd.Exec createAuthCmdExec() { - return new AuthCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InfoCmd.Exec createInfoCmdExec() { - return new InfoCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public PingCmd.Exec createPingCmdExec() { - return new PingCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public VersionCmd.Exec createVersionCmdExec() { - return new VersionCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public PullImageCmd.Exec createPullImageCmdExec() { - return new PullImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public PushImageCmd.Exec createPushImageCmdExec() { - return new PushImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public SaveImageCmd.Exec createSaveImageCmdExec() { - return new SaveImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CreateImageCmd.Exec createCreateImageCmdExec() { - return new CreateImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public LoadImageCmd.Exec createLoadImageCmdExec() { - return new LoadImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public SearchImagesCmd.Exec createSearchImagesCmdExec() { - return new SearchImagesCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RemoveImageCmd.Exec createRemoveImageCmdExec() { - return new RemoveImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ListImagesCmd.Exec createListImagesCmdExec() { - return new ListImagesCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InspectImageCmd.Exec createInspectImageCmdExec() { - return new InspectImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ListContainersCmd.Exec createListContainersCmdExec() { - return new ListContainersCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CreateContainerCmd.Exec createCreateContainerCmdExec() { - return new CreateContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public StartContainerCmd.Exec createStartContainerCmdExec() { - return new StartContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InspectContainerCmd.Exec createInspectContainerCmdExec() { - return new InspectContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ExecCreateCmd.Exec createExecCmdExec() { - return new ExecCreateCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RemoveContainerCmd.Exec createRemoveContainerCmdExec() { - return new RemoveContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public WaitContainerCmd.Exec createWaitContainerCmdExec() { - return new WaitContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public AttachContainerCmd.Exec createAttachContainerCmdExec() { - return new AttachContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ExecStartCmd.Exec createExecStartCmdExec() { - return new ExecStartCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InspectExecCmd.Exec createInspectExecCmdExec() { - return new InspectExecCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public LogContainerCmd.Exec createLogContainerCmdExec() { - return new LogContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec() { - return new CopyFileFromContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public StopContainerCmd.Exec createStopContainerCmdExec() { - return new StopContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ContainerDiffCmd.Exec createContainerDiffCmdExec() { - return new ContainerDiffCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public KillContainerCmd.Exec createKillContainerCmdExec() { - return new KillContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { - return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RenameContainerCmd.Exec createRenameContainerCmdExec() { - return new RenameContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RestartContainerCmd.Exec createRestartContainerCmdExec() { - return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CommitCmd.Exec createCommitCmdExec() { - return new CommitCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public BuildImageCmd.Exec createBuildImageCmdExec() { - return new BuildImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public TopContainerCmd.Exec createTopContainerCmdExec() { - return new TopContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public TagImageCmd.Exec createTagImageCmdExec() { - return new TagImageCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public PauseContainerCmd.Exec createPauseContainerCmdExec() { - return new PauseContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec() { - return new UnpauseContainerCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public EventsCmd.Exec createEventsCmdExec() { - return new EventsCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public StatsCmd.Exec createStatsCmdExec() { - return new StatsCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CreateVolumeCmd.Exec createCreateVolumeCmdExec() { - return new CreateVolumeCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InspectVolumeCmd.Exec createInspectVolumeCmdExec() { - return new InspectVolumeCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RemoveVolumeCmd.Exec createRemoveVolumeCmdExec() { - return new RemoveVolumeCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ListVolumesCmd.Exec createListVolumesCmdExec() { - return new ListVolumesCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ListNetworksCmd.Exec createListNetworksCmdExec() { - return new ListNetworksCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public InspectNetworkCmd.Exec createInspectNetworkCmdExec() { - return new InspectNetworkCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public CreateNetworkCmd.Exec createCreateNetworkCmdExec() { - return new CreateNetworkCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public RemoveNetworkCmd.Exec createRemoveNetworkCmdExec() { - return new RemoveNetworkCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public ConnectToNetworkCmd.Exec createConnectToNetworkCmdExec() { - return new ConnectToNetworkCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec() { - return new DisconnectFromNetworkCmdExec(getBaseResource(), getDockerClientConfig()); - } - - @Override - public void close() throws IOException { - checkNotNull(eventLoopGroup, "Factory not initialized. You probably forgot to call init()!"); - - eventLoopGroup.shutdownGracefully(); - } - - private WebTarget getBaseResource() { - return new WebTarget(channelProvider); - } +@Deprecated +public class DockerCmdExecFactoryImpl extends NettyDockerCmdExecFactory { } diff --git a/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java b/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java new file mode 100644 index 000000000..cead92e92 --- /dev/null +++ b/src/main/java/com/github/dockerjava/netty/NettyDockerCmdExecFactory.java @@ -0,0 +1,586 @@ +package com.github.dockerjava.netty; + +import com.github.dockerjava.api.command.AttachContainerCmd; +import com.github.dockerjava.api.command.AuthCmd; +import com.github.dockerjava.api.command.BuildImageCmd; +import com.github.dockerjava.api.command.CommitCmd; +import com.github.dockerjava.api.command.ConnectToNetworkCmd; +import com.github.dockerjava.api.command.ContainerDiffCmd; +import com.github.dockerjava.api.command.CopyArchiveFromContainerCmd; +import com.github.dockerjava.api.command.CopyArchiveToContainerCmd; +import com.github.dockerjava.api.command.CopyFileFromContainerCmd; +import com.github.dockerjava.api.command.CreateContainerCmd; +import com.github.dockerjava.api.command.CreateImageCmd; +import com.github.dockerjava.api.command.CreateNetworkCmd; +import com.github.dockerjava.api.command.CreateVolumeCmd; +import com.github.dockerjava.api.command.DisconnectFromNetworkCmd; +import com.github.dockerjava.api.command.DockerCmdExecFactory; +import com.github.dockerjava.api.command.EventsCmd; +import com.github.dockerjava.api.command.ExecCreateCmd; +import com.github.dockerjava.api.command.ExecStartCmd; +import com.github.dockerjava.api.command.InfoCmd; +import com.github.dockerjava.api.command.InspectContainerCmd; +import com.github.dockerjava.api.command.InspectExecCmd; +import com.github.dockerjava.api.command.InspectImageCmd; +import com.github.dockerjava.api.command.InspectNetworkCmd; +import com.github.dockerjava.api.command.InspectVolumeCmd; +import com.github.dockerjava.api.command.KillContainerCmd; +import com.github.dockerjava.api.command.ListContainersCmd; +import com.github.dockerjava.api.command.ListImagesCmd; +import com.github.dockerjava.api.command.ListNetworksCmd; +import com.github.dockerjava.api.command.ListVolumesCmd; +import com.github.dockerjava.api.command.LoadImageCmd; +import com.github.dockerjava.api.command.LogContainerCmd; +import com.github.dockerjava.api.command.PauseContainerCmd; +import com.github.dockerjava.api.command.PingCmd; +import com.github.dockerjava.api.command.PullImageCmd; +import com.github.dockerjava.api.command.PushImageCmd; +import com.github.dockerjava.api.command.RemoveContainerCmd; +import com.github.dockerjava.api.command.RemoveImageCmd; +import com.github.dockerjava.api.command.RemoveNetworkCmd; +import com.github.dockerjava.api.command.RemoveVolumeCmd; +import com.github.dockerjava.api.command.RestartContainerCmd; +import com.github.dockerjava.api.command.SaveImageCmd; +import com.github.dockerjava.api.command.SearchImagesCmd; +import com.github.dockerjava.api.command.StartContainerCmd; +import com.github.dockerjava.api.command.StatsCmd; +import com.github.dockerjava.api.command.StopContainerCmd; +import com.github.dockerjava.api.command.TagImageCmd; +import com.github.dockerjava.api.command.TopContainerCmd; +import com.github.dockerjava.api.command.UnpauseContainerCmd; +import com.github.dockerjava.api.command.UpdateContainerCmd; +import com.github.dockerjava.api.command.VersionCmd; +import com.github.dockerjava.api.command.WaitContainerCmd; +import com.github.dockerjava.api.command.RenameContainerCmd; +import com.github.dockerjava.core.DockerClientConfig; +import com.github.dockerjava.core.DockerClientImpl; +import com.github.dockerjava.core.SSLConfig; +import com.github.dockerjava.netty.exec.AttachContainerCmdExec; +import com.github.dockerjava.netty.exec.AuthCmdExec; +import com.github.dockerjava.netty.exec.BuildImageCmdExec; +import com.github.dockerjava.netty.exec.CommitCmdExec; +import com.github.dockerjava.netty.exec.ConnectToNetworkCmdExec; +import com.github.dockerjava.netty.exec.ContainerDiffCmdExec; +import com.github.dockerjava.netty.exec.CopyArchiveFromContainerCmdExec; +import com.github.dockerjava.netty.exec.CopyArchiveToContainerCmdExec; +import com.github.dockerjava.netty.exec.CopyFileFromContainerCmdExec; +import com.github.dockerjava.netty.exec.CreateContainerCmdExec; +import com.github.dockerjava.netty.exec.CreateImageCmdExec; +import com.github.dockerjava.netty.exec.CreateNetworkCmdExec; +import com.github.dockerjava.netty.exec.CreateVolumeCmdExec; +import com.github.dockerjava.netty.exec.DisconnectFromNetworkCmdExec; +import com.github.dockerjava.netty.exec.EventsCmdExec; +import com.github.dockerjava.netty.exec.ExecCreateCmdExec; +import com.github.dockerjava.netty.exec.ExecStartCmdExec; +import com.github.dockerjava.netty.exec.InfoCmdExec; +import com.github.dockerjava.netty.exec.InspectContainerCmdExec; +import com.github.dockerjava.netty.exec.InspectExecCmdExec; +import com.github.dockerjava.netty.exec.InspectImageCmdExec; +import com.github.dockerjava.netty.exec.InspectNetworkCmdExec; +import com.github.dockerjava.netty.exec.InspectVolumeCmdExec; +import com.github.dockerjava.netty.exec.KillContainerCmdExec; +import com.github.dockerjava.netty.exec.ListContainersCmdExec; +import com.github.dockerjava.netty.exec.ListImagesCmdExec; +import com.github.dockerjava.netty.exec.ListNetworksCmdExec; +import com.github.dockerjava.netty.exec.ListVolumesCmdExec; +import com.github.dockerjava.netty.exec.LoadImageCmdExec; +import com.github.dockerjava.netty.exec.LogContainerCmdExec; +import com.github.dockerjava.netty.exec.PauseContainerCmdExec; +import com.github.dockerjava.netty.exec.PingCmdExec; +import com.github.dockerjava.netty.exec.PullImageCmdExec; +import com.github.dockerjava.netty.exec.PushImageCmdExec; +import com.github.dockerjava.netty.exec.RemoveContainerCmdExec; +import com.github.dockerjava.netty.exec.RemoveImageCmdExec; +import com.github.dockerjava.netty.exec.RemoveNetworkCmdExec; +import com.github.dockerjava.netty.exec.RemoveVolumeCmdExec; +import com.github.dockerjava.netty.exec.RestartContainerCmdExec; +import com.github.dockerjava.netty.exec.SaveImageCmdExec; +import com.github.dockerjava.netty.exec.SearchImagesCmdExec; +import com.github.dockerjava.netty.exec.StartContainerCmdExec; +import com.github.dockerjava.netty.exec.StatsCmdExec; +import com.github.dockerjava.netty.exec.StopContainerCmdExec; +import com.github.dockerjava.netty.exec.TagImageCmdExec; +import com.github.dockerjava.netty.exec.TopContainerCmdExec; +import com.github.dockerjava.netty.exec.UnpauseContainerCmdExec; +import com.github.dockerjava.netty.exec.UpdateContainerCmdExec; +import com.github.dockerjava.netty.exec.VersionCmdExec; +import com.github.dockerjava.netty.exec.WaitContainerCmdExec; +import com.github.dockerjava.netty.exec.RenameContainerCmdExec; + +import io.netty.bootstrap.Bootstrap; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.EventLoopGroup; +import io.netty.channel.epoll.EpollDomainSocketChannel; +import io.netty.channel.epoll.EpollEventLoopGroup; +import io.netty.channel.nio.NioEventLoopGroup; +import io.netty.channel.socket.DuplexChannel; +import io.netty.channel.socket.SocketChannel; +import io.netty.channel.socket.nio.NioSocketChannel; +import io.netty.channel.unix.DomainSocketAddress; +import io.netty.channel.unix.UnixChannel; +import io.netty.handler.codec.http.HttpClientCodec; +import io.netty.handler.logging.LoggingHandler; +import io.netty.handler.ssl.SslHandler; +import io.netty.util.concurrent.DefaultThreadFactory; + +import org.bouncycastle.jce.provider.BouncyCastleProvider; + +import javax.net.ssl.SSLEngine; +import javax.net.ssl.SSLParameters; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.security.Security; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Experimental implementation of {@link DockerCmdExecFactory} that supports http connection hijacking that is needed to pass STDIN to the + * container. + * + * To use it just pass an instance via {@link DockerClientImpl#withDockerCmdExecFactory(DockerCmdExecFactory)} + * + * @see https://docs.docker.com/engine/reference/api/docker_remote_api_v1.21/#attach-to-a-container + * @see https://docs.docker.com/engine/reference/api/docker_remote_api_v1.21/#exec-start + * + * + * @author Marcus Linke + */ +public class NettyDockerCmdExecFactory implements DockerCmdExecFactory { + + private static String threadPrefix = "dockerjava-netty"; + + /* + * useful links: + * + * http://stackoverflow.com/questions/33296749/netty-connect-to-unix-domain-socket-failed + * http://netty.io/wiki/native-transports.html + * https://github.com/netty/netty/blob/master/example/src/main/java/io/netty/example/http/snoop/HttpSnoopClient.java + * https://github.com/slandelle/netty-request-chunking/blob/master/src/test/java/slandelle/ChunkingTest.java + */ + + private DockerClientConfig dockerClientConfig; + + private Bootstrap bootstrap; + + private EventLoopGroup eventLoopGroup; + + private NettyInitializer nettyInitializer; + + private ChannelProvider channelProvider = new ChannelProvider() { + @Override + public DuplexChannel getChannel() { + DuplexChannel channel = connect(); + channel.pipeline().addLast(new LoggingHandler(getClass())); + return channel; + } + }; + + @Override + public void init(DockerClientConfig dockerClientConfig) { + checkNotNull(dockerClientConfig, "config was not specified"); + this.dockerClientConfig = dockerClientConfig; + + bootstrap = new Bootstrap(); + + String scheme = dockerClientConfig.getDockerHost().getScheme(); + + if ("unix".equals(scheme)) { + nettyInitializer = new UnixDomainSocketInitializer(); + } else if ("tcp".equals(scheme)) { + nettyInitializer = new InetSocketInitializer(); + } + + eventLoopGroup = nettyInitializer.init(bootstrap, dockerClientConfig); + } + + private DuplexChannel connect() { + try { + return connect(bootstrap); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + private DuplexChannel connect(final Bootstrap bootstrap) throws InterruptedException { + return nettyInitializer.connect(bootstrap); + } + + private interface NettyInitializer { + EventLoopGroup init(final Bootstrap bootstrap, DockerClientConfig dockerClientConfig); + + DuplexChannel connect(final Bootstrap bootstrap) throws InterruptedException; + } + + 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) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(final UnixChannel channel) throws Exception { + channel.pipeline().addLast(new HttpClientCodec()); + } + }); + return epollEventLoopGroup; + } + + @Override + public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException { + return (DuplexChannel) bootstrap.connect(new DomainSocketAddress("/var/run/docker.sock")).sync().channel(); + } + } + + private class InetSocketInitializer implements NettyInitializer { + @Override + public EventLoopGroup init(Bootstrap bootstrap, final DockerClientConfig dockerClientConfig) { + EventLoopGroup nioEventLoopGroup = new NioEventLoopGroup(0, new DefaultThreadFactory(threadPrefix)); + + InetAddress addr = InetAddress.getLoopbackAddress(); + + final SocketAddress proxyAddress = new InetSocketAddress(addr, 8008); + + Security.addProvider(new BouncyCastleProvider()); + + bootstrap.group(nioEventLoopGroup).channel(NioSocketChannel.class) + .handler(new ChannelInitializer() { + @Override + protected void initChannel(final SocketChannel channel) throws Exception { + // channel.pipeline().addLast(new + // HttpProxyHandler(proxyAddress)); + channel.pipeline().addLast(new HttpClientCodec()); + } + }); + + return nioEventLoopGroup; + } + + @Override + public DuplexChannel connect(Bootstrap bootstrap) throws InterruptedException { + String host = dockerClientConfig.getDockerHost().getHost(); + int port = dockerClientConfig.getDockerHost().getPort(); + + if (port == -1) { + throw new RuntimeException("no port configured for " + host); + } + + DuplexChannel channel = (DuplexChannel) bootstrap.connect(host, port).sync().channel(); + + final SslHandler ssl = initSsl(dockerClientConfig); + + if (ssl != null) { + channel.pipeline().addFirst(ssl); + } + + return channel; + } + + private SslHandler initSsl(DockerClientConfig dockerClientConfig) { + SslHandler ssl = null; + + try { + String host = dockerClientConfig.getDockerHost().getHost(); + int port = dockerClientConfig.getDockerHost().getPort(); + + final SSLConfig sslConfig = dockerClientConfig.getSSLConfig(); + + if (sslConfig != null && sslConfig.getSSLContext() != null) { + + SSLEngine engine = sslConfig.getSSLContext().createSSLEngine(host, port); + engine.setUseClientMode(true); + engine.setSSLParameters(enableHostNameVerification(engine.getSSLParameters())); + + // in the future we may use HostnameVerifier like here: + // https://github.com/AsyncHttpClient/async-http-client/blob/1.8.x/src/main/java/com/ning/http/client/providers/netty/NettyConnectListener.java#L76 + + ssl = new SslHandler(engine); + } + + } catch (Exception e) { + throw new RuntimeException(e); + } + + return ssl; + } + } + + protected DockerClientConfig getDockerClientConfig() { + checkNotNull(dockerClientConfig, + "Factor not initialized, dockerClientConfig not set. You probably forgot to call init()!"); + return dockerClientConfig; + } + + public SSLParameters enableHostNameVerification(SSLParameters sslParameters) { + sslParameters.setEndpointIdentificationAlgorithm("HTTPS"); + return sslParameters; + } + + @Override + public CopyArchiveFromContainerCmd.Exec createCopyArchiveFromContainerCmdExec() { + return new CopyArchiveFromContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CopyArchiveToContainerCmd.Exec createCopyArchiveToContainerCmdExec() { + return new CopyArchiveToContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public AuthCmd.Exec createAuthCmdExec() { + return new AuthCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InfoCmd.Exec createInfoCmdExec() { + return new InfoCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public PingCmd.Exec createPingCmdExec() { + return new PingCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public VersionCmd.Exec createVersionCmdExec() { + return new VersionCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public PullImageCmd.Exec createPullImageCmdExec() { + return new PullImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public PushImageCmd.Exec createPushImageCmdExec() { + return new PushImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public SaveImageCmd.Exec createSaveImageCmdExec() { + return new SaveImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CreateImageCmd.Exec createCreateImageCmdExec() { + return new CreateImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public LoadImageCmd.Exec createLoadImageCmdExec() { + return new LoadImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public SearchImagesCmd.Exec createSearchImagesCmdExec() { + return new SearchImagesCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RemoveImageCmd.Exec createRemoveImageCmdExec() { + return new RemoveImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ListImagesCmd.Exec createListImagesCmdExec() { + return new ListImagesCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InspectImageCmd.Exec createInspectImageCmdExec() { + return new InspectImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ListContainersCmd.Exec createListContainersCmdExec() { + return new ListContainersCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CreateContainerCmd.Exec createCreateContainerCmdExec() { + return new CreateContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public StartContainerCmd.Exec createStartContainerCmdExec() { + return new StartContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InspectContainerCmd.Exec createInspectContainerCmdExec() { + return new InspectContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ExecCreateCmd.Exec createExecCmdExec() { + return new ExecCreateCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RemoveContainerCmd.Exec createRemoveContainerCmdExec() { + return new RemoveContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public WaitContainerCmd.Exec createWaitContainerCmdExec() { + return new WaitContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public AttachContainerCmd.Exec createAttachContainerCmdExec() { + return new AttachContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ExecStartCmd.Exec createExecStartCmdExec() { + return new ExecStartCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InspectExecCmd.Exec createInspectExecCmdExec() { + return new InspectExecCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public LogContainerCmd.Exec createLogContainerCmdExec() { + return new LogContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CopyFileFromContainerCmd.Exec createCopyFileFromContainerCmdExec() { + return new CopyFileFromContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public StopContainerCmd.Exec createStopContainerCmdExec() { + return new StopContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ContainerDiffCmd.Exec createContainerDiffCmdExec() { + return new ContainerDiffCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public KillContainerCmd.Exec createKillContainerCmdExec() { + return new KillContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public UpdateContainerCmd.Exec createUpdateContainerCmdExec() { + return new UpdateContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RenameContainerCmd.Exec createRenameContainerCmdExec() { + return new RenameContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RestartContainerCmd.Exec createRestartContainerCmdExec() { + return new RestartContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CommitCmd.Exec createCommitCmdExec() { + return new CommitCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public BuildImageCmd.Exec createBuildImageCmdExec() { + return new BuildImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public TopContainerCmd.Exec createTopContainerCmdExec() { + return new TopContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public TagImageCmd.Exec createTagImageCmdExec() { + return new TagImageCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public PauseContainerCmd.Exec createPauseContainerCmdExec() { + return new PauseContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public UnpauseContainerCmd.Exec createUnpauseContainerCmdExec() { + return new UnpauseContainerCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public EventsCmd.Exec createEventsCmdExec() { + return new EventsCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public StatsCmd.Exec createStatsCmdExec() { + return new StatsCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CreateVolumeCmd.Exec createCreateVolumeCmdExec() { + return new CreateVolumeCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InspectVolumeCmd.Exec createInspectVolumeCmdExec() { + return new InspectVolumeCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RemoveVolumeCmd.Exec createRemoveVolumeCmdExec() { + return new RemoveVolumeCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ListVolumesCmd.Exec createListVolumesCmdExec() { + return new ListVolumesCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ListNetworksCmd.Exec createListNetworksCmdExec() { + return new ListNetworksCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public InspectNetworkCmd.Exec createInspectNetworkCmdExec() { + return new InspectNetworkCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public CreateNetworkCmd.Exec createCreateNetworkCmdExec() { + return new CreateNetworkCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public RemoveNetworkCmd.Exec createRemoveNetworkCmdExec() { + return new RemoveNetworkCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public ConnectToNetworkCmd.Exec createConnectToNetworkCmdExec() { + return new ConnectToNetworkCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public DisconnectFromNetworkCmd.Exec createDisconnectFromNetworkCmdExec() { + return new DisconnectFromNetworkCmdExec(getBaseResource(), getDockerClientConfig()); + } + + @Override + public void close() throws IOException { + checkNotNull(eventLoopGroup, "Factory not initialized. You probably forgot to call init()!"); + + eventLoopGroup.shutdownGracefully(); + } + + private WebTarget getBaseResource() { + return new WebTarget(channelProvider); + } +} diff --git a/src/test/java/com/github/dockerjava/netty/AbstractNettyDockerClientTest.java b/src/test/java/com/github/dockerjava/netty/AbstractNettyDockerClientTest.java index 44a541808..57f7aa421 100644 --- a/src/test/java/com/github/dockerjava/netty/AbstractNettyDockerClientTest.java +++ b/src/test/java/com/github/dockerjava/netty/AbstractNettyDockerClientTest.java @@ -12,6 +12,6 @@ public abstract class AbstractNettyDockerClientTest extends AbstractDockerClient @Override protected TestDockerCmdExecFactory initTestDockerCmdExecFactory() { - return new TestDockerCmdExecFactory(new DockerCmdExecFactoryImpl()); + return new TestDockerCmdExecFactory(new NettyDockerCmdExecFactory()); } } From e8b8519bbfb32cc1c5f3b6533b8b32fe7950103a Mon Sep 17 00:00:00 2001 From: tjlee Date: Fri, 29 Jul 2016 17:11:02 +0300 Subject: [PATCH 207/855] [tests] Added integration tests for pause / unpause commands (#647) * [tests] Added integration tests for pause / unpause commands * [tests] added missing netty tests; fixed javadoc text; fixed annotations; --- .../core/command/PauseCmdImplTest.java | 103 +++++++++++++++ .../core/command/UnpauseCmdImplTest.java | 118 ++++++++++++++++++ .../netty/exec/PauseCmdImplTest.java | 103 +++++++++++++++ .../netty/exec/UnpauseCmdImplTest.java | 118 ++++++++++++++++++ .../dockerjava/utils/ContainerUtils.java | 70 +++++++++++ 5 files changed, 512 insertions(+) create mode 100644 src/test/java/com/github/dockerjava/core/command/PauseCmdImplTest.java create mode 100644 src/test/java/com/github/dockerjava/core/command/UnpauseCmdImplTest.java create mode 100644 src/test/java/com/github/dockerjava/netty/exec/PauseCmdImplTest.java create mode 100644 src/test/java/com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java create mode 100644 src/test/java/com/github/dockerjava/utils/ContainerUtils.java diff --git a/src/test/java/com/github/dockerjava/core/command/PauseCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/PauseCmdImplTest.java new file mode 100644 index 000000000..f100c4f89 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/PauseCmdImplTest.java @@ -0,0 +1,103 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.exception.InternalServerErrorException; +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.client.AbstractDockerClientTest; +import com.github.dockerjava.utils.ContainerUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; + +@Test(groups = {"integration", "ignoreInCircleCi"}) +public class PauseCmdImplTest extends AbstractDockerClientTest { + + public static final Logger LOG = LoggerFactory.getLogger(PauseCmdImplTest.class); + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void pauseRunningContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.pauseContainer(dockerClient, container); + } + + @Test(expectedExceptions = NotFoundException.class) + public void pauseNonExistingContainer() { + + dockerClient.pauseContainerCmd("non-existing").exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void pauseStoppedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.stopContainer(dockerClient, container); + + dockerClient.pauseContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void pausePausedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.pauseContainer(dockerClient, container); + + dockerClient.pauseContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void pauseCreatedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.pauseContainerCmd(container.getId()).exec(); + } +} diff --git a/src/test/java/com/github/dockerjava/core/command/UnpauseCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/UnpauseCmdImplTest.java new file mode 100644 index 000000000..f640c4182 --- /dev/null +++ b/src/test/java/com/github/dockerjava/core/command/UnpauseCmdImplTest.java @@ -0,0 +1,118 @@ +package com.github.dockerjava.core.command; + +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.exception.InternalServerErrorException; +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.client.AbstractDockerClientTest; +import com.github.dockerjava.utils.ContainerUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; + +@Test(groups = {"integration", "ignoreInCircleCi"}) +public class UnpauseCmdImplTest extends AbstractDockerClientTest { + + public static final Logger LOG = LoggerFactory.getLogger(UnpauseCmdImplTest.class); + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void unpausePausedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.pauseContainer(dockerClient, container); + + ContainerUtils.unpaseContainer(dockerClient, container); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void unpauseRunningContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + dockerClient.unpauseContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void unpauseStoppedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.stopContainer(dockerClient, container); + + dockerClient.unpauseContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = NotFoundException.class) + public void unpauseNonExistingContainer() { + + dockerClient.unpauseContainerCmd("non-existing").exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void unpauseCreatedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.unpauseContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void unpauseUnpausedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.pauseContainer(dockerClient, container); + + dockerClient.unpauseContainerCmd(container.getId()).exec(); + dockerClient.unpauseContainerCmd(container.getId()).exec(); + } +} diff --git a/src/test/java/com/github/dockerjava/netty/exec/PauseCmdImplTest.java b/src/test/java/com/github/dockerjava/netty/exec/PauseCmdImplTest.java new file mode 100644 index 000000000..612c3efd2 --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/exec/PauseCmdImplTest.java @@ -0,0 +1,103 @@ +package com.github.dockerjava.netty.exec; + +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.exception.InternalServerErrorException; +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.netty.AbstractNettyDockerClientTest; +import com.github.dockerjava.utils.ContainerUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; + +@Test(groups = {"integration", "ignoreInCircleCi"}) +public class PauseCmdImplTest extends AbstractNettyDockerClientTest { + + public static final Logger LOG = LoggerFactory.getLogger(PauseCmdImplTest.class); + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void pauseRunningContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.pauseContainer(dockerClient, container); + } + + @Test(expectedExceptions = NotFoundException.class) + public void pauseNonExistingContainer() { + + dockerClient.pauseContainerCmd("non-existing").exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void pauseStoppedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.stopContainer(dockerClient, container); + + dockerClient.pauseContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void pausePausedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.pauseContainer(dockerClient, container); + + dockerClient.pauseContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void pauseCreatedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.pauseContainerCmd(container.getId()).exec(); + } +} diff --git a/src/test/java/com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java b/src/test/java/com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java new file mode 100644 index 000000000..db91bc9f9 --- /dev/null +++ b/src/test/java/com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java @@ -0,0 +1,118 @@ +package com.github.dockerjava.netty.exec; + +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.exception.InternalServerErrorException; +import com.github.dockerjava.api.exception.NotFoundException; +import com.github.dockerjava.netty.AbstractNettyDockerClientTest; +import com.github.dockerjava.utils.ContainerUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +import java.lang.reflect.Method; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.isEmptyString; +import static org.hamcrest.Matchers.not; + +@Test(groups = {"integration", "ignoreInCircleCi"}) +public class UnpauseCmdImplTest extends AbstractNettyDockerClientTest { + + public static final Logger LOG = LoggerFactory.getLogger(UnpauseCmdImplTest.class); + + @BeforeTest + public void beforeTest() throws Exception { + super.beforeTest(); + } + + @AfterTest + public void afterTest() { + super.afterTest(); + } + + @BeforeMethod + public void beforeMethod(Method method) { + super.beforeMethod(method); + } + + @AfterMethod + public void afterMethod(ITestResult result) { + super.afterMethod(result); + } + + @Test + public void unpausePausedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.pauseContainer(dockerClient, container); + + ContainerUtils.unpaseContainer(dockerClient, container); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void unpauseRunningContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + dockerClient.unpauseContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void unpauseStoppedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.stopContainer(dockerClient, container); + + dockerClient.unpauseContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = NotFoundException.class) + public void unpauseNonExistingContainer() { + + dockerClient.unpauseContainerCmd("non-existing").exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void unpauseCreatedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.unpauseContainerCmd(container.getId()).exec(); + } + + @Test(expectedExceptions = InternalServerErrorException.class) + public void unpauseUnpausedContainer() { + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); + LOG.info("Created container: {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + ContainerUtils.startContainer(dockerClient, container); + + ContainerUtils.pauseContainer(dockerClient, container); + + dockerClient.unpauseContainerCmd(container.getId()).exec(); + dockerClient.unpauseContainerCmd(container.getId()).exec(); + } +} diff --git a/src/test/java/com/github/dockerjava/utils/ContainerUtils.java b/src/test/java/com/github/dockerjava/utils/ContainerUtils.java new file mode 100644 index 000000000..75be6c4d9 --- /dev/null +++ b/src/test/java/com/github/dockerjava/utils/ContainerUtils.java @@ -0,0 +1,70 @@ +package com.github.dockerjava.utils; + +import com.github.dockerjava.api.DockerClient; +import com.github.dockerjava.api.command.CreateContainerResponse; +import com.github.dockerjava.api.command.InspectContainerResponse; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; + +/** + * Container cmd utils + */ +public class ContainerUtils { + + private ContainerUtils() { + } + + /** + * Starts container and ensures that it running + * + * @param dockerClient docker client + * @param container container + */ + public static void startContainer(DockerClient dockerClient, CreateContainerResponse container) { + dockerClient.startContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + assertThat(inspectContainerResponse.getState().getRunning(), is(true)); + } + + /** + * Pauses container and ensures that it paused + * + * @param dockerClient docker client + * @param container container + */ + public static void pauseContainer(DockerClient dockerClient, CreateContainerResponse container) { + dockerClient.pauseContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + assertThat(inspectContainerResponse.getState().getPaused(), is(true)); + } + + /** + * Stops container and ensures that it stopped + * + * @param dockerClient docker client + * @param container container + */ + public static void stopContainer(DockerClient dockerClient, CreateContainerResponse container) { + dockerClient.stopContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + assertThat(inspectContainerResponse.getState().getRunning(), is(false)); + } + + /** + * Unpauses container and ensures that it unpaused (running) + * + * @param dockerClient docker client + * @param container container + */ + public static void unpaseContainer(DockerClient dockerClient, CreateContainerResponse container) { + dockerClient.unpauseContainerCmd(container.getId()).exec(); + + InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); + assertThat(inspectContainerResponse.getState().getPaused(), is(false)); + assertThat(inspectContainerResponse.getState().getRunning(), is(true)); + } +} From d78a1cfb3a1c3a198389c0f86c9d92caa37db8de Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 29 Jul 2016 19:58:13 +0300 Subject: [PATCH 208/855] Add 1.12.0 for tests --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index a8cbe29e2..a9e93162a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,7 +21,8 @@ env: - COVERITY_SCAN_NOTIFICATION_EMAIL="kanstantsin.sha@gmail.com" matrix: - - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.11.2-0~trusty" DEPLOY=true CODECOV=true + - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.12.0-0~trusty" + - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.12.0-0~trusty" - 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" - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.10.3-0~trusty" From 4c663e18bf1685600d4aa032a7517ab3f0f6042f Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 1 Aug 2016 16:57:52 +0300 Subject: [PATCH 209/855] Fix test for different API behaviour. (#642) --- .../github/dockerjava/core/RemoteApiVersion.java | 10 ++++++++++ .../netty/exec/ExecStartCmdExecTest.java | 16 +++++++++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java index 954ed9971..f40b5b4d5 100644 --- a/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java +++ b/src/main/java/com/github/dockerjava/core/RemoteApiVersion.java @@ -62,6 +62,16 @@ public class RemoteApiVersion implements Serializable { */ public static final RemoteApiVersion VERSION_1_22 = RemoteApiVersion.create(1, 22); + /** + * @see Docker API 1.22 + */ + public static final RemoteApiVersion VERSION_1_23 = RemoteApiVersion.create(1, 23); + + /** + * @see Docker API 1.22 + */ + public static final RemoteApiVersion VERSION_1_24 = RemoteApiVersion.create(1, 24); + /** * 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/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java index e87c56d74..52db7fe44 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/ExecStartCmdExecTest.java @@ -1,5 +1,8 @@ package com.github.dockerjava.netty.exec; +import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_22; +import static com.github.dockerjava.core.RemoteApiVersion.VERSION_1_23; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; @@ -12,6 +15,7 @@ import java.security.SecureRandom; import java.util.concurrent.TimeUnit; +import com.github.dockerjava.core.RemoteApiVersion; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -193,7 +197,8 @@ public void execStartNotAttachedStdin() throws Exception { ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId()) .withAttachStdout(true) .withAttachStdin(false) - .withCmd("/bin/sh").exec(); + .withCmd("/bin/sh") + .exec(); boolean completed = dockerClient.execStartCmd(execCreateCmdResponse.getId()) .withDetach(false) @@ -201,8 +206,13 @@ public void execStartNotAttachedStdin() throws Exception { .exec(new ExecStartResultCallback(stdout, System.err)) .awaitCompletion(5, TimeUnit.SECONDS); - // with v1.22 of the remote api the server closed the connection when no stdin was attached while exec create, so completed was true - assertFalse(completed, "The process was not finished."); assertEquals(stdout.toString(), ""); + + if (getVersion(dockerClient).isGreaterOrEqual(VERSION_1_23)) { + assertFalse(completed, "The process was not finished."); + } else { + assertTrue(completed, "with v1.22 of the remote api the server closed the connection when no stdin " + + "was attached while exec create, so completed was true"); + } } } From 6195eb888f34293217d463bb205041d51b2602dc Mon Sep 17 00:00:00 2001 From: tjlee Date: Mon, 1 Aug 2016 20:43:25 +0300 Subject: [PATCH 210/855] [tests] use expectedExceptions (#649) --- .../core/command/AuthCmdImplTest.java | 9 ++------- .../core/command/CommitCmdImplTest.java | 10 +++------- .../command/ContainerDiffCmdImplTest.java | 10 +++------- .../CopyArchiveFromContainerCmdImplTest.java | 9 +++------ .../CopyArchiveToContainerCmdImplTest.java | 10 +++------- .../CopyFileFromContainerCmdImplTest.java | 9 +++------ .../command/CreateContainerCmdImplTest.java | 8 ++------ .../command/KillContainerCmdImplTest.java | 8 ++------ .../command/RemoveContainerCmdImplTest.java | 9 +++------ .../core/command/RemoveImageCmdImplTest.java | 8 ++------ .../command/RemoveNetworkCmdImplTest.java | 9 +++------ .../core/command/RemoveVolumeCmdImplTest.java | 9 ++------- .../command/RestartContainerCmdImplTest.java | 9 ++------- .../command/StartContainerCmdImplTest.java | 17 ++++------------- .../command/StopContainerCmdImplTest.java | 8 ++------ .../core/command/TagImageCmdImplTest.java | 10 +++------- .../netty/exec/CommitCmdExecTest.java | 9 +++------ .../netty/exec/ContainerDiffCmdExecTest.java | 9 +++------ .../CopyArchiveFromContainerCmdExecTest.java | 9 +++------ .../CopyArchiveToContainerCmdExecTest.java | 10 +++------- .../CopyFileFromContainerCmdExecTest.java | 9 +++------ .../netty/exec/KillContainerCmdExecTest.java | 8 ++------ .../exec/RemoveContainerCmdExecTest.java | 9 +++------ .../netty/exec/RemoveImageCmdExecTest.java | 8 ++------ .../netty/exec/RemoveNetworkCmdExecTest.java | 9 +++------ .../netty/exec/RemoveVolumeCmdExecTest.java | 9 ++------- .../exec/RestartContainerCmdExecTest.java | 8 ++------ .../netty/exec/StartContainerCmdExecTest.java | 19 +++++-------------- .../netty/exec/StopContainerCmdExecTest.java | 8 ++------ .../netty/exec/TagImageCmdExecTest.java | 10 +++------- 30 files changed, 81 insertions(+), 205 deletions(-) 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 c01c8b8cd..887c99130 100644 --- a/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/AuthCmdImplTest.java @@ -45,14 +45,9 @@ public void testAuth() throws Exception { } // Disabled because of 500/InternalServerException - @Test(enabled = false) + @Test(enabled = false, expectedExceptions = UnauthorizedException.class, expectedExceptionsMessageRegExp = "Wrong login/password, please try again") public void testAuthInvalid() throws Exception { - try { - DockerClientBuilder.getInstance(config("garbage")).build().authCmd().exec(); - fail("Expected a UnauthorizedException caused by a bad password."); - } catch (UnauthorizedException e) { - assertEquals(e.getMessage(), "Wrong login/password, please try again\n"); - } + DockerClientBuilder.getInstance(config("garbage")).build().authCmd().exec(); } } 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 b8758d332..64e1d7ddf 100644 --- a/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CommitCmdImplTest.java @@ -68,13 +68,9 @@ public void commit() throws DockerException { assertThat(inspectImageResponse.getParent(), equalTo(busyboxImg.getId())); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void commitNonExistingContainer() throws DockerException { - try { - dockerClient.commitCmd("non-existent").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } - } + dockerClient.commitCmd("non-existent").exec(); + } } diff --git a/src/test/java/com/github/dockerjava/core/command/ContainerDiffCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ContainerDiffCmdImplTest.java index 62c7b2ec0..e51db21f4 100644 --- a/src/test/java/com/github/dockerjava/core/command/ContainerDiffCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/ContainerDiffCmdImplTest.java @@ -67,13 +67,9 @@ public void testContainerDiff() throws DockerException { assertThat(testChangeLog, hasField("kind", equalTo(1))); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void testContainerDiffWithNonExistingContainer() throws DockerException { - try { - dockerClient.containerDiffCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } - } + dockerClient.containerDiffCmd("non-existing").exec(); + } } diff --git a/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java index 9b30dd891..59c459382 100644 --- a/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CopyArchiveFromContainerCmdImplTest.java @@ -70,13 +70,10 @@ public void copyFromContainer() throws Exception { assertTrue(responseAsString.length() > 0); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void copyFromNonExistingContainer() throws Exception { - try { - dockerClient.copyArchiveFromContainerCmd("non-existing", "/test").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException ignored) { - } + + dockerClient.copyArchiveFromContainerCmd("non-existing", "/test").exec(); } @Test diff --git a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java index a1006277c..658c1f090 100644 --- a/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CopyArchiveToContainerCmdImplTest.java @@ -83,14 +83,10 @@ private void assertFileCopied(CreateContainerResponse container) throws IOExcept } } - @Test + @Test(expectedExceptions = NotFoundException.class) public void copyToNonExistingContainer() throws Exception { - try { - dockerClient.copyArchiveToContainerCmd("non-existing").withHostResource("src/test/resources/testReadFile") - .exec(); - fail("expected NotFoundException"); - } catch (NotFoundException ignored) { - } + + dockerClient.copyArchiveToContainerCmd("non-existing").withHostResource("src/test/resources/testReadFile").exec(); } @Test diff --git a/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java index 3e4e88612..8bd2c44fe 100644 --- a/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java @@ -62,12 +62,9 @@ public void copyFromContainer() throws Exception { assertTrue(responseAsString.length() > 0); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void copyFromNonExistingContainer() throws Exception { - try { - dockerClient.copyFileFromContainerCmd("non-existing", "/test").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException ignored) { - } + + dockerClient.copyFileFromContainerCmd("non-existing", "/test").exec(); } } 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 a9c0acb8c..214bb2f4a 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -231,7 +231,7 @@ public void createContainerWithHostname() throws Exception { assertThat(containerLog(container.getId()), containsString("HOSTNAME=docker-java")); } - @Test + @Test(expectedExceptions = ConflictException.class) public void createContainerWithName() throws DockerException { CreateContainerResponse container = dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container") @@ -245,12 +245,8 @@ public void createContainerWithName() throws DockerException { assertThat(inspectContainerResponse.getName(), equalTo("/container")); - try { - dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container").withCmd("env").exec(); - fail("Expected ConflictException"); - } catch (ConflictException e) { - } + dockerClient.createContainerCmd(BUSYBOX_IMAGE).withName("container").withCmd("env").exec(); } @Test diff --git a/src/test/java/com/github/dockerjava/core/command/KillContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/KillContainerCmdImplTest.java index 3ba85928e..c8589271e 100644 --- a/src/test/java/com/github/dockerjava/core/command/KillContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/KillContainerCmdImplTest.java @@ -67,14 +67,10 @@ public void killContainer() throws DockerException { } - @Test + @Test(expectedExceptions = NotFoundException.class) public void killNonExistingContainer() throws DockerException { - try { - dockerClient.killContainerCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + dockerClient.killContainerCmd("non-existing").exec(); } } diff --git a/src/test/java/com/github/dockerjava/core/command/RemoveContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RemoveContainerCmdImplTest.java index 87ace71df..26c8e0e19 100644 --- a/src/test/java/com/github/dockerjava/core/command/RemoveContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/RemoveContainerCmdImplTest.java @@ -68,13 +68,10 @@ public void removeContainer() throws DockerException { } - @Test + @Test(expectedExceptions = NotFoundException.class) public void removeNonExistingContainer() throws DockerException { - try { - dockerClient.removeContainerCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + + dockerClient.removeContainerCmd("non-existing").exec(); } } diff --git a/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java index 90be81c7f..4427da997 100644 --- a/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/RemoveImageCmdImplTest.java @@ -74,14 +74,10 @@ public void removeImage() throws DockerException, InterruptedException { assertThat(containers, matcher); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void removeNonExistingImage() throws DockerException, InterruptedException { - try { - dockerClient.removeImageCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + dockerClient.removeImageCmd("non-existing").exec(); } } diff --git a/src/test/java/com/github/dockerjava/core/command/RemoveNetworkCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RemoveNetworkCmdImplTest.java index e1e4e45fe..228e48c4d 100644 --- a/src/test/java/com/github/dockerjava/core/command/RemoveNetworkCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/RemoveNetworkCmdImplTest.java @@ -64,13 +64,10 @@ public void removeNetwork() throws DockerException { } - @Test + @Test(expectedExceptions = NotFoundException.class) public void removeNonExistingContainer() throws DockerException { - try { - dockerClient.removeNetworkCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + + dockerClient.removeNetworkCmd("non-existing").exec(); } } diff --git a/src/test/java/com/github/dockerjava/core/command/RemoveVolumeCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RemoveVolumeCmdImplTest.java index 249bf8493..9ed690b65 100644 --- a/src/test/java/com/github/dockerjava/core/command/RemoveVolumeCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/RemoveVolumeCmdImplTest.java @@ -41,7 +41,7 @@ public void afterMethod(ITestResult result) { super.afterMethod(result); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void removeVolume() throws DockerException { String volumeName = "volume1"; @@ -55,11 +55,6 @@ public void removeVolume() throws DockerException { dockerClient.removeVolumeCmd(volumeName).exec(); - try { - dockerClient.inspectVolumeCmd(volumeName).exec(); - fail("Expected NotFoundException"); - } catch (NotFoundException e) { - // just ignore - } + dockerClient.inspectVolumeCmd(volumeName).exec(); } } diff --git a/src/test/java/com/github/dockerjava/core/command/RestartContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/RestartContainerCmdImplTest.java index 4920ac087..84916f082 100644 --- a/src/test/java/com/github/dockerjava/core/command/RestartContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/RestartContainerCmdImplTest.java @@ -71,14 +71,9 @@ public void restartContainer() throws DockerException { dockerClient.killContainerCmd(container.getId()).exec(); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void restartNonExistingContainer() throws DockerException, InterruptedException { - try { - dockerClient.restartContainerCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + dockerClient.restartContainerCmd("non-existing").exec(); } - } diff --git a/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java index 2b32e00c5..4bb8f2b99 100644 --- a/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/StartContainerCmdImplTest.java @@ -251,7 +251,7 @@ public void startContainerWithRandomPortBindings() throws DockerException { } - @Test + @Test(expectedExceptions = InternalServerErrorException.class) public void startContainerWithConflictingPortBindings() throws DockerException { ExposedPort tcp22 = ExposedPort.tcp(22); @@ -268,13 +268,7 @@ public void startContainerWithConflictingPortBindings() throws DockerException { assertThat(container.getId(), not(isEmptyString())); - try { - dockerClient.startContainerCmd(container.getId()).exec(); - fail("expected InternalServerErrorException"); - } catch (InternalServerErrorException e) { - - } - + dockerClient.startContainerCmd(container.getId()).exec(); } @Test @@ -412,13 +406,10 @@ public void startContainer() throws DockerException { } } - @Test + @Test(expectedExceptions = NotFoundException.class) public void testStartNonExistingContainer() throws DockerException { - try { + dockerClient.startContainerCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } } /** diff --git a/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java index 913ed9474..382e5b29c 100644 --- a/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java @@ -76,14 +76,10 @@ public void testStopContainer() throws DockerException { } } - @Test + @Test(expectedExceptions = NotFoundException.class) public void testStopNonExistingContainer() throws DockerException { - try { - dockerClient.stopContainerCmd("non-existing").withTimeout(2).exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + dockerClient.stopContainerCmd("non-existing").withTimeout(2).exec(); } } diff --git a/src/test/java/com/github/dockerjava/core/command/TagImageCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/TagImageCmdImplTest.java index 94d4291d0..3bf033212 100644 --- a/src/test/java/com/github/dockerjava/core/command/TagImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/TagImageCmdImplTest.java @@ -49,15 +49,11 @@ public void tagImage() throws Exception { dockerClient.removeImageCmd("docker-java/busybox:" + tag).exec(); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void tagNonExistingImage() throws Exception { - String tag = "" + RandomUtils.nextInt(Integer.MAX_VALUE); - try { - dockerClient.tagImageCmd("non-existing", "docker-java/busybox", tag).exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + String tag = "" + RandomUtils.nextInt(Integer.MAX_VALUE); + dockerClient.tagImageCmd("non-existing", "docker-java/busybox", tag).exec(); } } 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 0186f4233..3d1a66333 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CommitCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CommitCmdExecTest.java @@ -68,13 +68,10 @@ public void commit() throws DockerException { assertThat(inspectImageResponse.getParent(), equalTo(busyboxImg.getId())); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void commitNonExistingContainer() throws DockerException { - try { - dockerClient.commitCmd("non-existent").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + + dockerClient.commitCmd("non-existent").exec(); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/ContainerDiffCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ContainerDiffCmdExecTest.java index 57c4b46a0..c21c426b5 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/ContainerDiffCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/ContainerDiffCmdExecTest.java @@ -68,13 +68,10 @@ public void testContainerDiff() throws DockerException { assertThat(testChangeLog, hasField("kind", equalTo(1))); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void testContainerDiffWithNonExistingContainer() throws DockerException { - try { - dockerClient.containerDiffCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + + dockerClient.containerDiffCmd("non-existing").exec(); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java index caec336a2..02b56156d 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveFromContainerCmdExecTest.java @@ -70,13 +70,10 @@ public void copyFromContainer() throws Exception { assertTrue(responseAsString.length() > 0); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void copyFromNonExistingContainer() throws Exception { - try { - dockerClient.copyArchiveFromContainerCmd("non-existing", "/test").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException ignored) { - } + + dockerClient.copyArchiveFromContainerCmd("non-existing", "/test").exec(); } @Test diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java index eb43b54de..d75d36ea8 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CopyArchiveToContainerCmdExecTest.java @@ -84,14 +84,10 @@ private void assertFileCopied(CreateContainerResponse container) throws IOExcept } } - @Test + @Test(expectedExceptions = NotFoundException.class) public void copyToNonExistingContainer() throws Exception { - try { - dockerClient.copyArchiveToContainerCmd("non-existing").withHostResource("src/test/resources/testReadFile") - .exec(); - fail("expected NotFoundException"); - } catch (NotFoundException ignored) { - } + + dockerClient.copyArchiveToContainerCmd("non-existing").withHostResource("src/test/resources/testReadFile").exec(); } @Test diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java index b9682c592..b512cfa69 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java @@ -62,12 +62,9 @@ public void copyFromContainer() throws Exception { assertTrue(responseAsString.length() > 0); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void copyFromNonExistingContainer() throws Exception { - try { - dockerClient.copyFileFromContainerCmd("non-existing", "/test").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException ignored) { - } + + dockerClient.copyFileFromContainerCmd("non-existing", "/test").exec(); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/KillContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/KillContainerCmdExecTest.java index 867373e63..d354c8df3 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/KillContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/KillContainerCmdExecTest.java @@ -67,14 +67,10 @@ public void killContainer() throws DockerException { } - @Test + @Test(expectedExceptions = NotFoundException.class) public void killNonExistingContainer() throws DockerException { - try { - dockerClient.killContainerCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + dockerClient.killContainerCmd("non-existing").exec(); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/RemoveContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RemoveContainerCmdExecTest.java index ffe456c09..1e7abebdb 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/RemoveContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/RemoveContainerCmdExecTest.java @@ -69,13 +69,10 @@ public void removeContainer() throws DockerException { } - @Test + @Test(expectedExceptions = NotFoundException.class) public void removeNonExistingContainer() throws DockerException { - try { - dockerClient.removeContainerCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + + dockerClient.removeContainerCmd("non-existing").exec(); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/RemoveImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RemoveImageCmdExecTest.java index e2f69ac1e..857bec714 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/RemoveImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/RemoveImageCmdExecTest.java @@ -74,14 +74,10 @@ public void removeImage() throws DockerException, InterruptedException { assertThat(containers, matcher); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void removeNonExistingImage() throws DockerException, InterruptedException { - try { - dockerClient.removeImageCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + dockerClient.removeImageCmd("non-existing").exec(); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/RemoveNetworkCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RemoveNetworkCmdExecTest.java index 9fda49f21..f8e7d26ca 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/RemoveNetworkCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/RemoveNetworkCmdExecTest.java @@ -64,13 +64,10 @@ public void removeNetwork() throws DockerException { } - @Test + @Test(expectedExceptions = NotFoundException.class) public void removeNonExistingContainer() throws DockerException { - try { - dockerClient.removeNetworkCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + + dockerClient.removeNetworkCmd("non-existing").exec(); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/RemoveVolumeCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RemoveVolumeCmdExecTest.java index 59aafde67..d7995861c 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/RemoveVolumeCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/RemoveVolumeCmdExecTest.java @@ -41,7 +41,7 @@ public void afterMethod(ITestResult result) { super.afterMethod(result); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void removeVolume() throws DockerException { String volumeName = "volume1"; @@ -55,11 +55,6 @@ public void removeVolume() throws DockerException { dockerClient.removeVolumeCmd(volumeName).exec(); - try { - dockerClient.inspectVolumeCmd(volumeName).exec(); - fail("Expected NotFoundException"); - } catch (NotFoundException e) { - // just ignore - } + dockerClient.inspectVolumeCmd(volumeName).exec(); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/RestartContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/RestartContainerCmdExecTest.java index 3360057a8..3b1ada5c2 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/RestartContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/RestartContainerCmdExecTest.java @@ -71,14 +71,10 @@ public void restartContainer() throws DockerException { dockerClient.killContainerCmd(container.getId()).exec(); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void restartNonExistingContainer() throws DockerException, InterruptedException { - try { - dockerClient.restartContainerCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + dockerClient.restartContainerCmd("non-existing").exec(); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java index f4a36c2b1..eed82fcd9 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/StartContainerCmdExecTest.java @@ -254,7 +254,7 @@ public void startContainerWithRandomPortBindings() throws DockerException { } - @Test + @Test(expectedExceptions = InternalServerErrorException.class) public void startContainerWithConflictingPortBindings() throws DockerException { ExposedPort tcp22 = ExposedPort.tcp(22); @@ -271,13 +271,7 @@ public void startContainerWithConflictingPortBindings() throws DockerException { assertThat(container.getId(), not(isEmptyString())); - try { - dockerClient.startContainerCmd(container.getId()).exec(); - fail("expected InternalServerErrorException"); - } catch (InternalServerErrorException e) { - - } - + dockerClient.startContainerCmd(container.getId()).exec(); } @Test @@ -415,13 +409,10 @@ public void startContainer() throws DockerException { } } - @Test + @Test(expectedExceptions = NotFoundException.class) public void testStartNonExistingContainer() throws DockerException { - try { - dockerClient.startContainerCmd("non-existing").exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + + dockerClient.startContainerCmd("non-existing").exec(); } /** diff --git a/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java index b3f545a42..1dca12890 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java @@ -76,14 +76,10 @@ public void testStopContainer() throws DockerException { } } - @Test + @Test(expectedExceptions = NotFoundException.class) public void testStopNonExistingContainer() throws DockerException { - try { - dockerClient.stopContainerCmd("non-existing").withTimeout(2).exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + dockerClient.stopContainerCmd("non-existing").withTimeout(2).exec(); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/TagImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/TagImageCmdExecTest.java index bbab169ef..6c84775ee 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/TagImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/TagImageCmdExecTest.java @@ -49,15 +49,11 @@ public void tagImage() throws Exception { dockerClient.removeImageCmd("docker-java/busybox:" + tag).exec(); } - @Test + @Test(expectedExceptions = NotFoundException.class) public void tagNonExistingImage() throws Exception { - String tag = "" + RandomUtils.nextInt(Integer.MAX_VALUE); - try { - dockerClient.tagImageCmd("non-existing", "docker-java/busybox", tag).exec(); - fail("expected NotFoundException"); - } catch (NotFoundException e) { - } + String tag = "" + RandomUtils.nextInt(Integer.MAX_VALUE); + dockerClient.tagImageCmd("non-existing", "docker-java/busybox", tag).exec(); } } From b1ed66b10c3def348091809d3ecc5234396d8190 Mon Sep 17 00:00:00 2001 From: tejksat Date: Mon, 1 Aug 2016 20:46:47 +0300 Subject: [PATCH 211/855] Fix for #643 (#648) * Fix for #643 .dockerignore rules handling refactored. A rule is translated to a regexp pattern and then a path is checked against it. * Fix for #643 Failing tests on Windows fixed: Windows file separator escaped. --- .../dockerjava/core/GoLangFileMatch.java | 305 +++++++++--------- .../core/dockerfile/Dockerfile.java | 19 +- .../dockerjava/core/GoLangFileMatchTest.java | 22 +- .../DockerfileAddMultipleFilesTest.java | 49 ++- .../.dockerignore | 3 + .../EffectiveDockerignorePatterns/Dockerfile | 3 + .../README-secret.md | 1 + .../EffectiveDockerignorePatterns/README.md | 0 .../.dockerignore | 3 + .../IneffectiveDockerignorePattern/Dockerfile | 3 + .../README-secret.md | 0 .../IneffectiveDockerignorePattern/README.md | 0 .../NestedDirsDockerignore/.dockerignore | 5 + .../NestedDirsDockerignore/Dockerfile | 3 + .../NestedDirsDockerignore/parent/README.md | 0 .../NestedDirsDockerignore/parent/a.txt | 0 .../parent/anotherChild/README-child.md | 0 .../anotherChild/grandChild/README-grand.md | 0 .../parent/anotherChild/grandChild/c.txt | 0 .../NestedDirsDockerignore/parent/child/b.txt | 0 20 files changed, 231 insertions(+), 185 deletions(-) create mode 100644 src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/.dockerignore create mode 100644 src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/Dockerfile create mode 100644 src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README-secret.md create mode 100644 src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README.md create mode 100644 src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/.dockerignore create mode 100644 src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/Dockerfile create mode 100644 src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/README-secret.md create mode 100644 src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/README.md create mode 100644 src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/.dockerignore create mode 100644 src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/Dockerfile create mode 100644 src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/README.md create mode 100644 src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/a.txt create mode 100644 src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/README-child.md create mode 100644 src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/grandChild/README-grand.md create mode 100644 src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/grandChild/c.txt create mode 100644 src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/child/b.txt diff --git a/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java b/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java index fa5dba722..09d5e4978 100644 --- a/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java +++ b/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java @@ -6,6 +6,7 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; @@ -49,6 +50,8 @@ private GoLangFileMatch() { public static final boolean IS_WINDOWS = File.separatorChar == '\\'; + private static final String PATTERN_CHARS_TO_ESCAPE = "\\.[]{}()*+-?^$|"; + public static boolean match(List patterns, File file) { return !match(patterns, file.getPath()).isEmpty(); } @@ -71,196 +74,194 @@ public static List match(List patterns, String name) { } public static boolean match(String pattern, String name) { - Pattern: while (!pattern.isEmpty()) { - ScanResult scanResult = scanChunk(pattern); - pattern = scanResult.pattern; - if (scanResult.star && StringUtils.isEmpty(scanResult.chunk)) { - // Trailing * matches rest of string unless it has a /. - return name.indexOf(File.separatorChar) < 0; - } - // Look for match at current position. - String matchResult = matchChunk(scanResult.chunk, name); + return buildPattern(pattern).matcher(name).matches(); + } - // if we're the last chunk, make sure we've exhausted the name - // otherwise we'll give a false result even if we could still match - // using the star - if (matchResult != null && (matchResult.isEmpty() || !pattern.isEmpty())) { - name = matchResult; - continue; - } - if (scanResult.star) { - for (int i = 0; i < name.length() && name.charAt(i) != File.separatorChar; i++) { - matchResult = matchChunk(scanResult.chunk, name.substring(i + 1)); - if (matchResult != null) { - // if we're the last chunk, make sure we exhausted the name - if (pattern.isEmpty() && !matchResult.isEmpty()) { - continue; - } - name = matchResult; - continue Pattern; - } - } + private static Pattern buildPattern(String pattern) { + StringBuilder patternStringBuilder = new StringBuilder("^"); + while (!pattern.isEmpty()) { + pattern = appendChunkPattern(patternStringBuilder, pattern); + + if (!pattern.isEmpty()) { + patternStringBuilder.append(quote(File.separatorChar)); } - return false; } - return name.isEmpty(); + patternStringBuilder.append("(").append(quote(File.separatorChar)).append(".*").append(")?"); + return Pattern.compile(patternStringBuilder.toString()); } - static ScanResult scanChunk(String pattern) { - boolean star = false; - if (!pattern.isEmpty() && pattern.charAt(0) == '*') { - pattern = pattern.substring(1); - star = true; + private static String quote(char separatorChar) { + if (StringUtils.contains(PATTERN_CHARS_TO_ESCAPE, separatorChar)) { + return "\\" + separatorChar; + } else { + return String.valueOf(separatorChar); } + } + + private static String appendChunkPattern(StringBuilder patternStringBuilder, String pattern) { + if (pattern.equals("**") || pattern.startsWith("**" + File.separator)) { + patternStringBuilder.append("(") + .append("[^").append(quote(File.separatorChar)).append("]*") + .append("(") + .append(quote(File.separatorChar)).append("[^").append(quote(File.separatorChar)).append("]*") + .append(")*").append(")?"); + return pattern.substring(pattern.length() == 2 ? 2 : 3); + } + boolean inRange = false; + int rangeFrom = 0; + RangeParseState rangeParseState = RangeParseState.CHAR_EXPECTED; + boolean isEsc = false; int i; - Scan: for (i = 0; i < pattern.length(); i++) { - switch (pattern.charAt(i)) { - case '\\': { - if (!IS_WINDOWS && i + 1 < pattern.length()) { - i++; + for (i = 0; i < pattern.length(); i++) { + char c = pattern.charAt(i); + switch (c) { + case '/': + if (!inRange) { + if (!IS_WINDOWS && !isEsc) { + // end of chunk + return pattern.substring(i + 1); + } else { + patternStringBuilder.append(quote(c)); + } + } else { + rangeParseState = nextStateAfterChar(rangeParseState); } + isEsc = false; break; - } - case '[': - inRange = true; - break; - case ']': - inRange = false; - break; - case '*': + case '\\': if (!inRange) { - break Scan; + if (!IS_WINDOWS) { + if (isEsc) { + patternStringBuilder.append(quote(c)); + isEsc = false; + } else { + isEsc = true; + } + } else { + // end of chunk + return pattern.substring(i + 1); + } + } else { + if (IS_WINDOWS || isEsc) { + rangeParseState = nextStateAfterChar(rangeParseState); + isEsc = false; + } else { + isEsc = true; + } } - } - } - return new ScanResult(star, pattern.substring(0, i), pattern.substring(i)); - } - - static String matchChunk(String chunk, String s) { - int chunkLength = chunk.length(); - int chunkOffset = 0; - int sLength = s.length(); - int sOffset = 0; - char r; - while (chunkOffset < chunkLength) { - if (sOffset == sLength) { - return null; - } - switch (chunk.charAt(chunkOffset)) { + break; case '[': - r = s.charAt(sOffset); - sOffset++; - chunkOffset++; - // We can't end right after '[', we're expecting at least - // a closing bracket and possibly a caret. - if (chunkOffset == chunkLength) { - throw new GoLangFileMatchException(); - } - // possibly negated - boolean negated = chunk.charAt(chunkOffset) == '^'; - if (negated) { - chunkOffset++; + if (!isEsc) { + if (inRange) { + //"[ is not expected, ] had not reached" + throw new GoLangFileMatchException(); + } + rangeFrom = i; + rangeParseState = RangeParseState.CHAR_EXPECTED; + inRange = true; + } else { + if (!inRange) { + patternStringBuilder.append(c); + } else { + rangeParseState = nextStateAfterChar(rangeParseState); + } } - // parse all ranges - boolean match = false; - int nrange = 0; - while (true) { - if (chunkOffset < chunkLength && chunk.charAt(chunkOffset) == ']' && nrange > 0) { - chunkOffset++; - break; + isEsc = false; + break; + case ']': + if (!isEsc) { + if (!inRange) { + //"] is not expected, [ was not met" + throw new GoLangFileMatchException(); } - GetEscResult result = getEsc(chunk, chunkOffset, chunkLength); - char lo = result.lo; - char hi = lo; - chunkOffset = result.chunkOffset; - if (chunk.charAt(chunkOffset) == '-') { - result = getEsc(chunk, ++chunkOffset, chunkLength); - chunkOffset = result.chunkOffset; - hi = result.lo; + if (rangeParseState == RangeParseState.CHAR_EXPECTED_AFTER_DASH) { + // character range not finished + throw new GoLangFileMatchException(); } - if (lo <= r && r <= hi) { - match = true; + patternStringBuilder.append(pattern.substring(rangeFrom, i + 1)); + inRange = false; + } else { + if (!inRange) { + patternStringBuilder.append(c); + } else { + rangeParseState = nextStateAfterChar(rangeParseState); } - nrange++; } - if (match == negated) { - return null; + isEsc = false; + break; + case '*': + if (!inRange) { + if (!isEsc) { + patternStringBuilder.append("[^").append(quote(File.separatorChar)).append("]*"); + } else { + patternStringBuilder.append(quote(c)); + } + } else { + rangeParseState = nextStateAfterChar(rangeParseState); } + isEsc = false; break; - case '?': - if (s.charAt(sOffset) == File.separatorChar) { - return null; + if (!inRange) { + if (!isEsc) { + patternStringBuilder.append("[^").append(quote(File.separatorChar)).append("]"); + } else { + patternStringBuilder.append(quote(c)); + } + } else { + rangeParseState = nextStateAfterChar(rangeParseState); } - sOffset++; - chunkOffset++; + isEsc = false; break; - case '\\': - if (!IS_WINDOWS) { - chunkOffset++; - if (chunkOffset == chunkLength) { - throw new GoLangFileMatchException(); + case '-': + if (!inRange) { + patternStringBuilder.append(quote(c)); + } else { + if (!isEsc) { + if (rangeParseState != RangeParseState.CHAR_OR_DASH_EXPECTED) { + // - not expected + throw new GoLangFileMatchException(); + } + rangeParseState = RangeParseState.CHAR_EXPECTED_AFTER_DASH; + } else { + rangeParseState = nextStateAfterChar(rangeParseState); } } - // fallthrough + isEsc = false; + break; default: - if (chunk.charAt(chunkOffset) != s.charAt(sOffset)) { - return null; + if (!inRange) { + patternStringBuilder.append(quote(c)); + } else { + rangeParseState = nextStateAfterChar(rangeParseState); } - sOffset++; - chunkOffset++; + isEsc = false; } } - return s.substring(sOffset); - } - - static GetEscResult getEsc(String chunk, int chunkOffset, int chunkLength) { - if (chunkOffset == chunkLength) { + if (isEsc) { + // "Escaped character missing" throw new GoLangFileMatchException(); } - char r = chunk.charAt(chunkOffset); - if (r == '-' || r == ']') { + if (inRange) { + // "Character range not finished" throw new GoLangFileMatchException(); } - if (r == '\\' && !IS_WINDOWS) { - chunkOffset++; - if (chunkOffset == chunkLength) { - throw new GoLangFileMatchException(); - } - - } - r = chunk.charAt(chunkOffset); - chunkOffset++; - if (chunkOffset == chunkLength) { - throw new GoLangFileMatchException(); - } - return new GetEscResult(r, chunkOffset); + return ""; } - private static final class ScanResult { - public boolean star; - - public String chunk; - - public String pattern; - - ScanResult(boolean star, String chunk, String pattern) { - this.star = star; - this.chunk = chunk; - this.pattern = pattern; + private static RangeParseState nextStateAfterChar(RangeParseState currentState) { + if (currentState == RangeParseState.CHAR_EXPECTED_AFTER_DASH) { + return RangeParseState.CHAR_EXPECTED; + } else { + return RangeParseState.CHAR_OR_DASH_EXPECTED; } } - private static final class GetEscResult { - public char lo; - - public int chunkOffset; - - GetEscResult(char lo, int chunkOffset) { - this.lo = lo; - this.chunkOffset = chunkOffset; - } + private enum RangeParseState { + CHAR_EXPECTED, + CHAR_OR_DASH_EXPECTED, + CHAR_EXPECTED_AFTER_DASH } } diff --git a/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java b/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java index c970d6c2d..9dcd20199 100644 --- a/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java +++ b/src/main/java/com/github/dockerjava/core/dockerfile/Dockerfile.java @@ -204,9 +204,10 @@ private List matchingIgnorePatterns(String fileName) { int lineNumber = 0; for (String pattern : ignores) { + String goLangPattern = pattern.startsWith("!") ? pattern.substring(1) : pattern; lineNumber++; try { - if (GoLangFileMatch.match(pattern, fileName)) { + if (GoLangFileMatch.match(goLangPattern, fileName)) { matches.add(pattern); } } catch (GoLangFileMatchException e) { @@ -233,21 +234,7 @@ private String effectiveMatchingIgnorePattern(File file) { String lastMatchingPattern = matchingPattern.get(matchingPattern.size() - 1); - int lastMatchingPatternIndex = ignores.lastIndexOf(lastMatchingPattern); - - if (lastMatchingPatternIndex == ignores.size() - 1) { - return lastMatchingPattern; - } - - List remainingIgnorePattern = ignores.subList(lastMatchingPatternIndex + 1, ignores.size()); - - for (String ignorePattern : remainingIgnorePattern) { - if (ignorePattern.equals("!" + relativeFilename)) { - return null; - } - } - - return lastMatchingPattern; + return !lastMatchingPattern.startsWith("!") ? lastMatchingPattern : null; } } } diff --git a/src/test/java/com/github/dockerjava/core/GoLangFileMatchTest.java b/src/test/java/com/github/dockerjava/core/GoLangFileMatchTest.java index 0fd870194..62b342595 100644 --- a/src/test/java/com/github/dockerjava/core/GoLangFileMatchTest.java +++ b/src/test/java/com/github/dockerjava/core/GoLangFileMatchTest.java @@ -5,13 +5,14 @@ import java.io.IOException; -import com.github.dockerjava.core.exception.GoLangFileMatchException; -import junit.framework.Assert; - import org.apache.commons.io.FilenameUtils; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.github.dockerjava.core.exception.GoLangFileMatchException; + +import junit.framework.Assert; + public class GoLangFileMatchTest { @Test(dataProvider = "getTestData") @@ -31,7 +32,7 @@ public void testMatch(MatchTestCase testCase) throws IOException { if (testCase.expectException) { Assert.fail("Expected GoFileMatchException"); } - Assert.assertEquals(testCase.matches, matched); + Assert.assertEquals(testCase.toString(), testCase.matches, matched); } catch (GoLangFileMatchException e) { if (!testCase.expectException) { throw e; @@ -41,12 +42,13 @@ public void testMatch(MatchTestCase testCase) throws IOException { @DataProvider public Object[][] getTestData() { - return new Object[][] {new Object[] {new MatchTestCase("abc", "abc", true, false)}, + return new Object[][] {new Object[] {new MatchTestCase("", "abc", false, false)}, + new Object[] {new MatchTestCase("abc", "abc", true, false)}, new Object[] {new MatchTestCase("*", "abc", true, false)}, new Object[] {new MatchTestCase("*c", "abc", true, false)}, new Object[] {new MatchTestCase("a*", "a", true, false)}, new Object[] {new MatchTestCase("a*", "abc", true, false)}, - new Object[] {new MatchTestCase("a*", "ab/c", false, false)}, + new Object[] {new MatchTestCase("a*", "ab/c", true, false)}, new Object[] {new MatchTestCase("a*/b", "abc/b", true, false)}, new Object[] {new MatchTestCase("a*/b", "a/c/b", false, false)}, new Object[] {new MatchTestCase("a*b*c*d*e*/f", "axbxcxdxe/f", true, false)}, @@ -92,9 +94,13 @@ public Object[][] getTestData() { new Object[] {new MatchTestCase("[", "a", false, true)}, new Object[] {new MatchTestCase("[^", "a", false, true)}, new Object[] {new MatchTestCase("[^bc", "a", false, true)}, - new Object[] {new MatchTestCase("a[", "a", false, false)}, + new Object[] {new MatchTestCase("a[", "a", false, true)}, new Object[] {new MatchTestCase("a[", "ab", false, true)}, - new Object[] {new MatchTestCase("*x", "xxx", true, false)}}; + new Object[] {new MatchTestCase("*x", "xxx", true, false)}, + new Object[] {new MatchTestCase("a", "a/b/c", true, false)}, + new Object[] {new MatchTestCase("*/b", "a/b/c", true, false)}, + new Object[] {new MatchTestCase("**/b/*/d", "a/b/c/d", true, false)}, + new Object[] {new MatchTestCase("**/c", "a/b/c", true, false)}}; } private final class MatchTestCase { diff --git a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java index 164246957..b37754a6a 100644 --- a/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java +++ b/src/test/java/com/github/dockerjava/core/dockerfile/DockerfileAddMultipleFilesTest.java @@ -1,20 +1,20 @@ package com.github.dockerjava.core.dockerfile; -import com.google.common.base.Function; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.testng.annotations.Test; +import static com.google.common.collect.Collections2.transform; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsInAnyOrder; import java.io.File; import java.io.IOException; import java.util.Collection; -import static com.google.common.collect.Collections2.transform; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.hamcrest.Matchers.containsInAnyOrder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; -public class DockerfileAddMultipleFilesTest { +import com.google.common.base.Function; + +public class DockerfileAddMultipleFilesTest { private static final Logger log = LoggerFactory.getLogger(DockerfileAddMultipleFilesTest.class); @@ -25,6 +25,37 @@ public String apply(File file) { } }; + @Test + public void nestedDirsPatterns() throws Exception { + File baseDir = fileFromBuildTestResource("dockerignore/NestedDirsDockerignore"); + Dockerfile dockerfile = new Dockerfile(new File(baseDir, "Dockerfile"), baseDir); + Dockerfile.ScannedResult result = dockerfile.parse(); + Collection filesToAdd = transform(result.filesToAdd, TO_FILE_NAMES); + + assertThat(filesToAdd, + containsInAnyOrder("Dockerfile", ".dockerignore", "README.md", "README-grand.md", "b.txt")); + } + + @Test + public void effectiveIgnorePatterns() throws Exception { + File baseDir = fileFromBuildTestResource("dockerignore/EffectiveDockerignorePatterns"); + Dockerfile dockerfile = new Dockerfile(new File(baseDir, "Dockerfile"), baseDir); + Dockerfile.ScannedResult result = dockerfile.parse(); + Collection filesToAdd = transform(result.filesToAdd, TO_FILE_NAMES); + + assertThat(filesToAdd, containsInAnyOrder("Dockerfile", ".dockerignore", "README.md")); + } + + @Test + public void ineffectiveIgnorePattern() throws Exception { + File baseDir = fileFromBuildTestResource("dockerignore/IneffectiveDockerignorePattern"); + Dockerfile dockerfile = new Dockerfile(new File(baseDir, "Dockerfile"), baseDir); + Dockerfile.ScannedResult result = dockerfile.parse(); + Collection filesToAdd = transform(result.filesToAdd, TO_FILE_NAMES); + + assertThat(filesToAdd, containsInAnyOrder("Dockerfile", ".dockerignore", "README.md", "README-secret.md")); + } + @Test public void addFiles() throws IOException { File baseDir = fileFromBuildTestResource("ADD/files"); diff --git a/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/.dockerignore b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/.dockerignore new file mode 100644 index 000000000..f22e777b8 --- /dev/null +++ b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/.dockerignore @@ -0,0 +1,3 @@ +*.md +!README*.md +README-secret.md \ No newline at end of file diff --git a/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/Dockerfile b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/Dockerfile new file mode 100644 index 000000000..65fa210c7 --- /dev/null +++ b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/Dockerfile @@ -0,0 +1,3 @@ +FROM ubuntu:latest + +CMD ["echo", "Success"] diff --git a/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README-secret.md b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README-secret.md new file mode 100644 index 000000000..64237b5a7 --- /dev/null +++ b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README-secret.md @@ -0,0 +1 @@ +No markdown files are included in the context except README files other than README-secret.md. \ No newline at end of file diff --git a/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README.md b/src/test/resources/buildTests/dockerignore/EffectiveDockerignorePatterns/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/.dockerignore b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/.dockerignore new file mode 100644 index 000000000..f1a1f3799 --- /dev/null +++ b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/.dockerignore @@ -0,0 +1,3 @@ +*.md +README-secret.md +!README*.md diff --git a/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/Dockerfile b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/Dockerfile new file mode 100644 index 000000000..65fa210c7 --- /dev/null +++ b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/Dockerfile @@ -0,0 +1,3 @@ +FROM ubuntu:latest + +CMD ["echo", "Success"] diff --git a/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/README-secret.md b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/README-secret.md new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/README.md b/src/test/resources/buildTests/dockerignore/IneffectiveDockerignorePattern/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/.dockerignore b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/.dockerignore new file mode 100644 index 000000000..d32df2a06 --- /dev/null +++ b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/.dockerignore @@ -0,0 +1,5 @@ +**/*.txt +parent/*/grandChild/README*.md +parent/anotherChild/README*.md +!parent/anotherChild/*/*.md +!parent/child \ No newline at end of file diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/Dockerfile b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/Dockerfile new file mode 100644 index 000000000..65fa210c7 --- /dev/null +++ b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/Dockerfile @@ -0,0 +1,3 @@ +FROM ubuntu:latest + +CMD ["echo", "Success"] diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/README.md b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/README.md new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/a.txt b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/a.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/README-child.md b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/README-child.md new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/grandChild/README-grand.md b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/grandChild/README-grand.md new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/grandChild/c.txt b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/anotherChild/grandChild/c.txt new file mode 100644 index 000000000..e69de29bb diff --git a/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/child/b.txt b/src/test/resources/buildTests/dockerignore/NestedDirsDockerignore/parent/child/b.txt new file mode 100644 index 000000000..e69de29bb From 5cf12cfbeec2b38f96915563e725d6e659fc025c Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 1 Aug 2016 20:50:45 +0300 Subject: [PATCH 212/855] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d28a9319..c8bf1d3c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ Change Log --- All changes +* Updated all dependencies +* [#643] (https://github.com/docker-java/docker-java/pull/643) Fixes for .dockerignore filtering * [#627] (https://github.com/docker-java/docker-java/pull/627) Implementation of POST /images/load endpoint * [#630] (https://github.com/docker-java/docker-java/pull/630) Fix: Second execution of a docker command in Netty implementation always fails * [#596] (https://github.com/docker-java/docker-java/pull/596) Refactor configuration of SSL to allow override with custom config From 1221eddda9a382734eb5bd25967a079fb2d20794 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 1 Aug 2016 23:02:31 +0300 Subject: [PATCH 213/855] Relax checkstyle --- src/test/resources/checkstyle/checkstyle-config.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/resources/checkstyle/checkstyle-config.xml b/src/test/resources/checkstyle/checkstyle-config.xml index 33508c723..76671ded3 100644 --- a/src/test/resources/checkstyle/checkstyle-config.xml +++ b/src/test/resources/checkstyle/checkstyle-config.xml @@ -92,7 +92,9 @@ - + + + From 6d8476e494280e122e4f2ef9b043d5870d28286f Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 1 Aug 2016 23:03:43 +0300 Subject: [PATCH 214/855] Document debug case (#641) * Document debug case --- docs/devel.adoc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/devel.adoc b/docs/devel.adoc index 50c6a7279..2305b89d0 100644 --- a/docs/devel.adoc +++ b/docs/devel.adoc @@ -23,3 +23,11 @@ * Integration tests for commands. * If model object has builders, then fill it with data and compare by `equals()` with expected response from docker daemon. If failed, then some fields mappings are wrong. + +### Debug + * When there are unreproducible Travis errors: + ** Try locally run test 10-20 times in IDE against the same docker daemon version and same connection type (tcp or socket). + ** Limit `.travis.yml` to single run (to not consume their resources with matrix run). + ** Remove `travis-logback.xml` replacement (build can't output everything in every run because travis has log limitation). + ** Set single test in `pom.xml` `for maven-failsafe-plugin` + ** Make PR or if you are maintainer push to branch, catch log and fix. From 227ca791733c73f2f7a413a1997c692931b37f85 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 1 Aug 2016 23:20:34 +0300 Subject: [PATCH 215/855] Disable java8 doc lint --- pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pom.xml b/pom.xml index 1d4328f9b..39695185b 100644 --- a/pom.xml +++ b/pom.xml @@ -352,6 +352,9 @@ jar + + -Xdoclint:none + From 0d9c3c3a70050557a9989e49f5fc1c777a08d625 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 1 Aug 2016 23:25:48 +0300 Subject: [PATCH 216/855] [maven-release-plugin] prepare release 3.0.1 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 39695185b..337dae2ed 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.1-SNAPSHOT + 3.0.1 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.1 From 4bd03a7e6162e2ef72c5365df1ea6d57f246688f Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 1 Aug 2016 23:25:56 +0300 Subject: [PATCH 217/855] [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 337dae2ed..d8db16134 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.1 + 3.0.2-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.1 + HEAD From fa3310dd02466b211c6d8256198b98533a1edb8a Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 1 Aug 2016 23:46:54 +0300 Subject: [PATCH 218/855] Update for release --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 159108dd8..1ec338523 100644 --- a/README.md +++ b/README.md @@ -21,8 +21,8 @@ Developer forum for [docker-java](https://groups.google.com/forum/?#!forum/docke ###### Prerequisites: -* Java 1.7 -* Maven 3.0.5 +* Java min 1.7 +* Maven 3 Build and run integration tests as follows: @@ -47,26 +47,26 @@ For secure tls (https) communication: DOCKER_HOST=tcp://127.0.0.1:2376 DOCKER_TLS_VERIFY=1 - DOCKER_CERT_PATH=/Users/marcus/.docker/machine/machines/docker-1.10.2 + DOCKER_CERT_PATH=/Users/marcus/.docker/machine/machines/docker-1.11.2 ### Latest release version -Supports a subset of the Docker Remote API [v1.22](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.22.md), Docker Server version 1.10.x +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 com.github.docker-java docker-java - 3.0.0 + 3.0.1 ### Latest development version -Supports a subset of the Docker Remote API [v1.22](https://github.com/docker/docker/blob/master/docs/reference/api/docker_remote_api_v1.22.md), Docker Server version 1.10.x +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 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/). com.github.docker-java docker-java - 3.0.1-SNAPSHOT + 3.0.2-SNAPSHOT @@ -82,7 +82,7 @@ There are a couple of configuration items, all of which have sensible defaults: * `DOCKER_TLS_VERIFY` enable/disable TLS verification (switch between `http` and `https` protocol) * `DOCKER_CERT_PATH` Path to the certificates needed for TLS verification * `DOCKER_CONFIG` Path for additional docker configuration files (like `.dockercfg`) -* `api.version` The API version, e.g. `1.21`. +* `api.version` The API version, e.g. `1.23`. * `registry.url` Your registry's address. * `registry.username` Your registry username (required to push containers). * `registry.password` Your registry password. @@ -98,7 +98,7 @@ In your application, e.g. .withDockerTlsVerify(true) .withDockerCertPath("/home/user/.docker/certs") .withDockerConfig("/home/user/.docker") - .withApiVersion("1.21") + .withApiVersion("1.23") .withRegistryUrl("https://index.docker.io/v1/") .withRegistryUsername("dockeruser") .withRegistryPassword("ilovedocker") @@ -112,7 +112,7 @@ In your application, e.g. DOCKER_TLS_VERIFY=1 DOCKER_CERT_PATH=/home/user/.docker/certs DOCKER_CONFIG=/home/user/.docker - api.version=1.21 + api.version=1.23 registry.url=https://index.docker.io/v1/ registry.username=dockeruser registry.password=ilovedocker From c2e4f2c54fdd136ee9c800a38bce4c160b7d5582 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 2 Aug 2016 01:36:09 +0300 Subject: [PATCH 219/855] Include integration tests (#652) --- pom.xml | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d8db16134..2e0523feb 100644 --- a/pom.xml +++ b/pom.xml @@ -508,13 +508,28 @@ prepare-agent + - report + post-unit-test test report + + + pre-integration-test + pre-integration-test + + prepare-agent-integration + + + + report-integration + + report-integration + + From da6b013dbc169caafad565fe244356981887d27b Mon Sep 17 00:00:00 2001 From: Alexander Koshevoy Date: Tue, 2 Aug 2016 15:37:58 +0300 Subject: [PATCH 220/855] Fix checkstyle of GoLangFileMatch --- .../dockerjava/core/GoLangFileMatch.java | 18 ++++++------------ .../exception/GoLangFileMatchException.java | 3 +++ 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java b/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java index 09d5e4978..b26b7db44 100644 --- a/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java +++ b/src/main/java/com/github/dockerjava/core/GoLangFileMatch.java @@ -154,8 +154,7 @@ private static String appendChunkPattern(StringBuilder patternStringBuilder, Str case '[': if (!isEsc) { if (inRange) { - //"[ is not expected, ] had not reached" - throw new GoLangFileMatchException(); + throw new GoLangFileMatchException("[ not expected, closing bracket ] not yet reached"); } rangeFrom = i; rangeParseState = RangeParseState.CHAR_EXPECTED; @@ -172,12 +171,10 @@ private static String appendChunkPattern(StringBuilder patternStringBuilder, Str case ']': if (!isEsc) { if (!inRange) { - //"] is not expected, [ was not met" - throw new GoLangFileMatchException(); + throw new GoLangFileMatchException("] is not expected, [ was not met"); } if (rangeParseState == RangeParseState.CHAR_EXPECTED_AFTER_DASH) { - // character range not finished - throw new GoLangFileMatchException(); + throw new GoLangFileMatchException("Character range not finished"); } patternStringBuilder.append(pattern.substring(rangeFrom, i + 1)); inRange = false; @@ -220,8 +217,7 @@ private static String appendChunkPattern(StringBuilder patternStringBuilder, Str } else { if (!isEsc) { if (rangeParseState != RangeParseState.CHAR_OR_DASH_EXPECTED) { - // - not expected - throw new GoLangFileMatchException(); + throw new GoLangFileMatchException("- character not expected"); } rangeParseState = RangeParseState.CHAR_EXPECTED_AFTER_DASH; } else { @@ -240,12 +236,10 @@ private static String appendChunkPattern(StringBuilder patternStringBuilder, Str } } if (isEsc) { - // "Escaped character missing" - throw new GoLangFileMatchException(); + throw new GoLangFileMatchException("Escaped character missing"); } if (inRange) { - // "Character range not finished" - throw new GoLangFileMatchException(); + throw new GoLangFileMatchException("Character range not finished"); } return ""; } diff --git a/src/main/java/com/github/dockerjava/core/exception/GoLangFileMatchException.java b/src/main/java/com/github/dockerjava/core/exception/GoLangFileMatchException.java index 3bbdc2a72..2d92389e7 100644 --- a/src/main/java/com/github/dockerjava/core/exception/GoLangFileMatchException.java +++ b/src/main/java/com/github/dockerjava/core/exception/GoLangFileMatchException.java @@ -7,4 +7,7 @@ public class GoLangFileMatchException extends IllegalArgumentException { private static final long serialVersionUID = -1204971075600864898L; + public GoLangFileMatchException(String s) { + super(s); + } } From b87e0d668a2dfd233fd4178cd6f4a1ae3ec6b9cf Mon Sep 17 00:00:00 2001 From: monksy Date: Tue, 2 Aug 2016 14:29:08 -0500 Subject: [PATCH 221/855] Fixed a bad implimentation reference DockerClientConfig is an interface and does not have a method called: DockerClientConfig.createDefaultConfigBuilder(). --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ec338523..feddb82a2 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ There are three ways to configure, in descending order of precedence: #### Programmatic: In your application, e.g. - DockerClientConfig config = DockerClientConfig.createDefaultConfigBuilder() + DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder() .withDockerHost("tcp://my-docker-host.tld:2376") .withDockerTlsVerify(true) .withDockerCertPath("/home/user/.docker/certs") From fd421d800e735efe3e860999e564f54d45219bcd Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 3 Aug 2016 03:13:53 +0300 Subject: [PATCH 222/855] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index feddb82a2..da474ff85 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.github.docker-java/docker-java.svg?maxAge=2592000)]() +[![Maven Central](https://img.shields.io/maven-central/v/com.github.docker-java/docker-java.svg)]() +[![Bintray](https://api.bintray.com/packages/kostyasha/maven/com.github.docker-java%3Adocker-java/images/download.svg)](https://bintray.com/kostyasha/maven/com.github.docker-java%3Adocker-java/_latestVersion) [![Reference Status](https://www.versioneye.com/java/com.github.docker-java:docker-java/reference_badge.svg?style=flat)](https://www.versioneye.com/java/com.github.docker-java:docker-java/references) [![Build Status](https://travis-ci.org/docker-java/docker-java.svg?branch=master)](https://travis-ci.org/docker-java/docker-java) [![Coverity Scan Build Status](https://scan.coverity.com/projects/9177/badge.svg?flat=1)](https://scan.coverity.com/projects/9177) From f355e6e756589804cd683e0da279435066a2dc61 Mon Sep 17 00:00:00 2001 From: Pavel Eremeev Date: Thu, 11 Aug 2016 01:31:06 +0300 Subject: [PATCH 223/855] Ability to set container shm size (#659) * Added setShmSize option to 'create container' command * Changed shmSize type to Long * Exposed hostConfig --- .../api/command/CreateContainerCmd.java | 6 ++++++ .../dockerjava/api/model/HostConfig.java | 6 +++--- .../core/command/CreateContainerCmdImpl.java | 11 +++++++++++ .../command/CreateContainerCmdImplTest.java | 18 ++++++++++++++++++ .../netty/exec/CreateContainerCmdExecTest.java | 18 ++++++++++++++++++ 5 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java index 196763560..77bf100ac 100644 --- a/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/CreateContainerCmd.java @@ -6,6 +6,7 @@ import com.github.dockerjava.api.model.Capability; import com.github.dockerjava.api.model.Device; import com.github.dockerjava.api.model.ExposedPort; +import com.github.dockerjava.api.model.HostConfig; import com.github.dockerjava.api.model.Link; import com.github.dockerjava.api.model.LogConfig; import com.github.dockerjava.api.model.LxcConf; @@ -187,6 +188,9 @@ public interface CreateContainerCmd extends SyncDockerCmd securityOpts) { /** * @see #shmSize */ - public HostConfig withShmSize(String shmSize) { + public HostConfig withShmSize(Long shmSize) { this.shmSize = shmSize; return this; } diff --git a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java index 0b6944b04..f3cfefa05 100644 --- a/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/CreateContainerCmdImpl.java @@ -472,6 +472,11 @@ public String getPidMode() { return hostConfig.getPidMode(); } + @Override + public HostConfig getHostConfig() { + return hostConfig; + } + @Override public String getCgroupParent() { return hostConfig.getCgroupParent(); @@ -976,6 +981,12 @@ public CreateContainerCmd withPidMode(String pidMode) { return this; } + @Override + public CreateContainerCmd withHostConfig(HostConfig hostConfig) { + this.hostConfig = hostConfig; + return this; + } + @Override public String toString() { return ToStringBuilder.reflectionToString(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 214bb2f4a..7babafc91 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -10,6 +10,7 @@ import com.github.dockerjava.api.model.Device; import com.github.dockerjava.api.model.ExposedPort; import com.github.dockerjava.api.model.Frame; +import com.github.dockerjava.api.model.HostConfig; import com.github.dockerjava.api.model.Link; import com.github.dockerjava.api.model.LogConfig; import com.github.dockerjava.api.model.Network; @@ -21,6 +22,7 @@ import com.github.dockerjava.api.model.Ports.Binding; import com.github.dockerjava.client.AbstractDockerClientTest; +import org.apache.commons.io.FileUtils; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -735,4 +737,20 @@ public void createContainerWithCgroupParent() throws DockerException { assertThat(inspectContainer.getHostConfig().getCgroupParent(), is("/parent")); } + + @SuppressWarnings("Duplicates") + @Test + public void createContainerWithShmSize() throws DockerException { + HostConfig hostConfig = new HostConfig().withShmSize(96 * FileUtils.ONE_MB); + 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(); + + assertEquals(inspectContainerResponse.getHostConfig().getShmSize(), hostConfig.getShmSize()); + } } 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 ec35f930a..2213ca7b7 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java @@ -9,6 +9,7 @@ import com.github.dockerjava.api.model.ContainerNetwork; import com.github.dockerjava.api.model.Device; import com.github.dockerjava.api.model.ExposedPort; +import com.github.dockerjava.api.model.HostConfig; import com.github.dockerjava.api.model.Link; import com.github.dockerjava.api.model.LogConfig; import com.github.dockerjava.api.model.Network; @@ -20,6 +21,7 @@ import com.github.dockerjava.api.model.VolumesFrom; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; +import org.apache.commons.io.FileUtils; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; @@ -676,4 +678,20 @@ public void createContainerWithCgroupParent() throws DockerException { assertThat(inspectContainer.getHostConfig().getCgroupParent(), is("/parent")); } + + @SuppressWarnings("Duplicates") + @Test + public void createContainerWithShmSize() throws DockerException { + HostConfig hostConfig = new HostConfig().withShmSize(96 * FileUtils.ONE_MB); + 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(); + + assertEquals(inspectContainerResponse.getHostConfig().getShmSize(), hostConfig.getShmSize()); + } } From 5893681e3969507afa4915ccab5636ee6c18f5b0 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 11 Aug 2016 11:25:29 +0300 Subject: [PATCH 224/855] [maven-release-plugin] prepare release 3.0.2 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 2e0523feb..0dfef8ca9 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.2-SNAPSHOT + 3.0.2 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.2 From 701aa0b25bf2c0ad0f3ec0096e287b1c6660a0c5 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 11 Aug 2016 11:25:35 +0300 Subject: [PATCH 225/855] [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 0dfef8ca9..208d52705 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.2 + 3.0.3-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.2 + HEAD From ee76c14d3b9340a3e1c0ed83d530a58afe424aa4 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 11 Aug 2016 11:38:33 +0300 Subject: [PATCH 226/855] Update CHANGELOG.md --- CHANGELOG.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8bf1d3c5..132f3c6b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,15 @@ Change Log === -3.0.1-SNAPSHOT ---- +## 3.0.3-SNAPSHOT + + +## 3.0.2 + * Enhanced Dockerignore filtering. + * Added shmsize for hostconfig. + * Exposed HostConfig instead of spaghetty calls. + +## 3.0.1 All changes * Updated all dependencies From e8f82e829befe25e6f45a4f8363c09a4af776a46 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 14 Aug 2016 16:36:33 +0300 Subject: [PATCH 227/855] Update .travis.yml (#654) --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index a9e93162a..ba8c62ad0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,12 +21,12 @@ env: - COVERITY_SCAN_NOTIFICATION_EMAIL="kanstantsin.sha@gmail.com" matrix: - - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.12.0-0~trusty" - - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.12.0-0~trusty" + - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.12.0-0~trusty" CODECOV=true + - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.12.0-0~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" - - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.10.3-0~trusty" - - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.10.3-0~trusty" + - 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 # - repo="testing" DOCKER_HOST="tcp://127.0.0.1:2375" # - repo="testing" DOCKER_HOST="unix:///var/run/docker.sock" # - repo="experimental" DOCKER_HOST="tcp://127.0.0.1:2375" From 7af8f8f4eacb13bd4de09dfaf14b8dffc63d733c Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 14 Aug 2016 17:06:05 +0300 Subject: [PATCH 228/855] Fix body request for jersey. --- .../github/dockerjava/jaxrs/StartContainerCmdExec.java | 10 +++++----- .../dockerjava/netty/exec/StartContainerCmdExec.java | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/github/dockerjava/jaxrs/StartContainerCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/StartContainerCmdExec.java index 0f75c4f2f..2851a26c7 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/StartContainerCmdExec.java +++ b/src/main/java/com/github/dockerjava/jaxrs/StartContainerCmdExec.java @@ -1,7 +1,5 @@ package com.github.dockerjava.jaxrs; -import static javax.ws.rs.client.Entity.entity; - import javax.ws.rs.client.WebTarget; import javax.ws.rs.core.MediaType; @@ -22,11 +20,13 @@ public StartContainerCmdExec(WebTarget baseResource, DockerClientConfig dockerCl @Override protected Void execute(StartContainerCmd command) { - WebTarget webResource = getBaseResource().path("/containers/{id}/start").resolveTemplate("id", - command.getContainerId()); + WebTarget webResource = getBaseResource().path("/containers/{id}/start") + .resolveTemplate("id", command.getContainerId()); LOGGER.trace("POST: {}", webResource); - webResource.request().accept(MediaType.APPLICATION_JSON).post(entity(command, MediaType.APPLICATION_JSON)) + webResource.request() + .accept(MediaType.APPLICATION_JSON) + .post(null) .close(); return null; diff --git a/src/main/java/com/github/dockerjava/netty/exec/StartContainerCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/StartContainerCmdExec.java index 12f2d8cbc..039006f2d 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/StartContainerCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/StartContainerCmdExec.java @@ -23,7 +23,9 @@ protected Void execute(StartContainerCmd command) { command.getContainerId()); LOGGER.trace("POST: {}", webResource); - webResource.request().accept(MediaType.APPLICATION_JSON).post(command); + webResource.request() + .accept(MediaType.APPLICATION_JSON) + .post(command); return null; } From 8a3108fbb5cd844fff8e7eaef4bf509fe8299227 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 14 Aug 2016 17:29:57 +0300 Subject: [PATCH 229/855] Fix integration tests --- .../get-docker-com.sh | 2 +- .travis/travis-before-install.sh | 53 +++++++++++++++++-- 2 files changed, 49 insertions(+), 6 deletions(-) rename get-docker-com.sh => .travis/get-docker-com.sh (99%) diff --git a/get-docker-com.sh b/.travis/get-docker-com.sh similarity index 99% rename from get-docker-com.sh rename to .travis/get-docker-com.sh index 66ca4aefc..d9c0142a2 100755 --- a/get-docker-com.sh +++ b/.travis/get-docker-com.sh @@ -310,4 +310,4 @@ do_install() { # wrapped up in a function so that we have some protection against only getting # half the file during "curl | sh" -do_install \ No newline at end of file +do_install diff --git a/.travis/travis-before-install.sh b/.travis/travis-before-install.sh index 13034fc74..6935f7a7d 100755 --- a/.travis/travis-before-install.sh +++ b/.travis/travis-before-install.sh @@ -3,6 +3,7 @@ sudo apt-get install -y -q ca-certificates +export HOST_PORT=2375 echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-certificates.crt @@ -21,7 +22,10 @@ sudo -E apt-get install -q -y wget sudo -E apt-get -q -y --purge remove docker-engine sudo -E apt-cache policy docker-engine -./get-docker-com.sh +./.travis/get-docker-com.sh + +sudo -E stop docker + #mkdir "${HOME}/.cache" || : #pushd "${HOME}/.cache" # wget -N "https://apt.dockerproject.org/repo/pool/main/d/docker-engine/docker-engine_${DOCKER_VERSION}_amd64.deb" @@ -31,10 +35,49 @@ sudo -E apt-cache policy docker-engine #rm -f "src/test/resources/logback.xml" mv "src/test/resources/travis-logback.xml" "src/test/resources/logback.xml" -echo 'DOCKER_OPTS="-H=unix:///var/run/docker.sock -H=tcp://127.0.0.1:2375"' | sudo tee -a /etc/default/docker -sudo -E restart docker -sleep 10 -docker version +# https://github.com/docker/docker/issues/18113 +sudo rm /var/lib/docker/network/files/local-kv.db + +sudo cat /etc/default/docker + +cat << EOF | sudo tee /etc/default/docker +DOCKER_OPTS="\ +--dns 8.8.8.8 \ +--dns 8.8.4.4 \ +-D \ +-H=unix:///var/run/docker.sock \ +-H=tcp://0.0.0.0:${HOST_PORT} \ +" +EOF + +sudo cat /etc/default/docker +sudo bash -c ':> /var/log/upstart/docker.log' + +date +sudo -E start docker + +tries=20 +sleep=5 +for i in $(seq 1 $tries); do + if sudo grep "API listen on" /var/log/upstart/docker.log ; then + echo "Docker started. Delay $(($i * $sleep))" + break + elif [[ $i -ge $tries ]]; then + echo "Docker didn't start. Exiting!" + sudo cat /var/log/upstart/docker.log + exit 1 + else + echo "Docker didn't start, sleeping for 5 secs..." + sleep $sleep + fi +done + + +sudo ss -antpl + +curl -V + +docker version || sudo cat /var/log/upstart/docker.log docker info set +u From 699080417ae678d77da5b46ef39a36810d620329 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 14 Aug 2016 21:30:49 +0300 Subject: [PATCH 230/855] Fix network test. --- .../command/ConnectToNetworkCmdImplTest.java | 40 ++++++++++++------ .../exec/ConnectToNetworkCmdExecTest.java | 41 +++++++++++++------ 2 files changed, 57 insertions(+), 24 deletions(-) diff --git a/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java index 84bb59a81..207d2a0d5 100644 --- a/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/ConnectToNetworkCmdImplTest.java @@ -3,6 +3,7 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.CreateNetworkResponse; import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.exception.DockerException; import com.github.dockerjava.api.model.ContainerNetwork; import com.github.dockerjava.api.model.Network; import com.github.dockerjava.client.AbstractDockerClientTest; @@ -16,6 +17,10 @@ import java.lang.reflect.Method; import java.util.Collections; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + @Test(groups = "integration") public class ConnectToNetworkCmdImplTest extends AbstractDockerClientTest { @@ -60,38 +65,49 @@ public void connectToNetwork() throws InterruptedException { @Test public void connectToNetworkWithContainerNetwork() throws InterruptedException { + final String NETWORK_SUBNET = "10.100.102.0/24"; + final String NETWORK_NAME = "jerseyTestNetwork"; + final String CONTAINER_IP = "10.100.102.100"; + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("sleep", "9999") + .exec(); - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); dockerClient.startContainerCmd(container.getId()).exec(); + try { + dockerClient.removeNetworkCmd(NETWORK_NAME).exec(); + } catch (DockerException ignore) { + } + CreateNetworkResponse network = dockerClient.createNetworkCmd() - .withName("testNetwork") + .withName(NETWORK_NAME) .withIpam(new Network.Ipam() - .withConfig(new Network.Ipam.Config() - .withSubnet("10.100.100.0/24"))) + .withConfig(new Network.Ipam.Config() + .withSubnet(NETWORK_SUBNET))) .exec(); dockerClient.connectToNetworkCmd() .withNetworkId(network.getId()) .withContainerId(container.getId()) .withContainerNetwork(new ContainerNetwork() - .withAliases("testing") - .withIpamConfig(new ContainerNetwork.Ipam() - .withIpv4Address("10.100.100.100"))) + .withAliases("aliasName") + .withIpamConfig(new ContainerNetwork.Ipam() + .withIpv4Address(CONTAINER_IP))) .exec(); Network updatedNetwork = dockerClient.inspectNetworkCmd().withNetworkId(network.getId()).exec(); Network.ContainerNetworkConfig containerNetworkConfig = updatedNetwork.getContainers().get(container.getId()); assertNotNull(containerNetworkConfig); - assertEquals(containerNetworkConfig.getIpv4Address(), "10.100.100.100/24"); + assertThat(containerNetworkConfig.getIpv4Address(), is(CONTAINER_IP + "/24")); InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); - ContainerNetwork testNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get("testNetwork"); + ContainerNetwork testNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get(NETWORK_NAME); assertNotNull(testNetwork); - assertEquals(testNetwork.getAliases(), Collections.singletonList("testing")); - assertEquals(testNetwork.getGateway(), "10.100.100.1"); - assertEquals(testNetwork.getIpAddress(), "10.100.100.100"); + assertThat(testNetwork.getAliases(), hasItem("aliasName")); + assertEquals(testNetwork.getGateway(), "10.100.102.1"); + assertEquals(testNetwork.getIpAddress(), CONTAINER_IP); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java index ee1a681b6..7e290a98e 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/ConnectToNetworkCmdExecTest.java @@ -3,6 +3,8 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.CreateNetworkResponse; import com.github.dockerjava.api.command.InspectContainerResponse; +import com.github.dockerjava.api.exception.DockerException; +import com.github.dockerjava.api.exception.NotFoundException; import com.github.dockerjava.api.model.ContainerNetwork; import com.github.dockerjava.api.model.Network; import com.github.dockerjava.netty.AbstractNettyDockerClientTest; @@ -17,6 +19,10 @@ import java.lang.reflect.Method; import java.util.Collections; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + @Test(groups = "integration") public class ConnectToNetworkCmdExecTest extends AbstractNettyDockerClientTest { @@ -61,38 +67,49 @@ public void connectToNetwork() throws InterruptedException { @Test public void connectToNetworkWithContainerNetwork() throws InterruptedException { + final String NETWORK_SUBNET = "10.100.101.0/24"; + final String NETWORK_NAME = "nettyTestNetwork"; + final String CONTAINER_IP = "10.100.101.100"; + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox") + .withCmd("sleep", "9999") + .exec(); - CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999").exec(); dockerClient.startContainerCmd(container.getId()).exec(); + try { + dockerClient.removeNetworkCmd(NETWORK_NAME).exec(); + } catch (DockerException ignore) { + } + CreateNetworkResponse network = dockerClient.createNetworkCmd() - .withName("testNetwork") + .withName(NETWORK_NAME) .withIpam(new Network.Ipam() - .withConfig(new Network.Ipam.Config() - .withSubnet("10.100.100.0/24"))) + .withConfig(new Network.Ipam.Config() + .withSubnet(NETWORK_SUBNET))) .exec(); dockerClient.connectToNetworkCmd() .withNetworkId(network.getId()) .withContainerId(container.getId()) .withContainerNetwork(new ContainerNetwork() - .withAliases("testing") - .withIpamConfig(new ContainerNetwork.Ipam() - .withIpv4Address("10.100.100.100"))) + .withAliases("aliasName") + .withIpamConfig(new ContainerNetwork.Ipam() + .withIpv4Address(CONTAINER_IP))) .exec(); Network updatedNetwork = dockerClient.inspectNetworkCmd().withNetworkId(network.getId()).exec(); Network.ContainerNetworkConfig containerNetworkConfig = updatedNetwork.getContainers().get(container.getId()); assertNotNull(containerNetworkConfig); - assertEquals(containerNetworkConfig.getIpv4Address(), "10.100.100.100/24"); + assertThat(containerNetworkConfig.getIpv4Address(), is(CONTAINER_IP + "/24")); InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); - ContainerNetwork testNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get("testNetwork"); + ContainerNetwork testNetwork = inspectContainerResponse.getNetworkSettings().getNetworks().get(NETWORK_NAME); assertNotNull(testNetwork); - assertEquals(testNetwork.getAliases(), Collections.singletonList("testing")); - assertEquals(testNetwork.getGateway(), "10.100.100.1"); - assertEquals(testNetwork.getIpAddress(), "10.100.100.100"); + assertThat(testNetwork.getAliases(), hasItem("aliasName")); + assertEquals(testNetwork.getGateway(), "10.100.101.1"); + assertEquals(testNetwork.getIpAddress(), CONTAINER_IP); } } From a68cf85da7918886c669e7ddc92e6c246046a4ea Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 14 Aug 2016 21:33:15 +0300 Subject: [PATCH 231/855] Fix create with alias tests. --- .../dockerjava/core/command/CreateContainerCmdImplTest.java | 2 +- .../dockerjava/netty/exec/CreateContainerCmdExecTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 7babafc91..1f62527e9 100644 --- a/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CreateContainerCmdImplTest.java @@ -375,7 +375,7 @@ public void createContainerWithAlias() throws DockerException { .exec(); ContainerNetwork aliasNet = inspectContainerResponse.getNetworkSettings().getNetworks().get("aliasNet"); - assertEquals(aliasNet.getAliases(), Collections.singletonList("server")); + assertThat(aliasNet.getAliases(), hasItem("server")); } @Test 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 2213ca7b7..3694ca7fb 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java @@ -370,7 +370,7 @@ public void createContainerWithAlias() throws DockerException { .exec(); ContainerNetwork aliasNet = inspectContainerResponse.getNetworkSettings().getNetworks().get("aliasNet"); - assertEquals(aliasNet.getAliases(), Collections.singletonList("server")); + assertThat(aliasNet.getAliases(), hasItem("server")); } @Test From af891e25521d6b09f0213f458be256933caded06 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 14 Aug 2016 21:38:58 +0300 Subject: [PATCH 232/855] Fix test for 1.24 --- src/main/java/com/github/dockerjava/api/DockerClient.java | 1 + .../core/command/CopyFileFromContainerCmdImplTest.java | 8 ++++++++ .../netty/exec/CopyFileFromContainerCmdExecTest.java | 7 +++++++ 3 files changed, 16 insertions(+) diff --git a/src/main/java/com/github/dockerjava/api/DockerClient.java b/src/main/java/com/github/dockerjava/api/DockerClient.java index 491c11ac8..832890e87 100644 --- a/src/main/java/com/github/dockerjava/api/DockerClient.java +++ b/src/main/java/com/github/dockerjava/api/DockerClient.java @@ -170,6 +170,7 @@ public interface DockerClient extends Closeable { * @return created command * @see #copyArchiveFromContainerCmd(String, String) * @deprecated since docker API version 1.20, replaced by {@link #copyArchiveFromContainerCmd(String, String)} + * since 1.24 fails. */ @Deprecated CopyFileFromContainerCmd copyFileFromContainerCmd(@Nonnull String containerId, @Nonnull String resource); diff --git a/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java index 8bd2c44fe..ec66287eb 100644 --- a/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/CopyFileFromContainerCmdImplTest.java @@ -1,5 +1,6 @@ package com.github.dockerjava.core.command; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.isEmptyOrNullString; import static org.hamcrest.Matchers.not; @@ -7,7 +8,10 @@ import java.io.InputStream; import java.lang.reflect.Method; +import com.github.dockerjava.core.RemoteApiVersion; +import com.github.dockerjava.utils.TestUtils; import org.testng.ITestResult; +import org.testng.SkipException; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeMethod; @@ -43,6 +47,10 @@ public void afterMethod(ITestResult result) { @Test public void copyFromContainer() throws Exception { + if (getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_24)) { + throw new SkipException("Doesn't work since 1.24"); + } + // TODO extract this into a shared method CreateContainerResponse container = dockerClient.createContainerCmd("busybox") .withName("docker-java-itest-copyFromContainer").withCmd("touch", "/copyFromContainer").exec(); diff --git a/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java index b512cfa69..1060ae82a 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CopyFileFromContainerCmdExecTest.java @@ -1,5 +1,6 @@ package com.github.dockerjava.netty.exec; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.isEmptyOrNullString; import static org.hamcrest.Matchers.not; @@ -7,7 +8,9 @@ import java.io.InputStream; 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; @@ -43,6 +46,10 @@ public void afterMethod(ITestResult result) { @Test public void copyFromContainer() throws Exception { + if (getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_24)) { + throw new SkipException("Doesn't work since 1.24"); + } + // TODO extract this into a shared method CreateContainerResponse container = dockerClient.createContainerCmd("busybox") .withName("docker-java-itest-copyFromContainer").withCmd("touch", "/copyFromContainer").exec(); From 78a2a007303f93211fca4398198f977cf4bba173 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 14 Aug 2016 21:39:09 +0300 Subject: [PATCH 233/855] Fix typo --- .../com/github/dockerjava/core/command/UnpauseCmdImplTest.java | 2 +- .../com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java | 2 +- src/test/java/com/github/dockerjava/utils/ContainerUtils.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test/java/com/github/dockerjava/core/command/UnpauseCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/UnpauseCmdImplTest.java index f640c4182..2f41b67ae 100644 --- a/src/test/java/com/github/dockerjava/core/command/UnpauseCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/UnpauseCmdImplTest.java @@ -56,7 +56,7 @@ public void unpausePausedContainer() { ContainerUtils.pauseContainer(dockerClient, container); - ContainerUtils.unpaseContainer(dockerClient, container); + ContainerUtils.unpauseContainer(dockerClient, container); } @Test(expectedExceptions = InternalServerErrorException.class) diff --git a/src/test/java/com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java b/src/test/java/com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java index db91bc9f9..cb30babc4 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/UnpauseCmdImplTest.java @@ -56,7 +56,7 @@ public void unpausePausedContainer() { ContainerUtils.pauseContainer(dockerClient, container); - ContainerUtils.unpaseContainer(dockerClient, container); + ContainerUtils.unpauseContainer(dockerClient, container); } @Test(expectedExceptions = InternalServerErrorException.class) diff --git a/src/test/java/com/github/dockerjava/utils/ContainerUtils.java b/src/test/java/com/github/dockerjava/utils/ContainerUtils.java index 75be6c4d9..206be0693 100644 --- a/src/test/java/com/github/dockerjava/utils/ContainerUtils.java +++ b/src/test/java/com/github/dockerjava/utils/ContainerUtils.java @@ -60,7 +60,7 @@ public static void stopContainer(DockerClient dockerClient, CreateContainerRespo * @param dockerClient docker client * @param container container */ - public static void unpaseContainer(DockerClient dockerClient, CreateContainerResponse container) { + public static void unpauseContainer(DockerClient dockerClient, CreateContainerResponse container) { dockerClient.unpauseContainerCmd(container.getId()).exec(); InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); From a520aaa56b0e8cb05dc7a84da7b04377418c2f55 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 15 Aug 2016 00:35:48 +0300 Subject: [PATCH 234/855] Fix test again? --- .../dockerjava/netty/exec/AttachContainerCmdExecTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java index 7daa59b25..d3e8094cf 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java @@ -93,7 +93,7 @@ public void attachContainerWithStdin() throws Exception { dockerClient.startContainerCmd(container.getId()).exec(); - Thread.sleep(SECONDS.toMillis(3)); //wait bash initialisation + Thread.sleep(SECONDS.toMillis(10)); //wait bash initialisation InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); From 03b1c72caced14037d3531a636508d48a16e874f Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 15 Aug 2016 13:58:19 +0300 Subject: [PATCH 235/855] Update CHANGELOG.md --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 132f3c6b1..64bea7c57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ Change Log === +## Next -## 3.0.3-SNAPSHOT - +## 3.0.3 + * [JERSEY] Don't send body for start container request. ## 3.0.2 * Enhanced Dockerignore filtering. From ec124aeee4edf771204dd1d8d7c680df65502610 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 15 Aug 2016 14:05:51 +0300 Subject: [PATCH 236/855] [maven-release-plugin] prepare release 3.0.3 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 208d52705..4327d0b60 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.3-SNAPSHOT + 3.0.3 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.3 From 76bfdc9f4da0a280310212a53ae959b6e66834a4 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 15 Aug 2016 14:05:57 +0300 Subject: [PATCH 237/855] [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 4327d0b60..586d2a209 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.3 + 3.0.4-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.3 + HEAD From 03b8bb0ceaa45f044ef8ded07a3edf194fd8cd68 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 15 Aug 2016 14:41:19 +0300 Subject: [PATCH 238/855] Don't fail build because of coverity --- .travis/travis-script.sh | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/.travis/travis-script.sh b/.travis/travis-script.sh index aeae555ef..1cdc84fa5 100755 --- a/.travis/travis-script.sh +++ b/.travis/travis-script.sh @@ -1,12 +1,34 @@ #!/usr/bin/env bash -set -ex + IS_COVERITY_SCAN_BRANCH=`ruby -e "puts '${TRAVIS_BRANCH}' =~ /\\A$COVERITY_SCAN_BRANCH_PATTERN\\z/ ? 1 : 0"` +export COVERITY_ALLOWED=true +# Verify upload is permitted +AUTH_RES=`curl -s --form project="$COVERITY_SCAN_PROJECT_NAME" --form token="$COVERITY_SCAN_TOKEN" $SCAN_URL/api/upload_permitted` +if [ "$AUTH_RES" = "Access denied" ]; then + echo -e "\033[33;1mCoverity Scan API access denied. Check COVERITY_SCAN_PROJECT_NAME and COVERITY_SCAN_TOKEN.\033[0m" + COVERITY_ALLOWED=false +else + AUTH=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['upload_permitted']"` + if [ "$AUTH" = "true" ]; then + echo -e "\033[33;1mCoverity Scan analysis authorized per quota.\033[0m" + else + WHEN=`echo $AUTH_RES | ruby -e "require 'rubygems'; require 'json'; puts JSON[STDIN.read]['next_upload_permitted_at']"` + echo -e "\033[33;1mCoverity Scan analysis NOT authorized until $WHEN.\033[0m" + + COVERITY_ALLOWED=false + fi +fi + +set -ex if [ "${FAST_BUILD}" == "true" ]; then - if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$COVERITY" == "true" ] && [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then + if [ "$TRAVIS_PULL_REQUEST" == "false" ] && + [ "$COVERITY" == "true" ] && + [ "$IS_COVERITY_SCAN_BRANCH" = "1" ] && + [ "$COVERITY_ALLOWED" == "true" ]; then export COVERITY_SCAN_BUILD_COMMAND="mvn package" #curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash ./.travis/travisci_build_coverity_scan.sh @@ -14,7 +36,10 @@ if [ "${FAST_BUILD}" == "true" ]; then mvn package fi else - if [ "$TRAVIS_PULL_REQUEST" == "false" ] && [ "$COVERITY" == "true" ] && [ "$IS_COVERITY_SCAN_BRANCH" = "1" ]; then + if [ "$TRAVIS_PULL_REQUEST" == "false" ] && + [ "$COVERITY" == "true" ] && + [ "$IS_COVERITY_SCAN_BRANCH" = "1" ] && + [ "$COVERITY_ALLOWED" == "true" ]; then export COVERITY_SCAN_BUILD_COMMAND="mvn verify" #curl -s "https://scan.coverity.com/scripts/travisci_build_coverity_scan.sh" | bash ./.travis/travisci_build_coverity_scan.sh From 26c0e277de537edfe623ea6ec531a08c5fbb296e Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 15 Aug 2016 14:48:52 +0300 Subject: [PATCH 239/855] Adjust developers --- pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pom.xml b/pom.xml index 586d2a209..a14a31e5f 100644 --- a/pom.xml +++ b/pom.xml @@ -32,6 +32,16 @@ + + marcuslinke + Marcus Linke + marcus.linke@gmx.de + + + kostyasha + Kanstantsin Shautsou + kanstantsin.sha@gmail.com + kpelykh Konstantin Pelykh From f2826175e86239c85a327c10ae98c181a8f6e762 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 15 Aug 2016 15:17:23 +0300 Subject: [PATCH 240/855] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index da474ff85..e65215648 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.1 + 3.0.3 ### 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.2-SNAPSHOT + 3.0.4-SNAPSHOT From b93d0636ef0e3c24966753c79273b19aba601d97 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 15 Aug 2016 19:59:42 +0300 Subject: [PATCH 241/855] Don't hide utils --- .../github/dockerjava/core/util/CertificateUtils.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) 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 c760331d6..b5a5dcae6 100644 --- a/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java +++ b/src/main/java/com/github/dockerjava/core/util/CertificateUtils.java @@ -72,7 +72,7 @@ public static KeyStore createKeyStore(final String keypem, final String certpem) /** * from "cert.pem" String */ - private static List loadCertificates(final String certpem) throws IOException, + public static List loadCertificates(final String certpem) throws IOException, CertificateException { final StringReader certReader = new StringReader(certpem); try (BufferedReader reader = new BufferedReader(certReader)) { @@ -83,7 +83,7 @@ private static List loadCertificates(final String certpem) throws I /** * "cert.pem" from reader */ - private static List loadCertificates(final Reader reader) throws IOException, + public static List loadCertificates(final Reader reader) throws IOException, CertificateException { try (PEMParser pemParser = new PEMParser(reader)) { List certificates = new ArrayList<>(); @@ -105,7 +105,7 @@ private static List loadCertificates(final Reader reader) throws IO * Return private key ("key.pem") from Reader */ @CheckForNull - private static PrivateKey loadPrivateKey(final Reader reader) throws IOException, NoSuchAlgorithmException, + public static PrivateKey loadPrivateKey(final Reader reader) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { try (PEMParser pemParser = new PEMParser(reader)) { Object readObject = pemParser.readObject(); @@ -138,7 +138,7 @@ private static PrivateKey loadPrivateKey(final Reader reader) throws IOException } @CheckForNull - private static PrivateKey guessKey(byte[] encodedKey) throws NoSuchAlgorithmException { + public static PrivateKey guessKey(byte[] encodedKey) throws NoSuchAlgorithmException { //no way to know, so iterate for (String guessFactory : new String[]{"RSA", "ECDSA"}) { try { @@ -157,7 +157,7 @@ private static PrivateKey guessKey(byte[] encodedKey) throws NoSuchAlgorithmExce * Return KeyPair from "key.pem" */ @CheckForNull - private static PrivateKey loadPrivateKey(final String keypem) throws IOException, NoSuchAlgorithmException, + public static PrivateKey loadPrivateKey(final String keypem) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { try (StringReader certReader = new StringReader(keypem); BufferedReader reader = new BufferedReader(certReader)) { From 203fa3903b76c0e539cb7de702dded78039853d9 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 15 Aug 2016 20:51:40 +0300 Subject: [PATCH 242/855] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64bea7c57..1011a4815 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ Change Log === ## Next +## 3.0.4 + * Make cert util methods public. + ## 3.0.3 * [JERSEY] Don't send body for start container request. From d2b511f45e14791887e1861044ca6d3cc4b44ff4 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 15 Aug 2016 20:57:23 +0300 Subject: [PATCH 243/855] [maven-release-plugin] prepare release 3.0.4 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a14a31e5f..854782b2c 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.4-SNAPSHOT + 3.0.4 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.4 From f751dc25cc9fc38c9e643a068e793d32f54c1664 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Mon, 15 Aug 2016 20:57:31 +0300 Subject: [PATCH 244/855] [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 854782b2c..6d1ccca18 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.4 + 3.0.5-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.4 + HEAD From 36d17ca42b9fd706b864ac3d11380bd8c4ccbac6 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Tue, 16 Aug 2016 22:07:15 +0300 Subject: [PATCH 245/855] Update devel.adoc https://github.com/jenkinsci/credentials-plugin/blob/master/CONTRIBUTING.md --- docs/devel.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/devel.adoc b/docs/devel.adoc index 2305b89d0..1b6295662 100644 --- a/docs/devel.adoc +++ b/docs/devel.adoc @@ -13,6 +13,7 @@ ** Provide full information on field: *** For models define API version with `@since {@link RemoteApiVersion#VERSION_1_X}`. ** getters/setters should refernce to field `@see #$field`. + * If it is `Serializable` it shall have a `serialVersionUID` field. Unless code has shipped to users, the initial value of the `serialVersionUID` field shall be `1L`. ### Coding style * TBD, some initial styling already enforced with checkstyle. From e95f78621d4c3aeb8fad9b79f8b5a1093a8e8547 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 Aug 2016 10:39:14 +0300 Subject: [PATCH 246/855] Update Events to 1.24 model (#669) * added event type in Event class #650 * added missing import for JsonProperty * added CheckForNull * Sync event model to 1.24 Signed-off-by: Kanstantsin Shautsou --- .../github/dockerjava/api/model/Event.java | 184 ++++++++++++++++-- .../dockerjava/api/model/EventActor.java | 77 ++++++++ .../dockerjava/api/model/EventType.java | 55 ++++++ .../dockerjava/api/model/EventsTest.java | 64 ++++++ .../resources/samples/1.24/events/docs1.json | 17 ++ 5 files changed, 384 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/github/dockerjava/api/model/EventActor.java create mode 100644 src/main/java/com/github/dockerjava/api/model/EventType.java create mode 100644 src/test/java/com/github/dockerjava/api/model/EventsTest.java create mode 100644 src/test/resources/samples/1.24/events/docs1.json diff --git a/src/main/java/com/github/dockerjava/api/model/Event.java b/src/main/java/com/github/dockerjava/api/model/Event.java index 202f5a350..b8024b5ee 100644 --- a/src/main/java/com/github/dockerjava/api/model/Event.java +++ b/src/main/java/com/github/dockerjava/api/model/Event.java @@ -1,10 +1,17 @@ package com.github.dockerjava.api.model; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.annotation.CheckForNull; + +import static org.apache.commons.lang.builder.ToStringStyle.SHORT_PREFIX_STYLE; /** * Representation of a Docker event. @@ -12,16 +19,60 @@ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) public class Event { + + /** + * @since 1.16 + */ + @JsonProperty("status") private String status; + /** + * @since 1.16 + */ + @JsonProperty("id") private String id; + /** + * @since 1.16 + */ + @JsonProperty("from") private String from; + /** + * ?? + */ + @JsonProperty("node") + private Node node; + + /* + * @since 1. + */ + @JsonProperty("Type") + private EventType type; + + /** + * @since 1.22 + */ + @JsonProperty("Action") + private String action; + + /** + * @since 1.22 + */ + @JsonProperty("Actor") + private EventActor actor; + + /** + * @since 1.16 + */ + @JsonProperty("time") private Long time; - @JsonIgnoreProperties - private Node node; + /** + * @since 1.21 + */ + @JsonProperty("timeNano") + private Long timeNano; /** * Default constructor for the deserialization. @@ -32,16 +83,12 @@ public Event() { /** * Constructor. * - * @param id - * Container ID - * @param status - * Status string. List of statuses is available in Docker API v.1.16 - * @param from - * Image, from which the container has been created - * @param time - * Event time The time is specified in milliseconds since January 1, 1970, 00:00:00 GMT - * @since TODO + * @param id Container ID + * @param status Status string. List of statuses is available in Docker API v.1.16 + * @param from Image, from which the container has been created + * @param time Event time The time is specified in milliseconds since January 1, 1970, 00:00:00 GMT + * @since 1.16 */ public Event(String status, String id, String from, Long time) { this.status = status; @@ -60,6 +107,14 @@ public String getStatus() { return status; } + /** + * @see #status + */ + public Event withStatus(String status) { + this.status = status; + return this; + } + /** * Get ID of docker container. * @@ -69,6 +124,14 @@ public String getId() { return id; } + /** + * @see #id + */ + public Event withId(String id) { + this.id = id; + return this; + } + /** * Get source image of the container. * @@ -78,6 +141,14 @@ public String getFrom() { return from; } + /** + * @see #from + */ + public Event withFrom(String from) { + this.from = from; + return this; + } + /** * Get the event time. The time is specified in milliseconds since January 1, 1970, 00:00:00 GMT * @@ -87,6 +158,30 @@ public Long getTime() { return time; } + /** + * @see #time + */ + public Event withTime(Long time) { + this.time = time; + return this; + } + + /** + * @see #timeNano + */ + @CheckForNull + public Long getTimeNano() { + return timeNano; + } + + /** + * @see #timeNano + */ + public Event withTimenano(Long timenano) { + this.timeNano = timenano; + return this; + } + /** * Returns the node when working against docker swarm */ @@ -94,8 +189,71 @@ public Node getNode() { return node; } + /** + * @see #node + */ + public Event withNode(Node node) { + this.node = node; + return this; + } + + @CheckForNull + public EventType getType() { + return type; + } + + /** + * @see #type + */ + public Event withType(EventType type) { + this.type = type; + return this; + } + + /** + * @see #action + */ + @CheckForNull + public String getAction() { + return action; + } + + /** + * @see #action + */ + public Event withAction(String action) { + this.action = action; + return this; + } + + /** + * @see #actor + */ + @CheckForNull + public EventActor getActor() { + return actor; + } + + /** + * @see #actor + */ + public Event withEventActor(EventActor actor) { + this.actor = actor; + return this; + } + @Override public String toString() { - return ToStringBuilder.reflectionToString(this); + return ToStringBuilder.reflectionToString(this, SHORT_PREFIX_STYLE); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); } } diff --git a/src/main/java/com/github/dockerjava/api/model/EventActor.java b/src/main/java/com/github/dockerjava/api/model/EventActor.java new file mode 100644 index 000000000..f7b0abbf3 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/EventActor.java @@ -0,0 +1,77 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import javax.annotation.CheckForNull; +import java.io.Serializable; +import java.util.Map; + +/** + * @author Kanstantsin Shautsou + * @since 1.22 + */ +public class EventActor implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * @since 1.22 + */ + @JsonProperty("ID") + private String id; + + /** + * @since 1.22 + */ + @JsonProperty("Attributes") + private Map attributes; + + /** + * @see #id + */ + @CheckForNull + public String getId() { + return id; + } + + /** + * @see #id + */ + public EventActor withId(String id) { + this.id = id; + return this; + } + + /** + * @see #attributes + */ + @CheckForNull + public Map getAttributes() { + return attributes; + } + + /** + * @see #attributes + */ + public EventActor withAttributes(Map attributes) { + this.attributes = attributes; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @Override + public boolean equals(Object o) { + return EqualsBuilder.reflectionEquals(this, o); + } + + @Override + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } +} diff --git a/src/main/java/com/github/dockerjava/api/model/EventType.java b/src/main/java/com/github/dockerjava/api/model/EventType.java new file mode 100644 index 000000000..697c1e429 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/EventType.java @@ -0,0 +1,55 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonValue; + +import javax.annotation.Nonnull; +import java.util.HashMap; +import java.util.Map; + +/** + * @since 1.24 + */ +public enum EventType { + /** + * @since 1.24 + */ + CONTAINER("container"), + + /** + * @since 1.24 + */ + DAEMON("daemon"), + + /** + * @since 1.24 + */ + IMAGE("image"), + NETWORK("network"), + PLUGIN("plugin"), + VOLUME("volume"); + + private static final Map EVENT_TYPES = new HashMap<>(); + + static { + for (EventType t : values()) { + EVENT_TYPES.put(t.name().toLowerCase(), t); + } + } + + private String value; + + EventType(@Nonnull String value) { + this.value = value; + } + + @JsonValue + public String getValue() { + return value; + } + + @JsonCreator + public static EventType forValue(String s) { + return EVENT_TYPES.get(s); + } +} diff --git a/src/test/java/com/github/dockerjava/api/model/EventsTest.java b/src/test/java/com/github/dockerjava/api/model/EventsTest.java new file mode 100644 index 000000000..ce62c7d5f --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/model/EventsTest.java @@ -0,0 +1,64 @@ +package com.github.dockerjava.api.model; + +import com.fasterxml.jackson.databind.JavaType; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.github.dockerjava.core.RemoteApiVersion; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.util.HashMap; + +import static com.github.dockerjava.api.model.EventType.CONTAINER; +import static com.github.dockerjava.test.serdes.JSONSamples.testRoundTrip; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.notNullValue; + +/** + * @author Kanstantsin Shautsou + */ +public class EventsTest { + + @Test + public void serderDocs1() throws IOException { + final ObjectMapper mapper = new ObjectMapper(); + final JavaType type = mapper.getTypeFactory().uncheckedSimpleType(Event.class); + + final Event event = testRoundTrip(RemoteApiVersion.VERSION_1_24, + "/events/docs1.json", + type + ); + + assertThat(event, notNullValue()); + assertThat(event.getType(), is(CONTAINER)); + assertThat(event.getAction(), is("create")); + assertThat(event.getId(), is("ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743")); + assertThat(event.getFrom(), is("alpine")); + assertThat(event.getTime(), is(1461943101L)); + assertThat(event.getNode(), nullValue()); + assertThat(event.getTimeNano(), is(1461943101381709551L)); + + final HashMap attributes = new HashMap<>(); + attributes.put("com.example.some-label", "some-label-value"); + attributes.put("image", "alpine"); + attributes.put("name", "my-container"); + + final EventActor actor = new EventActor() + .withId("ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743") + .withAttributes(attributes); + + final Event event1 = new Event() + .withType(CONTAINER) + .withStatus("create") + .withId("ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743") + .withFrom("alpine") + .withTime(1461943101L) + .withTimenano(1461943101381709551L) + .withAction("create") + .withEventActor(actor); + + assertThat(event1, equalTo(event)); + } +} diff --git a/src/test/resources/samples/1.24/events/docs1.json b/src/test/resources/samples/1.24/events/docs1.json new file mode 100644 index 000000000..f62f2284e --- /dev/null +++ b/src/test/resources/samples/1.24/events/docs1.json @@ -0,0 +1,17 @@ +{ + "status": "create", + "id": "ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743", + "from": "alpine", + "Type": "container", + "Action": "create", + "Actor": { + "ID": "ede54ee1afda366ab42f824e8a5ffd195155d853ceaec74a927f249ea270c743", + "Attributes": { + "com.example.some-label": "some-label-value", + "image": "alpine", + "name": "my-container" + } + }, + "time": 1461943101, + "timeNano": 1461943101381709551 +} From bb83b03207cd6a641616f1112a5a5f32d40f2467 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 Aug 2016 12:02:14 +0300 Subject: [PATCH 247/855] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1011a4815..bd6c2d278 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ Change Log === ## Next +## 3.0.5 + * Events updated to 1.24 API model. + ## 3.0.4 * Make cert util methods public. From af8374f622d442a81ae558fa757c03d879fa2848 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 Aug 2016 13:37:57 +0300 Subject: [PATCH 248/855] [maven-release-plugin] prepare release 3.0.5 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 6d1ccca18..00a4561b5 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.5-SNAPSHOT + 3.0.5 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.5 From 8c456c2334c656a6ca20cc502440fdf01175f577 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 Aug 2016 13:38:04 +0300 Subject: [PATCH 249/855] [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 00a4561b5..b1b6d96a9 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.5 + 3.0.6-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.5 + HEAD From 96d7ddbea9a442875b33406d81b9ea678c1fb5b1 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 17 Aug 2016 00:16:21 +0300 Subject: [PATCH 250/855] Make all models serializable --- .../dockerjava/api/model/AuthConfig.java | 4 +- .../api/model/AuthConfigurations.java | 4 +- .../dockerjava/api/model/AuthResponse.java | 6 +- .../com/github/dockerjava/api/model/Bind.java | 5 +- .../github/dockerjava/api/model/Binds.java | 4 +- .../api/model/BuildResponseItem.java | 1 - .../dockerjava/api/model/ChangeLog.java | 5 +- .../dockerjava/api/model/Container.java | 4 +- .../dockerjava/api/model/ContainerConfig.java | 4 +- .../api/model/ContainerHostConfig.java | 6 +- .../api/model/ContainerNetwork.java | 5 +- .../api/model/ContainerNetworkSettings.java | 5 +- .../dockerjava/api/model/ContainerPort.java | 4 +- .../github/dockerjava/api/model/Device.java | 4 +- .../dockerjava/api/model/DriverStatus.java | 7 ++- .../dockerjava/api/model/ErrorDetail.java | 6 +- .../dockerjava/api/model/ErrorResponse.java | 6 +- .../github/dockerjava/api/model/Event.java | 5 +- .../dockerjava/api/model/ExposedPort.java | 4 +- .../dockerjava/api/model/ExposedPorts.java | 4 +- .../github/dockerjava/api/model/Frame.java | 5 +- .../dockerjava/api/model/HostConfig.java | 4 +- .../dockerjava/api/model/Identifier.java | 8 ++- .../github/dockerjava/api/model/Image.java | 5 +- .../com/github/dockerjava/api/model/Info.java | 4 +- .../api/model/InfoRegistryConfig.java | 5 +- .../com/github/dockerjava/api/model/Link.java | 5 +- .../github/dockerjava/api/model/Links.java | 4 +- .../dockerjava/api/model/LogConfig.java | 4 +- .../github/dockerjava/api/model/LxcConf.java | 6 +- .../github/dockerjava/api/model/Network.java | 4 +- .../dockerjava/api/model/NetworkSettings.java | 4 +- .../com/github/dockerjava/api/model/Node.java | 5 +- .../dockerjava/api/model/PortBinding.java | 6 +- .../github/dockerjava/api/model/Ports.java | 4 +- .../dockerjava/api/model/Repository.java | 5 +- .../dockerjava/api/model/ResponseItem.java | 1 - .../dockerjava/api/model/RestartPolicy.java | 5 +- .../dockerjava/api/model/SearchItem.java | 5 +- .../dockerjava/api/model/Statistics.java | 4 +- .../github/dockerjava/api/model/Ulimit.java | 5 +- .../github/dockerjava/api/model/Version.java | 4 +- .../github/dockerjava/api/model/Volume.java | 5 +- .../dockerjava/api/model/VolumeBind.java | 6 +- .../dockerjava/api/model/VolumeBinds.java | 5 +- .../github/dockerjava/api/model/VolumeRW.java | 4 +- .../github/dockerjava/api/model/Volumes.java | 4 +- .../dockerjava/api/model/VolumesFrom.java | 4 +- .../dockerjava/api/model/VolumesRW.java | 5 +- .../dockerjava/api/model/WaitResponse.java | 5 +- .../api/ModelsSerializableTest.java | 63 +++++++++++++++++++ 51 files changed, 244 insertions(+), 52 deletions(-) create mode 100644 src/test/java/com/github/dockerjava/api/ModelsSerializableTest.java diff --git a/src/main/java/com/github/dockerjava/api/model/AuthConfig.java b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java index 849f26a21..074c6db61 100644 --- a/src/main/java/com/github/dockerjava/api/model/AuthConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/AuthConfig.java @@ -8,9 +8,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; import javax.annotation.CheckForNull; +import java.io.Serializable; @JsonInclude(Include.NON_NULL) -public class AuthConfig { +public class AuthConfig implements Serializable { + private static final long serialVersionUID = 1L; /** * For backwards compatibility. Make sure you update the properties if you change this. diff --git a/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java b/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java index e8edbc950..baa8fc0b4 100644 --- a/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java +++ b/src/main/java/com/github/dockerjava/api/model/AuthConfigurations.java @@ -1,11 +1,13 @@ package com.github.dockerjava.api.model; +import java.io.Serializable; import java.util.Map; import java.util.TreeMap; import com.fasterxml.jackson.annotation.JsonProperty; -public class AuthConfigurations { +public class AuthConfigurations implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("configs") private Map configs = new TreeMap<>(); 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 cb5d9df80..cd6908185 100644 --- a/src/main/java/com/github/dockerjava/api/model/AuthResponse.java +++ b/src/main/java/com/github/dockerjava/api/model/AuthResponse.java @@ -2,7 +2,11 @@ import com.fasterxml.jackson.annotation.JsonProperty; -public class AuthResponse { +import java.io.Serializable; + +public class AuthResponse implements Serializable { + private static final long serialVersionUID = 1L; + @JsonProperty("Status") private String status; diff --git a/src/main/java/com/github/dockerjava/api/model/Bind.java b/src/main/java/com/github/dockerjava/api/model/Bind.java index bf02bbad2..0995c87ac 100644 --- a/src/main/java/com/github/dockerjava/api/model/Bind.java +++ b/src/main/java/com/github/dockerjava/api/model/Bind.java @@ -3,11 +3,14 @@ import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; +import java.io.Serializable; + /** * Represents a host path being bind mounted as a {@link Volume} in a Docker container. * The Bind can be in read only or read write access mode. */ -public class Bind { +public class Bind implements Serializable { + private static final long serialVersionUID = 1L; private String path; diff --git a/src/main/java/com/github/dockerjava/api/model/Binds.java b/src/main/java/com/github/dockerjava/api/model/Binds.java index 917cfdcbd..b24c3208d 100644 --- a/src/main/java/com/github/dockerjava/api/model/Binds.java +++ b/src/main/java/com/github/dockerjava/api/model/Binds.java @@ -1,6 +1,7 @@ package com.github.dockerjava.api.model; import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -19,7 +20,8 @@ @JsonSerialize(using = Binds.Serializer.class) @JsonDeserialize(using = Binds.Deserializer.class) -public class Binds { +public class Binds implements Serializable { + private static final long serialVersionUID = 1L; private Bind[] binds; diff --git a/src/main/java/com/github/dockerjava/api/model/BuildResponseItem.java b/src/main/java/com/github/dockerjava/api/model/BuildResponseItem.java index a53a1df9a..7236be23d 100644 --- a/src/main/java/com/github/dockerjava/api/model/BuildResponseItem.java +++ b/src/main/java/com/github/dockerjava/api/model/BuildResponseItem.java @@ -8,7 +8,6 @@ */ @JsonIgnoreProperties(ignoreUnknown = true) public class BuildResponseItem extends ResponseItem { - private static final long serialVersionUID = -1252904184236343612L; private static final String BUILD_SUCCESS = "Successfully built"; diff --git a/src/main/java/com/github/dockerjava/api/model/ChangeLog.java b/src/main/java/com/github/dockerjava/api/model/ChangeLog.java index 36804362c..04b36f5ce 100644 --- a/src/main/java/com/github/dockerjava/api/model/ChangeLog.java +++ b/src/main/java/com/github/dockerjava/api/model/ChangeLog.java @@ -5,13 +5,16 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + /** * * @author Konstantin Pelykh (kpelykh@gmail.com) * */ @JsonIgnoreProperties(ignoreUnknown = true) -public class ChangeLog { +public class ChangeLog implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("Path") private String path; diff --git a/src/main/java/com/github/dockerjava/api/model/Container.java b/src/main/java/com/github/dockerjava/api/model/Container.java index 47492920d..9e04362ce 100644 --- a/src/main/java/com/github/dockerjava/api/model/Container.java +++ b/src/main/java/com/github/dockerjava/api/model/Container.java @@ -11,6 +11,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import javax.annotation.CheckForNull; +import java.io.Serializable; import java.util.Map; /** @@ -20,7 +21,8 @@ */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) -public class Container { +public class Container implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("Command") private String command; 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 224da3272..191126798 100644 --- a/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/ContainerConfig.java @@ -10,6 +10,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import javax.annotation.CheckForNull; +import java.io.Serializable; import java.util.Map; /** @@ -19,7 +20,8 @@ */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) -public class ContainerConfig { +public class ContainerConfig implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("AttachStderr") private Boolean attachStderr; diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java b/src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java index 43a5a94b1..8d0c3fe37 100644 --- a/src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/ContainerHostConfig.java @@ -6,6 +6,8 @@ import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; +import java.io.Serializable; + /** * Used in {@link Container} * @@ -13,7 +15,9 @@ * @author Kanstantsin Shautsou */ @JsonIgnoreProperties(ignoreUnknown = true) -public class ContainerHostConfig { +public class ContainerHostConfig implements Serializable { + private static final long serialVersionUID = 1L; + @JsonProperty("NetworkMode") private String networkMode; diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java b/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java index 9b2160e98..bc7e12d33 100644 --- a/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java +++ b/src/main/java/com/github/dockerjava/api/model/ContainerNetwork.java @@ -9,6 +9,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import javax.annotation.CheckForNull; +import java.io.Serializable; import java.util.Arrays; import java.util.List; @@ -21,7 +22,9 @@ * @author Kanstantsin Shautsou */ @JsonIgnoreProperties(ignoreUnknown = true) -public class ContainerNetwork { +public class ContainerNetwork implements Serializable { + private static final long serialVersionUID = 1L; + /** * FIXME verify */ diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java b/src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java index 7f4b17be5..bc6165874 100644 --- a/src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java +++ b/src/main/java/com/github/dockerjava/api/model/ContainerNetworkSettings.java @@ -7,6 +7,7 @@ import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.lang.builder.ToStringBuilder; +import java.io.Serializable; import java.util.Map; /** @@ -16,7 +17,9 @@ * @since {@link RemoteApiVersion#VERSION_1_22} */ @JsonIgnoreProperties(ignoreUnknown = true) -public class ContainerNetworkSettings { +public class ContainerNetworkSettings implements Serializable { + private static final long serialVersionUID = 1L; + /** * @since {@link RemoteApiVersion#VERSION_1_22} */ diff --git a/src/main/java/com/github/dockerjava/api/model/ContainerPort.java b/src/main/java/com/github/dockerjava/api/model/ContainerPort.java index 09f718ef6..5924e53df 100644 --- a/src/main/java/com/github/dockerjava/api/model/ContainerPort.java +++ b/src/main/java/com/github/dockerjava/api/model/ContainerPort.java @@ -7,13 +7,15 @@ import org.apache.commons.lang.builder.ToStringBuilder; import javax.annotation.CheckForNull; +import java.io.Serializable; /** * @author Kanstantsin Shautsou * @see Container */ @JsonIgnoreProperties(ignoreUnknown = true) -public class ContainerPort { +public class ContainerPort implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("IP") private String ip; diff --git a/src/main/java/com/github/dockerjava/api/model/Device.java b/src/main/java/com/github/dockerjava/api/model/Device.java index f2b75e3f5..7d73710fd 100644 --- a/src/main/java/com/github/dockerjava/api/model/Device.java +++ b/src/main/java/com/github/dockerjava/api/model/Device.java @@ -12,12 +12,14 @@ import com.fasterxml.jackson.annotation.JsonProperty; import javax.annotation.Nonnull; +import java.io.Serializable; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; @JsonInclude(Include.NON_NULL) -public class Device { +public class Device implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("CgroupPermissions") private String cGroupPermissions = ""; diff --git a/src/main/java/com/github/dockerjava/api/model/DriverStatus.java b/src/main/java/com/github/dockerjava/api/model/DriverStatus.java index 3e2b5037a..7c1374aae 100644 --- a/src/main/java/com/github/dockerjava/api/model/DriverStatus.java +++ b/src/main/java/com/github/dockerjava/api/model/DriverStatus.java @@ -7,12 +7,15 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + /** - * Created by ben on 12/12/13. + * @author ben */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) -public class DriverStatus { +public class DriverStatus implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("Root Dir") private String rootDir; diff --git a/src/main/java/com/github/dockerjava/api/model/ErrorDetail.java b/src/main/java/com/github/dockerjava/api/model/ErrorDetail.java index 62018a4e0..92e869d2a 100644 --- a/src/main/java/com/github/dockerjava/api/model/ErrorDetail.java +++ b/src/main/java/com/github/dockerjava/api/model/ErrorDetail.java @@ -4,8 +4,12 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + @JsonInclude(Include.NON_NULL) -public class ErrorDetail { +public class ErrorDetail implements Serializable { + private static final long serialVersionUID = 1L; + @JsonProperty private String message; diff --git a/src/main/java/com/github/dockerjava/api/model/ErrorResponse.java b/src/main/java/com/github/dockerjava/api/model/ErrorResponse.java index 172bd5c79..f6abfc3eb 100644 --- a/src/main/java/com/github/dockerjava/api/model/ErrorResponse.java +++ b/src/main/java/com/github/dockerjava/api/model/ErrorResponse.java @@ -4,8 +4,12 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + @JsonInclude(Include.NON_NULL) -public class ErrorResponse { +public class ErrorResponse implements Serializable { + private static final long serialVersionUID = 1L; + @JsonProperty private ErrorDetail errorDetail; diff --git a/src/main/java/com/github/dockerjava/api/model/Event.java b/src/main/java/com/github/dockerjava/api/model/Event.java index b8024b5ee..6e4b6f3c2 100644 --- a/src/main/java/com/github/dockerjava/api/model/Event.java +++ b/src/main/java/com/github/dockerjava/api/model/Event.java @@ -13,12 +13,15 @@ import static org.apache.commons.lang.builder.ToStringStyle.SHORT_PREFIX_STYLE; +import java.io.Serializable; + /** * Representation of a Docker event. */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) -public class Event { +public class Event implements Serializable { + private static final long serialVersionUID = 1L; /** * @since 1.16 diff --git a/src/main/java/com/github/dockerjava/api/model/ExposedPort.java b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java index ec95f6273..26d727ff4 100644 --- a/src/main/java/com/github/dockerjava/api/model/ExposedPort.java +++ b/src/main/java/com/github/dockerjava/api/model/ExposedPort.java @@ -4,6 +4,7 @@ import static com.github.dockerjava.api.model.InternetProtocol.UDP; import java.io.IOException; +import java.io.Serializable; import java.util.Map.Entry; import org.apache.commons.lang.builder.EqualsBuilder; @@ -30,7 +31,8 @@ */ @JsonDeserialize(using = ExposedPort.Deserializer.class) @JsonSerialize(using = ExposedPort.Serializer.class) -public class ExposedPort { +public class ExposedPort implements Serializable { + private static final long serialVersionUID = 1L; private final InternetProtocol protocol; diff --git a/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java b/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java index 0ecb879b6..7670212e1 100644 --- a/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java +++ b/src/main/java/com/github/dockerjava/api/model/ExposedPorts.java @@ -1,6 +1,7 @@ package com.github.dockerjava.api.model; import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -21,7 +22,8 @@ @JsonSerialize(using = ExposedPorts.Serializer.class) @JsonDeserialize(using = ExposedPorts.Deserializer.class) -public class ExposedPorts { +public class ExposedPorts implements Serializable { + private static final long serialVersionUID = 1L; private ExposedPort[] exposedPorts; diff --git a/src/main/java/com/github/dockerjava/api/model/Frame.java b/src/main/java/com/github/dockerjava/api/model/Frame.java index 0ad16e8c6..9b1376f82 100644 --- a/src/main/java/com/github/dockerjava/api/model/Frame.java +++ b/src/main/java/com/github/dockerjava/api/model/Frame.java @@ -1,11 +1,14 @@ package com.github.dockerjava.api.model; +import java.io.Serializable; import java.util.Arrays; /** * Represents a logging frame. */ -public class Frame { +public class Frame implements Serializable { + private static final long serialVersionUID = 1L; + private final StreamType streamType; private final byte[] payload; 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 5dada65cc..062082a03 100644 --- a/src/main/java/com/github/dockerjava/api/model/HostConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/HostConfig.java @@ -11,6 +11,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import javax.annotation.CheckForNull; +import java.io.Serializable; import java.util.Arrays; import java.util.List; @@ -20,7 +21,8 @@ */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) -public class HostConfig { +public class HostConfig implements Serializable { + private static final long serialVersionUID = 1L; private static final List PREDEFINED_NETWORKS = Arrays.asList("bridge", "host", "none"); diff --git a/src/main/java/com/github/dockerjava/api/model/Identifier.java b/src/main/java/com/github/dockerjava/api/model/Identifier.java index 1051d857f..8f1c871a7 100644 --- a/src/main/java/com/github/dockerjava/api/model/Identifier.java +++ b/src/main/java/com/github/dockerjava/api/model/Identifier.java @@ -3,10 +3,14 @@ import com.google.common.base.Objects; import com.google.common.base.Optional; +import java.io.Serializable; + /** - * Created by magnayn on 22/07/2014. + * @author magnayn */ -public class Identifier { +public class Identifier implements Serializable { + private static final long serialVersionUID = 1L; + public final Repository repository; public final Optional tag; diff --git a/src/main/java/com/github/dockerjava/api/model/Image.java b/src/main/java/com/github/dockerjava/api/model/Image.java index 496db275e..78fee9f79 100644 --- a/src/main/java/com/github/dockerjava/api/model/Image.java +++ b/src/main/java/com/github/dockerjava/api/model/Image.java @@ -7,6 +7,8 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + /** * * @author Konstantin Pelykh (kpelykh@gmail.com) @@ -14,7 +16,8 @@ */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) -public class Image { +public class Image implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("Created") private Long created; diff --git a/src/main/java/com/github/dockerjava/api/model/Info.java b/src/main/java/com/github/dockerjava/api/model/Info.java index 7270eceb8..51abe5dac 100644 --- a/src/main/java/com/github/dockerjava/api/model/Info.java +++ b/src/main/java/com/github/dockerjava/api/model/Info.java @@ -9,6 +9,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import javax.annotation.CheckForNull; +import java.io.Serializable; import java.util.List; import java.util.Map; @@ -19,7 +20,8 @@ */ @JsonInclude(Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -public class Info { +public class Info implements Serializable { + private static final long serialVersionUID = 1L; /** * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} diff --git a/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java b/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java index 956aaebe3..2c2be5cfd 100644 --- a/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/InfoRegistryConfig.java @@ -7,6 +7,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import javax.annotation.CheckForNull; +import java.io.Serializable; import java.util.List; import java.util.Map; @@ -14,7 +15,9 @@ * @since ~{@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_20} */ @JsonIgnoreProperties(ignoreUnknown = true) -public final class InfoRegistryConfig { +public final class InfoRegistryConfig implements Serializable { + private static final long serialVersionUID = 1L; + @JsonProperty("IndexConfigs") private Map indexConfigs; diff --git a/src/main/java/com/github/dockerjava/api/model/Link.java b/src/main/java/com/github/dockerjava/api/model/Link.java index 89647306c..346aedcb0 100644 --- a/src/main/java/com/github/dockerjava/api/model/Link.java +++ b/src/main/java/com/github/dockerjava/api/model/Link.java @@ -3,12 +3,15 @@ import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; +import java.io.Serializable; + /** * Represents a network link between two Docker containers. The container with the name {@link #getName()} is made available in the target * container with the aliased name {@link #getAlias()}. This involves creating an entry in /etc/hosts and some environment * variables in the target container as well as creating a network bridge between both containers. */ -public class Link { +public class Link implements Serializable { + private static final long serialVersionUID = 1L; private final String name; diff --git a/src/main/java/com/github/dockerjava/api/model/Links.java b/src/main/java/com/github/dockerjava/api/model/Links.java index 2d678b3a3..1eb66ae42 100644 --- a/src/main/java/com/github/dockerjava/api/model/Links.java +++ b/src/main/java/com/github/dockerjava/api/model/Links.java @@ -1,6 +1,7 @@ package com.github.dockerjava.api.model; import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -20,7 +21,8 @@ @JsonSerialize(using = Links.Serializer.class) @JsonDeserialize(using = Links.Deserializer.class) -public class Links { +public class Links implements Serializable { + private static final long serialVersionUID = 1L; private final Link[] links; 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 f4fd0e958..e2a066101 100644 --- a/src/main/java/com/github/dockerjava/api/model/LogConfig.java +++ b/src/main/java/com/github/dockerjava/api/model/LogConfig.java @@ -1,6 +1,7 @@ package com.github.dockerjava.api.model; import java.io.IOException; +import java.io.Serializable; import java.util.Map; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -26,7 +27,8 @@ * docker will ignore them. In most cases setting the config option to null will suffice. Consult the docker remote API for a more detailed * and up-to-date explanation of the available types and their options. */ -public class LogConfig { +public class LogConfig implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("Type") public LoggingType type = null; diff --git a/src/main/java/com/github/dockerjava/api/model/LxcConf.java b/src/main/java/com/github/dockerjava/api/model/LxcConf.java index aeb854285..0a60086fb 100644 --- a/src/main/java/com/github/dockerjava/api/model/LxcConf.java +++ b/src/main/java/com/github/dockerjava/api/model/LxcConf.java @@ -4,8 +4,12 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + @JsonInclude(Include.NON_NULL) -public class LxcConf { +public class LxcConf implements Serializable { + private static final long serialVersionUID = 1L; + @JsonProperty("Key") public String key; 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 6f4114914..c0f9f36eb 100644 --- a/src/main/java/com/github/dockerjava/api/model/Network.java +++ b/src/main/java/com/github/dockerjava/api/model/Network.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.apache.commons.lang.builder.ToStringBuilder; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -12,7 +13,8 @@ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) -public class Network { +public class Network implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("Id") private String id; diff --git a/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java b/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java index 1d523bf4b..8fcd8fb9b 100644 --- a/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java +++ b/src/main/java/com/github/dockerjava/api/model/NetworkSettings.java @@ -8,6 +8,7 @@ import com.github.dockerjava.core.RemoteApiVersion; import org.apache.commons.lang.builder.ToStringBuilder; +import java.io.Serializable; import java.util.Map; /** @@ -16,7 +17,8 @@ * */ @JsonIgnoreProperties(ignoreUnknown = true) -public class NetworkSettings { +public class NetworkSettings implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("Bridge") private String bridge; diff --git a/src/main/java/com/github/dockerjava/api/model/Node.java b/src/main/java/com/github/dockerjava/api/model/Node.java index 9e8580e0a..89b391c0a 100644 --- a/src/main/java/com/github/dockerjava/api/model/Node.java +++ b/src/main/java/com/github/dockerjava/api/model/Node.java @@ -4,11 +4,14 @@ import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + /** * A node as returned by the /events API, for instance, when Swarm is used. */ @JsonInclude(Include.NON_NULL) -public class Node { +public class Node implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("Name") private String name; diff --git a/src/main/java/com/github/dockerjava/api/model/PortBinding.java b/src/main/java/com/github/dockerjava/api/model/PortBinding.java index e163272d7..9a30b6cd2 100644 --- a/src/main/java/com/github/dockerjava/api/model/PortBinding.java +++ b/src/main/java/com/github/dockerjava/api/model/PortBinding.java @@ -6,6 +6,8 @@ import com.github.dockerjava.api.model.Ports.Binding; +import java.io.Serializable; + /** * In a {@link PortBinding}, a network socket on the Docker host, expressed as a {@link Binding}, is bound to an {@link ExposedPort} of a * container. A {@link PortBinding} corresponds to the --publish (-p) option of the docker run (and @@ -15,7 +17,9 @@ * existing port bindings from a container configuration in {@link NetworkSettings#getPorts()} and {@link HostConfig#getPortBindings()}. In * that context, a Map<ExposedPort, Binding[]> is used. */ -public class PortBinding { +public class PortBinding implements Serializable { + private static final long serialVersionUID = 1L; + private final Binding binding; private final ExposedPort exposedPort; diff --git a/src/main/java/com/github/dockerjava/api/model/Ports.java b/src/main/java/com/github/dockerjava/api/model/Ports.java index 904a31c4e..673852d9e 100644 --- a/src/main/java/com/github/dockerjava/api/model/Ports.java +++ b/src/main/java/com/github/dockerjava/api/model/Ports.java @@ -16,6 +16,7 @@ import org.apache.commons.lang.builder.EqualsBuilder; import java.io.IOException; +import java.io.Serializable; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -35,7 +36,8 @@ @SuppressWarnings(value = "checkstyle:equalshashcode") @JsonDeserialize(using = Ports.Deserializer.class) @JsonSerialize(using = Ports.Serializer.class) -public class Ports { +public class Ports implements Serializable { + private static final long serialVersionUID = 1L; private final Map ports = new HashMap(); diff --git a/src/main/java/com/github/dockerjava/api/model/Repository.java b/src/main/java/com/github/dockerjava/api/model/Repository.java index 1e814a1b5..f4e4b9ab8 100644 --- a/src/main/java/com/github/dockerjava/api/model/Repository.java +++ b/src/main/java/com/github/dockerjava/api/model/Repository.java @@ -1,5 +1,6 @@ package com.github.dockerjava.api.model; +import java.io.Serializable; import java.net.MalformedURLException; import java.net.URL; @@ -8,7 +9,9 @@ /** * A repository or image name. */ -public class Repository { +public class Repository implements Serializable { + private static final long serialVersionUID = 1L; + public final String name; /** diff --git a/src/main/java/com/github/dockerjava/api/model/ResponseItem.java b/src/main/java/com/github/dockerjava/api/model/ResponseItem.java index 12a090db8..6663b4bf0 100644 --- a/src/main/java/com/github/dockerjava/api/model/ResponseItem.java +++ b/src/main/java/com/github/dockerjava/api/model/ResponseItem.java @@ -15,7 +15,6 @@ */ @JsonIgnoreProperties(ignoreUnknown = true) public class ResponseItem implements Serializable { - private static final long serialVersionUID = -5187169652557467828L; @JsonProperty("stream") 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 ac6c4a318..1f77b8b9d 100644 --- a/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java +++ b/src/main/java/com/github/dockerjava/api/model/RestartPolicy.java @@ -7,6 +7,8 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + /** * Container restart policy * @@ -26,7 +28,8 @@ * @author Marcus Linke * */ -public class RestartPolicy { +public class RestartPolicy implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("MaximumRetryCount") private Integer maximumRetryCount = 0; diff --git a/src/main/java/com/github/dockerjava/api/model/SearchItem.java b/src/main/java/com/github/dockerjava/api/model/SearchItem.java index 0a5843838..4e1663655 100644 --- a/src/main/java/com/github/dockerjava/api/model/SearchItem.java +++ b/src/main/java/com/github/dockerjava/api/model/SearchItem.java @@ -5,13 +5,16 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + /** * * @author Konstantin Pelykh (kpelykh@gmail.com) * */ @JsonIgnoreProperties(ignoreUnknown = true) -public class SearchItem { +public class SearchItem implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("star_count") private Integer starCount; 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 21b9ca923..cf8c1b77e 100644 --- a/src/main/java/com/github/dockerjava/api/model/Statistics.java +++ b/src/main/java/com/github/dockerjava/api/model/Statistics.java @@ -1,5 +1,6 @@ package com.github.dockerjava.api.model; +import java.io.Serializable; import java.util.Map; import javax.annotation.CheckForNull; @@ -16,7 +17,8 @@ */ @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(Include.NON_NULL) -public class Statistics { +public class Statistics implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("read") private String read; diff --git a/src/main/java/com/github/dockerjava/api/model/Ulimit.java b/src/main/java/com/github/dockerjava/api/model/Ulimit.java index 7427fb0cc..abcf298bd 100644 --- a/src/main/java/com/github/dockerjava/api/model/Ulimit.java +++ b/src/main/java/com/github/dockerjava/api/model/Ulimit.java @@ -7,10 +7,13 @@ import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + /** * @author Vangie Du (duwan@live.com) */ -public class Ulimit { +public class Ulimit implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("Name") private String name; diff --git a/src/main/java/com/github/dockerjava/api/model/Version.java b/src/main/java/com/github/dockerjava/api/model/Version.java index 004c85f22..f08c411e2 100644 --- a/src/main/java/com/github/dockerjava/api/model/Version.java +++ b/src/main/java/com/github/dockerjava/api/model/Version.java @@ -8,6 +8,7 @@ import org.apache.commons.lang.builder.ToStringBuilder; import javax.annotation.CheckForNull; +import java.io.Serializable; /** * Used for `/version` @@ -16,7 +17,8 @@ * @see VersionCmd */ @JsonIgnoreProperties(ignoreUnknown = true) -public class Version { +public class Version implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("ApiVersion") private String apiVersion; diff --git a/src/main/java/com/github/dockerjava/api/model/Volume.java b/src/main/java/com/github/dockerjava/api/model/Volume.java index 655a8dbfc..46989f79c 100644 --- a/src/main/java/com/github/dockerjava/api/model/Volume.java +++ b/src/main/java/com/github/dockerjava/api/model/Volume.java @@ -3,12 +3,15 @@ import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; +import java.io.Serializable; + /** * Represents a bind mounted volume in a Docker container. * * @see Bind */ -public class Volume { +public class Volume implements Serializable { + private static final long serialVersionUID = 1L; private String path; diff --git a/src/main/java/com/github/dockerjava/api/model/VolumeBind.java b/src/main/java/com/github/dockerjava/api/model/VolumeBind.java index cf9c077ab..f78fc587e 100644 --- a/src/main/java/com/github/dockerjava/api/model/VolumeBind.java +++ b/src/main/java/com/github/dockerjava/api/model/VolumeBind.java @@ -1,6 +1,10 @@ package com.github.dockerjava.api.model; -public class VolumeBind { +import java.io.Serializable; + +public class VolumeBind implements Serializable { + private static final long serialVersionUID = 1L; + private final String hostPath; private final String containerPath; diff --git a/src/main/java/com/github/dockerjava/api/model/VolumeBinds.java b/src/main/java/com/github/dockerjava/api/model/VolumeBinds.java index d8303ec84..aeef19e9f 100644 --- a/src/main/java/com/github/dockerjava/api/model/VolumeBinds.java +++ b/src/main/java/com/github/dockerjava/api/model/VolumeBinds.java @@ -1,6 +1,7 @@ package com.github.dockerjava.api.model; import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -22,7 +23,9 @@ // This is not going to be serialized @JsonDeserialize(using = VolumeBinds.Deserializer.class) @JsonSerialize(using = VolumeBinds.Serializer.class) -public class VolumeBinds { +public class VolumeBinds implements Serializable { + private static final long serialVersionUID = 1L; + private final VolumeBind[] binds; public VolumeBinds(VolumeBind... binds) { diff --git a/src/main/java/com/github/dockerjava/api/model/VolumeRW.java b/src/main/java/com/github/dockerjava/api/model/VolumeRW.java index 7c4bdfb26..229cee3ed 100644 --- a/src/main/java/com/github/dockerjava/api/model/VolumeRW.java +++ b/src/main/java/com/github/dockerjava/api/model/VolumeRW.java @@ -1,6 +1,7 @@ package com.github.dockerjava.api.model; import java.io.IOException; +import java.io.Serializable; import java.util.Map.Entry; import org.apache.commons.lang.builder.EqualsBuilder; @@ -29,7 +30,8 @@ @JsonDeserialize(using = VolumeRW.Deserializer.class) @JsonSerialize(using = VolumeRW.Serializer.class) @Deprecated -public class VolumeRW { +public class VolumeRW implements Serializable { + private static final long serialVersionUID = 1L; private Volume volume; diff --git a/src/main/java/com/github/dockerjava/api/model/Volumes.java b/src/main/java/com/github/dockerjava/api/model/Volumes.java index 46175548d..3246b0e8e 100644 --- a/src/main/java/com/github/dockerjava/api/model/Volumes.java +++ b/src/main/java/com/github/dockerjava/api/model/Volumes.java @@ -1,6 +1,7 @@ package com.github.dockerjava.api.model; import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -21,7 +22,8 @@ @JsonSerialize(using = Volumes.Serializer.class) @JsonDeserialize(using = Volumes.Deserializer.class) -public class Volumes { +public class Volumes implements Serializable { + private static final long serialVersionUID = 1L; private Volume[] volumes; diff --git a/src/main/java/com/github/dockerjava/api/model/VolumesFrom.java b/src/main/java/com/github/dockerjava/api/model/VolumesFrom.java index f027b6d71..fb52ff3f7 100644 --- a/src/main/java/com/github/dockerjava/api/model/VolumesFrom.java +++ b/src/main/java/com/github/dockerjava/api/model/VolumesFrom.java @@ -1,6 +1,7 @@ package com.github.dockerjava.api.model; import java.io.IOException; +import java.io.Serializable; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; @@ -19,7 +20,8 @@ @JsonSerialize(using = VolumesFrom.Serializer.class) @JsonDeserialize(using = VolumesFrom.Deserializer.class) -public class VolumesFrom { +public class VolumesFrom implements Serializable { + private static final long serialVersionUID = 1L; private String container; diff --git a/src/main/java/com/github/dockerjava/api/model/VolumesRW.java b/src/main/java/com/github/dockerjava/api/model/VolumesRW.java index f54f8242c..1b12bd13d 100644 --- a/src/main/java/com/github/dockerjava/api/model/VolumesRW.java +++ b/src/main/java/com/github/dockerjava/api/model/VolumesRW.java @@ -1,6 +1,7 @@ package com.github.dockerjava.api.model; import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -22,7 +23,9 @@ // This is not going to be serialized @JsonSerialize(using = VolumesRW.Serializer.class) @JsonDeserialize(using = VolumesRW.Deserializer.class) -public class VolumesRW { +public class VolumesRW implements Serializable { + private static final long serialVersionUID = 1L; + private final VolumeRW[] volumesRW; public VolumesRW(VolumeRW... binds) { diff --git a/src/main/java/com/github/dockerjava/api/model/WaitResponse.java b/src/main/java/com/github/dockerjava/api/model/WaitResponse.java index a2ab16f6f..0cab338b2 100644 --- a/src/main/java/com/github/dockerjava/api/model/WaitResponse.java +++ b/src/main/java/com/github/dockerjava/api/model/WaitResponse.java @@ -3,11 +3,14 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonProperty; +import java.io.Serializable; + /** * Represents a wait container command response */ @JsonIgnoreProperties(ignoreUnknown = true) -public class WaitResponse { +public class WaitResponse implements Serializable { + private static final long serialVersionUID = 1L; @JsonProperty("StatusCode") private Integer statusCode; diff --git a/src/test/java/com/github/dockerjava/api/ModelsSerializableTest.java b/src/test/java/com/github/dockerjava/api/ModelsSerializableTest.java new file mode 100644 index 000000000..770b136c9 --- /dev/null +++ b/src/test/java/com/github/dockerjava/api/ModelsSerializableTest.java @@ -0,0 +1,63 @@ +package com.github.dockerjava.api; + +import com.github.dockerjava.api.model.Binds; +import com.github.dockerjava.api.model.BuildResponseItem; +import com.github.dockerjava.api.model.PullResponseItem; +import com.github.dockerjava.api.model.PushResponseItem; +import com.github.dockerjava.api.model.ResponseItem; +import com.google.common.reflect.ClassPath.ClassInfo; +import org.apache.commons.lang.reflect.FieldUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import java.io.IOException; +import java.io.Serializable; +import java.util.Arrays; +import java.util.List; + +import static com.google.common.reflect.ClassPath.from; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.object.IsCompatibleType.typeCompatibleWith; +import static org.junit.Assert.assertThat; + +/** + * @author Kanstantsin Shautsou + */ +public class ModelsSerializableTest { + private static final Logger LOG = LoggerFactory.getLogger(ModelsSerializableTest.class); + + private List excludeClasses = Arrays.asList( + Binds.class.getName(), + BuildResponseItem.class.getName(), + PullResponseItem.class.getName(), + PushResponseItem.class.getName(), + ResponseItem.class.getName() + ); + + @Test + public void allModelsSerializable() throws IOException, NoSuchFieldException, IllegalAccessException { + final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + for (ClassInfo classInfo : from(contextClassLoader).getTopLevelClasses("com.github.dockerjava.api.model")) { + if (classInfo.getName().endsWith("Test")) { + continue; + } + + final Class aClass = classInfo.load(); + if (aClass.getProtectionDomain().getCodeSource().getLocation().getPath().endsWith("test-classes/") + || aClass.isEnum()) { + continue; + } + + LOG.debug("aClass: {}", aClass); + assertThat(aClass, typeCompatibleWith(Serializable.class)); + + final Object serialVersionUID = FieldUtils.readDeclaredStaticField(aClass, "serialVersionUID", true); + if (!excludeClasses.contains(aClass.getName())) { + assertThat(serialVersionUID, instanceOf(Long.class)); + assertThat("Follow devel docs", (Long) serialVersionUID, is(1L)); + } + } + } +} From 0183bd6271d09be07c38bfdda27d473f44f34225 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 19 Aug 2016 00:46:48 +0300 Subject: [PATCH 251/855] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd6c2d278..e2361ea85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ Change Log === ## Next +## 3.0.7 + * Make all models Serializable + ## 3.0.5 * Events updated to 1.24 API model. From e7c5f278fcf783023a6a94c422da50aa85c84437 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 19 Aug 2016 00:47:09 +0300 Subject: [PATCH 252/855] Typo --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2361ea85..8582d4eef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ Change Log === ## Next -## 3.0.7 +## 3.0.6 * Make all models Serializable ## 3.0.5 From 75309ffdeed2dcca8e679e6580a308f2e61527aa Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 19 Aug 2016 02:13:36 +0300 Subject: [PATCH 253/855] Add maven-central link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e65215648..039657807 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Maven Central](https://img.shields.io/maven-central/v/com.github.docker-java/docker-java.svg)]() +[![Maven Central](https://img.shields.io/maven-central/v/com.github.docker-java/docker-java.svg)](https://mvnrepository.com/artifact/com.github.docker-java/docker-java) [![Bintray](https://api.bintray.com/packages/kostyasha/maven/com.github.docker-java%3Adocker-java/images/download.svg)](https://bintray.com/kostyasha/maven/com.github.docker-java%3Adocker-java/_latestVersion) [![Reference Status](https://www.versioneye.com/java/com.github.docker-java:docker-java/reference_badge.svg?style=flat)](https://www.versioneye.com/java/com.github.docker-java:docker-java/references) [![Build Status](https://travis-ci.org/docker-java/docker-java.svg?branch=master)](https://travis-ci.org/docker-java/docker-java) From c8ab23f0609cb2323114f5ce41cdce87627f956e Mon Sep 17 00:00:00 2001 From: tejksat Date: Sun, 28 Aug 2016 18:00:03 +0300 Subject: [PATCH 254/855] Fix for #670 (#680) JSON decoding disabled on /images/load command execution. --- .../dockerjava/netty/InvocationBuilder.java | 31 +++++++++++++++++++ .../netty/exec/LoadImageCmdExec.java | 7 ++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java index 9669d6818..d76918bcb 100644 --- a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java +++ b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java @@ -69,6 +69,12 @@ public void onNext(T object) { } } + public class SkipResultCallback extends ResultCallbackTemplate, Void> { + @Override + public void onNext(Void object) { + } + } + private ChannelProvider channelProvider; private String resource; @@ -401,6 +407,31 @@ public void post(TypeReference typeReference, ResultCallback resultCal channel.pipeline().addLast(new JsonObjectDecoder()); channel.pipeline().addLast(jsonResponseHandler); + postChunkedStreamRequest(requestProvider, channel, body); + } + + public void postStream(InputStream body) { + SkipResultCallback resultCallback = new SkipResultCallback(); + + HttpRequestProvider requestProvider = httpPostRequestProvider(null); + + Channel channel = getChannel(); + + HttpResponseHandler responseHandler = new HttpResponseHandler(requestProvider, resultCallback); + + channel.pipeline().addLast(new ChunkedWriteHandler()); + channel.pipeline().addLast(responseHandler); + + postChunkedStreamRequest(requestProvider, channel, body); + + try { + resultCallback.awaitCompletion(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + private void postChunkedStreamRequest(HttpRequestProvider requestProvider, Channel channel, InputStream body) { HttpRequest request = requestProvider.getHttpRequest(resource); // don't accept FullHttpRequest here diff --git a/src/main/java/com/github/dockerjava/netty/exec/LoadImageCmdExec.java b/src/main/java/com/github/dockerjava/netty/exec/LoadImageCmdExec.java index 23581119f..30ee716a5 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/LoadImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/LoadImageCmdExec.java @@ -3,7 +3,6 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.fasterxml.jackson.core.type.TypeReference; import com.github.dockerjava.api.command.LoadImageCmd; import com.github.dockerjava.core.DockerClientConfig; import com.github.dockerjava.netty.WebTarget; @@ -22,8 +21,8 @@ protected Void execute(LoadImageCmd command) { WebTarget webResource = getBaseResource().path("/images/load"); LOGGER.trace("POST: {}", webResource); - return webResource.request() - .post(new TypeReference() { - }, command.getImageStream()); + webResource.request().postStream(command.getImageStream()); + + return null; } } From f44616f0808e1caede610594a769327a38158687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Kubry=C5=84ski?= Date: Sun, 28 Aug 2016 17:43:31 +0200 Subject: [PATCH 255/855] Fix #682 - Add LogPath to docker inspect response (#683) * Fix #682 - Add LogPath to docker inspect response * Fix #682 - Add LogPath to docker inspect response - fixes after code review * Fix #682 - Add LogPath to docker inspect response - add javadoc * Fix #682 - Add LogPath to docker inspect response - clean test assertion --- .../api/command/InspectContainerResponse.java | 11 +++++++++++ .../api/command/InspectContainerResponseTest.java | 2 ++ 2 files changed, 13 insertions(+) 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 59a267e9d..c8027b0ed 100644 --- a/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java +++ b/src/main/java/com/github/dockerjava/api/command/InspectContainerResponse.java @@ -53,6 +53,12 @@ public class InspectContainerResponse { @JsonProperty("HostsPath") private String hostsPath; + /** + * @since {@link RemoteApiVersion#VERSION_1_17} + */ + @JsonProperty("LogPath") + private String logPath; + @JsonProperty("Id") private String id; @@ -168,6 +174,11 @@ public String getHostsPath() { return hostsPath; } + @CheckForNull + public String getLogPath() { + return logPath; + } + public String getName() { return name; } 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 f64cf4ead..cd4562b4a 100644 --- a/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java +++ b/src/test/java/com/github/dockerjava/api/command/InspectContainerResponseTest.java @@ -22,6 +22,7 @@ import static com.github.dockerjava.test.serdes.JSONTestHelper.testRoundTrip; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.core.IsNot.not; @@ -51,6 +52,7 @@ public void roundTrip_full() throws IOException { assertEquals(response.getVolumesRW()[1].getVolume().getPath(), "/bar/foo/myvol2"); assertFalse(response.getVolumesRW()[1].getAccessMode().toBoolean()); assertTrue(response.getVolumesRW()[0].getAccessMode().toBoolean()); + assertThat(response.getLogPath(), is("/mnt/sda1/var/lib/docker/containers/469e5edd8d5b33e3c905a7ffc97360ec6ee211d6782815fbcd144568045819e1/469e5edd8d5b33e3c905a7ffc97360ec6ee211d6782815fbcd144568045819e1-json.log")); } @Test From bcb2ab947ff1020dfd89838a29d540bf802e2e31 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 28 Aug 2016 18:45:25 +0300 Subject: [PATCH 256/855] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8582d4eef..735283ae8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ Change Log ## Next ## 3.0.6 - * Make all models Serializable + * Make all models Serializable. + * [NETTY] Fix loadImage responce on 1.24 API. + * LogPath field for inspect container. ## 3.0.5 * Events updated to 1.24 API model. From d9f6969e0c8bb7756c0d4301b23688477e3da2d5 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Sun, 28 Aug 2016 21:10:49 +0300 Subject: [PATCH 257/855] Wait more for this test --- .../dockerjava/netty/exec/AttachContainerCmdExecTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java index d3e8094cf..8b5759c69 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java @@ -115,7 +115,7 @@ public void onNext(Frame frame) { .withFollowStream(true) .withStdIn(stdin) .exec(callback) - .awaitCompletion(15, SECONDS); + .awaitCompletion(30, SECONDS); callback.close(); assertThat(callback.toString(), containsString(snippet)); From 615c89f30ee301ba47bd5ef82a7549b251a7be5f Mon Sep 17 00:00:00 2001 From: tejksat Date: Wed, 31 Aug 2016 01:05:13 +0300 Subject: [PATCH 258/855] Fix for #687 --- .../exec/AttachContainerCmdExecTest.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java index 8b5759c69..66219dc72 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/AttachContainerCmdExecTest.java @@ -6,11 +6,10 @@ import static org.hamcrest.Matchers.isEmptyString; import static org.hamcrest.Matchers.not; -import java.io.ByteArrayInputStream; import java.io.File; -import java.io.InputStream; +import java.io.PipedInputStream; +import java.io.PipedOutputStream; import java.lang.reflect.Method; -import java.util.concurrent.TimeUnit; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; @@ -93,8 +92,6 @@ public void attachContainerWithStdin() throws Exception { dockerClient.startContainerCmd(container.getId()).exec(); - Thread.sleep(SECONDS.toMillis(10)); //wait bash initialisation - InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); assertTrue(inspectContainerResponse.getState().getRunning()); @@ -107,15 +104,20 @@ public void onNext(Frame frame) { } }; - InputStream stdin = new ByteArrayInputStream((snippet + "\n").getBytes()); + PipedOutputStream out = new PipedOutputStream(); + PipedInputStream in = new PipedInputStream(out); dockerClient.attachContainerCmd(container.getId()) .withStdErr(true) .withStdOut(true) .withFollowStream(true) - .withStdIn(stdin) - .exec(callback) - .awaitCompletion(30, SECONDS); + .withStdIn(in) + .exec(callback); + + out.write((snippet + "\n").getBytes()); + out.flush(); + + callback.awaitCompletion(15, SECONDS); callback.close(); assertThat(callback.toString(), containsString(snippet)); From 74d506dca45c0cc64f567311227c7108ca0101c6 Mon Sep 17 00:00:00 2001 From: tejksat Date: Mon, 5 Sep 2016 08:42:35 +0300 Subject: [PATCH 259/855] Fix http response input stream resource leak (#633) there are several problems in the original code: - not releasing `ByteBuf` queued; - queuing `ByteBuf` until all data is read what effectively leads to `OutOfDirectMemoryError` if the data read is too big. This happens if you try to copy too big file or folder from a container. To fix this `ResponseCallback` (which in `awaitResult()` waits in fact for `readComplete()` channel method invocation) replaced with `AsyncResultCallback`; - actually queuing `ByteBuf` anyway leads to `OutOfDirectMemoryError` if data consumption is slower (the next point) than obtaining it; - poor performance because of the byte-by-byte reads. --- .../dockerjava/netty/InvocationBuilder.java | 56 ++++++- .../handler/HttpResponseStreamHandler.java | 137 ++++++++++++++---- .../netty/exec/SaveImageCmdExecTest.java | 5 +- .../HttpResponseStreamHandlerTest.java | 90 +++++++++++- 4 files changed, 249 insertions(+), 39 deletions(-) diff --git a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java index d76918bcb..26b950e4e 100644 --- a/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java +++ b/src/main/java/com/github/dockerjava/netty/InvocationBuilder.java @@ -27,6 +27,7 @@ import java.io.InputStream; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.CountDownLatch; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; @@ -75,6 +76,57 @@ public void onNext(Void object) { } } + /** + * Implementation of {@link ResultCallback} with the single result event expected. + */ + public static class AsyncResultCallback + extends ResultCallbackTemplate, A_RES_T> { + + private A_RES_T result = null; + + private final CountDownLatch resultReady = new CountDownLatch(1); + + @Override + public void onNext(A_RES_T object) { + onResult(object); + } + + private void onResult(A_RES_T object) { + if (resultReady.getCount() == 0) { + throw new IllegalStateException("Result has already been set"); + } + + try { + result = object; + } finally { + resultReady.countDown(); + } + } + + @Override + public void close() throws IOException { + try { + super.close(); + } finally { + resultReady.countDown(); + } + } + + /** + * Blocks until {@link ResultCallback#onNext(Object)} was called for the first time + */ + @SuppressWarnings("unchecked") + public A_RES_T awaitResult() { + try { + resultReady.await(); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + getFirstError(); + return result; + } + } + private ChannelProvider channelProvider; private String resource; @@ -203,7 +255,7 @@ public InputStream post(final Object entity) { Channel channel = getChannel(); - ResponseCallback callback = new ResponseCallback(); + AsyncResultCallback callback = new AsyncResultCallback<>(); HttpResponseHandler responseHandler = new HttpResponseHandler(requestProvider, callback); HttpResponseStreamHandler streamHandler = new HttpResponseStreamHandler(callback); @@ -454,7 +506,7 @@ public InputStream get() { Channel channel = getChannel(); - ResponseCallback resultCallback = new ResponseCallback(); + AsyncResultCallback resultCallback = new AsyncResultCallback<>(); HttpResponseHandler responseHandler = new HttpResponseHandler(requestProvider, resultCallback); diff --git a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java index 706228d04..596334640 100644 --- a/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java +++ b/src/main/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandler.java @@ -6,9 +6,6 @@ import java.io.IOException; import java.io.InputStream; -import java.util.concurrent.LinkedTransferQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import com.github.dockerjava.api.async.ResultCallback; @@ -19,45 +16,87 @@ */ public class HttpResponseStreamHandler extends SimpleChannelInboundHandler { - private HttpResponseInputStream stream = new HttpResponseInputStream(); + private ResultCallback resultCallback; + + private final HttpResponseInputStream stream = new HttpResponseInputStream(); public HttpResponseStreamHandler(ResultCallback resultCallback) { - resultCallback.onNext(stream); + this.resultCallback = resultCallback; } @Override protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) throws Exception { + invokeCallbackOnFirstRead(); + stream.write(msg.copy()); } + private void invokeCallbackOnFirstRead() { + if (resultCallback != null) { + resultCallback.onNext(stream); + resultCallback = null; + } + } + @Override - public void channelReadComplete(ChannelHandlerContext ctx) throws Exception { - stream.close(); - super.channelReadComplete(ctx); + public void channelInactive(ChannelHandlerContext ctx) throws Exception { + stream.writeComplete(); + + super.channelInactive(ctx); } public static class HttpResponseInputStream extends InputStream { - private AtomicBoolean closed = new AtomicBoolean(false); + private boolean writeCompleted = false; - private LinkedTransferQueue queue = new LinkedTransferQueue(); + private boolean closed = false; private ByteBuf current = null; - public void write(ByteBuf byteBuf) { - queue.put(byteBuf); + private final Object lock = new Object(); + + public void write(ByteBuf byteBuf) throws InterruptedException { + synchronized (lock) { + if (closed) { + return; + } + while (current != null) { + lock.wait(); + + if (closed) { + return; + } + } + current = byteBuf; + + lock.notifyAll(); + } + } + + public void writeComplete() { + synchronized (lock) { + writeCompleted = true; + + lock.notifyAll(); + } } @Override public void close() throws IOException { - closed.set(true); - super.close(); + synchronized (lock) { + closed = true; + releaseCurrent(); + + lock.notifyAll(); + } } @Override public int available() throws IOException { - poll(); - return readableBytes(); + synchronized (lock) { + poll(0); + return readableBytes(); + } } private int readableBytes() { @@ -66,34 +105,72 @@ private int readableBytes() { } else { return 0; } - } @Override public int read() throws IOException { + byte[] b = new byte[1]; + int n = read(b, 0, 1); + return n != -1 ? b[0] : -1; + } - poll(); + @Override + public int read(byte[] b, int off, int len) throws IOException { + synchronized (lock) { + off = poll(off); - if (readableBytes() == 0) { - if (closed.get()) { + if (current == null) { return -1; + } else { + int availableBytes = Math.min(len, current.readableBytes() - off); + current.readBytes(b, off, availableBytes); + return availableBytes; } } + } - if (current != null && current.readableBytes() > 0) { - return current.readByte() & 0xff; - } else { - return read(); + private int poll(int off) throws IOException { + synchronized (lock) { + while (readableBytes() <= off) { + try { + if (closed) { + throw new IOException("Stream closed"); + } + + off -= releaseCurrent(); + if (writeCompleted) { + return off; + } + while (current == null) { + lock.wait(); + + if (closed) { + throw new IOException("Stream closed"); + } + if (writeCompleted && current == null) { + return off; + } + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + return off; } } - private void poll() { - if (readableBytes() == 0) { - try { - current = queue.poll(50, TimeUnit.MILLISECONDS); - } catch (InterruptedException e) { - throw new RuntimeException(e); + private int releaseCurrent() { + synchronized (lock) { + if (current != null) { + int n = current.readableBytes(); + current.release(); + current = null; + + lock.notifyAll(); + + return n; } + return 0; } } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/SaveImageCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/SaveImageCmdExecTest.java index 0527b793f..a2fab38a7 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/SaveImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/SaveImageCmdExecTest.java @@ -47,8 +47,9 @@ public void afterMethod(ITestResult result) { @Test public void saveImage() throws Exception { - InputStream image = IOUtils.toBufferedInputStream(dockerClient.saveImageCmd("busybox").exec()); - assertThat(image.available(), greaterThan(0)); + try (InputStream image = dockerClient.saveImageCmd("busybox").exec()) { + assertThat(image.available(), greaterThan(0)); + } } diff --git a/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java index 6652f3eba..eea9ddc0f 100644 --- a/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java +++ b/src/test/java/com/github/dockerjava/netty/handler/HttpResponseStreamHandlerTest.java @@ -1,13 +1,21 @@ package com.github.dockerjava.netty.handler; +import static com.github.dockerjava.netty.handler.HttpResponseStreamHandler.HttpResponseInputStream; +import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; -import java.io.InputStream; - import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufInputStream; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; + +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + import org.apache.commons.io.IOUtils; import org.mockito.Mockito; import org.testng.annotations.Test; @@ -25,9 +33,81 @@ public void testNoBytesSkipped() throws Exception { ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); ByteBuf buffer = generateByteBuf(); streamHandler.channelRead0(ctx, buffer); - streamHandler.channelReadComplete(ctx); + streamHandler.channelInactive(ctx); + + try (InputStream inputStream = callback.getInputStream()) { + assertTrue(IOUtils.contentEquals(inputStream, new ByteBufInputStream(buffer))); + } + } + + @Test + public void testReadByteByByte() throws Exception { + ResultCallbackTest callback = new ResultCallbackTest(); + HttpResponseStreamHandler streamHandler = new HttpResponseStreamHandler(callback); + ChannelHandlerContext ctx = Mockito.mock(ChannelHandlerContext.class); + ByteBuf buffer = generateByteBuf(); + streamHandler.channelRead0(ctx, buffer); + streamHandler.channelInactive(ctx); + + try (InputStream inputStream = callback.getInputStream()) { + for (int i = 0; i < buffer.readableBytes(); i++) { + int b = inputStream.read(); + assertEquals(b, buffer.getByte(i)); + } + assertTrue(inputStream.read() == -1); + } + } + + @Test + public void testCloseResponseStreamBeforeWrite() throws Exception { + HttpResponseInputStream inputStream = new HttpResponseInputStream(); + ByteBuf buffer = generateByteBuf(); + + inputStream.write(buffer); + inputStream.close(); + inputStream.write(buffer); + } + + @Test + public void testCloseResponseStreamOnWrite() throws Exception { + final HttpResponseInputStream inputStream = new HttpResponseInputStream(); + + final ByteBuf buffer = generateByteBuf(); + + final CountDownLatch firstWrite = new CountDownLatch(1); + + ExecutorService executor = Executors.newSingleThreadExecutor(); + Future submit = executor.submit(new Runnable() { + @Override + public void run() { + try { + inputStream.write(buffer); + firstWrite.countDown(); + inputStream.write(buffer); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + }); + + firstWrite.await(); + assertTrue(inputStream.available() > 0); + + // second write should have started + Thread.sleep(500L); + inputStream.close(); + + submit.get(); + } + + @Test(expectedExceptions = IOException.class) + public void testReadClosedResponseStream() throws Exception { + HttpResponseInputStream inputStream = new HttpResponseInputStream(); + ByteBuf buffer = generateByteBuf(); - assertTrue(IOUtils.contentEquals(callback.getInputStream(), new ByteBufInputStream(buffer))); + inputStream.write(buffer); + inputStream.close(); + inputStream.read(); } private ByteBuf generateByteBuf() { @@ -46,7 +126,7 @@ public void onNext(InputStream stream) { this.stream = stream; } - public InputStream getInputStream() { + private InputStream getInputStream() { return stream; } } From d07e2f6be5ee4f87dd97ce725e0b9fe22c66cd8b Mon Sep 17 00:00:00 2001 From: Jiapeng Yang Date: Sat, 10 Sep 2016 01:26:56 +0800 Subject: [PATCH 260/855] =?UTF-8?q?Bugfix:donot=20throw=20RuntimeException?= =?UTF-8?q?=20when=20a=20error=20occured=20in=20awaitComp=E2=80=A6=20(#700?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bugfix:donot throw RuntimeException when a error occured in awaitCompletion(long,TimeUnit) * Fix indentation * fix format error,use docker-java-formatter.xml --- .../github/dockerjava/core/async/ResultCallbackTemplate.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java b/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java index f120012af..2437fc878 100644 --- a/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java +++ b/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java @@ -99,7 +99,9 @@ public RC_T awaitCompletion() throws InterruptedException { * before {@link ResultCallback#onComplete()} was called. */ public boolean awaitCompletion(long timeout, TimeUnit timeUnit) throws InterruptedException { - return completed.await(timeout, timeUnit); + boolean result = completed.await(timeout, timeUnit); + getFirstError(); + return result; } /** From 95e5075874a355bb90a365de52082932278ed9a3 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 9 Sep 2016 20:27:56 +0300 Subject: [PATCH 261/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 735283ae8..f8b6dcd86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ Change Log * Make all models Serializable. * [NETTY] Fix loadImage responce on 1.24 API. * LogPath field for inspect container. + * [#700] (https://github.com/docker-java/docker-java/pull/700) Bugfix:donot throw RuntimeException when a error occured in awaitCompletion(long,TimeUnit) ## 3.0.5 * Events updated to 1.24 API model. From d39d7f210ab6c9190b21b70f3ec6117e5d4f9864 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Sat, 10 Sep 2016 18:54:03 +0200 Subject: [PATCH 262/855] Fix issue with jersey and unix domain sockets (#697) --- .gitignore | 3 +- pom.xml | 29 +- .../core/async/ResultCallbackTemplate.java | 10 +- .../util/WrappedResponseInputStream.java | 5 +- .../http/impl/io/ChunkedInputStream.java | 337 ++++++++++++++ .../newsclub/net/unix/AFUNIXSocketImpl.java | 415 ++++++++++++++++++ .../core/command/EventsCmdImplTest.java | 120 ++--- .../command/StopContainerCmdImplTest.java | 8 +- .../command/UpdateContainerCmdImplTest.java | 4 +- .../netty/exec/EventsCmdExecTest.java | 116 ++--- .../netty/exec/StopContainerCmdExecTest.java | 12 +- .../exec/UpdateContainerCmdExecTest.java | 4 +- 12 files changed, 914 insertions(+), 149 deletions(-) create mode 100644 src/main/java/org/apache/http/impl/io/ChunkedInputStream.java create mode 100644 src/main/java/org/newsclub/net/unix/AFUNIXSocketImpl.java diff --git a/.gitignore b/.gitignore index 8f1fdc779..a705c1129 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,5 @@ target *.log #Ignore Test Output -test-output \ No newline at end of file +test-output +/.checkstyle diff --git a/pom.xml b/pom.xml index b1b6d96a9..5cc227ee3 100644 --- a/pom.xml +++ b/pom.xml @@ -1,4 +1,5 @@ - + 4.0.0 @@ -67,7 +68,7 @@ 1.7.21 1.54 - 2015-01-27T15-02-14 + 2.0.4 19.0 @@ -115,11 +116,15 @@ ${jersey.version} - de.gesellix - unix-socket-factory - ${unix-socket-factory.version} + com.kohlschutter.junixsocket + junixsocket-common + ${junixsocket.version} + + + com.kohlschutter.junixsocket + junixsocket-native-common + ${junixsocket.version} - org.apache.commons commons-compress @@ -266,13 +271,6 @@ - - - - - - - @@ -419,7 +417,7 @@ true 1 integration - integration-auth + integration-auth **/*Test.java @@ -483,7 +481,8 @@ true true false - + src/test/resources/checkstyle/checkstyle-config.xml diff --git a/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java b/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java index 2437fc878..2238dfcea 100644 --- a/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java +++ b/src/main/java/com/github/dockerjava/core/async/ResultCallbackTemplate.java @@ -75,11 +75,13 @@ public void onComplete() { @Override public void close() throws IOException { - closed = true; - if (stream != null) { - stream.close(); + if (!closed) { + closed = true; + if (stream != null) { + stream.close(); + } + completed.countDown(); } - completed.countDown(); } /** diff --git a/src/main/java/com/github/dockerjava/jaxrs/util/WrappedResponseInputStream.java b/src/main/java/com/github/dockerjava/jaxrs/util/WrappedResponseInputStream.java index afe0dce92..4ec74ddcc 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/util/WrappedResponseInputStream.java +++ b/src/main/java/com/github/dockerjava/jaxrs/util/WrappedResponseInputStream.java @@ -53,9 +53,12 @@ public int available() throws IOException { } public void close() throws IOException { + if (closed) { + return; + } closed = true; - response.close(); delegate.close(); + response.close(); } public void mark(int readlimit) { diff --git a/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java b/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java new file mode 100644 index 000000000..17c339e3e --- /dev/null +++ b/src/main/java/org/apache/http/impl/io/ChunkedInputStream.java @@ -0,0 +1,337 @@ +// Modified version (see https://github.com/docker-java/docker-java/pull/697) +/* + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +package org.apache.http.impl.io; + +import java.io.IOException; +import java.io.InputStream; + +import org.apache.http.ConnectionClosedException; +import org.apache.http.Header; +import org.apache.http.HttpException; +import org.apache.http.MalformedChunkCodingException; +import org.apache.http.TruncatedChunkException; +import org.apache.http.config.MessageConstraints; +import org.apache.http.io.BufferInfo; +import org.apache.http.io.SessionInputBuffer; +import org.apache.http.util.Args; +import org.apache.http.util.CharArrayBuffer; + +/** + * Implements chunked transfer coding. The content is received in small chunks. + * Entities transferred using this input stream can be of unlimited length. + * After the stream is read to the end, it provides access to the trailers, + * if any. + *

+ * Note that this class NEVER closes the underlying stream, even when close + * gets called. Instead, it will read until the "end" of its chunking on + * close, which allows for the seamless execution of subsequent HTTP 1.1 + * requests, while not requiring the client to remember to read the entire + * contents of the response. + * + * + * @since 4.0 + * + */ +public class ChunkedInputStream extends InputStream { + + private static final int CHUNK_LEN = 1; + private static final int CHUNK_DATA = 2; + private static final int CHUNK_CRLF = 3; + private static final int CHUNK_INVALID = Integer.MAX_VALUE; + + private static final int BUFFER_SIZE = 2048; + + /** The session input buffer */ + private final SessionInputBuffer in; + private final CharArrayBuffer buffer; + private final MessageConstraints constraints; + + private int state; + + /** The chunk size */ + private long chunkSize; + + /** The current position within the current chunk */ + private long pos; + + /** True if we've reached the end of stream */ + private boolean eof = false; + + /** True if this stream is closed */ + private boolean closed = false; + + private Header[] footers = new Header[] {}; + + /** + * Wraps session input stream and reads chunk coded input. + * + * @param in The session input buffer + * @param constraints Message constraints. If {@code null} + * {@link MessageConstraints#DEFAULT} will be used. + * + * @since 4.4 + */ + public ChunkedInputStream(final SessionInputBuffer in, final MessageConstraints constraints) { + super(); + this.in = Args.notNull(in, "Session input buffer"); + this.pos = 0L; + this.buffer = new CharArrayBuffer(16); + this.constraints = constraints != null ? constraints : MessageConstraints.DEFAULT; + this.state = CHUNK_LEN; + } + + /** + * Wraps session input stream and reads chunk coded input. + * + * @param in The session input buffer + */ + public ChunkedInputStream(final SessionInputBuffer in) { + this(in, null); + } + + @Override + public int available() throws IOException { + if (this.in instanceof BufferInfo) { + final int len = ((BufferInfo) this.in).length(); + return (int) Math.min(len, this.chunkSize - this.pos); + } else { + return 0; + } + } + + /** + *

Returns all the data in a chunked stream in coalesced form. A chunk + * is followed by a CRLF. The method returns -1 as soon as a chunksize of 0 + * is detected.

+ * + *

Trailer headers are read automatically at the end of the stream and + * can be obtained with the getResponseFooters() method.

+ * + * @return -1 of the end of the stream has been reached or the next data + * byte + * @throws IOException in case of an I/O error + */ + @Override + public int read() throws IOException { + if (this.closed) { + throw new IOException("Attempted read from closed stream."); + } + if (this.eof) { + return -1; + } + if (state != CHUNK_DATA) { + nextChunk(); + if (this.eof) { + return -1; + } + } + final int b = in.read(); + if (b != -1) { + pos++; + if (pos >= chunkSize) { + state = CHUNK_CRLF; + } + } + return b; + } + + /** + * Read some bytes from the stream. + * @param b The byte array that will hold the contents from the stream. + * @param off The offset into the byte array at which bytes will start to be + * placed. + * @param len the maximum number of bytes that can be returned. + * @return The number of bytes returned or -1 if the end of stream has been + * reached. + * @throws IOException in case of an I/O error + */ + @Override + public int read(final byte[] b, final int off, final int len) throws IOException { + + if (closed) { + throw new IOException("Attempted read from closed stream."); + } + + if (eof) { + return -1; + } + if (state != CHUNK_DATA) { + nextChunk(); + if (eof) { + return -1; + } + } + final int bytesRead = in.read(b, off, (int) Math.min(len, chunkSize - pos)); + if (bytesRead != -1) { + pos += bytesRead; + if (pos >= chunkSize) { + state = CHUNK_CRLF; + } + return bytesRead; + } else { + eof = true; + throw new TruncatedChunkException("Truncated chunk " + + "( expected size: " + chunkSize + + "; actual size: " + pos + ")"); + } + } + + /** + * Read some bytes from the stream. + * @param b The byte array that will hold the contents from the stream. + * @return The number of bytes returned or -1 if the end of stream has been + * reached. + * @throws IOException in case of an I/O error + */ + @Override + public int read(final byte[] b) throws IOException { + return read(b, 0, b.length); + } + + /** + * Read the next chunk. + * @throws IOException in case of an I/O error + */ + private void nextChunk() throws IOException { + if (state == CHUNK_INVALID) { + throw new MalformedChunkCodingException("Corrupt data stream"); + } + try { + chunkSize = getChunkSize(); + if (chunkSize < 0L) { + throw new MalformedChunkCodingException("Negative chunk size"); + } + state = CHUNK_DATA; + pos = 0L; + if (chunkSize == 0L) { + eof = true; + parseTrailerHeaders(); + } + } catch (MalformedChunkCodingException ex) { + state = CHUNK_INVALID; + throw ex; + } + } + + /** + * Expects the stream to start with a chunksize in hex with optional + * comments after a semicolon. The line must end with a CRLF: "a3; some + * comment\r\n" Positions the stream at the start of the next line. + */ + private long getChunkSize() throws IOException { + final int st = this.state; + switch (st) { + case CHUNK_CRLF: + this.buffer.clear(); + final int bytesRead1 = this.in.readLine(this.buffer); + if (bytesRead1 == -1) { + throw new MalformedChunkCodingException( + "CRLF expected at end of chunk"); + } + if (!this.buffer.isEmpty()) { + throw new MalformedChunkCodingException( + "Unexpected content at the end of chunk"); + } + state = CHUNK_LEN; + //$FALL-THROUGH$ + case CHUNK_LEN: + this.buffer.clear(); + final int bytesRead2 = this.in.readLine(this.buffer); + if (bytesRead2 == -1) { + throw new ConnectionClosedException("Premature end of chunk coded message body: " + + "closing chunk expected"); + } + int separator = this.buffer.indexOf(';'); + if (separator < 0) { + separator = this.buffer.length(); + } + final String s = this.buffer.substringTrimmed(0, separator); + try { + return Long.parseLong(s, 16); + } catch (final NumberFormatException e) { + throw new MalformedChunkCodingException("Bad chunk header: " + s); + } + default: + throw new IllegalStateException("Inconsistent codec state"); + } + } + + /** + * Reads and stores the Trailer headers. + * @throws IOException in case of an I/O error + */ + private void parseTrailerHeaders() throws IOException { + try { + this.footers = AbstractMessageParser.parseHeaders(in, + constraints.getMaxHeaderCount(), + constraints.getMaxLineLength(), + null); + } catch (final HttpException ex) { + final IOException ioe = new MalformedChunkCodingException("Invalid footer: " + + ex.getMessage()); + ioe.initCause(ex); + throw ioe; + } + } + + /** + * Upon close, this reads the remainder of the chunked message, + * leaving the underlying socket at a position to start reading the + * next response without scanning. + * @throws IOException in case of an I/O error + */ + @Override + public void close() throws IOException { + if (!closed) { + try { + if (!eof && state != CHUNK_INVALID) { + // read and discard the remainder of the message + final byte[] buff = new byte[BUFFER_SIZE]; + try { + while (read(buff) >= 0) { + continue; + } + } catch (ConnectionClosedException e) { + // just ignore + } catch (TruncatedChunkException e) { + // just ignore + } + } + } finally { + eof = true; + closed = true; + } + } + } + + public Header[] getFooters() { + return this.footers.clone(); + } + +} diff --git a/src/main/java/org/newsclub/net/unix/AFUNIXSocketImpl.java b/src/main/java/org/newsclub/net/unix/AFUNIXSocketImpl.java new file mode 100644 index 000000000..869d987f2 --- /dev/null +++ b/src/main/java/org/newsclub/net/unix/AFUNIXSocketImpl.java @@ -0,0 +1,415 @@ +// Modified version (see https://github.com/docker-java/docker-java/pull/697) +/** + * junixsocket + * + * Copyright (c) 2009,2014 Christian KohlschΓΌtter + * + * The author licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.newsclub.net.unix; + +import java.io.FileDescriptor; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketImpl; +import java.net.SocketOptions; + +/** + * The Java-part of the {@link AFUNIXSocket} implementation. + * + * @author Christian KohlschΓΌtter + */ +class AFUNIXSocketImpl extends SocketImpl { + private static final int SHUT_RD = 0; + private static final int SHUT_WR = 1; + private static final int SHUT_RD_WR = 2; + + private String socketFile; + private boolean closed = false; + private boolean bound = false; + private boolean connected = false; + + private boolean closedInputStream = false; + private boolean closedOutputStream = false; + + private final AFUNIXInputStream in = new AFUNIXInputStream(); + private final AFUNIXOutputStream out = new AFUNIXOutputStream(); + + AFUNIXSocketImpl() { + super(); + this.fd = new FileDescriptor(); + } + + FileDescriptor getFD() { + return fd; + } + + @Override + protected void accept(SocketImpl socket) throws IOException { + final AFUNIXSocketImpl si = (AFUNIXSocketImpl) socket; + NativeUnixSocket.accept(socketFile, fd, si.fd); + si.socketFile = socketFile; + si.connected = true; + } + + @Override + protected int available() throws IOException { + return NativeUnixSocket.available(fd); + } + + protected void bind(SocketAddress addr) throws IOException { + bind(0, addr); + } + + protected void bind(int backlog, SocketAddress addr) throws IOException { + if (!(addr instanceof AFUNIXSocketAddress)) { + throw new SocketException("Cannot bind to this type of address: " + addr.getClass()); + } + final AFUNIXSocketAddress socketAddress = (AFUNIXSocketAddress) addr; + socketFile = socketAddress.getSocketFile(); + NativeUnixSocket.bind(socketFile, fd, backlog); + bound = true; + this.localport = socketAddress.getPort(); + } + + @Override + @SuppressWarnings("hiding") + protected void bind(InetAddress host, int port) throws IOException { + throw new SocketException("Cannot bind to this type of address: " + InetAddress.class); + } + + private void checkClose() throws IOException { + //if (closedInputStream && closedOutputStream) { + // close(); + //} + } + + @Override + protected synchronized void close() throws IOException { + if (closed) { + return; + } + closed = true; + if (fd.valid()) { + NativeUnixSocket.shutdown(fd, SHUT_RD_WR); + NativeUnixSocket.close(fd); + } + if (bound) { + NativeUnixSocket.unlink(socketFile); + } + connected = false; + } + + @Override + @SuppressWarnings("hiding") + protected void connect(String host, int port) throws IOException { + throw new SocketException("Cannot bind to this type of address: " + InetAddress.class); + } + + @Override + @SuppressWarnings("hiding") + protected void connect(InetAddress address, int port) throws IOException { + throw new SocketException("Cannot bind to this type of address: " + InetAddress.class); + } + + @Override + protected void connect(SocketAddress addr, int timeout) throws IOException { + if (!(addr instanceof AFUNIXSocketAddress)) { + throw new SocketException("Cannot bind to this type of address: " + addr.getClass()); + } + final AFUNIXSocketAddress socketAddress = (AFUNIXSocketAddress) addr; + socketFile = socketAddress.getSocketFile(); + NativeUnixSocket.connect(socketFile, fd); + this.address = socketAddress.getAddress(); + this.port = socketAddress.getPort(); + this.localport = 0; + this.connected = true; + } + + @Override + protected void create(boolean stream) throws IOException { + } + + @Override + protected InputStream getInputStream() throws IOException { + if (!connected && !bound) { + throw new IOException("Not connected/not bound"); + } + return in; + } + + @Override + protected OutputStream getOutputStream() throws IOException { + if (!connected && !bound) { + throw new IOException("Not connected/not bound"); + } + return out; + } + + @Override + protected void listen(int backlog) throws IOException { + NativeUnixSocket.listen(fd, backlog); + } + + @Override + protected void sendUrgentData(int data) throws IOException { + NativeUnixSocket.write(fd, new byte[] {(byte) (data & 0xFF)}, 0, 1); + } + + private final class AFUNIXInputStream extends InputStream { + private boolean streamClosed = false; + + @Override + public int read(byte[] buf, int off, int len) throws IOException { + if (streamClosed) { + throw new IOException("This InputStream has already been closed."); + } + if (len == 0) { + return 0; + } + if (closed) { + return -1; + } + int maxRead = buf.length - off; + if (len > maxRead) { + len = maxRead; + } + try { + return NativeUnixSocket.read(fd, buf, off, len); + } catch (final IOException e) { + throw (IOException) new IOException(e.getMessage() + " at " + + AFUNIXSocketImpl.this.toString()).initCause(e); + } + } + + @Override + public int read() throws IOException { + final byte[] buf1 = new byte[1]; + final int numRead = read(buf1, 0, 1); + if (numRead <= 0) { + return -1; + } else { + return buf1[0] & 0xFF; + } + } + + @Override + public void close() throws IOException { + if (streamClosed) { + return; + } + streamClosed = true; + if (fd.valid()) { + NativeUnixSocket.shutdown(fd, SHUT_RD); + } + + closedInputStream = true; + checkClose(); + } + + @Override + public int available() throws IOException { + final int av = NativeUnixSocket.available(fd); + return av; + } + } + + private final class AFUNIXOutputStream extends OutputStream { + private boolean streamClosed = false; + + @Override + public void write(int oneByte) throws IOException { + final byte[] buf1 = new byte[] {(byte) oneByte}; + write(buf1, 0, 1); + } + + @Override + public void write(byte[] buf, int off, int len) throws IOException { + if (streamClosed) { + throw new AFUNIXSocketException("This OutputStream has already been closed."); + } + if (len > buf.length - off) { + throw new IndexOutOfBoundsException(); + } + try { + while (len > 0 && !Thread.interrupted()) { + final int written = NativeUnixSocket.write(fd, buf, off, len); + if (written == -1) { + throw new IOException("Unspecific error while writing"); + } + len -= written; + off += written; + } + } catch (final IOException e) { + throw (IOException) new IOException(e.getMessage() + " at " + + AFUNIXSocketImpl.this.toString()).initCause(e); + } + } + + @Override + public void close() throws IOException { + if (streamClosed) { + return; + } + streamClosed = true; + if (fd.valid()) { + NativeUnixSocket.shutdown(fd, SHUT_WR); + } + closedOutputStream = true; + checkClose(); + } + } + + @Override + public String toString() { + return super.toString() + "[fd=" + fd + "; file=" + this.socketFile + "; connected=" + + connected + "; bound=" + bound + "]"; + } + + private static int expectInteger(Object value) throws SocketException { + try { + return (Integer) value; + } catch (final ClassCastException e) { + throw new AFUNIXSocketException("Unsupported value: " + value, e); + } catch (final NullPointerException e) { + throw new AFUNIXSocketException("Value must not be null", e); + } + } + + private static int expectBoolean(Object value) throws SocketException { + try { + return ((Boolean) value).booleanValue() ? 1 : 0; + } catch (final ClassCastException e) { + throw new AFUNIXSocketException("Unsupported value: " + value, e); + } catch (final NullPointerException e) { + throw new AFUNIXSocketException("Value must not be null", e); + } + } + + @Override + public Object getOption(int optID) throws SocketException { + try { + switch (optID) { + case SocketOptions.SO_KEEPALIVE: + case SocketOptions.TCP_NODELAY: + return NativeUnixSocket.getSocketOptionInt(fd, optID) != 0 ? true : false; + case SocketOptions.SO_LINGER: + case SocketOptions.SO_TIMEOUT: + case SocketOptions.SO_RCVBUF: + case SocketOptions.SO_SNDBUF: + return NativeUnixSocket.getSocketOptionInt(fd, optID); + default: + throw new AFUNIXSocketException("Unsupported option: " + optID); + } + } catch (final AFUNIXSocketException e) { + throw e; + } catch (final Exception e) { + throw new AFUNIXSocketException("Error while getting option", e); + } + } + + @Override + public void setOption(int optID, Object value) throws SocketException { + try { + switch (optID) { + case SocketOptions.SO_LINGER: + + if (value instanceof Boolean) { + final boolean b = (Boolean) value; + if (b) { + throw new SocketException("Only accepting Boolean.FALSE here"); + } + NativeUnixSocket.setSocketOptionInt(fd, optID, -1); + return; + } + NativeUnixSocket.setSocketOptionInt(fd, optID, expectInteger(value)); + return; + case SocketOptions.SO_RCVBUF: + case SocketOptions.SO_SNDBUF: + case SocketOptions.SO_TIMEOUT: + NativeUnixSocket.setSocketOptionInt(fd, optID, expectInteger(value)); + return; + case SocketOptions.SO_KEEPALIVE: + case SocketOptions.TCP_NODELAY: + NativeUnixSocket.setSocketOptionInt(fd, optID, expectBoolean(value)); + return; + default: + throw new AFUNIXSocketException("Unsupported option: " + optID); + } + } catch (final AFUNIXSocketException e) { + throw e; + } catch (final Exception e) { + throw new AFUNIXSocketException("Error while setting option", e); + } + } + + @Override + protected void shutdownInput() throws IOException { + if (!closed && fd.valid()) { + NativeUnixSocket.shutdown(fd, SHUT_RD); + } + } + + @Override + protected void shutdownOutput() throws IOException { + if (!closed && fd.valid()) { + NativeUnixSocket.shutdown(fd, SHUT_WR); + } + } + + /** + * Changes the behavior to be somewhat lenient with respect to the specification. + * + * In particular, we ignore calls to {@link Socket#getTcpNoDelay()} and + * {@link Socket#setTcpNoDelay(boolean)}. + */ + static class Lenient extends AFUNIXSocketImpl { + Lenient() { + super(); + } + + @Override + public void setOption(int optID, Object value) throws SocketException { + try { + super.setOption(optID, value); + } catch (SocketException e) { + switch (optID) { + case SocketOptions.TCP_NODELAY: + return; + default: + throw e; + } + } + } + + @Override + public Object getOption(int optID) throws SocketException { + try { + return super.getOption(optID); + } catch (SocketException e) { + switch (optID) { + case SocketOptions.TCP_NODELAY: + case SocketOptions.SO_KEEPALIVE: + return false; + default: + throw e; + } + } + } + } +} diff --git a/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java index 939f95087..d05327a06 100644 --- a/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/EventsCmdImplTest.java @@ -17,11 +17,14 @@ import com.github.dockerjava.api.model.Event; import com.github.dockerjava.client.AbstractDockerClientTest; +/* + * NOTE: These tests may fail if there is a difference between local and daemon time + * (this is especially a problem when using boot2docker as time may not in sync + * with the virtualbox host system) + */ @Test(groups = "integration") public class EventsCmdImplTest extends AbstractDockerClientTest { - private static int KNOWN_NUM_EVENTS = 4; - private static String getEpochTime() { return String.valueOf(System.currentTimeMillis() / 1000); } @@ -46,9 +49,6 @@ public void afterMethod(ITestResult result) { super.afterMethod(result); } - /* - * This specific test may fail with boot2docker as time may not in sync with host system - */ @Test public void testEventStreamTimeBound() throws Exception { // Don't include other tests events @@ -58,82 +58,84 @@ public void testEventStreamTimeBound() throws Exception { int expectedEvents = generateEvents(); String endTime = getEpochTime(); - CountDownLatch countDownLatch = new CountDownLatch(expectedEvents); - EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch); - - dockerClient.eventsCmd().withSince(startTime).withUntil(endTime).exec(eventCallback); + EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents); - Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS); + dockerClient.eventsCmd() + .withSince(startTime) + .withUntil(endTime) + .exec(eventCallback); - eventCallback.close(); + List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES); - assertTrue(zeroCount, "Received only: " + eventCallback.getEvents()); + // we may receive more events as expected + assertTrue(events.size() >= expectedEvents, "Received events: " + events); } @Test - public void testEventStreaming1() throws Exception { - // Don't include other tests events - TimeUnit.SECONDS.sleep(1); - - CountDownLatch countDownLatch = new CountDownLatch(KNOWN_NUM_EVENTS); - EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch); - - dockerClient.eventsCmd().withSince(getEpochTime()).exec(eventCallback); - - generateEvents(); - - Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS); - - eventCallback.close(); - assertTrue(zeroCount, "Received only: " + eventCallback.getEvents()); - } - - @Test - public void testEventStreaming2() throws Exception { + public void testEventStreaming() throws Exception { // Don't include other tests events TimeUnit.SECONDS.sleep(1); + + String startTime = getEpochTime(); + int expectedEvents = generateEvents(); - CountDownLatch countDownLatch = new CountDownLatch(KNOWN_NUM_EVENTS); - EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch); + EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents); - dockerClient.eventsCmd().withSince(getEpochTime()).exec(eventCallback); + dockerClient.eventsCmd() + .withSince(startTime) + .exec(eventCallback); generateEvents(); - Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS); - - eventCallback.close(); - assertTrue(zeroCount, "Received only: " + eventCallback.getEvents()); + List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES); + + // we may receive more events as expected + assertTrue(events.size() >= expectedEvents, "Received events: " + events); } + public void testEventStreamingWithFilter() throws Exception { // Don't include other tests events TimeUnit.SECONDS.sleep(1); + + String startTime = getEpochTime(); + int expectedEvents = 1; - CountDownLatch countDownLatch = new CountDownLatch(1); - EventsTestCallback eventCallback = dockerClient.eventsCmd().withEventFilter("start") - .exec(new EventsTestCallback(countDownLatch)); + EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents); + + dockerClient.eventsCmd() + .withSince(startTime) + .withEventFilter("start") + .exec(eventCallback); generateEvents(); - Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS); - - eventCallback.close(); - assertTrue(zeroCount, "Received only: " + eventCallback.getEvents()); + List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES); + + // we should get exactly one "start" event here + assertEquals(events.size(), expectedEvents, "Received events: " + events); } /** - * This method generates {#link KNOWN_NUM_EVENTS} events + * This method generates some events and returns the number of events being generated */ private int generateEvents() throws Exception { - String testImage = "busybox"; + String testImage = "busybox:latest"; dockerClient.pullImageCmd(testImage).exec(new PullImageResultCallback()).awaitSuccess(); - CreateContainerResponse container = dockerClient.createContainerCmd(testImage).withCmd("sleep", "9999").exec(); dockerClient.startContainerCmd(container.getId()).exec(); - dockerClient.stopContainerCmd(container.getId()).exec(); - return KNOWN_NUM_EVENTS; + dockerClient.stopContainerCmd(container.getId()).withTimeout(1).exec(); + + // generates 5 events with remote api 1.24: + + // Event[status=pull,id=busybox:latest,from=,node=,type=IMAGE,action=pull,actor=com.github.dockerjava.api.model.EventActor@417db6d7[id=busybox:latest,attributes={name=busybox}],time=1473455186,timeNano=1473455186436681587] + // Event[status=create,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=create,actor=com.github.dockerjava.api.model.EventActor@40bcec[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport}],time=1473455186,timeNano=1473455186470713257] + // Event[status=,id=,from=,node=,type=NETWORK,action=connect,actor=com.github.dockerjava.api.model.EventActor@318a1b01[id=10870ceb13abb7cf841ea68868472da881b33c8ed08d2cde7dbb39d7c24d1d27,attributes={container=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c, name=bridge, type=bridge}],time=1473455186,timeNano=1473455186544318466] + // Event[status=start,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=start,actor=com.github.dockerjava.api.model.EventActor@606f43a3[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport}],time=1473455186,timeNano=1473455186786163819] + // Event[status=kill,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=kill,actor=com.github.dockerjava.api.model.EventActor@72a9ffcf[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport, signal=15}],time=1473455186,timeNano=1473455186792963392] + + return 5; } private class EventsTestCallback extends EventsResultCallback { @@ -142,18 +144,24 @@ private class EventsTestCallback extends EventsResultCallback { private final List events = new ArrayList(); - public EventsTestCallback(CountDownLatch countDownLatch) { - this.countDownLatch = countDownLatch; + public EventsTestCallback(int expextedEvents) { + this.countDownLatch = new CountDownLatch(expextedEvents); } public void onNext(Event event) { LOG.info("Received event #{}: {}", countDownLatch.getCount(), event); - countDownLatch.countDown(); events.add(event); + countDownLatch.countDown(); } - - public List getEvents() { - return new ArrayList(events); + + public List awaitExpectedEvents(long timeout, TimeUnit unit ) { + try { + countDownLatch.await(timeout, unit); + close(); + } catch (Exception e) { + throw new RuntimeException(e); + } + return new ArrayList(events); } } } diff --git a/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java index 382e5b29c..7ae6a09cc 100644 --- a/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/StopContainerCmdImplTest.java @@ -69,11 +69,9 @@ public void testStopContainer() throws DockerException { assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false))); final Integer exitCode = inspectContainerResponse.getState().getExitCode(); - if (apiVersion.equals(VERSION_1_22)) { - assertThat(exitCode, is(0)); - } else { - assertThat(exitCode, not(0)); - } + + assertThat(exitCode, is(137)); + } @Test(expectedExceptions = NotFoundException.class) diff --git a/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java b/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java index 3c7a9fd47..df53d671b 100644 --- a/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/UpdateContainerCmdImplTest.java @@ -79,7 +79,7 @@ public void updateContainer() throws DockerException, IOException { // .withCpusetCpus("0") // depends on env .withCpusetMems("0") .withMemory(314572800L) - .withMemorySwap(514288000L) +// .withMemorySwap(514288000L) Your kernel does not support swap limit capabilities, memory limited without swap. .withMemoryReservation(209715200L) // .withKernelMemory(52428800) Can not update kernel memory to a running container, please stop it first. .exec(); @@ -102,7 +102,7 @@ public void updateContainer() throws DockerException, IOException { assertThat(afterHostConfig.getCpusetMems(), is("0")); assertThat(afterHostConfig.getMemoryReservation(), is(209715200L)); - assertThat(afterHostConfig.getMemorySwap(), is(514288000L)); +// assertThat(afterHostConfig.getMemorySwap(), is(514288000L)); } diff --git a/src/test/java/com/github/dockerjava/netty/exec/EventsCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/EventsCmdExecTest.java index a634e2562..2a446569d 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/EventsCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/EventsCmdExecTest.java @@ -22,8 +22,6 @@ @Test(groups = "integration") public class EventsCmdExecTest extends AbstractNettyDockerClientTest { - private static int KNOWN_NUM_EVENTS = 4; - private static String getEpochTime() { return String.valueOf(System.currentTimeMillis() / 1000); } @@ -48,9 +46,6 @@ public void afterMethod(ITestResult result) { super.afterMethod(result); } - /* - * This specific test may fail with boot2docker as time may not in sync with host system - */ @Test public void testEventStreamTimeBound() throws Exception { // Don't include other tests events @@ -60,82 +55,84 @@ public void testEventStreamTimeBound() throws Exception { int expectedEvents = generateEvents(); String endTime = getEpochTime(); - CountDownLatch countDownLatch = new CountDownLatch(expectedEvents); - EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch); - - dockerClient.eventsCmd().withSince(startTime).withUntil(endTime).exec(eventCallback); - - Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS); - - eventCallback.close(); - - assertTrue(zeroCount, "Received only: " + eventCallback.getEvents()); - } - - @Test - public void testEventStreaming1() throws Exception { - // Don't include other tests events - TimeUnit.SECONDS.sleep(1); - - CountDownLatch countDownLatch = new CountDownLatch(KNOWN_NUM_EVENTS); - EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch); + EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents); - dockerClient.eventsCmd().withSince(getEpochTime()).exec(eventCallback); + dockerClient.eventsCmd() + .withSince(startTime) + .withUntil(endTime) + .exec(eventCallback); - generateEvents(); - - Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS); + List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES); - eventCallback.close(); - assertTrue(zeroCount, "Received only: " + eventCallback.getEvents()); + // we may receive more events as expected + assertTrue(events.size() >= expectedEvents, "Received events: " + events); } @Test - public void testEventStreaming2() throws Exception { + public void testEventStreaming() throws Exception { // Don't include other tests events TimeUnit.SECONDS.sleep(1); + + String startTime = getEpochTime(); + int expectedEvents = generateEvents(); - CountDownLatch countDownLatch = new CountDownLatch(KNOWN_NUM_EVENTS); - EventsTestCallback eventCallback = new EventsTestCallback(countDownLatch); + EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents); - dockerClient.eventsCmd().withSince(getEpochTime()).exec(eventCallback); + dockerClient.eventsCmd() + .withSince(startTime) + .exec(eventCallback); generateEvents(); - Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS); - - eventCallback.close(); - assertTrue(zeroCount, "Received only: " + eventCallback.getEvents()); + List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES); + + // we may receive more events as expected + assertTrue(events.size() >= expectedEvents, "Received events: " + events); } + public void testEventStreamingWithFilter() throws Exception { // Don't include other tests events TimeUnit.SECONDS.sleep(1); + + String startTime = getEpochTime(); + int expectedEvents = 1; - CountDownLatch countDownLatch = new CountDownLatch(1); - EventsTestCallback eventCallback = dockerClient.eventsCmd().withEventFilter("start") - .exec(new EventsTestCallback(countDownLatch)); + EventsTestCallback eventCallback = new EventsTestCallback(expectedEvents); + + dockerClient.eventsCmd() + .withSince(startTime) + .withEventFilter("start") + .exec(eventCallback); generateEvents(); - Boolean zeroCount = countDownLatch.await(10, TimeUnit.SECONDS); - - eventCallback.close(); - assertTrue(zeroCount, "Received only: " + eventCallback.getEvents()); + List events = eventCallback.awaitExpectedEvents(3, TimeUnit.MINUTES); + + // we should get exactly one "start" event here + assertEquals(events.size(), expectedEvents, "Received events: " + events); } /** - * This method generates {#link KNOWN_NUM_EVENTS} events + * This method generates some events and returns the number of events being generated */ private int generateEvents() throws Exception { - String testImage = "busybox"; + String testImage = "busybox:latest"; dockerClient.pullImageCmd(testImage).exec(new PullImageResultCallback()).awaitSuccess(); - CreateContainerResponse container = dockerClient.createContainerCmd(testImage).withCmd("sleep", "9999").exec(); dockerClient.startContainerCmd(container.getId()).exec(); - dockerClient.stopContainerCmd(container.getId()).exec(); - return KNOWN_NUM_EVENTS; + dockerClient.stopContainerCmd(container.getId()).withTimeout(1).exec(); + + // generates 5 events with remote api 1.24: + + // Event[status=pull,id=busybox:latest,from=,node=,type=IMAGE,action=pull,actor=com.github.dockerjava.api.model.EventActor@417db6d7[id=busybox:latest,attributes={name=busybox}],time=1473455186,timeNano=1473455186436681587] + // Event[status=create,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=create,actor=com.github.dockerjava.api.model.EventActor@40bcec[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport}],time=1473455186,timeNano=1473455186470713257] + // Event[status=,id=,from=,node=,type=NETWORK,action=connect,actor=com.github.dockerjava.api.model.EventActor@318a1b01[id=10870ceb13abb7cf841ea68868472da881b33c8ed08d2cde7dbb39d7c24d1d27,attributes={container=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c, name=bridge, type=bridge}],time=1473455186,timeNano=1473455186544318466] + // Event[status=start,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=start,actor=com.github.dockerjava.api.model.EventActor@606f43a3[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport}],time=1473455186,timeNano=1473455186786163819] + // Event[status=kill,id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,from=busybox:latest,node=,type=CONTAINER,action=kill,actor=com.github.dockerjava.api.model.EventActor@72a9ffcf[id=6ec10182cde227040bfead8547b63105e6bbc4e94b99f6098bfad6e158ce0d3c,attributes={image=busybox:latest, name=sick_lamport, signal=15}],time=1473455186,timeNano=1473455186792963392] + + return 5; } private class EventsTestCallback extends EventsResultCallback { @@ -144,18 +141,25 @@ private class EventsTestCallback extends EventsResultCallback { private final List events = new ArrayList(); - public EventsTestCallback(CountDownLatch countDownLatch) { - this.countDownLatch = countDownLatch; + public EventsTestCallback(int expextedEvents) { + this.countDownLatch = new CountDownLatch(expextedEvents); } public void onNext(Event event) { LOG.info("Received event #{}: {}", countDownLatch.getCount(), event); - countDownLatch.countDown(); events.add(event); + countDownLatch.countDown(); } - - public List getEvents() { - return new ArrayList(events); + + public List awaitExpectedEvents(long timeout, TimeUnit unit ) { + try { + countDownLatch.await(timeout, unit); + close(); + } catch (Exception e) { + throw new RuntimeException(e); + } + return new ArrayList(events); } } } + diff --git a/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java index 1dca12890..063bcee30 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/StopContainerCmdExecTest.java @@ -61,7 +61,7 @@ public void testStopContainer() throws DockerException { dockerClient.startContainerCmd(container.getId()).exec(); LOG.info("Stopping container: {}", container.getId()); - dockerClient.stopContainerCmd(container.getId()).withTimeout(2).exec(); + dockerClient.stopContainerCmd(container.getId()).withTimeout(10).exec(); InspectContainerResponse inspectContainerResponse = dockerClient.inspectContainerCmd(container.getId()).exec(); LOG.info("Container Inspect: {}", inspectContainerResponse.toString()); @@ -69,17 +69,15 @@ public void testStopContainer() throws DockerException { assertThat(inspectContainerResponse.getState().getRunning(), is(equalTo(false))); final Integer exitCode = inspectContainerResponse.getState().getExitCode(); - if (apiVersion.equals(VERSION_1_22)) { - assertThat(exitCode, is(0)); - } else { - assertThat(exitCode, not(0)); - } + + assertThat(exitCode, is(137)); + } @Test(expectedExceptions = NotFoundException.class) public void testStopNonExistingContainer() throws DockerException { - dockerClient.stopContainerCmd("non-existing").withTimeout(2).exec(); + dockerClient.stopContainerCmd("non-existing").withTimeout(10).exec(); } } diff --git a/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java b/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java index 1134afd6d..681839c17 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/UpdateContainerCmdExecTest.java @@ -78,7 +78,7 @@ public void updateContainer() throws DockerException, IOException { // .withCpusetCpus("0") // depends on env .withCpusetMems("0") .withMemory(314572800L) - .withMemorySwap(514288000L) +// .withMemorySwap(514288000L) Your kernel does not support swap limit capabilities, memory limited without swap. .withMemoryReservation(209715200L) // .withKernelMemory(52428800) Can not update kernel memory to a running container, please stop it first. .exec(); @@ -101,7 +101,7 @@ public void updateContainer() throws DockerException, IOException { assertThat(afterHostConfig.getCpusetMems(), is("0")); assertThat(afterHostConfig.getMemoryReservation(), is(209715200L)); - assertThat(afterHostConfig.getMemorySwap(), is(514288000L)); +// assertThat(afterHostConfig.getMemorySwap(), is(514288000L)); } } From 1bfe308c5321fb3e136fd5c5add09e424f3fec86 Mon Sep 17 00:00:00 2001 From: Martin Caslavsky Date: Mon, 12 Sep 2016 18:53:50 +0200 Subject: [PATCH 263/855] Allow to configure connection pool timeout (#703) The default connection pool timeout of Apache HTTP Client is -1 (unlimited) --- .../jaxrs/JerseyDockerCmdExecFactory.java | 15 ++++++++++++--- 1 file changed, 12 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 3339a2696..73bab979e 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java +++ b/src/main/java/com/github/dockerjava/jaxrs/JerseyDockerCmdExecFactory.java @@ -20,6 +20,7 @@ import com.github.dockerjava.api.command.UpdateContainerCmd; import com.github.dockerjava.core.SSLConfig; +import org.apache.http.client.config.RequestConfig; import org.apache.http.config.RegistryBuilder; import org.apache.http.conn.socket.ConnectionSocketFactory; import org.apache.http.conn.socket.PlainConnectionSocketFactory; @@ -110,6 +111,8 @@ public class JerseyDockerCmdExecFactory implements DockerCmdExecFactory { private Integer maxPerRouteConnections = null; + private Integer connectionRequestTimeout = null; + private ClientRequestFilter[] clientRequestFilters = null; private ClientResponseFilter[] clientResponseFilters = null; @@ -216,9 +219,10 @@ public void shutdown() { clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER, connManager); // Configure connection pool timeout - // clientConfig.property(ApacheClientProperties.REQUEST_CONFIG, RequestConfig.custom() - // .setConnectionRequestTimeout(1000).build()); - + if (connectionRequestTimeout != null) { + clientConfig.property(ApacheClientProperties.REQUEST_CONFIG, RequestConfig.custom() + .setConnectionRequestTimeout(connectionRequestTimeout).build()); + } ClientBuilder clientBuilder = ClientBuilder.newBuilder().withConfig(clientConfig); if (sslContext != null) { @@ -570,6 +574,11 @@ public JerseyDockerCmdExecFactory withMaxPerRouteConnections(Integer maxPerRoute return this; } + public JerseyDockerCmdExecFactory withConnectionRequestTimeout(Integer connectionRequestTimeout) { + this.connectionRequestTimeout = connectionRequestTimeout; + return this; + } + public JerseyDockerCmdExecFactory withClientResponseFilters(ClientResponseFilter... clientResponseFilter) { this.clientResponseFilters = clientResponseFilter; return this; From c31716377f29bb2ece8f83bfaefc8368c3c72abb Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 14 Sep 2016 01:15:42 +0300 Subject: [PATCH 264/855] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8b6dcd86..908c2d906 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,8 @@ Change Log ## Next ## 3.0.6 + * Fixed issue with jersey and unix domain sockets. + * [#703](https://github.com/docker-java/docker-java/pull/703) Allow to configure connection pool timeout. * Make all models Serializable. * [NETTY] Fix loadImage responce on 1.24 API. * LogPath field for inspect container. From 03181feda5bbaced61edb715fec600a5236775e3 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 14 Sep 2016 01:21:10 +0300 Subject: [PATCH 265/855] [maven-release-plugin] prepare release 3.0.6 --- pom.xml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 5cc227ee3..3727ac2e9 100644 --- a/pom.xml +++ b/pom.xml @@ -1,5 +1,4 @@ - + 4.0.0 @@ -11,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.6-SNAPSHOT + 3.0.6 docker-java https://github.com/docker-java/docker-java @@ -29,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.6 From c3e03be12299c34988980ade3dc7d7a6d3956b12 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 14 Sep 2016 01:21:17 +0300 Subject: [PATCH 266/855] [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 3727ac2e9..216c48631 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ com.github.docker-java docker-java jar - 3.0.6 + 3.0.7-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.6 + HEAD From 450a51670e5667e0789127f2a2d7e1a4d0fcbcb5 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Wed, 14 Sep 2016 01:33:47 +0300 Subject: [PATCH 267/855] Update .travis.yml --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ba8c62ad0..d055f76e0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,8 +21,8 @@ env: - COVERITY_SCAN_NOTIFICATION_EMAIL="kanstantsin.sha@gmail.com" matrix: - - repo="main" DOCKER_HOST="tcp://127.0.0.1:2375" DOCKER_VERSION="1.12.0-0~trusty" CODECOV=true - - repo="main" DOCKER_HOST="unix:///var/run/docker.sock" DOCKER_VERSION="1.12.0-0~trusty" CODECOV=true + - 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.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 305b73a9763f8d47bdc9698ecfaa9c844a6e087f Mon Sep 17 00:00:00 2001 From: Corey Beres Date: Wed, 28 Sep 2016 20:34:55 -0400 Subject: [PATCH 268/855] Label image during build #681 (#684) * Ability to set labels on image build (#681) * Check API version in new tests (#681) * remove unnecessary this (#681) * change withLabel to withLabels (#681) --- .../dockerjava/api/command/BuildImageCmd.java | 11 ++++++++ .../core/command/BuildImageCmdImpl.java | 16 ++++++++++++ .../dockerjava/jaxrs/BuildImageCmdExec.java | 25 +++++++++++++------ .../netty/exec/BuildImageCmdExec.java | 23 +++++++++++------ .../core/command/BuildImageCmdImplTest.java | 24 ++++++++++++++++++ .../netty/exec/BuildImageCmdExecTest.java | 24 ++++++++++++++++++ .../resources/buildTests/labels/Dockerfile | 3 +++ 7 files changed, 111 insertions(+), 15 deletions(-) create mode 100644 src/test/resources/buildTests/labels/Dockerfile 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 20b23e903..ac98db2f9 100644 --- a/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/BuildImageCmd.java @@ -101,6 +101,12 @@ public interface BuildImageCmd extends AsyncDockerCmd getLabels(); + // setters BuildImageCmd withTag(String tag); @@ -145,6 +151,11 @@ public interface BuildImageCmd extends AsyncDockerCmd labels); + interface Exec extends DockerCmdAsyncExec { } 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 487f0b264..c34b05155 100644 --- a/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/BuildImageCmdImpl.java @@ -56,6 +56,8 @@ public class BuildImageCmdImpl extends AbstrAsyncDockerCmd buildArgs; + private Map labels; + public BuildImageCmdImpl(BuildImageCmd.Exec exec) { super(exec); } @@ -149,6 +151,11 @@ public Map getBuildArgs() { return buildArgs; } + @Override + public Map getLabels() { + return labels; + } + // getter lib specific @Override @@ -303,6 +310,15 @@ public BuildImageCmd withShmsize(Long shmsize) { return this; } + /** + * @see #labels + */ + @Override + public BuildImageCmd withLabels(Map labels) { + this.labels = labels; + return this; + } + @Override public void close() { super.close(); diff --git a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java index 43e7687eb..2a7aea40e 100644 --- a/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/jaxrs/BuildImageCmdExec.java @@ -24,6 +24,7 @@ import java.io.IOException; import java.net.URLEncoder; +import java.util.Map; public class BuildImageCmdExec extends AbstrAsyncDockerCmdExec implements BuildImageCmd.Exec { @@ -99,19 +100,14 @@ protected AbstractCallbackNotifier callbackNotifier(BuildImag webTarget = webTarget.queryParam("rm", "false"); } - if (command.getBuildArgs() != null && !command.getBuildArgs().isEmpty()) { - try { - webTarget = webTarget.queryParam("buildargs", - URLEncoder.encode(MAPPER.writeValueAsString(command.getBuildArgs()), "UTF-8")); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + webTarget = writeMap(webTarget, "buildargs", command.getBuildArgs()); if (command.getShmsize() != null) { webTarget = webTarget.queryParam("shmsize", command.getShmsize()); } + webTarget = writeMap(webTarget, "labels", command.getLabels()); + webTarget.property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.CHUNKED); webTarget.property(ClientProperties.CHUNKED_ENCODING_SIZE, 1024 * 1024); @@ -123,4 +119,17 @@ protected AbstractCallbackNotifier callbackNotifier(BuildImag entity(command.getTarInputStream(), "application/tar") ); } + + private WebTarget writeMap(WebTarget webTarget, String name, Map value) { + if (value != null && !value.isEmpty()) { + try { + return webTarget.queryParam(name, + URLEncoder.encode(MAPPER.writeValueAsString(value), "UTF-8")); + } catch (IOException e) { + throw new RuntimeException(e); + } + } else { + return webTarget; + } + } } 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 f4ff04576..43152570e 100644 --- a/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java +++ b/src/main/java/com/github/dockerjava/netty/exec/BuildImageCmdExec.java @@ -15,6 +15,7 @@ import com.github.dockerjava.netty.WebTarget; import java.io.IOException; +import java.util.Map; public class BuildImageCmdExec extends AbstrAsyncDockerCmdExec implements BuildImageCmd.Exec { @@ -85,18 +86,14 @@ protected Void execute0(BuildImageCmd command, ResultCallback webTarget = webTarget.queryParam("cpusetcpus", command.getCpusetcpus()); } - if (command.getBuildArgs() != null && !command.getBuildArgs().isEmpty()) { - try { - webTarget = webTarget.queryParam("buildargs", MAPPER.writeValueAsString(command.getBuildArgs())); - } catch (IOException e) { - throw new RuntimeException(e); - } - } + webTarget = writeMap(webTarget, "buildargs", command.getBuildArgs()); if (command.getShmsize() != null) { webTarget = webTarget.queryParam("shmsize", command.getShmsize()); } + webTarget = writeMap(webTarget, "labels", command.getLabels()); + LOGGER.trace("POST: {}", webTarget); InvocationBuilder builder = resourceWithOptionalAuthConfig(command, webTarget.request()) @@ -109,4 +106,16 @@ 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 31f3c3045..cb4c1b2a8 100644 --- a/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java +++ b/src/test/java/com/github/dockerjava/core/command/BuildImageCmdImplTest.java @@ -1,5 +1,6 @@ package com.github.dockerjava.core.command; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; @@ -12,11 +13,13 @@ import java.io.InputStream; import java.lang.reflect.Method; import java.util.Collection; +import java.util.Collections; import java.util.UUID; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.TrueFileFilter; import org.testng.ITestResult; +import org.testng.SkipException; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeMethod; @@ -33,6 +36,7 @@ import com.github.dockerjava.api.model.PortBinding; import com.github.dockerjava.api.model.Ports.Binding; import com.github.dockerjava.client.AbstractDockerClientTest; +import com.github.dockerjava.core.RemoteApiVersion; import com.github.dockerjava.core.util.CompressArchiveUtil; @Test(groups = "integration") @@ -250,6 +254,26 @@ public void buildArgs() throws Exception { assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc")); } + @Test + public void labels() throws Exception { + if (!getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_23)) { + throw new SkipException("API version should be >= 1.23"); + } + + File baseDir = fileFromBuildTestResource("labels"); + + String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true) + .withLabels(Collections.singletonMap("test", "abc")) + .exec(new BuildImageResultCallback()) + .awaitImageId(); + + InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); + assertThat(inspectImageResponse, not(nullValue())); + LOG.info("Image Inspect: {}", inspectImageResponse.toString()); + + assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc")); + } + 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 1474ef25f..f567dcfc8 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/BuildImageCmdExecTest.java @@ -1,5 +1,6 @@ package com.github.dockerjava.netty.exec; +import static com.github.dockerjava.utils.TestUtils.getVersion; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; @@ -12,11 +13,13 @@ import java.io.InputStream; import java.lang.reflect.Method; import java.util.Collection; +import java.util.Collections; import java.util.UUID; import org.apache.commons.io.FileUtils; import org.apache.commons.io.filefilter.TrueFileFilter; import org.testng.ITestResult; +import org.testng.SkipException; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeMethod; @@ -34,6 +37,7 @@ import com.github.dockerjava.api.model.PortBinding; import com.github.dockerjava.api.model.Ports; import com.github.dockerjava.api.model.Ports.Binding; +import com.github.dockerjava.core.RemoteApiVersion; import com.github.dockerjava.core.command.BuildImageResultCallback; import com.github.dockerjava.core.command.PushImageResultCallback; import com.github.dockerjava.core.command.WaitContainerResultCallback; @@ -255,6 +259,26 @@ public void buildArgs() throws Exception { assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc")); } + @Test + public void labels() throws Exception { + if (!getVersion(dockerClient).isGreaterOrEqual(RemoteApiVersion.VERSION_1_23)) { + throw new SkipException("API version should be >= 1.23"); + } + + File baseDir = fileFromBuildTestResource("labels"); + + String imageId = dockerClient.buildImageCmd(baseDir).withNoCache(true) + .withLabels(Collections.singletonMap("test", "abc")) + .exec(new BuildImageResultCallback()) + .awaitImageId(); + + InspectImageResponse inspectImageResponse = dockerClient.inspectImageCmd(imageId).exec(); + assertThat(inspectImageResponse, not(nullValue())); + LOG.info("Image Inspect: {}", inspectImageResponse.toString()); + + assertThat(inspectImageResponse.getConfig().getLabels().get("test"), equalTo("abc")); + } + public void dockerfileNotInBaseDirectory() throws Exception { File baseDirectory = fileFromBuildTestResource("dockerfileNotInBaseDirectory"); File dockerfile = fileFromBuildTestResource("dockerfileNotInBaseDirectory/dockerfileFolder/Dockerfile"); diff --git a/src/test/resources/buildTests/labels/Dockerfile b/src/test/resources/buildTests/labels/Dockerfile new file mode 100644 index 000000000..6a8106b86 --- /dev/null +++ b/src/test/resources/buildTests/labels/Dockerfile @@ -0,0 +1,3 @@ +FROM ubuntu:latest + +CMD ["echo", "Success"] From 1ec83d60ea4a30a6e22aa5620fa4ca01f8d23e21 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Thu, 29 Sep 2016 03:35:36 +0300 Subject: [PATCH 269/855] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 908c2d906..efbed07d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ Change Log === -## Next +## Next 3.0.7 + * Label image during build ## 3.0.6 * Fixed issue with jersey and unix domain sockets. From 069987852c842e3bba85ed3325a8877c36f9e87f Mon Sep 17 00:00:00 2001 From: Christopher Dancy Date: Fri, 30 Sep 2016 13:39:51 -0400 Subject: [PATCH 270/855] Expose 'User' property on ExecCreateCmd (#707) (#708) * Expose 'User' property on ExecCreateCmd (#707) --- .../dockerjava/api/command/ExecCreateCmd.java | 5 +++ .../core/command/ExecCreateCmdImpl.java | 17 +++++++++ .../core/command/ExecCreateCmdImplTest.java | 2 +- .../core/command/ExecStartCmdImplTest.java | 37 ++++++++++++++----- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java b/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java index fe2329290..829ebf8ee 100644 --- a/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java +++ b/src/main/java/com/github/dockerjava/api/command/ExecCreateCmd.java @@ -20,6 +20,9 @@ public interface ExecCreateCmd extends SyncDockerCmd { @CheckForNull Boolean hasTtyEnabled(); + @CheckForNull + String getUser(); + ExecCreateCmd withAttachStderr(Boolean attachStderr); ExecCreateCmd withAttachStdin(Boolean attachStdin); @@ -32,6 +35,8 @@ public interface ExecCreateCmd extends SyncDockerCmd { ExecCreateCmd withTty(Boolean tty); + ExecCreateCmd withUser(String user); + interface Exec extends DockerCmdSyncExec { } diff --git a/src/main/java/com/github/dockerjava/core/command/ExecCreateCmdImpl.java b/src/main/java/com/github/dockerjava/core/command/ExecCreateCmdImpl.java index 14da4626a..fc8bf1c0b 100644 --- a/src/main/java/com/github/dockerjava/core/command/ExecCreateCmdImpl.java +++ b/src/main/java/com/github/dockerjava/core/command/ExecCreateCmdImpl.java @@ -26,6 +26,12 @@ public class ExecCreateCmdImpl extends AbstrDockerCmd 0); } + + @Test(groups = "ignoreInCircleCi", expectedExceptions = NotFoundException.class) + public void execStartWithNonExistentUser() throws Exception { + String containerName = "generated_" + new SecureRandom().nextInt(); + + CreateContainerResponse container = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + .withName(containerName).exec(); + LOG.info("Created container {}", container.toString()); + assertThat(container.getId(), not(isEmptyString())); + + dockerClient.startContainerCmd(container.getId()).exec(); + + ExecCreateCmdResponse execCreateCmdResponse = dockerClient.execCreateCmd(container.getId()) + .withAttachStdout(true).withCmd("touch", "/execStartTest.log").withUser("NonExistentUser").exec(); + dockerClient.execStartCmd(execCreateCmdResponse.getId()).withDetach(false).withTty(true) + .exec(new ExecStartResultCallback(System.out, System.err)).awaitCompletion(); + + dockerClient.copyArchiveFromContainerCmd(container.getId(), "/execStartTest.log").exec(); + } } From b3be4fb1b9cdf3c1cd6a7d30ac91fff2d2e31264 Mon Sep 17 00:00:00 2001 From: Kanstantsin Shautsou Date: Fri, 30 Sep 2016 21:32:07 +0300 Subject: [PATCH 271/855] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index efbed07d8..8f41b2938 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Change Log === ## Next 3.0.7 * Label image during build + * Expose 'User' property on ExecCreateCmd #707 #708 ## 3.0.6 * Fixed issue with jersey and unix domain sockets. From 5736b4bb235afab960866b0d0f18bb7aa7a3e527 Mon Sep 17 00:00:00 2001 From: Hendrik-H Date: Fri, 7 Oct 2016 22:33:51 +0200 Subject: [PATCH 272/855] Support volumes propagation flags (Issue 554) (#705) * Support nocopy option in volume binds (#688) * support volumes propagation flags, fixes #554 * renamed values to match java convention --- .../com/github/dockerjava/api/model/Bind.java | 54 ++++++++++++- .../dockerjava/api/model/PropagationMode.java | 50 ++++++++++++ .../github/dockerjava/api/model/BindTest.java | 79 +++++++++++++++++++ .../exec/CreateContainerCmdExecTest.java | 37 +++++++++ 4 files changed, 217 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/github/dockerjava/api/model/PropagationMode.java diff --git a/src/main/java/com/github/dockerjava/api/model/Bind.java b/src/main/java/com/github/dockerjava/api/model/Bind.java index 0995c87ac..9a7ebf18d 100644 --- a/src/main/java/com/github/dockerjava/api/model/Bind.java +++ b/src/main/java/com/github/dockerjava/api/model/Bind.java @@ -18,24 +18,48 @@ public class Bind implements Serializable { private AccessMode accessMode; + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_23} + */ + private Boolean noCopy; + /** * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_17} */ private SELContext secMode; + /** + * @since {@link com.github.dockerjava.core.RemoteApiVersion#VERSION_1_22} + */ + private PropagationMode propagationMode; + public Bind(String path, Volume volume) { this(path, volume, AccessMode.DEFAULT, SELContext.DEFAULT); } + public Bind(String path, Volume volume, Boolean noCopy) { + this(path, volume, AccessMode.DEFAULT, SELContext.DEFAULT, noCopy); + } + public Bind(String path, Volume volume, AccessMode accessMode) { this(path, volume, accessMode, SELContext.DEFAULT); } public Bind(String path, Volume volume, AccessMode accessMode, SELContext secMode) { + this(path, volume, accessMode, secMode, null); + } + + public Bind(String path, Volume volume, AccessMode accessMode, SELContext secMode, Boolean noCopy) { + this(path, volume, accessMode, secMode, noCopy, PropagationMode.DEFAULT_MODE); + } + + public Bind(String path, Volume volume, AccessMode accessMode, SELContext secMode, Boolean noCopy, PropagationMode propagationMode) { this.path = path; this.volume = volume; this.accessMode = accessMode; this.secMode = secMode; + this.noCopy = noCopy; + this.propagationMode = propagationMode; } public String getPath() { @@ -54,6 +78,14 @@ public SELContext getSecMode() { return secMode; } + public Boolean getNoCopy() { + return noCopy; + } + + public PropagationMode getPropagationMode() { + return propagationMode; + } + /** * Parses a bind mount specification to a {@link Bind}. * @@ -74,15 +106,25 @@ public static Bind parse(String serialized) { String[] flags = parts[2].split(","); AccessMode accessMode = AccessMode.DEFAULT; SELContext seMode = SELContext.DEFAULT; + Boolean nocopy = null; + PropagationMode propagationMode = PropagationMode.DEFAULT_MODE; for (String p : flags) { if (p.length() == 2) { accessMode = AccessMode.valueOf(p.toLowerCase()); + } else if ("nocopy".equals(p)) { + nocopy = true; + } else if (PropagationMode.SHARED.toString().equals(p)) { + propagationMode = PropagationMode.SHARED; + } else if (PropagationMode.SLAVE.toString().equals(p)) { + propagationMode = PropagationMode.SLAVE; + } else if (PropagationMode.PRIVATE.toString().equals(p)) { + propagationMode = PropagationMode.PRIVATE; } else { seMode = SELContext.fromString(p); } } - return new Bind(parts[0], new Volume(parts[1]), accessMode, seMode); + return new Bind(parts[0], new Volume(parts[1]), accessMode, seMode, nocopy, propagationMode); } default: { throw new IllegalArgumentException(); @@ -102,6 +144,8 @@ public boolean equals(Object obj) { .append(volume, other.getVolume()) .append(accessMode, other.getAccessMode()) .append(secMode, other.getSecMode()) + .append(noCopy, other.getNoCopy()) + .append(propagationMode, other.getPropagationMode()) .isEquals(); } else { return super.equals(obj); @@ -115,6 +159,8 @@ public int hashCode() { .append(volume) .append(accessMode) .append(secMode) + .append(noCopy) + .append(propagationMode) .toHashCode(); } @@ -127,10 +173,12 @@ public int hashCode() { */ @Override public String toString() { - return String.format("%s:%s:%s%s", + return String.format("%s:%s:%s%s%s%s", path, volume.getPath(), accessMode.toString(), - secMode != SELContext.none ? "," + secMode.toString() : ""); + secMode != SELContext.none ? "," + secMode.toString() : "", + noCopy != null ? ",nocopy" : "", + propagationMode != PropagationMode.DEFAULT_MODE ? "," + propagationMode.toString() : ""); } } diff --git a/src/main/java/com/github/dockerjava/api/model/PropagationMode.java b/src/main/java/com/github/dockerjava/api/model/PropagationMode.java new file mode 100644 index 000000000..9be7d6e43 --- /dev/null +++ b/src/main/java/com/github/dockerjava/api/model/PropagationMode.java @@ -0,0 +1,50 @@ +package com.github.dockerjava.api.model; + +/** + * The propagation mode of a file system or file: shared, slave or private. + * + * @see https://github.com/docker/docker/pull/17034 + * @since 1.22 + */ +public enum PropagationMode { + /** default */ + DEFAULT(""), + + /** shared */ + SHARED("shared"), + + /** slave */ + SLAVE("slave"), + + /** private */ + PRIVATE("private"); + + /** + * The default {@link PropagationMode}: {@link #DEFAULT} + */ + public static final PropagationMode DEFAULT_MODE = DEFAULT; + + private String value; + + PropagationMode(String v) { + value = v; + } + + @Override + public String toString() { + return value; + } + + public static PropagationMode fromString(String v) { + switch (v) { + case "shared": + return SHARED; + case "slave": + return SLAVE; + case "private": + return PRIVATE; + default: + return DEFAULT; + } + } +} diff --git a/src/test/java/com/github/dockerjava/api/model/BindTest.java b/src/test/java/com/github/dockerjava/api/model/BindTest.java index 3204ee716..2e6fd8353 100644 --- a/src/test/java/com/github/dockerjava/api/model/BindTest.java +++ b/src/test/java/com/github/dockerjava/api/model/BindTest.java @@ -3,6 +3,7 @@ import static com.github.dockerjava.api.model.AccessMode.ro; import static com.github.dockerjava.api.model.AccessMode.rw; import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.core.Is.is; import org.testng.annotations.Test; @@ -16,6 +17,8 @@ public void parseUsingDefaultAccessMode() { assertThat(bind.getVolume().getPath(), is("/container")); assertThat(bind.getAccessMode(), is(AccessMode.DEFAULT)); assertThat(bind.getSecMode(), is(SELContext.none)); + assertThat(bind.getNoCopy(), nullValue()); + assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE)); } @Test @@ -25,6 +28,52 @@ public void parseReadWrite() { assertThat(bind.getVolume().getPath(), is("/container")); assertThat(bind.getAccessMode(), is(rw)); assertThat(bind.getSecMode(), is(SELContext.none)); + assertThat(bind.getNoCopy(), nullValue()); + assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE)); + } + + @Test + public void parseReadWriteNoCopy() { + Bind bind = Bind.parse("/host:/container:rw,nocopy"); + assertThat(bind.getPath(), is("/host")); + assertThat(bind.getVolume().getPath(), is("/container")); + assertThat(bind.getAccessMode(), is(rw)); + assertThat(bind.getSecMode(), is(SELContext.none)); + assertThat(bind.getNoCopy(), is(true)); + assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE)); + } + + @Test + public void parseReadWriteShared() { + Bind bind = Bind.parse("/host:/container:rw,shared"); + assertThat(bind.getPath(), is("/host")); + assertThat(bind.getVolume().getPath(), is("/container")); + assertThat(bind.getAccessMode(), is(rw)); + assertThat(bind.getSecMode(), is(SELContext.none)); + assertThat(bind.getNoCopy(), nullValue()); + assertThat(bind.getPropagationMode(), is(PropagationMode.SHARED)); + } + + @Test + public void parseReadWriteSlave() { + Bind bind = Bind.parse("/host:/container:rw,slave"); + assertThat(bind.getPath(), is("/host")); + assertThat(bind.getVolume().getPath(), is("/container")); + assertThat(bind.getAccessMode(), is(rw)); + assertThat(bind.getSecMode(), is(SELContext.none)); + assertThat(bind.getNoCopy(), nullValue()); + assertThat(bind.getPropagationMode(), is(PropagationMode.SLAVE)); + } + + @Test + public void parseReadWritePrivate() { + Bind bind = Bind.parse("/host:/container:rw,private"); + assertThat(bind.getPath(), is("/host")); + assertThat(bind.getVolume().getPath(), is("/container")); + assertThat(bind.getAccessMode(), is(rw)); + assertThat(bind.getSecMode(), is(SELContext.none)); + assertThat(bind.getNoCopy(), nullValue()); + assertThat(bind.getPropagationMode(), is(PropagationMode.PRIVATE)); } @Test @@ -34,6 +83,8 @@ public void parseReadOnly() { assertThat(bind.getVolume().getPath(), is("/container")); assertThat(bind.getAccessMode(), is(ro)); assertThat(bind.getSecMode(), is(SELContext.none)); + assertThat(bind.getNoCopy(), nullValue()); + assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE)); } @Test @@ -43,12 +94,16 @@ public void parseSELOnly() { assertThat(bind.getVolume().getPath(), is("/container")); assertThat(bind.getAccessMode(), is(AccessMode.DEFAULT)); assertThat(bind.getSecMode(), is(SELContext.single)); + assertThat(bind.getNoCopy(), nullValue()); + assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE)); bind = Bind.parse("/host:/container:z"); assertThat(bind.getPath(), is("/host")); assertThat(bind.getVolume().getPath(), is("/container")); assertThat(bind.getAccessMode(), is(AccessMode.DEFAULT)); assertThat(bind.getSecMode(), is(SELContext.shared)); + assertThat(bind.getNoCopy(), nullValue()); + assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE)); } @Test @@ -58,6 +113,8 @@ public void parseReadWriteSEL() { assertThat(bind.getVolume().getPath(), is("/container")); assertThat(bind.getAccessMode(), is(rw)); assertThat(bind.getSecMode(), is(SELContext.single)); + assertThat(bind.getNoCopy(), nullValue()); + assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE)); } @Test @@ -67,6 +124,8 @@ public void parseReadOnlySEL() { assertThat(bind.getVolume().getPath(), is("/container")); assertThat(bind.getAccessMode(), is(ro)); assertThat(bind.getSecMode(), is(SELContext.shared)); + assertThat(bind.getNoCopy(), nullValue()); + assertThat(bind.getPropagationMode(), is(PropagationMode.DEFAULT_MODE)); } @Test(expectedExceptions = IllegalArgumentException.class, expectedExceptionsMessageRegExp = "Error parsing Bind.*") @@ -94,6 +153,26 @@ public void toStringReadWrite() { assertThat(Bind.parse("/host:/container:rw").toString(), is("/host:/container:rw")); } + @Test + public void toStringReadWriteNoCopy() { + assertThat(Bind.parse("/host:/container:rw,nocopy").toString(), is("/host:/container:rw,nocopy")); + } + + @Test + public void toStringReadWriteShared() { + assertThat(Bind.parse("/host:/container:rw,shared").toString(), is("/host:/container:rw,shared")); + } + + @Test + public void toStringReadWriteSlave() { + assertThat(Bind.parse("/host:/container:rw,slave").toString(), is("/host:/container:rw,slave")); + } + + @Test + public void toStringReadWritePrivate() { + assertThat(Bind.parse("/host:/container:rw,private").toString(), is("/host:/container:rw,private")); + } + @Test public void toStringDefaultAccessMode() { assertThat(Bind.parse("/host:/container").toString(), is("/host:/container:rw")); 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 3694ca7fb..aa97b8839 100644 --- a/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java +++ b/src/test/java/com/github/dockerjava/netty/exec/CreateContainerCmdExecTest.java @@ -2,6 +2,7 @@ import com.github.dockerjava.api.command.CreateContainerResponse; import com.github.dockerjava.api.command.CreateNetworkResponse; +import com.github.dockerjava.api.command.CreateVolumeResponse; import com.github.dockerjava.api.command.InspectContainerResponse; import com.github.dockerjava.api.exception.ConflictException; import com.github.dockerjava.api.exception.DockerException; @@ -15,6 +16,7 @@ import com.github.dockerjava.api.model.Network; import com.github.dockerjava.api.model.Ports; import com.github.dockerjava.api.model.Ports.Binding; +import com.github.dockerjava.core.RemoteApiVersion; import com.github.dockerjava.api.model.RestartPolicy; import com.github.dockerjava.api.model.Ulimit; import com.github.dockerjava.api.model.Volume; @@ -23,6 +25,7 @@ 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; @@ -40,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; @@ -138,6 +142,39 @@ public void createContainerWithReadOnlyVolume() throws DockerException { // assertFalse(inspectContainerResponse.getMounts().get(0).getRW()); } + @Test + public void createContainerWithNoCopyVolumes() throws DockerException { + final RemoteApiVersion apiVersion = getVersion(dockerClient); + + if (!apiVersion.isGreaterOrEqual(RemoteApiVersion.VERSION_1_23)) { + throw new SkipException("API version should be >= 1.23"); + } + + Volume volume1 = new Volume("/opt/webapp1"); + String container1Name = UUID.randomUUID().toString(); + + CreateVolumeResponse volumeResponse = dockerClient.createVolumeCmd().withName("webapp1").exec(); + assertThat(volumeResponse.getName(), equalTo("webapp1")); + assertThat(volumeResponse.getDriver(), equalTo("local")); + assertThat(volumeResponse.getMountpoint(), containsString("/webapp1/")); + + Bind bind1 = new Bind("webapp1", volume1, true); + + CreateContainerResponse container1 = dockerClient.createContainerCmd("busybox").withCmd("sleep", "9999") + .withName(container1Name) + .withBinds(bind1).exec(); + LOG.info("Created container1 {}", container1.toString()); + + InspectContainerResponse inspectContainerResponse1 = dockerClient.inspectContainerCmd(container1.getId()).exec(); + + assertThat(Arrays.asList(inspectContainerResponse1.getHostConfig().getBinds()), contains(bind1)); + assertThat(inspectContainerResponse1, mountedVolumes(contains(volume1))); + + assertThat(inspectContainerResponse1.getMounts().get(0).getDestination(), equalTo(volume1)); + assertThat(inspectContainerResponse1.getMounts().get(0).getMode(), equalTo("rw,nocopy")); + assertThat(inspectContainerResponse1.getMounts().get(0).getRW(), equalTo(true)); + } + @Test public void createContainerWithVolumesFrom() throws DockerException { From 6c748c61330cc996c78d5c294e40d98c8294e37e Mon Sep 17 00:00:00 2001 From: valerijf Date: Tue, 11 Oct 2016 13:23:26 +0200 Subject: [PATCH 273/855] 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 274/855] 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 75e9a2cd3d1bf1489f7a94fd9dc8d624359fa430 Mon Sep 17 00:00:00 2001 From: marcuslinke Date: Thu, 27 Oct 2016 20:09:07 +0200 Subject: [PATCH 275/855] 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 cead92e92..c91d4af21 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 276/855] 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 039657807..c2fa5d854 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 277/855] 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 3c04924a2deb4419bf6d987ed615bec88e7ed4f4 Mon Sep 17 00:00:00 2001 From: ooxi Date: Fri, 25 Nov 2016 08:36:37 +0100 Subject: [PATCH 278/855] 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 039657807..79bad7fa9 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 279/855] 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 79bad7fa9..d5052e6b9 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 280/855] 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 a9a15bb36..9d13ec71e 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 281/855] 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 f796fd7c9..539ac7f75 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 9d13ec71e..5857227ae 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 54e70c511..3a4238b22 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 000000000..3ab173fba --- /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 000000000..73ab82aca --- /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 282/855] 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 73bab979e..4b7f2f67e 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 283/855] 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 062082a03..d808ef245 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 1f62527e9..7c625ea94 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 aa97b8839..ab2bd36a0 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 284/855] [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 216c48631..609059f0b 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 285/855] [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 609059f0b..852ad8283 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 286/855] 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 8f41b2938..ca927c2c3 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 287/855] 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 b5a5dcae6..63e66952d 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 36c00c076..9c7120d1f 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 000000000..53b571269 --- /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 000000000..8e67cb783 --- /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 288/855] 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 887c99130..2a9ce0fbf 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 690d478f4..d753fca2b 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 289/855] 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 c5da5bab6..a182751b8 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 534cce52c..1c8ad26a4 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 64e1d7ddf..a6195ed4d 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 3d1a66333..8d8f6e6bb 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 290/855] Test all latest --- .travis.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d055f76e0..69aa64780 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 291/855] 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 69aa64780..eaf11b514 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 292/855] rerun failing tests count to 3 --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 852ad8283..726afefa4 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 293/855] 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 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 294/855] 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 961c282de..5e4a7fa57 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 295/855] 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 296/855] 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 297/855] [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 298/855] [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 299/855] 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 300/855] 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 301/855] 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 302/855] 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 303/855] 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 304/855] 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 305/855] 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 306/855] 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 307/855] 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 308/855] [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 309/855] [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 310/855] 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 311/855] 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 312/855] 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 313/855] 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 314/855] 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 315/855] 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 316/855] 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 317/855] 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 318/855] 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 319/855] [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 320/855] [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 321/855] 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 322/855] 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 323/855] 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 324/855] 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 @@