Use Docker CLI context to determine daemon host address for image building

Configuration files managed by the Docker CLI are now used to determine
the host address of the Docker daemon used when building images using
buildpacks when a host address is not configured with environment
variables or build tool plugin configuration.

Closes gh-36445
This commit is contained in:
Scott Frederick
2023-07-13 14:27:14 -06:00
parent 283dc37db3
commit 4393a2244c
26 changed files with 660 additions and 86 deletions

View File

@@ -40,7 +40,7 @@ import org.springframework.boot.buildpack.platform.docker.DockerApi;
import org.springframework.boot.buildpack.platform.docker.DockerApi.ContainerApi;
import org.springframework.boot.buildpack.platform.docker.DockerApi.ImageApi;
import org.springframework.boot.buildpack.platform.docker.DockerApi.VolumeApi;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerHost;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
import org.springframework.boot.buildpack.platform.docker.configuration.ResolvedDockerHost;
import org.springframework.boot.buildpack.platform.docker.type.Binding;
import org.springframework.boot.buildpack.platform.docker.type.ContainerConfig;
@@ -246,7 +246,8 @@ class LifecycleTests {
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
BuildRequest request = getTestRequest();
createLifecycle(request, ResolvedDockerHost.from(new DockerHost("tcp://192.168.1.2:2376"))).execute();
createLifecycle(request, ResolvedDockerHost.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376")))
.execute();
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-inherit-remote.json"));
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
}
@@ -257,7 +258,8 @@ class LifecycleTests {
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
given(this.docker.container().wait(any())).willReturn(ContainerStatus.of(0, null));
BuildRequest request = getTestRequest();
createLifecycle(request, ResolvedDockerHost.from(new DockerHost("/var/alt.sock"))).execute();
createLifecycle(request, ResolvedDockerHost.from(DockerHostConfiguration.forAddress("/var/alt.sock")))
.execute();
assertPhaseWasRun("creator", withExpectedConfig("lifecycle-creator-inherit-local.json"));
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://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.springframework.boot.buildpack.platform.docker.configuration;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfigurationMetadata.DockerContext;
import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
/**
* Tests for {@link DockerConfigurationMetadata}.
*
* @author Scott Frederick
*/
class DockerConfigurationMetadataTests extends AbstractJsonTests {
private final Map<String, String> environment = new LinkedHashMap<>();
@Test
void configWithContextIsRead() throws Exception {
this.environment.put("DOCKER_CONFIG", pathToResource("with-context/config.json"));
DockerConfigurationMetadata config = DockerConfigurationMetadata.from(this.environment::get);
assertThat(config.getConfiguration().getCurrentContext()).isEqualTo("test-context");
assertThat(config.getContext().getDockerHost()).isEqualTo("unix:///home/user/.docker/docker.sock");
assertThat(config.getContext().isTlsVerify()).isFalse();
assertThat(config.getContext().getTlsPath()).isNull();
}
@Test
void configWithoutContextIsRead() throws Exception {
this.environment.put("DOCKER_CONFIG", pathToResource("without-context/config.json"));
DockerConfigurationMetadata config = DockerConfigurationMetadata.from(this.environment::get);
assertThat(config.getConfiguration().getCurrentContext()).isNull();
assertThat(config.getContext().getDockerHost()).isNull();
assertThat(config.getContext().isTlsVerify()).isFalse();
assertThat(config.getContext().getTlsPath()).isNull();
}
@Test
void configWithDefaultContextIsRead() throws Exception {
this.environment.put("DOCKER_CONFIG", pathToResource("with-default-context/config.json"));
DockerConfigurationMetadata config = DockerConfigurationMetadata.from(this.environment::get);
assertThat(config.getConfiguration().getCurrentContext()).isEqualTo("default");
assertThat(config.getContext().getDockerHost()).isNull();
assertThat(config.getContext().isTlsVerify()).isFalse();
assertThat(config.getContext().getTlsPath()).isNull();
}
@Test
void configIsReadWithProvidedContext() throws Exception {
this.environment.put("DOCKER_CONFIG", pathToResource("with-default-context/config.json"));
DockerConfigurationMetadata config = DockerConfigurationMetadata.from(this.environment::get);
DockerContext context = config.forContext("test-context");
assertThat(context.getDockerHost()).isEqualTo("unix:///home/user/.docker/docker.sock");
assertThat(context.isTlsVerify()).isTrue();
assertThat(context.getTlsPath()).matches("^.*/with-default-context/contexts/tls/[a-zA-z0-9]*/docker$");
}
@Test
void invalidContextThrowsException() throws Exception {
this.environment.put("DOCKER_CONFIG", pathToResource("with-default-context/config.json"));
assertThatIllegalArgumentException()
.isThrownBy(() -> DockerConfigurationMetadata.from(this.environment::get).forContext("invalid-context"))
.withMessageContaining("Docker context 'invalid-context' does not exist");
}
@Test
void configIsEmptyWhenConfigFileDoesNotExist() {
this.environment.put("DOCKER_CONFIG", "docker-config-dummy-path");
DockerConfigurationMetadata config = DockerConfigurationMetadata.from(this.environment::get);
assertThat(config.getConfiguration().getCurrentContext()).isNull();
assertThat(config.getContext().getDockerHost()).isNull();
assertThat(config.getContext().isTlsVerify()).isFalse();
}
private String pathToResource(String resource) throws URISyntaxException {
URL url = getClass().getResource(resource);
return Paths.get(url.toURI()).getParent().toAbsolutePath().toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,8 +17,11 @@
package org.springframework.boot.buildpack.platform.docker.configuration;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -28,6 +31,8 @@ import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
/**
@@ -41,7 +46,8 @@ class ResolvedDockerHostTests {
@Test
@DisabledOnOs(OS.WINDOWS)
void resolveWhenDockerHostIsNullReturnsLinuxDefault() {
void resolveWhenDockerHostIsNullReturnsLinuxDefault() throws Exception {
this.environment.put("DOCKER_CONFIG", pathToResource("with-default-context/config.json"));
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get, null);
assertThat(dockerHost.getAddress()).isEqualTo("/var/run/docker.sock");
assertThat(dockerHost.isSecure()).isFalse();
@@ -50,7 +56,8 @@ class ResolvedDockerHostTests {
@Test
@EnabledOnOs(OS.WINDOWS)
void resolveWhenDockerHostIsNullReturnsWindowsDefault() {
void resolveWhenDockerHostIsNullReturnsWindowsDefault() throws Exception {
this.environment.put("DOCKER_CONFIG", pathToResource("with-default-context/config.json"));
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get, null);
assertThat(dockerHost.getAddress()).isEqualTo("//./pipe/docker_engine");
assertThat(dockerHost.isSecure()).isFalse();
@@ -59,8 +66,10 @@ class ResolvedDockerHostTests {
@Test
@DisabledOnOs(OS.WINDOWS)
void resolveWhenDockerHostAddressIsNullReturnsLinuxDefault() {
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get, new DockerHost(null));
void resolveWhenDockerHostAddressIsNullReturnsLinuxDefault() throws Exception {
this.environment.put("DOCKER_CONFIG", pathToResource("with-default-context/config.json"));
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
DockerHostConfiguration.forAddress(null));
assertThat(dockerHost.getAddress()).isEqualTo("/var/run/docker.sock");
assertThat(dockerHost.isSecure()).isFalse();
assertThat(dockerHost.getCertificatePath()).isNull();
@@ -70,7 +79,7 @@ class ResolvedDockerHostTests {
void resolveWhenDockerHostAddressIsLocalReturnsAddress(@TempDir Path tempDir) throws IOException {
String socketFilePath = Files.createTempFile(tempDir, "remote-transport", null).toAbsolutePath().toString();
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
new DockerHost(socketFilePath, false, null));
DockerHostConfiguration.forAddress(socketFilePath));
assertThat(dockerHost.isLocalFileReference()).isTrue();
assertThat(dockerHost.isRemote()).isFalse();
assertThat(dockerHost.getAddress()).isEqualTo(socketFilePath);
@@ -82,7 +91,7 @@ class ResolvedDockerHostTests {
void resolveWhenDockerHostAddressIsLocalWithSchemeReturnsAddress(@TempDir Path tempDir) throws IOException {
String socketFilePath = Files.createTempFile(tempDir, "remote-transport", null).toAbsolutePath().toString();
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
new DockerHost("unix://" + socketFilePath, false, null));
DockerHostConfiguration.forAddress("unix://" + socketFilePath));
assertThat(dockerHost.isLocalFileReference()).isTrue();
assertThat(dockerHost.isRemote()).isFalse();
assertThat(dockerHost.getAddress()).isEqualTo(socketFilePath);
@@ -93,7 +102,7 @@ class ResolvedDockerHostTests {
@Test
void resolveWhenDockerHostAddressIsHttpReturnsAddress() {
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
new DockerHost("http://docker.example.com", false, null));
DockerHostConfiguration.forAddress("http://docker.example.com"));
assertThat(dockerHost.isLocalFileReference()).isFalse();
assertThat(dockerHost.isRemote()).isTrue();
assertThat(dockerHost.getAddress()).isEqualTo("http://docker.example.com");
@@ -104,7 +113,7 @@ class ResolvedDockerHostTests {
@Test
void resolveWhenDockerHostAddressIsHttpsReturnsAddress() {
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
new DockerHost("https://docker.example.com", true, "/cert-path"));
DockerHostConfiguration.forAddress("https://docker.example.com", true, "/cert-path"));
assertThat(dockerHost.isLocalFileReference()).isFalse();
assertThat(dockerHost.isRemote()).isTrue();
assertThat(dockerHost.getAddress()).isEqualTo("https://docker.example.com");
@@ -115,7 +124,7 @@ class ResolvedDockerHostTests {
@Test
void resolveWhenDockerHostAddressIsTcpReturnsAddress() {
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
new DockerHost("tcp://192.168.99.100:2376", true, "/cert-path"));
DockerHostConfiguration.forAddress("tcp://192.168.99.100:2376", true, "/cert-path"));
assertThat(dockerHost.isLocalFileReference()).isFalse();
assertThat(dockerHost.isRemote()).isTrue();
assertThat(dockerHost.getAddress()).isEqualTo("tcp://192.168.99.100:2376");
@@ -128,7 +137,7 @@ class ResolvedDockerHostTests {
String socketFilePath = Files.createTempFile(tempDir, "remote-transport", null).toAbsolutePath().toString();
this.environment.put("DOCKER_HOST", socketFilePath);
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
new DockerHost("/unused", true, "/unused"));
DockerHostConfiguration.forAddress("/unused"));
assertThat(dockerHost.isLocalFileReference()).isTrue();
assertThat(dockerHost.isRemote()).isFalse();
assertThat(dockerHost.getAddress()).isEqualTo(socketFilePath);
@@ -141,7 +150,7 @@ class ResolvedDockerHostTests {
String socketFilePath = Files.createTempFile(tempDir, "remote-transport", null).toAbsolutePath().toString();
this.environment.put("DOCKER_HOST", "unix://" + socketFilePath);
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
new DockerHost("/unused", true, "/unused"));
DockerHostConfiguration.forAddress("/unused"));
assertThat(dockerHost.isLocalFileReference()).isTrue();
assertThat(dockerHost.isRemote()).isFalse();
assertThat(dockerHost.getAddress()).isEqualTo(socketFilePath);
@@ -155,7 +164,7 @@ class ResolvedDockerHostTests {
this.environment.put("DOCKER_TLS_VERIFY", "1");
this.environment.put("DOCKER_CERT_PATH", "/cert-path");
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
new DockerHost("tcp://1.1.1.1", false, "/unused"));
DockerHostConfiguration.forAddress("tcp://1.1.1.1"));
assertThat(dockerHost.isLocalFileReference()).isFalse();
assertThat(dockerHost.isRemote()).isTrue();
assertThat(dockerHost.getAddress()).isEqualTo("tcp://192.168.99.100:2376");
@@ -163,4 +172,39 @@ class ResolvedDockerHostTests {
assertThat(dockerHost.getCertificatePath()).isEqualTo("/cert-path");
}
@Test
void resolveWithDockerHostContextReturnsAddress() throws Exception {
this.environment.put("DOCKER_CONFIG", pathToResource("with-default-context/config.json"));
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get,
DockerHostConfiguration.forContext("test-context"));
assertThat(dockerHost.getAddress()).isEqualTo("/home/user/.docker/docker.sock");
assertThat(dockerHost.isSecure()).isTrue();
assertThat(dockerHost.getCertificatePath()).isNotNull();
}
@Test
void resolveWithDockerConfigMetadataContextReturnsAddress() throws Exception {
this.environment.put("DOCKER_CONFIG", pathToResource("with-context/config.json"));
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get, null);
assertThat(dockerHost.getAddress()).isEqualTo("/home/user/.docker/docker.sock");
assertThat(dockerHost.isSecure()).isFalse();
assertThat(dockerHost.getCertificatePath()).isNull();
}
@Test
void resolveWhenEnvironmentHasAddressAndContextPrefersContext() throws Exception {
this.environment.put("DOCKER_CONFIG", pathToResource("with-context/config.json"));
this.environment.put("DOCKER_CONTEXT", "test-context");
this.environment.put("DOCKER_HOST", "notused");
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(this.environment::get, null);
assertThat(dockerHost.getAddress()).isEqualTo("/home/user/.docker/docker.sock");
assertThat(dockerHost.isSecure()).isFalse();
assertThat(dockerHost.getCertificatePath()).isNull();
}
private String pathToResource(String resource) throws URISyntaxException {
URL url = getClass().getResource(resource);
return Paths.get(url.toURI()).getParent().toAbsolutePath().toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,7 +23,7 @@ import java.nio.file.Path;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerHost;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
import static org.assertj.core.api.Assertions.assertThat;
@@ -37,21 +37,21 @@ class HttpTransportTests {
@Test
void createWhenDockerHostVariableIsAddressReturnsRemote() {
HttpTransport transport = HttpTransport.create(new DockerHost("tcp://192.168.1.0"));
HttpTransport transport = HttpTransport.create(DockerHostConfiguration.forAddress("tcp://192.168.1.0"));
assertThat(transport).isInstanceOf(RemoteHttpClientTransport.class);
}
@Test
void createWhenDockerHostVariableIsFileReturnsLocal(@TempDir Path tempDir) throws IOException {
String dummySocketFilePath = Files.createTempFile(tempDir, "http-transport", null).toAbsolutePath().toString();
HttpTransport transport = HttpTransport.create(new DockerHost(dummySocketFilePath));
HttpTransport transport = HttpTransport.create(DockerHostConfiguration.forAddress(dummySocketFilePath));
assertThat(transport).isInstanceOf(LocalHttpClientTransport.class);
}
@Test
void createWhenDockerHostVariableIsUnixSchemePrefixedFileReturnsLocal(@TempDir Path tempDir) throws IOException {
String dummySocketFilePath = "unix://" + Files.createTempFile(tempDir, "http-transport", null).toAbsolutePath();
HttpTransport transport = HttpTransport.create(new DockerHost(dummySocketFilePath));
HttpTransport transport = HttpTransport.create(DockerHostConfiguration.forAddress(dummySocketFilePath));
assertThat(transport).isInstanceOf(LocalHttpClientTransport.class);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@ import java.nio.file.Paths;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerHost;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
import org.springframework.boot.buildpack.platform.docker.configuration.ResolvedDockerHost;
import static org.assertj.core.api.Assertions.assertThat;
@@ -39,24 +39,28 @@ class LocalHttpClientTransportTests {
@Test
void createWhenDockerHostIsFileReturnsTransport(@TempDir Path tempDir) throws IOException {
String socketFilePath = Files.createTempFile(tempDir, "remote-transport", null).toAbsolutePath().toString();
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(new DockerHost(socketFilePath));
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(DockerHostConfiguration.forAddress(socketFilePath));
LocalHttpClientTransport transport = LocalHttpClientTransport.create(dockerHost);
assertThat(transport).isNotNull();
assertThat(transport.getHost().toHostString()).isEqualTo(socketFilePath);
}
@Test
void createWhenDockerHostIsFileThatDoesNotExistReturnsTransport(@TempDir Path tempDir) {
String socketFilePath = Paths.get(tempDir.toString(), "dummy").toAbsolutePath().toString();
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(new DockerHost(socketFilePath));
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(DockerHostConfiguration.forAddress(socketFilePath));
LocalHttpClientTransport transport = LocalHttpClientTransport.create(dockerHost);
assertThat(transport).isNotNull();
assertThat(transport.getHost().toHostString()).isEqualTo(socketFilePath);
}
@Test
void createWhenDockerHostIsAddressReturnsTransport() {
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(new DockerHost("tcp://192.168.1.2:2376"));
ResolvedDockerHost dockerHost = ResolvedDockerHost
.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376"));
LocalHttpClientTransport transport = LocalHttpClientTransport.create(dockerHost);
assertThat(transport).isNotNull();
assertThat(transport.getHost().toHostString()).isEqualTo("tcp://192.168.1.2:2376");
}
}

View File

@@ -23,7 +23,7 @@ import javax.net.ssl.SSLContext;
import org.apache.hc.core5.http.HttpHost;
import org.junit.jupiter.api.Test;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerHost;
import org.springframework.boot.buildpack.platform.docker.configuration.DockerConfiguration.DockerHostConfiguration;
import org.springframework.boot.buildpack.platform.docker.configuration.ResolvedDockerHost;
import org.springframework.boot.buildpack.platform.docker.ssl.SslContextFactory;
@@ -49,28 +49,31 @@ class RemoteHttpClientTransportTests {
@Test
void createIfPossibleWhenDockerHostIsDefaultReturnsNull() {
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(new DockerHost(null));
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(DockerHostConfiguration.forAddress(null));
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(dockerHost);
assertThat(transport).isNull();
}
@Test
void createIfPossibleWhenDockerHostIsFileReturnsNull() {
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(new DockerHost("unix:///var/run/socket.sock"));
ResolvedDockerHost dockerHost = ResolvedDockerHost
.from(DockerHostConfiguration.forAddress("unix:///var/run/socket.sock"));
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(dockerHost);
assertThat(transport).isNull();
}
@Test
void createIfPossibleWhenDockerHostIsAddressReturnsTransport() {
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(new DockerHost("tcp://192.168.1.2:2376"));
ResolvedDockerHost dockerHost = ResolvedDockerHost
.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376"));
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(dockerHost);
assertThat(transport).isNotNull();
}
@Test
void createIfPossibleWhenNoTlsVerifyUsesHttp() {
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(new DockerHost("tcp://192.168.1.2:2376"));
ResolvedDockerHost dockerHost = ResolvedDockerHost
.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376"));
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(dockerHost);
assertThat(transport.getHost()).satisfies(hostOf("http", "192.168.1.2", 2376));
}
@@ -80,14 +83,15 @@ class RemoteHttpClientTransportTests {
SslContextFactory sslContextFactory = mock(SslContextFactory.class);
given(sslContextFactory.forDirectory("/test-cert-path")).willReturn(SSLContext.getDefault());
ResolvedDockerHost dockerHost = ResolvedDockerHost
.from(new DockerHost("tcp://192.168.1.2:2376", true, "/test-cert-path"));
.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376", true, "/test-cert-path"));
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(dockerHost, sslContextFactory);
assertThat(transport.getHost()).satisfies(hostOf("https", "192.168.1.2", 2376));
}
@Test
void createIfPossibleWhenTlsVerifyWithMissingCertPathThrowsException() {
ResolvedDockerHost dockerHost = ResolvedDockerHost.from(new DockerHost("tcp://192.168.1.2:2376", true, null));
ResolvedDockerHost dockerHost = ResolvedDockerHost
.from(DockerHostConfiguration.forAddress("tcp://192.168.1.2:2376", true, null));
assertThatIllegalArgumentException().isThrownBy(() -> RemoteHttpClientTransport.createIfPossible(dockerHost))
.withMessageContaining("Docker host TLS verification requires trust material");
}

View File

@@ -0,0 +1,12 @@
{
"Name": "test-context",
"Metadata": {
"Description": "A context for testing"
},
"Endpoints": {
"docker": {
"Host": "unix:///home/user/.docker/docker.sock",
"SkipTLSVerify": true
}
}
}

View File

@@ -0,0 +1,12 @@
{
"Name": "test-context",
"Metadata": {
"Description": "A context for testing"
},
"Endpoints": {
"docker": {
"Host": "unix:///home/user/.docker/docker.sock",
"SkipTLSVerify": false
}
}
}