diff --git a/docs/features/configuration.md b/docs/features/configuration.md index e40c14af4c..da476b533f 100644 --- a/docs/features/configuration.md +++ b/docs/features/configuration.md @@ -95,3 +95,5 @@ Path to Docker's socket. Used by Ryuk, Docker Compose, and a few other container 5. If the socket contains the unix schema, the schema is removed (e.g. `unix:///var/run/docker.sock` -> `/var/run/docker.sock`) 6. Else, the default location of the docker socket is used: `/var/run/docker.sock` + +In any case, if the docker socket schema is `tcp://`, the default docker socket path will be returned. diff --git a/internal/testcontainersdocker/docker_host.go b/internal/testcontainersdocker/docker_host.go index 6013595964..1da54a4a4a 100644 --- a/internal/testcontainersdocker/docker_host.go +++ b/internal/testcontainersdocker/docker_host.go @@ -81,6 +81,8 @@ func ExtractDockerHost(ctx context.Context) string { // 4. Else, Get the current Docker Host from the existing strategies: see ExtractDockerHost. // 5. If the socket contains the unix schema, the schema is removed (e.g. unix:///var/run/docker.sock -> /var/run/docker.sock) // 6. Else, the default location of the docker socket is used (/var/run/docker.sock) +// +// In any case, if the docker socket schema is "tcp://", the default docker socket path will be returned. func ExtractDockerSocket(ctx context.Context) string { dockerSocketPathOnce.Do(func() { dockerSocketPathCache = extractDockerSocket(ctx) @@ -133,19 +135,28 @@ func extractDockerSocket(ctx context.Context) string { // and receiving an instance of the Docker API client interface. // This internal method is handy for testing purposes, passing a mock type simulating the desired behaviour. func extractDockerSocketFromClient(ctx context.Context, cli client.APIClient) string { - tcHost, err := testcontainersHostFromProperties(ctx) - if err == nil { + // check that the socket is not a tcp or unix socket + checkDockerSocketFn := func(socket string) string { // this use case will cover the case when the docker host is a tcp socket - if strings.HasPrefix(tcHost, "tcp://") { - return "/var/run/docker.sock" + if strings.HasPrefix(socket, TCPSchema) { + return DockerSocketPath } - return tcHost + if strings.HasPrefix(socket, DockerSocketSchema) { + return strings.Replace(socket, DockerSocketSchema, "", 1) + } + + return socket + } + + tcHost, err := testcontainersHostFromProperties(ctx) + if err == nil { + return checkDockerSocketFn(tcHost) } testcontainersDockerSocket, err := dockerSocketOverridePath(ctx) if err == nil { - return testcontainersDockerSocket + return checkDockerSocketFn(testcontainersDockerSocket) } info, err := cli.Info(ctx) @@ -155,16 +166,12 @@ func extractDockerSocketFromClient(ctx context.Context, cli client.APIClient) st // Because Docker Desktop runs in a VM, we need to use the default docker path for rootless docker if info.OperatingSystem == "Docker Desktop" { - return "/var/run/docker.sock" + return DockerSocketPath } dockerHost := extractDockerHost(ctx) - if strings.HasPrefix(dockerHost, DockerSocketSchema) { - return strings.Replace(dockerHost, DockerSocketSchema, "", 1) - } - - return dockerHost + return checkDockerSocketFn(dockerHost) } // dockerHostFromEnv returns the docker host from the DOCKER_HOST environment variable, if it's not empty diff --git a/internal/testcontainersdocker/docker_host_test.go b/internal/testcontainersdocker/docker_host_test.go index dbbe2cf9b5..35fbbd7446 100644 --- a/internal/testcontainersdocker/docker_host_test.go +++ b/internal/testcontainersdocker/docker_host_test.go @@ -13,6 +13,9 @@ import ( "github.com/testcontainers/testcontainers-go/internal/config" ) +// testRemoteHost is a testcontainers host defined in the properties file for testing purposes +var testRemoteHost = TCPSchema + "127.0.0.1:12345" + var ( originalDockerSocketPath string originalDockerSocketPathWithSchema string @@ -55,14 +58,13 @@ func TestExtractDockerHost(t *testing.T) { t.Run("Testcontainers Host is resolved first", func(t *testing.T) { t.Setenv("DOCKER_HOST", "/path/to/docker.sock") - tmpHost := "tcp://127.0.0.1:12345" - content := "tc.host=" + tmpHost + content := "tc.host=" + testRemoteHost setupTestcontainersProperties(t, content) host := extractDockerHost(context.Background()) - assert.Equal(t, tmpHost, host) + assert.Equal(t, testRemoteHost, host) }) t.Run("Docker Host as environment variable", func(t *testing.T) { @@ -123,14 +125,13 @@ func TestExtractDockerHost(t *testing.T) { t.Cleanup(resetSocketOverrideFn) t.Run("Testcontainers host is defined in properties", func(t *testing.T) { - tmpSocket := "tcp://127.0.0.1:12345" - content := "tc.host=" + tmpSocket + content := "tc.host=" + testRemoteHost setupTestcontainersProperties(t, content) socket, err := testcontainersHostFromProperties(context.Background()) require.Nil(t, err) - assert.Equal(t, tmpSocket, socket) + assert.Equal(t, testRemoteHost, socket) }) t.Run("Testcontainers host is not defined in properties", func(t *testing.T) { @@ -269,18 +270,16 @@ func TestExtractDockerSocketFromClient(t *testing.T) { setupDockerHostNotFound(t) t.Run("Docker socket from Testcontainers host defined in properties", func(t *testing.T) { - tmpSocket := "tcp://127.0.0.1:12345" - content := "tc.host=" + tmpSocket + content := "tc.host=" + testRemoteHost setupTestcontainersProperties(t, content) socket := extractDockerSocketFromClient(context.Background(), mockCli{OS: "foo"}) - assert.Equal(t, "/var/run/docker.sock", socket) + assert.Equal(t, DockerSocketPath, socket) }) t.Run("Docker socket from Testcontainers host takes precedence over TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", func(t *testing.T) { - tmpSocket := "tcp://127.0.0.1:12345" - content := "tc.host=" + tmpSocket + content := "tc.host=" + testRemoteHost setupTestcontainersProperties(t, content) @@ -288,7 +287,7 @@ func TestExtractDockerSocketFromClient(t *testing.T) { t.Setenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "/path/to/docker.sock") socket := extractDockerSocketFromClient(context.Background(), mockCli{OS: "foo"}) - assert.Equal(t, "/var/run/docker.sock", socket) + assert.Equal(t, DockerSocketPath, socket) }) t.Run("Docker Socket as Testcontainers environment variable", func(t *testing.T) { @@ -302,6 +301,20 @@ func TestExtractDockerSocketFromClient(t *testing.T) { assert.Equal(t, "/path/to/docker.sock", host) }) + t.Run("Docker Socket as Testcontainers environment variable, removes prefixes", func(t *testing.T) { + setupTestcontainersProperties(t, "") + + t.Cleanup(resetSocketOverrideFn) + + t.Setenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "unix:///path/to/docker.sock") + host := extractDockerSocketFromClient(context.Background(), mockCli{OS: "foo"}) + assert.Equal(t, "/path/to/docker.sock", host) + + t.Setenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", testRemoteHost) + host = extractDockerSocketFromClient(context.Background(), mockCli{OS: "foo"}) + assert.Equal(t, DockerSocketPath, host) + }) + t.Run("Unix Docker Socket is passed as DOCKER_HOST variable (Docker Desktop)", func(t *testing.T) { setupTestcontainersProperties(t, "") @@ -313,7 +326,7 @@ func TestExtractDockerSocketFromClient(t *testing.T) { socket := extractDockerSocketFromClient(ctx, mockCli{OS: "Docker Desktop"}) - assert.Equal(t, "/var/run/docker.sock", socket) + assert.Equal(t, DockerSocketPath, socket) }) t.Run("Unix Docker Socket is passed as DOCKER_HOST variable (Not Docker Desktop)", func(t *testing.T) { @@ -329,6 +342,23 @@ func TestExtractDockerSocketFromClient(t *testing.T) { assert.Equal(t, "/this/is/a/sample.sock", socket) }) + + t.Run("Unix Docker Socket is passed as DOCKER_HOST variable (Not Docker Desktop), removes prefixes", func(t *testing.T) { + setupTestcontainersProperties(t, "") + + t.Cleanup(resetSocketOverrideFn) + + ctx := context.Background() + os.Unsetenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE") + + t.Setenv("DOCKER_HOST", "unix:///this/is/a/sample.sock") + socket := extractDockerSocketFromClient(ctx, mockCli{OS: "Ubuntu"}) + assert.Equal(t, "/this/is/a/sample.sock", socket) + + t.Setenv("DOCKER_HOST", testRemoteHost) + socket = extractDockerSocketFromClient(ctx, mockCli{OS: "Ubuntu"}) + assert.Equal(t, DockerSocketPath, socket) + }) } func TestInAContainer(t *testing.T) { diff --git a/internal/testcontainersdocker/docker_socket.go b/internal/testcontainersdocker/docker_socket.go index 9f93c5fe1a..04697aa950 100644 --- a/internal/testcontainersdocker/docker_socket.go +++ b/internal/testcontainersdocker/docker_socket.go @@ -8,3 +8,6 @@ var DockerSocketPath = "/var/run/docker.sock" // DockerSocketPathWithSchema is the path to the docker socket under unix systems with the unix schema. var DockerSocketPathWithSchema = DockerSocketSchema + DockerSocketPath + +// TCPSchema is the tcp schema. +var TCPSchema = "tcp://"