Support local socket path in DOCKER_HOST

Prior to this commit, if a DOCKER_HOST environment variable was present
when attempting to communicate with a Docker daemon, it was assumed
that the value of that variable was an address that could be used to
create an HTTP connection to a remote daemon. In some cases, the value
of the variable is the path to a local socket file, which would cause
the HTTP connection to fail.

This commit adds additional validation of the value of the DOCKER_HOST
environment variable to determine whether it is a remote address or
a local socket file and create the appropriate connection type.

Fixes gh-21173
This commit is contained in:
Scott Frederick
2020-05-12 09:57:39 -05:00
parent 86e6ec04b2
commit 90ce472252
5 changed files with 56 additions and 14 deletions

View File

@@ -16,10 +16,14 @@
package org.springframework.boot.buildpack.platform.docker.transport;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import static org.assertj.core.api.Assertions.assertThat;
@@ -27,16 +31,25 @@ import static org.assertj.core.api.Assertions.assertThat;
* Tests for {@link HttpTransport}.
*
* @author Phillip Webb
* @author Scott Frederick
*/
class HttpTransportTests {
@Test
void createWhenHasDockerHostVariableReturnsRemote() {
Map<String, String> environment = Collections.singletonMap("DOCKER_HOST", "192.168.1.0");
void createWhenDockerHostVariableIsAddressReturnsRemote() {
Map<String, String> environment = Collections.singletonMap("DOCKER_HOST", "tcp://192.168.1.0");
HttpTransport transport = HttpTransport.create(environment::get);
assertThat(transport).isInstanceOf(RemoteHttpClientTransport.class);
}
@Test
void createWhenDockerHostVariableIsFileReturnsLocal(@TempDir Path tempDir) throws IOException {
String dummySocketFilePath = Files.createTempFile(tempDir, "http-transport", null).toAbsolutePath().toString();
Map<String, String> environment = Collections.singletonMap("DOCKER_HOST", dummySocketFilePath);
HttpTransport transport = HttpTransport.create(environment::get);
assertThat(transport).isInstanceOf(LocalHttpClientTransport.class);
}
@Test
void createWhenDoesNotHaveDockerHostVariableReturnsLocal() {
HttpTransport transport = HttpTransport.create((name) -> null);

View File

@@ -16,6 +16,9 @@
package org.springframework.boot.buildpack.platform.docker.transport;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Consumer;
@@ -24,6 +27,7 @@ import javax.net.ssl.SSLContext;
import org.apache.http.HttpHost;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import org.springframework.boot.buildpack.platform.docker.ssl.SslContextFactory;
@@ -40,7 +44,7 @@ import static org.mockito.Mockito.mock;
*/
class RemoteHttpClientTransportTests {
private Map<String, String> environment = new LinkedHashMap<>();
private final Map<String, String> environment = new LinkedHashMap<>();
@Test
void createIfPossibleWhenDockerHostIsNotSetReturnsNull() {
@@ -49,7 +53,16 @@ class RemoteHttpClientTransportTests {
}
@Test
void createIfPossibleWhenDockerHostIsSetReturnsTransport() {
void createIfPossibleWhenDockerHostIsFileReturnsNull(@TempDir Path tempDir) throws IOException {
String dummySocketFilePath = Files.createTempFile(tempDir, "remote-transport", null).toAbsolutePath()
.toString();
this.environment.put("DOCKER_HOST", dummySocketFilePath);
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(this.environment::get);
assertThat(transport).isNull();
}
@Test
void createIfPossibleWhenDockerHostIsAddressReturnsTransport() {
this.environment.put("DOCKER_HOST", "tcp://192.168.1.2:2376");
RemoteHttpClientTransport transport = RemoteHttpClientTransport.createIfPossible(this.environment::get);
assertThat(transport).isNotNull();