Skip to content

Commit

Permalink
chore: extract docker host calculation to an internal package (#796)
Browse files Browse the repository at this point in the history
  • Loading branch information
mdelapenya authored Jan 30, 2023
1 parent 898a14d commit 9fb8074
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 81 deletions.
7 changes: 4 additions & 3 deletions docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
specs "github.com/opencontainers/image-spec/specs-go/v1"

tcexec "github.com/testcontainers/testcontainers-go/exec"
"github.com/testcontainers/testcontainers-go/internal/testcontainersdocker"
"github.com/testcontainers/testcontainers-go/wait"
)

Expand Down Expand Up @@ -983,7 +984,7 @@ func (p *DockerProvider) CreateContainer(ctx context.Context, req ContainerReque
// the reaper does not need to start a reaper for itself
isReaperContainer := strings.EqualFold(req.Image, reaperImage(reaperOpts.ImageName))
if !req.SkipReaper && !isReaperContainer {
r, err := newReaper(context.WithValue(ctx, dockerHostContextKey, p.host), sessionID.String(), p, req.ReaperOptions...)
r, err := newReaper(context.WithValue(ctx, testcontainersdocker.DockerHostContextKey, p.host), sessionID.String(), p, req.ReaperOptions...)
if err != nil {
return nil, fmt.Errorf("%w: creating reaper failed", err)
}
Expand Down Expand Up @@ -1200,7 +1201,7 @@ func (p *DockerProvider) ReuseOrCreateContainer(ctx context.Context, req Contain
sessionID := sessionID()
var termSignal chan bool
if !req.SkipReaper {
r, err := newReaper(context.WithValue(ctx, dockerHostContextKey, p.host), sessionID.String(), p, req.ReaperOptions...)
r, err := newReaper(context.WithValue(ctx, testcontainersdocker.DockerHostContextKey, p.host), sessionID.String(), p, req.ReaperOptions...)
if err != nil {
return nil, fmt.Errorf("%w: creating reaper failed", err)
}
Expand Down Expand Up @@ -1355,7 +1356,7 @@ func (p *DockerProvider) CreateNetwork(ctx context.Context, req NetworkRequest)
var termSignal chan bool
if !req.SkipReaper {
sessionID := sessionID()
r, err := newReaper(context.WithValue(ctx, dockerHostContextKey, p.host), sessionID.String(), p, req.ReaperOptions...)
r, err := newReaper(context.WithValue(ctx, testcontainersdocker.DockerHostContextKey, p.host), sessionID.String(), p, req.ReaperOptions...)
if err != nil {
return nil, fmt.Errorf("%w: creating network reaper failed", err)
}
Expand Down
40 changes: 40 additions & 0 deletions internal/testcontainersdocker/docker_host.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package testcontainersdocker

import (
"context"
"net/url"
"os"
)

type dockerHostContext string

var DockerHostContextKey = dockerHostContext("docker_host")

// Extracts the docker host from the context, or returns the default value
func ExtractDockerHost(ctx context.Context) (dockerHostPath string) {
if dockerHostPath = os.Getenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE"); dockerHostPath != "" {
return dockerHostPath
}

dockerHostPath = "/var/run/docker.sock"

var hostRawURL string
if h, ok := ctx.Value(DockerHostContextKey).(string); !ok || h == "" {
return dockerHostPath
} else {
hostRawURL = h
}
var hostURL *url.URL
if u, err := url.Parse(hostRawURL); err != nil {
return dockerHostPath
} else {
hostURL = u
}

switch hostURL.Scheme {
case "unix":
return hostURL.Path
default:
return dockerHostPath
}
}
47 changes: 47 additions & 0 deletions internal/testcontainersdocker/docker_host_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package testcontainersdocker

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
)

func Test_ExtractDockerHost(t *testing.T) {
t.Run("Docker Host as environment variable", func(t *testing.T) {
t.Setenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "/path/to/docker.sock")
host := ExtractDockerHost(context.Background())

assert.Equal(t, "/path/to/docker.sock", host)
})

t.Run("Default Docker Host", func(t *testing.T) {
host := ExtractDockerHost(context.Background())

assert.Equal(t, "/var/run/docker.sock", host)
})

t.Run("Malformed Docker Host is passed in context", func(t *testing.T) {
ctx := context.Background()

host := ExtractDockerHost(context.WithValue(ctx, DockerHostContextKey, "path-to-docker-sock"))

assert.Equal(t, "/var/run/docker.sock", host)
})

t.Run("Malformed Schema Docker Host is passed in context", func(t *testing.T) {
ctx := context.Background()

host := ExtractDockerHost(context.WithValue(ctx, DockerHostContextKey, "http://path to docker sock"))

assert.Equal(t, "/var/run/docker.sock", host)
})

t.Run("Unix Docker Host is passed in context", func(t *testing.T) {
ctx := context.Background()

host := ExtractDockerHost(context.WithValue(ctx, DockerHostContextKey, "unix:///this/is/a/sample.sock"))

assert.Equal(t, "/this/is/a/sample.sock", host)
})
}
40 changes: 4 additions & 36 deletions reaper.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import (
"context"
"fmt"
"net"
"net/url"
"os"
"strings"
"sync"
"time"

"github.com/docker/go-connections/nat"

"github.com/testcontainers/testcontainers-go/internal/testcontainersdocker"
"github.com/testcontainers/testcontainers-go/wait"
)

Expand All @@ -24,12 +23,9 @@ const (
ReaperDefaultImage = "docker.io/testcontainers/ryuk:0.3.4"
)

type reaperContextKey string

var (
dockerHostContextKey = reaperContextKey("docker_host")
reaper *Reaper // We would like to create reaper only once
mutex sync.Mutex
reaper *Reaper // We would like to create reaper only once
mutex sync.Mutex
)

// ReaperProvider represents a provider for the reaper to run itself with
Expand All @@ -54,7 +50,7 @@ func newReaper(ctx context.Context, sessionID string, provider ReaperProvider, o
return reaper, nil
}

dockerHost := extractDockerHost(ctx)
dockerHost := testcontainersdocker.ExtractDockerHost(ctx)

// Otherwise create a new one
reaper = &Reaper{
Expand Down Expand Up @@ -181,34 +177,6 @@ func (r *Reaper) Labels() map[string]string {
}
}

func extractDockerHost(ctx context.Context) (dockerHostPath string) {
if dockerHostPath = os.Getenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE"); dockerHostPath != "" {
return dockerHostPath
}

dockerHostPath = "/var/run/docker.sock"

var hostRawURL string
if h, ok := ctx.Value(dockerHostContextKey).(string); !ok || h == "" {
return dockerHostPath
} else {
hostRawURL = h
}
var hostURL *url.URL
if u, err := url.Parse(hostRawURL); err != nil {
return dockerHostPath
} else {
hostURL = u
}

switch hostURL.Scheme {
case "unix":
return hostURL.Path
default:
return dockerHostPath
}
}

func reaperImage(reaperImageName string) string {
if reaperImageName == "" {
return ReaperDefaultImage
Expand Down
44 changes: 2 additions & 42 deletions reaper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/docker/go-connections/nat"
"github.com/stretchr/testify/assert"
"github.com/testcontainers/testcontainers-go/internal/testcontainersdocker"
"github.com/testcontainers/testcontainers-go/wait"
)

Expand Down Expand Up @@ -88,7 +89,7 @@ func Test_NewReaper(t *testing.T) {
return req
}),
config: TestContainersConfig{},
ctx: context.WithValue(context.TODO(), dockerHostContextKey, "unix:///value/in/context.sock"),
ctx: context.WithValue(context.TODO(), testcontainersdocker.DockerHostContextKey, "unix:///value/in/context.sock"),
},
{
name: "with registry credentials",
Expand Down Expand Up @@ -123,47 +124,6 @@ func Test_NewReaper(t *testing.T) {
}
}

func Test_ExtractDockerHost(t *testing.T) {
defer func() { reaper = nil }()

t.Run("Docker Host as environment variable", func(t *testing.T) {
t.Setenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "/path/to/docker.sock")
host := extractDockerHost(context.Background())

assert.Equal(t, "/path/to/docker.sock", host)
})

t.Run("Default Docker Host", func(t *testing.T) {
host := extractDockerHost(context.Background())

assert.Equal(t, "/var/run/docker.sock", host)
})

t.Run("Malformed Docker Host is passed in context", func(t *testing.T) {
ctx := context.Background()

host := extractDockerHost(context.WithValue(ctx, dockerHostContextKey, "path-to-docker-sock"))

assert.Equal(t, "/var/run/docker.sock", host)
})

t.Run("Malformed Schema Docker Host is passed in context", func(t *testing.T) {
ctx := context.Background()

host := extractDockerHost(context.WithValue(ctx, dockerHostContextKey, "http://path to docker sock"))

assert.Equal(t, "/var/run/docker.sock", host)
})

t.Run("Unix Docker Host is passed in context", func(t *testing.T) {
ctx := context.Background()

host := extractDockerHost(context.WithValue(ctx, dockerHostContextKey, "unix:///this/is/a/sample.sock"))

assert.Equal(t, "/this/is/a/sample.sock", host)
})
}

func Test_ReaperForNetwork(t *testing.T) {
defer func() { reaper = nil }()

Expand Down

0 comments on commit 9fb8074

Please sign in to comment.