From 54c41f5327c3f78b17dd56e6f7aa958382f7c0ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Tue, 29 Nov 2022 18:04:59 +0100 Subject: [PATCH 01/17] Support reading currentContext property in config.json --- .../github/dockerjava/core/DockerConfigFile.java | 13 ++++++++++++- .../dockerjava/core/DockerConfigFileTest.java | 8 ++++++++ .../validDockerConfigWithCurrentContext/config.json | 4 ++++ 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 docker-java/src/test/resources/testAuthConfigFile/validDockerConfigWithCurrentContext/config.json diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerConfigFile.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerConfigFile.java index eb5a94e2e..64e0b758c 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerConfigFile.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerConfigFile.java @@ -5,6 +5,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.github.dockerjava.api.model.AuthConfig; import com.github.dockerjava.api.model.AuthConfigurations; +import java.util.Objects; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; @@ -29,6 +30,9 @@ public class DockerConfigFile { @JsonProperty private final Map auths; + @JsonProperty + private String currentContext; + public DockerConfigFile() { this(new HashMap<>()); } @@ -46,6 +50,10 @@ void addAuthConfig(AuthConfig config) { auths.put(config.getRegistryAddress(), config); } + void setCurrentContext(String currentContext) { + this.currentContext = currentContext; + } + @CheckForNull public AuthConfig resolveAuthConfig(@CheckForNull String hostname) { if (StringUtils.isEmpty(hostname) || AuthConfig.DEFAULT_SERVER_ADDRESS.equals(hostname)) { @@ -104,6 +112,9 @@ public boolean equals(Object obj) { return false; } else if (!auths.equals(other.auths)) return false; + if (!Objects.equals(currentContext, other.currentContext)) { + return false; + } return true; } @@ -111,7 +122,7 @@ public boolean equals(Object obj) { @Override public String toString() { - return "DockerConfigFile [auths=" + auths + "]"; + return "DockerConfigFile [auths=" + auths + ", currentContext='" + currentContext + "']"; } @Nonnull diff --git a/docker-java/src/test/java/com/github/dockerjava/core/DockerConfigFileTest.java b/docker-java/src/test/java/com/github/dockerjava/core/DockerConfigFileTest.java index 83bc124e9..ce1a59cc0 100644 --- a/docker-java/src/test/java/com/github/dockerjava/core/DockerConfigFileTest.java +++ b/docker-java/src/test/java/com/github/dockerjava/core/DockerConfigFileTest.java @@ -150,6 +150,14 @@ public void validDockerConfig() throws IOException { assertThat(runTest("validDockerConfig"), is(expected)); } + @Test + public void validDockerConfigWithCurrentContext() throws IOException { + DockerConfigFile expected = new DockerConfigFile(); + expected.setCurrentContext("expectedContext"); + + assertThat(runTest("validDockerConfigWithCurrentContext"), is(expected)); + } + @Test public void nonExistent() throws IOException { DockerConfigFile expected = new DockerConfigFile(); diff --git a/docker-java/src/test/resources/testAuthConfigFile/validDockerConfigWithCurrentContext/config.json b/docker-java/src/test/resources/testAuthConfigFile/validDockerConfigWithCurrentContext/config.json new file mode 100644 index 000000000..8c5963f87 --- /dev/null +++ b/docker-java/src/test/resources/testAuthConfigFile/validDockerConfigWithCurrentContext/config.json @@ -0,0 +1,4 @@ +{ + "auths": {}, + "currentContext": "expectedContext" +} From c303d71414d2e674510abbd5a828dddcff92a989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Tue, 29 Nov 2022 20:37:35 +0100 Subject: [PATCH 02/17] Add a main method to test the thing --- .../core/DockerClientBuilderTest.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java b/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java index be0bfda8a..b90eb8a56 100644 --- a/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java +++ b/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java @@ -1,7 +1,11 @@ package com.github.dockerjava.core; +import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.DockerCmdExecFactory; +import com.github.dockerjava.httpclient5.ApacheDockerHttpClient; +import com.github.dockerjava.transport.DockerHttpClient; +import java.time.Duration; import org.junit.Test; import java.util.ArrayList; @@ -73,4 +77,33 @@ private synchronized Throwable getException() { return exception; } } + + public static void main(String[] args) { + // This is what we want to just work + DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder() + .withDockerHost("unix:///Users/simon/.colima/default/docker.sock") + .build(); + + DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder() + .dockerHost(config.getDockerHost()) + .sslConfig(config.getSSLConfig()) + .maxConnections(100) + .connectionTimeout(Duration.ofSeconds(30)) + .responseTimeout(Duration.ofSeconds(45)) + .build(); + + DockerClient dockerClient = DockerClientImpl.getInstance(config, httpClient); + + dockerClient.pingCmd().exec(); + System.out.println("Containers:"); + dockerClient.listContainersCmd().exec().stream().forEach(container -> { + System.out.println(container.getCommand()); + }); + System.out.println("Images:"); + dockerClient.listImagesCmd().exec().stream().forEach(image -> { + System.out.println(image.getId()); + }); + + } + } From d4963d2ceac6affe1298e719ad78220d5bb09860 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Wed, 30 Nov 2022 08:29:58 +0100 Subject: [PATCH 03/17] Read the docker config file earlier so we can use it to determine host --- .../core/DefaultDockerClientConfig.java | 39 +++++++++++++------ .../dockerjava/core/DockerConfigFile.java | 4 ++ .../core/DefaultDockerClientConfigTest.java | 13 +++---- .../core/DockerClientBuilderTest.java | 5 +-- .../dockerjava/core/DockerClientImplTest.java | 3 +- 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java index 7f17295f3..7c01c1143 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -87,11 +87,12 @@ public class DefaultDockerClientConfig implements Serializable, DockerClientConf private final RemoteApiVersion apiVersion; - private DockerConfigFile dockerConfig = null; + private final DockerConfigFile dockerConfig; - DefaultDockerClientConfig(URI dockerHost, String dockerConfigPath, String apiVersion, String registryUrl, - String registryUsername, String registryPassword, String registryEmail, SSLConfig sslConfig) { + DefaultDockerClientConfig(URI dockerHost, DockerConfigFile dockerConfigFile, String dockerConfigPath, String apiVersion, String registryUrl, + String registryUsername, String registryPassword, String registryEmail, SSLConfig sslConfig) { this.dockerHost = checkDockerHostScheme(dockerHost); + this.dockerConfig = dockerConfigFile; this.dockerConfigPath = dockerConfigPath; this.apiVersion = RemoteApiVersion.parseConfigWithDefault(apiVersion); this.sslConfig = sslConfig; @@ -258,13 +259,6 @@ public String getDockerConfigPath() { @Nonnull public DockerConfigFile getDockerConfig() { - if (dockerConfig == null) { - try { - dockerConfig = DockerConfigFile.loadConfig(getObjectMapper(), getDockerConfigPath()); - } catch (IOException e) { - throw new DockerClientException("Failed to parse docker configuration file", e); - } - } return dockerConfig; } @@ -443,14 +437,35 @@ public DefaultDockerClientConfig build() { sslConfig = customSslConfig; } + final DockerConfigFile dockerConfigFile = readDockerConfig(); + URI dockerHostUri = dockerHost != null ? dockerHost - : URI.create(SystemUtils.IS_OS_WINDOWS ? WINDOWS_DEFAULT_DOCKER_HOST : DEFAULT_DOCKER_HOST); + : dockerHostFromContextOrDefault(dockerConfigFile); - return new DefaultDockerClientConfig(dockerHostUri, dockerConfig, apiVersion, registryUrl, registryUsername, + return new DefaultDockerClientConfig(dockerHostUri, dockerConfigFile, dockerConfig, apiVersion, registryUrl, registryUsername, registryPassword, registryEmail, sslConfig); } + private DockerConfigFile readDockerConfig() { + try { + return DockerConfigFile.loadConfig(DockerClientConfig.getDefaultObjectMapper(), dockerConfig); + } catch (IOException e) { + throw new DockerClientException("Failed to parse docker configuration file", e); + } + } + + private static URI dockerHostFromContextOrDefault(DockerConfigFile dockerConfigFile) { + final String currentContext = dockerConfigFile.getCurrentContext(); + if (currentContext != null) { + System.out.println("Reading context from " + currentContext); + // TODO: Read the context + return URI.create("unix:///Users/simon/.colima/default/docker.sock"); + } else { + return URI.create(SystemUtils.IS_OS_WINDOWS ? WINDOWS_DEFAULT_DOCKER_HOST : DEFAULT_DOCKER_HOST); + } + } + private String checkDockerCertPath(String dockerCertPath) { if (StringUtils.isEmpty(dockerCertPath)) { throw new DockerClientException( diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerConfigFile.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerConfigFile.java index 64e0b758c..825796a74 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerConfigFile.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerConfigFile.java @@ -54,6 +54,10 @@ void setCurrentContext(String currentContext) { this.currentContext = currentContext; } + public String getCurrentContext() { + return currentContext; + } + @CheckForNull public AuthConfig resolveAuthConfig(@CheckForNull String hostname) { if (StringUtils.isEmpty(hostname) || AuthConfig.DEFAULT_SERVER_ADDRESS.equals(hostname)) { diff --git a/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java b/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java index 02b7e34ae..dba758e22 100644 --- a/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java +++ b/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java @@ -1,6 +1,5 @@ package com.github.dockerjava.core; -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; @@ -32,7 +31,7 @@ private static DefaultDockerClientConfig newExampleConfig() { String dockerCertPath = dockerCertPath(); - return new DefaultDockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + return new DefaultDockerClientConfig(URI.create("tcp://foo"), new DockerConfigFile(), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", new LocalDirectorySSLConfig(dockerCertPath)); } @@ -161,7 +160,7 @@ public void serializableTest() { @Test() public void testSslContextEmpty() throws Exception { - new DefaultDockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + new DefaultDockerClientConfig(URI.create("tcp://foo"), new DockerConfigFile(), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", null); } @@ -169,14 +168,14 @@ public void testSslContextEmpty() throws Exception { @Test() public void testTlsVerifyAndCertPath() throws Exception { - new DefaultDockerClientConfig(URI.create("tcp://foo"), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + new DefaultDockerClientConfig(URI.create("tcp://foo"), new DockerConfigFile(), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", new LocalDirectorySSLConfig(dockerCertPath())); } @Test() public void testAnyHostScheme() throws Exception { URI dockerHost = URI.create("a" + UUID.randomUUID().toString().replace("-", "") + "://foo"); - new DefaultDockerClientConfig(dockerHost, "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + new DefaultDockerClientConfig(dockerHost, new DockerConfigFile(), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", null); } @@ -252,7 +251,7 @@ public void dockerHostSetExplicitlyIfSetToDefaultByUser() { 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", + "unix://foo"), new DockerConfigFile(), cfgFile.getAbsolutePath(), "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", null); AuthConfigurations authConfigurations = clientConfig.getAuthConfigurations(); @@ -268,7 +267,7 @@ public void testGetAuthConfigurationsFromDockerCfg() throws URISyntaxException { 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", + "unix://foo"), new DockerConfigFile(), cfgFile.getAbsolutePath(), "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", null); AuthConfigurations authConfigurations = clientConfig.getAuthConfigurations(); diff --git a/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java b/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java index b90eb8a56..ed82f7fab 100644 --- a/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java +++ b/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java @@ -3,6 +3,7 @@ import com.github.dockerjava.api.DockerClient; import com.github.dockerjava.api.command.DockerCmdExecFactory; +import com.github.dockerjava.api.model.PushResponseItem; import com.github.dockerjava.httpclient5.ApacheDockerHttpClient; import com.github.dockerjava.transport.DockerHttpClient; import java.time.Duration; @@ -80,9 +81,7 @@ private synchronized Throwable getException() { public static void main(String[] args) { // This is what we want to just work - DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder() - .withDockerHost("unix:///Users/simon/.colima/default/docker.sock") - .build(); + DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder().build(); DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder() .dockerHost(config.getDockerHost()) diff --git a/docker-java/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java b/docker-java/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java index 08f658d52..8ff17857f 100644 --- a/docker-java/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java +++ b/docker-java/src/test/java/com/github/dockerjava/core/DockerClientImplTest.java @@ -12,7 +12,8 @@ public class DockerClientImplTest { @Test public void configuredInstanceAuthConfig() throws Exception { // given a config with null serverAddress - DefaultDockerClientConfig dockerClientConfig = new DefaultDockerClientConfig(URI.create("tcp://foo"), null, null, null, "", "", "", null); + DefaultDockerClientConfig dockerClientConfig = new DefaultDockerClientConfig(URI.create("tcp://foo"), + new DockerConfigFile(), null, null, null, "", "", "", null); DockerClientImpl dockerClient = DockerClientImpl.getInstance(dockerClientConfig); // when we get the auth config From bab79a3377c0bdd2e396dbf40d9211b8715a0913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Wed, 30 Nov 2022 09:21:51 +0100 Subject: [PATCH 04/17] Start at reading context meta file --- .../core/DockerContextMetaFile.java | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java new file mode 100644 index 000000000..00fa3bf8f --- /dev/null +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java @@ -0,0 +1,55 @@ +package com.github.dockerjava.core; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.IOException; +import javax.annotation.CheckForNull; + +public class DockerContextMetaFile { + @JsonProperty("Name") + String name; + + @JsonProperty("Endpoints") + Endpoints endpoints; + + public static class Endpoints { + @JsonProperty("docker") + Docker docker; + + public static class Docker { + @JsonProperty("Host") + String host; + + @JsonProperty("SkipTLSVerify") + boolean skipTLSVerify; + } + } + + public static DockerContextMetaFile loadContextMeta(ObjectMapper objectMapper, File dockerContextMetaFile) throws IOException { + try { + return objectMapper.readValue(dockerContextMetaFile, DockerContextMetaFile.class); + } catch (IOException e) { + throw new IOException("Failed to parse docker context meta file " + dockerContextMetaFile, e); + } + } + + public static void loadAllContextMetaFiles() { + // TODO + } + + public static void findContextMetaFile(String context) { + // TODO + } + + public static void main(String[] args) { + ObjectMapper mapper = DefaultObjectMapperHolder.INSTANCE.getObjectMapper().copy(); + try { + DockerContextMetaFile dockerContextMetaFile = loadContextMeta(mapper, + new File("/Users/simon/.docker/contexts/meta/f24fd3749c1368328e2b149bec149cb6795619f244c5b584e844961215dadd16/meta.json")); + System.out.println(dockerContextMetaFile.endpoints.docker.host); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} From bc952ec7f9d8baab5cde056102578fe9c32d97e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Thu, 1 Dec 2022 11:50:38 +0100 Subject: [PATCH 05/17] Start of reading all docker context meta files --- .../core/DockerContextMetaFile.java | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java index 00fa3bf8f..3b190d0c6 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java @@ -4,6 +4,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import java.io.File; import java.io.IOException; +import java.util.Arrays; +import java.util.Objects; +import java.util.stream.Stream; import javax.annotation.CheckForNull; public class DockerContextMetaFile { @@ -34,8 +37,24 @@ public static DockerContextMetaFile loadContextMeta(ObjectMapper objectMapper, F } } - public static void loadAllContextMetaFiles() { - // TODO + public static DockerContextMetaFile loadContextMetaOrNull(ObjectMapper objectMapper, File dockerContextMetaFile) { + try { + loadContextMeta(objectMapper, dockerContextMetaFile) + } catch (Exception exception) { + return null; + } + } + + public static Stream loadAllContextMetaFiles(ObjectMapper objectMapper, File dockerConfigPath) throws IOException { + final File contextPath = new File(dockerConfigPath, "contexts/meta"); + File[] files = contextPath.listFiles(); + if (files == null) { + return Stream.of(); + } + return Arrays.stream(files) + .map(dir -> new File(dir, "meta.json")) + .map(file -> loadContextMetaOrNull(objectMapper, file)) + .filter(Objects::nonNull); } public static void findContextMetaFile(String context) { @@ -43,6 +62,9 @@ public static void findContextMetaFile(String context) { } public static void main(String[] args) { + // TODO: We should support the DOCKER_CONTEXT env var as per https://docs.docker.com/engine/context/working-with-contexts/ + loadAllContextMetaFiles(new File("/Users/simon/.docker")); + ObjectMapper mapper = DefaultObjectMapperHolder.INSTANCE.getObjectMapper().copy(); try { DockerContextMetaFile dockerContextMetaFile = loadContextMeta(mapper, From de12bf8998f9dd59fadaa9a7676e241cc175d55b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Fri, 2 Dec 2022 22:34:59 +0100 Subject: [PATCH 06/17] Make docker context loading work --- .../core/DefaultDockerClientConfig.java | 16 +++--- .../core/DockerContextMetaFile.java | 53 ++++++++++--------- .../core/DockerClientBuilderTest.java | 1 - 3 files changed, 37 insertions(+), 33 deletions(-) diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java index 7c01c1143..3fa8c060c 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -1,10 +1,12 @@ package com.github.dockerjava.core; +import com.fasterxml.jackson.databind.ObjectMapper; 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; +import java.util.Optional; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.SystemUtils; import org.apache.commons.lang3.builder.EqualsBuilder; @@ -455,15 +457,13 @@ private DockerConfigFile readDockerConfig() { } } - private static URI dockerHostFromContextOrDefault(DockerConfigFile dockerConfigFile) { + private URI dockerHostFromContextOrDefault(DockerConfigFile dockerConfigFile) { final String currentContext = dockerConfigFile.getCurrentContext(); - if (currentContext != null) { - System.out.println("Reading context from " + currentContext); - // TODO: Read the context - return URI.create("unix:///Users/simon/.colima/default/docker.sock"); - } else { - return URI.create(SystemUtils.IS_OS_WINDOWS ? WINDOWS_DEFAULT_DOCKER_HOST : DEFAULT_DOCKER_HOST); - } + return URI.create(Optional.ofNullable(currentContext) + .flatMap(context -> DockerContextMetaFile.findContextMetaFile( + DockerClientConfig.getDefaultObjectMapper(), new File(dockerConfig), context)) + .flatMap(DockerContextMetaFile::host) + .orElse(SystemUtils.IS_OS_WINDOWS ? WINDOWS_DEFAULT_DOCKER_HOST : DEFAULT_DOCKER_HOST)); } private String checkDockerCertPath(String dockerCertPath) { diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java index 3b190d0c6..e98ab9075 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java @@ -6,8 +6,8 @@ import java.io.IOException; import java.util.Arrays; import java.util.Objects; +import java.util.Optional; import java.util.stream.Stream; -import javax.annotation.CheckForNull; public class DockerContextMetaFile { @JsonProperty("Name") @@ -29,23 +29,21 @@ public static class Docker { } } - public static DockerContextMetaFile loadContextMeta(ObjectMapper objectMapper, File dockerContextMetaFile) throws IOException { - try { - return objectMapper.readValue(dockerContextMetaFile, DockerContextMetaFile.class); - } catch (IOException e) { - throw new IOException("Failed to parse docker context meta file " + dockerContextMetaFile, e); + public Optional host() { + if (endpoints != null && endpoints.docker != null) { + return Optional.ofNullable(endpoints.docker.host); } + return Optional.empty(); } - public static DockerContextMetaFile loadContextMetaOrNull(ObjectMapper objectMapper, File dockerContextMetaFile) { - try { - loadContextMeta(objectMapper, dockerContextMetaFile) - } catch (Exception exception) { - return null; - } + public static Optional findContextMetaFile(ObjectMapper objectMapper, File dockerConfigPath, String context) { + return loadAllContextMetaFiles(objectMapper, dockerConfigPath) + .filter(metaFile -> metaFile.endpoints != null && metaFile.endpoints.docker != null) + .filter(metaFile -> Objects.equals(metaFile.name, context)) + .findFirst(); } - public static Stream loadAllContextMetaFiles(ObjectMapper objectMapper, File dockerConfigPath) throws IOException { + public static Stream loadAllContextMetaFiles(ObjectMapper objectMapper, File dockerConfigPath) { final File contextPath = new File(dockerConfigPath, "contexts/meta"); File[] files = contextPath.listFiles(); if (files == null) { @@ -57,21 +55,28 @@ public static Stream loadAllContextMetaFiles(ObjectMapper .filter(Objects::nonNull); } - public static void findContextMetaFile(String context) { - // TODO + public static DockerContextMetaFile loadContextMetaOrNull(ObjectMapper objectMapper, File dockerContextMetaFile) { + try { + return loadContextMeta(objectMapper, dockerContextMetaFile); + } catch (Exception exception) { + return null; + } } - - public static void main(String[] args) { - // TODO: We should support the DOCKER_CONTEXT env var as per https://docs.docker.com/engine/context/working-with-contexts/ - loadAllContextMetaFiles(new File("/Users/simon/.docker")); - ObjectMapper mapper = DefaultObjectMapperHolder.INSTANCE.getObjectMapper().copy(); + public static DockerContextMetaFile loadContextMeta(ObjectMapper objectMapper, File dockerContextMetaFile) throws IOException { try { - DockerContextMetaFile dockerContextMetaFile = loadContextMeta(mapper, - new File("/Users/simon/.docker/contexts/meta/f24fd3749c1368328e2b149bec149cb6795619f244c5b584e844961215dadd16/meta.json")); - System.out.println(dockerContextMetaFile.endpoints.docker.host); + return objectMapper.readValue(dockerContextMetaFile, DockerContextMetaFile.class); } catch (IOException e) { - throw new RuntimeException(e); + throw new IOException("Failed to parse docker context meta file " + dockerContextMetaFile, e); } } + + public static void main(String[] args) { + ObjectMapper mapper = DefaultObjectMapperHolder.INSTANCE.getObjectMapper().copy(); + String host = findContextMetaFile(mapper, new File("/Users/simon/.docker"), "colima") + .map(file -> file.endpoints.docker.host) + .orElse(null); + + System.out.printf("Host is %s\n", host); + } } diff --git a/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java b/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java index ed82f7fab..91ac1ba93 100644 --- a/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java +++ b/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java @@ -80,7 +80,6 @@ private synchronized Throwable getException() { } public static void main(String[] args) { - // This is what we want to just work DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder().build(); DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder() From 5c77b04a624f50d42a6d1e501878ed42c523d754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Fri, 2 Dec 2022 22:39:10 +0100 Subject: [PATCH 07/17] Checkstyle --- .../github/dockerjava/core/DefaultDockerClientConfig.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java index 3fa8c060c..a76832e82 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -1,6 +1,5 @@ package com.github.dockerjava.core; -import com.fasterxml.jackson.databind.ObjectMapper; import com.github.dockerjava.api.exception.DockerClientException; import com.github.dockerjava.api.model.AuthConfig; import com.github.dockerjava.api.model.AuthConfigurations; @@ -91,8 +90,9 @@ public class DefaultDockerClientConfig implements Serializable, DockerClientConf private final DockerConfigFile dockerConfig; - DefaultDockerClientConfig(URI dockerHost, DockerConfigFile dockerConfigFile, String dockerConfigPath, String apiVersion, String registryUrl, - String registryUsername, String registryPassword, String registryEmail, SSLConfig sslConfig) { + DefaultDockerClientConfig(URI dockerHost, DockerConfigFile dockerConfigFile, String dockerConfigPath, String apiVersion, + String registryUrl, String registryUsername, String registryPassword, String registryEmail, + SSLConfig sslConfig) { this.dockerHost = checkDockerHostScheme(dockerHost); this.dockerConfig = dockerConfigFile; this.dockerConfigPath = dockerConfigPath; From f700d506dd401fb8853e2ed7df17aca1391bf499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Mon, 16 Jan 2023 21:00:16 +0100 Subject: [PATCH 08/17] Find meta file more directly through hash function --- .../core/DefaultDockerClientConfig.java | 2 +- .../core/DockerContextMetaFile.java | 36 ++++++++----------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java index a76832e82..0d1e3e281 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -460,7 +460,7 @@ private DockerConfigFile readDockerConfig() { private URI dockerHostFromContextOrDefault(DockerConfigFile dockerConfigFile) { final String currentContext = dockerConfigFile.getCurrentContext(); return URI.create(Optional.ofNullable(currentContext) - .flatMap(context -> DockerContextMetaFile.findContextMetaFile( + .flatMap(context -> DockerContextMetaFile.loadContextMetaFile( DockerClientConfig.getDefaultObjectMapper(), new File(dockerConfig), context)) .flatMap(DockerContextMetaFile::host) .orElse(SystemUtils.IS_OS_WINDOWS ? WINDOWS_DEFAULT_DOCKER_HOST : DEFAULT_DOCKER_HOST)); diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java index e98ab9075..2b79af268 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java @@ -2,14 +2,16 @@ import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.hash.HashFunction; +import com.google.common.hash.Hashing; import java.io.File; import java.io.IOException; -import java.util.Arrays; -import java.util.Objects; +import java.nio.charset.StandardCharsets; import java.util.Optional; -import java.util.stream.Stream; public class DockerContextMetaFile { + private static HashFunction metaHashFunction = Hashing.sha256(); + @JsonProperty("Name") String name; @@ -36,23 +38,14 @@ public Optional host() { return Optional.empty(); } - public static Optional findContextMetaFile(ObjectMapper objectMapper, File dockerConfigPath, String context) { - return loadAllContextMetaFiles(objectMapper, dockerConfigPath) - .filter(metaFile -> metaFile.endpoints != null && metaFile.endpoints.docker != null) - .filter(metaFile -> Objects.equals(metaFile.name, context)) - .findFirst(); - } - - public static Stream loadAllContextMetaFiles(ObjectMapper objectMapper, File dockerConfigPath) { - final File contextPath = new File(dockerConfigPath, "contexts/meta"); - File[] files = contextPath.listFiles(); - if (files == null) { - return Stream.of(); - } - return Arrays.stream(files) - .map(dir -> new File(dir, "meta.json")) - .map(file -> loadContextMetaOrNull(objectMapper, file)) - .filter(Objects::nonNull); + public static Optional loadContextMetaFile(ObjectMapper objectMapper, File dockerConfigPath, String context) { + final File path = dockerConfigPath.toPath() + .resolve("contexts") + .resolve("meta") + .resolve(metaHashFunction.hashString(context, StandardCharsets.UTF_8).toString()) + .resolve("meta.json") + .toFile(); + return Optional.ofNullable(loadContextMetaOrNull(objectMapper, path)); } public static DockerContextMetaFile loadContextMetaOrNull(ObjectMapper objectMapper, File dockerContextMetaFile) { @@ -73,7 +66,8 @@ public static DockerContextMetaFile loadContextMeta(ObjectMapper objectMapper, F public static void main(String[] args) { ObjectMapper mapper = DefaultObjectMapperHolder.INSTANCE.getObjectMapper().copy(); - String host = findContextMetaFile(mapper, new File("/Users/simon/.docker"), "colima") + Optional colima = loadContextMetaFile(mapper, new File("/Users/simon/.docker"), "colima"); + String host = colima .map(file -> file.endpoints.docker.host) .orElse(null); From 046d08f2c79412214398f296117c7c7f6531e3d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Thu, 2 Feb 2023 20:52:06 +0100 Subject: [PATCH 09/17] Add very failing test for supporting DOCKER_CONTEXT env var --- .../dockerjava/core/DefaultDockerClientConfig.java | 2 ++ .../core/DefaultDockerClientConfigTest.java | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java index 0d1e3e281..516d6596e 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -38,6 +38,8 @@ public class DefaultDockerClientConfig implements Serializable, DockerClientConf public static final String DOCKER_HOST = "DOCKER_HOST"; + public static final String DOCKER_CONTEXT = "DOCKER_CONTEXT"; + public static final String DOCKER_TLS_VERIFY = "DOCKER_TLS_VERIFY"; public static final String DOCKER_CONFIG = "DOCKER_CONFIG"; diff --git a/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java b/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java index dba758e22..068a34d0f 100644 --- a/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java +++ b/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java @@ -68,6 +68,20 @@ public void environmentDockerHost() throws Exception { assertEquals(config.getDockerHost(), URI.create("tcp://baz:8768")); } + @Test + public void environmentDockerContext() throws Exception { + // given docker context + Map env = new HashMap<>(); + env.put(DefaultDockerClientConfig.DOCKER_CONTEXT, "testcontext"); + + // when you build a config + DefaultDockerClientConfig config = buildConfig(env, new Properties()); + + // Then we want the host specified by the context. But hey, where is that even going to come from? We haven't set up any test + // fixtures for the context.... + assertEquals("thetestcontexthost.com", config.getDockerHost()); + } + @Test public void environment() throws Exception { From 2bf43e42b4031a291505932d0ceeead58e1e6ee6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Fri, 3 Feb 2023 09:04:24 +0100 Subject: [PATCH 10/17] Add a mock home directory with docker context json and meta files --- .../core/DefaultDockerClientConfigTest.java | 31 ++++++++++++++----- .../dockerContextHomeDir/.docker/config.json | 4 +++ .../meta.json | 12 +++++++ .../meta.json | 12 +++++++ 4 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 docker-java/src/test/resources/dockerContextHomeDir/.docker/config.json create mode 100644 docker-java/src/test/resources/dockerContextHomeDir/.docker/contexts/meta/51699a7c75211315f1dbf6ecc40dfb0ffdd4ee11ecb2ce7853c9751aea1f9444/meta.json create mode 100644 docker-java/src/test/resources/dockerContextHomeDir/.docker/contexts/meta/d090e08f0c9167acd72adef6d9fa07ec2de3a873cdd545dd8cb7fc7a10a1331a/meta.json diff --git a/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java b/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java index 068a34d0f..966671e81 100644 --- a/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java +++ b/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java @@ -69,17 +69,34 @@ public void environmentDockerHost() throws Exception { } @Test - public void environmentDockerContext() throws Exception { - // given docker context + public void dockerContextFromConfig() throws Exception { + // given home directory with docker contexts configured + Properties systemProperties = new Properties(); + systemProperties.setProperty("user.home", "target/test-classes/dockerContextHomeDir"); + + // and an empty environment Map env = new HashMap<>(); - env.put(DefaultDockerClientConfig.DOCKER_CONTEXT, "testcontext"); // when you build a config - DefaultDockerClientConfig config = buildConfig(env, new Properties()); + DefaultDockerClientConfig config = buildConfig(env, systemProperties); + + assertEquals(URI.create("unix:///configcontext.sock"), config.getDockerHost()); + } + + @Test + public void dockerContextFromEnvironmentVariable() throws Exception { + // given home directory with docker contexts + Properties systemProperties = new Properties(); + systemProperties.setProperty("user.home", "target/test-classes/dockerContextHomeDir"); + + // and an environment variable that overrides docker context + Map env = new HashMap<>(); + env.put(DefaultDockerClientConfig.DOCKER_CONTEXT, "envvarcontext"); + + // when you build a config + DefaultDockerClientConfig config = buildConfig(env, systemProperties); - // Then we want the host specified by the context. But hey, where is that even going to come from? We haven't set up any test - // fixtures for the context.... - assertEquals("thetestcontexthost.com", config.getDockerHost()); + assertEquals(URI.create("unix:///envvarcontext.sock"), config.getDockerHost()); } @Test diff --git a/docker-java/src/test/resources/dockerContextHomeDir/.docker/config.json b/docker-java/src/test/resources/dockerContextHomeDir/.docker/config.json new file mode 100644 index 000000000..5bb2ebebe --- /dev/null +++ b/docker-java/src/test/resources/dockerContextHomeDir/.docker/config.json @@ -0,0 +1,4 @@ +{ + "auths": {}, + "currentContext": "configcontext" +} diff --git a/docker-java/src/test/resources/dockerContextHomeDir/.docker/contexts/meta/51699a7c75211315f1dbf6ecc40dfb0ffdd4ee11ecb2ce7853c9751aea1f9444/meta.json b/docker-java/src/test/resources/dockerContextHomeDir/.docker/contexts/meta/51699a7c75211315f1dbf6ecc40dfb0ffdd4ee11ecb2ce7853c9751aea1f9444/meta.json new file mode 100644 index 000000000..c6456d6b8 --- /dev/null +++ b/docker-java/src/test/resources/dockerContextHomeDir/.docker/contexts/meta/51699a7c75211315f1dbf6ecc40dfb0ffdd4ee11ecb2ce7853c9751aea1f9444/meta.json @@ -0,0 +1,12 @@ +{ + "Name": "envvarcontext", + "Metadata": { + "Description": "envvarcontext" + }, + "Endpoints": { + "docker": { + "Host": "unix:///envvarcontext.sock", + "SkipTLSVerify": false + } + } +} diff --git a/docker-java/src/test/resources/dockerContextHomeDir/.docker/contexts/meta/d090e08f0c9167acd72adef6d9fa07ec2de3a873cdd545dd8cb7fc7a10a1331a/meta.json b/docker-java/src/test/resources/dockerContextHomeDir/.docker/contexts/meta/d090e08f0c9167acd72adef6d9fa07ec2de3a873cdd545dd8cb7fc7a10a1331a/meta.json new file mode 100644 index 000000000..adff3b1c9 --- /dev/null +++ b/docker-java/src/test/resources/dockerContextHomeDir/.docker/contexts/meta/d090e08f0c9167acd72adef6d9fa07ec2de3a873cdd545dd8cb7fc7a10a1331a/meta.json @@ -0,0 +1,12 @@ +{ + "Name": "configcontext", + "Metadata": { + "Description": "configcontext" + }, + "Endpoints": { + "docker": { + "Host": "unix:///configcontext.sock", + "SkipTLSVerify": false + } + } +} From d6162d005b86fe18ce6b7596ea695fa50e0582c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Fri, 3 Feb 2023 20:23:31 +0100 Subject: [PATCH 11/17] Implement support for DOCKER_CONTEXT environment variable --- .../core/DefaultDockerClientConfig.java | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java index 516d6596e..34b8dd5a2 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -179,6 +179,13 @@ private static Properties overrideDockerPropertiesWithEnv(Properties properties, } } + if (env.containsKey(DOCKER_CONTEXT)) { + String value = env.get(DOCKER_CONTEXT); + if (value != null && value.trim().length() != 0) { + overriddenProperties.setProperty(DOCKER_CONTEXT, value); + } + } + for (Map.Entry envEntry : env.entrySet()) { String envKey = envEntry.getKey(); if (CONFIG_KEYS.contains(envKey)) { @@ -323,7 +330,7 @@ public static class Builder { private URI dockerHost; private String apiVersion, registryUsername, registryPassword, registryEmail, registryUrl, dockerConfig, - dockerCertPath; + dockerCertPath, dockerContext; private Boolean dockerTlsVerify; @@ -341,6 +348,7 @@ public Builder withProperties(Properties p) { } return withDockerTlsVerify(p.getProperty(DOCKER_TLS_VERIFY)) + .withDockerContext(p.getProperty(DOCKER_CONTEXT)) .withDockerConfig(p.getProperty(DOCKER_CONFIG)) .withDockerCertPath(p.getProperty(DOCKER_CERT_PATH)) .withApiVersion(p.getProperty(API_VERSION)) @@ -399,6 +407,11 @@ public final Builder withDockerConfig(String dockerConfig) { return this; } + public final Builder withDockerContext(String dockerContext) { + this.dockerContext = dockerContext; + return this; + } + public final Builder withDockerTlsVerify(String dockerTlsVerify) { if (dockerTlsVerify != null) { String trimmed = dockerTlsVerify.trim(); @@ -443,9 +456,10 @@ public DefaultDockerClientConfig build() { final DockerConfigFile dockerConfigFile = readDockerConfig(); + final String context = (dockerContext != null) ? dockerContext : dockerConfigFile.getCurrentContext(); URI dockerHostUri = dockerHost != null ? dockerHost - : dockerHostFromContextOrDefault(dockerConfigFile); + : dockerHostFromContextOrDefault(context); return new DefaultDockerClientConfig(dockerHostUri, dockerConfigFile, dockerConfig, apiVersion, registryUrl, registryUsername, registryPassword, registryEmail, sslConfig); @@ -459,9 +473,8 @@ private DockerConfigFile readDockerConfig() { } } - private URI dockerHostFromContextOrDefault(DockerConfigFile dockerConfigFile) { - final String currentContext = dockerConfigFile.getCurrentContext(); - return URI.create(Optional.ofNullable(currentContext) + private URI dockerHostFromContextOrDefault(String dockerContext) { + return URI.create(Optional.ofNullable(dockerContext) .flatMap(context -> DockerContextMetaFile.loadContextMetaFile( DockerClientConfig.getDefaultObjectMapper(), new File(dockerConfig), context)) .flatMap(DockerContextMetaFile::host) From 7938143eaf82a6bd9afcc4fdaaa1c5d21cee3d69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Sat, 4 Feb 2023 20:43:24 +0100 Subject: [PATCH 12/17] Make config.json in someHomeDir valid --- .../src/test/resources/someHomeDir/.docker/config.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker-java/src/test/resources/someHomeDir/.docker/config.json b/docker-java/src/test/resources/someHomeDir/.docker/config.json index 630394039..02ed0cf7f 100644 --- a/docker-java/src/test/resources/someHomeDir/.docker/config.json +++ b/docker-java/src/test/resources/someHomeDir/.docker/config.json @@ -1,9 +1,9 @@ { "auths":{ "https://index.docker.io/v1/":{ - "auth":"XXXX=", + "auth":"dXNlcm5hbWU6cGFzc3dvcmQ=", "email":"foo.bar@test.com" } } -} \ No newline at end of file +} From 49149419ca58c5235a38573322b3964e160788c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Sun, 5 Feb 2023 11:28:40 +0100 Subject: [PATCH 13/17] Fix tests --- .../core/DefaultDockerClientConfigTest.java | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java b/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java index 966671e81..d5b751145 100644 --- a/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java +++ b/docker-java/src/test/java/com/github/dockerjava/core/DefaultDockerClientConfigTest.java @@ -3,6 +3,7 @@ import com.github.dockerjava.api.model.AuthConfig; import com.github.dockerjava.api.model.AuthConfigurations; import com.google.common.io.Resources; +import java.io.IOException; import org.apache.commons.lang3.SerializationUtils; import org.junit.Test; @@ -26,13 +27,26 @@ public class DefaultDockerClientConfigTest { public static final DefaultDockerClientConfig EXAMPLE_CONFIG = newExampleConfig(); + public static final DefaultDockerClientConfig EXAMPLE_CONFIG_FULLY_LOADED = newExampleConfigFullyLoaded(); private static DefaultDockerClientConfig newExampleConfig() { - String dockerCertPath = dockerCertPath(); + return new DefaultDockerClientConfig(URI.create("tcp://foo"), null, "dockerConfig", "apiVersion", "registryUrl", + "registryUsername", "registryPassword", "registryEmail", + new LocalDirectorySSLConfig(dockerCertPath)); + } - return new DefaultDockerClientConfig(URI.create("tcp://foo"), new DockerConfigFile(), "dockerConfig", "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", + private static DefaultDockerClientConfig newExampleConfigFullyLoaded() { + try { + String dockerCertPath = dockerCertPath(); + String dockerConfig = "dockerConfig"; + DockerConfigFile loadedConfigFile = DockerConfigFile.loadConfig(DockerClientConfig.getDefaultObjectMapper(), dockerConfig); + return new DefaultDockerClientConfig(URI.create("tcp://foo"), loadedConfigFile, dockerConfig, "apiVersion", "registryUrl", + "registryUsername", "registryPassword", "registryEmail", new LocalDirectorySSLConfig(dockerCertPath)); + } catch (IOException exception) { + throw new RuntimeException(exception); + } } private static String homeDir() { @@ -118,7 +132,7 @@ public void environment() throws Exception { DefaultDockerClientConfig config = buildConfig(env, new Properties()); // then we get the example object - assertEquals(config, EXAMPLE_CONFIG); + assertEquals(EXAMPLE_CONFIG_FULLY_LOADED, config); } @Test @@ -177,7 +191,7 @@ public void systemProperties() throws Exception { DefaultDockerClientConfig config = buildConfig(Collections. emptyMap(), systemProperties); // then it is the same as the example - assertEquals(config, EXAMPLE_CONFIG); + assertEquals(EXAMPLE_CONFIG_FULLY_LOADED, config); } @@ -279,10 +293,12 @@ public void dockerHostSetExplicitlyIfSetToDefaultByUser() { @Test - public void testGetAuthConfigurationsFromDockerCfg() throws URISyntaxException { + public void testGetAuthConfigurationsFromDockerCfg() throws URISyntaxException, IOException { File cfgFile = new File(Resources.getResource("com.github.dockerjava.core/registry.v1").toURI()); + DockerConfigFile dockerConfigFile = + DockerConfigFile.loadConfig(DockerClientConfig.getDefaultObjectMapper(), cfgFile.getAbsolutePath()); DefaultDockerClientConfig clientConfig = new DefaultDockerClientConfig(URI.create( - "unix://foo"), new DockerConfigFile(), cfgFile.getAbsolutePath(), "apiVersion", "registryUrl", "registryUsername", "registryPassword", + "unix://foo"), dockerConfigFile, cfgFile.getAbsolutePath(), "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", null); AuthConfigurations authConfigurations = clientConfig.getAuthConfigurations(); @@ -295,10 +311,12 @@ public void testGetAuthConfigurationsFromDockerCfg() throws URISyntaxException { } @Test - public void testGetAuthConfigurationsFromConfigJson() throws URISyntaxException { + public void testGetAuthConfigurationsFromConfigJson() throws URISyntaxException, IOException { File cfgFile = new File(Resources.getResource("com.github.dockerjava.core/registry.v2").toURI()); + DockerConfigFile dockerConfigFile = + DockerConfigFile.loadConfig(DockerClientConfig.getDefaultObjectMapper(), cfgFile.getAbsolutePath()); DefaultDockerClientConfig clientConfig = new DefaultDockerClientConfig(URI.create( - "unix://foo"), new DockerConfigFile(), cfgFile.getAbsolutePath(), "apiVersion", "registryUrl", "registryUsername", "registryPassword", + "unix://foo"), dockerConfigFile, cfgFile.getAbsolutePath(), "apiVersion", "registryUrl", "registryUsername", "registryPassword", "registryEmail", null); AuthConfigurations authConfigurations = clientConfig.getAuthConfigurations(); From 2f1481bcbde1abd0bec222e924350fc5332f3e94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Tue, 7 Feb 2023 06:35:47 +0100 Subject: [PATCH 14/17] Update docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Eddú Meléndez Gonzales --- .../github/dockerjava/core/DockerContextMetaFile.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java index 2b79af268..a7c539104 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java @@ -63,14 +63,4 @@ public static DockerContextMetaFile loadContextMeta(ObjectMapper objectMapper, F throw new IOException("Failed to parse docker context meta file " + dockerContextMetaFile, e); } } - - public static void main(String[] args) { - ObjectMapper mapper = DefaultObjectMapperHolder.INSTANCE.getObjectMapper().copy(); - Optional colima = loadContextMetaFile(mapper, new File("/Users/simon/.docker"), "colima"); - String host = colima - .map(file -> file.endpoints.docker.host) - .orElse(null); - - System.out.printf("Host is %s\n", host); - } } From 9a8d2498f1d577afab4440f8631917af67df455f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Tue, 7 Feb 2023 06:36:05 +0100 Subject: [PATCH 15/17] Update docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Eddú Meléndez Gonzales --- .../core/DockerClientBuilderTest.java | 26 ------------------- 1 file changed, 26 deletions(-) diff --git a/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java b/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java index 91ac1ba93..43e700fd8 100644 --- a/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java +++ b/docker-java/src/test/java/com/github/dockerjava/core/DockerClientBuilderTest.java @@ -78,30 +78,4 @@ private synchronized Throwable getException() { return exception; } } - - public static void main(String[] args) { - DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder().build(); - - DockerHttpClient httpClient = new ApacheDockerHttpClient.Builder() - .dockerHost(config.getDockerHost()) - .sslConfig(config.getSSLConfig()) - .maxConnections(100) - .connectionTimeout(Duration.ofSeconds(30)) - .responseTimeout(Duration.ofSeconds(45)) - .build(); - - DockerClient dockerClient = DockerClientImpl.getInstance(config, httpClient); - - dockerClient.pingCmd().exec(); - System.out.println("Containers:"); - dockerClient.listContainersCmd().exec().stream().forEach(container -> { - System.out.println(container.getCommand()); - }); - System.out.println("Images:"); - dockerClient.listImagesCmd().exec().stream().forEach(image -> { - System.out.println(image.getId()); - }); - - } - } From c9462942e473b2a37f65a2e76ef47e8c62273446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Tue, 7 Feb 2023 06:48:32 +0100 Subject: [PATCH 16/17] Naming changes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Eddú Meléndez Gonzales --- .../dockerjava/core/DefaultDockerClientConfig.java | 6 +++--- .../github/dockerjava/core/DockerContextMetaFile.java | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java index 34b8dd5a2..731051b0d 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DefaultDockerClientConfig.java @@ -459,7 +459,7 @@ public DefaultDockerClientConfig build() { final String context = (dockerContext != null) ? dockerContext : dockerConfigFile.getCurrentContext(); URI dockerHostUri = dockerHost != null ? dockerHost - : dockerHostFromContextOrDefault(context); + : resolveDockerHost(context); return new DefaultDockerClientConfig(dockerHostUri, dockerConfigFile, dockerConfig, apiVersion, registryUrl, registryUsername, registryPassword, registryEmail, sslConfig); @@ -473,9 +473,9 @@ private DockerConfigFile readDockerConfig() { } } - private URI dockerHostFromContextOrDefault(String dockerContext) { + private URI resolveDockerHost(String dockerContext) { return URI.create(Optional.ofNullable(dockerContext) - .flatMap(context -> DockerContextMetaFile.loadContextMetaFile( + .flatMap(context -> DockerContextMetaFile.resolveContextMetaFile( DockerClientConfig.getDefaultObjectMapper(), new File(dockerConfig), context)) .flatMap(DockerContextMetaFile::host) .orElse(SystemUtils.IS_OS_WINDOWS ? WINDOWS_DEFAULT_DOCKER_HOST : DEFAULT_DOCKER_HOST)); diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java index a7c539104..3b2ddbc80 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java @@ -38,25 +38,25 @@ public Optional host() { return Optional.empty(); } - public static Optional loadContextMetaFile(ObjectMapper objectMapper, File dockerConfigPath, String context) { + public static Optional resolveContextMetaFile(ObjectMapper objectMapper, File dockerConfigPath, String context) { final File path = dockerConfigPath.toPath() .resolve("contexts") .resolve("meta") .resolve(metaHashFunction.hashString(context, StandardCharsets.UTF_8).toString()) .resolve("meta.json") .toFile(); - return Optional.ofNullable(loadContextMetaOrNull(objectMapper, path)); + return Optional.ofNullable(loadContextMeta(objectMapper, path)); } - public static DockerContextMetaFile loadContextMetaOrNull(ObjectMapper objectMapper, File dockerContextMetaFile) { + public static DockerContextMetaFile loadContextMeta(ObjectMapper objectMapper, File dockerContextMetaFile) { try { - return loadContextMeta(objectMapper, dockerContextMetaFile); + return parseContextMeta(objectMapper, dockerContextMetaFile); } catch (Exception exception) { return null; } } - public static DockerContextMetaFile loadContextMeta(ObjectMapper objectMapper, File dockerContextMetaFile) throws IOException { + public static DockerContextMetaFile parseContextMeta(ObjectMapper objectMapper, File dockerContextMetaFile) throws IOException { try { return objectMapper.readValue(dockerContextMetaFile, DockerContextMetaFile.class); } catch (IOException e) { From 88cea47d18cce4339a202ae7ad66fe68ee00d533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20K=C3=A5gedal=20Reimer?= Date: Tue, 7 Feb 2023 06:51:53 +0100 Subject: [PATCH 17/17] Naming fix --- .../com/github/dockerjava/core/DockerContextMetaFile.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java index 3b2ddbc80..a52304c8e 100644 --- a/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java +++ b/docker-java-core/src/main/java/com/github/dockerjava/core/DockerContextMetaFile.java @@ -45,18 +45,18 @@ public static Optional resolveContextMetaFile(ObjectMappe .resolve(metaHashFunction.hashString(context, StandardCharsets.UTF_8).toString()) .resolve("meta.json") .toFile(); - return Optional.ofNullable(loadContextMeta(objectMapper, path)); + return Optional.ofNullable(loadContextMetaFile(objectMapper, path)); } - public static DockerContextMetaFile loadContextMeta(ObjectMapper objectMapper, File dockerContextMetaFile) { + public static DockerContextMetaFile loadContextMetaFile(ObjectMapper objectMapper, File dockerContextMetaFile) { try { - return parseContextMeta(objectMapper, dockerContextMetaFile); + return parseContextMetaFile(objectMapper, dockerContextMetaFile); } catch (Exception exception) { return null; } } - public static DockerContextMetaFile parseContextMeta(ObjectMapper objectMapper, File dockerContextMetaFile) throws IOException { + public static DockerContextMetaFile parseContextMetaFile(ObjectMapper objectMapper, File dockerContextMetaFile) throws IOException { try { return objectMapper.readValue(dockerContextMetaFile, DockerContextMetaFile.class); } catch (IOException e) {