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:
@@ -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'");
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"currentContext": "test-context"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"Name": "test-context",
|
||||
"Metadata": {
|
||||
"Description": "A context for testing"
|
||||
},
|
||||
"Endpoints": {
|
||||
"docker": {
|
||||
"Host": "unix:///home/user/.docker/docker.sock",
|
||||
"SkipTLSVerify": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"currentContext": "default"
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"Name": "test-context",
|
||||
"Metadata": {
|
||||
"Description": "A context for testing"
|
||||
},
|
||||
"Endpoints": {
|
||||
"docker": {
|
||||
"Host": "unix:///home/user/.docker/docker.sock",
|
||||
"SkipTLSVerify": false
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user