From 1c74f2c14da154303e05d563cc08331a1fdecfe7 Mon Sep 17 00:00:00 2001 From: robmry <148866618+robmry@users.noreply.github.com> Date: Thu, 23 Oct 2025 23:09:18 +0100 Subject: [PATCH] Update to moby 29.0.0 api/client New Go modules with lots of breaking changes: - moby/moby/api 1.52.0 - moby/moby/client 0.1.0 Signed-off-by: Rob Murray --- client/client.container.go | 23 ++- client/client.container_benchmarks_test.go | 10 +- client/client.container_test.go | 35 ++-- client/client.go | 7 +- client/client.image.go | 4 +- client/client.network.go | 4 +- client/client.volume.go | 4 +- client/client_benchmark_test.go | 2 +- client/client_test.go | 10 +- client/daemon.go | 26 +-- client/examples_test.go | 6 +- client/go.mod | 21 +-- client/go.sum | 83 +-------- client/options.go | 2 +- client/types.go | 25 ++- config/auth.go | 5 +- config/auth_test.go | 3 +- config/config.go | 3 +- config/config_benchmarks_test.go | 3 +- config/config_test.go | 3 +- config/credentials_helpers.go | 2 +- config/go.mod | 6 +- config/go.sum | 4 +- config/types.go | 2 +- container/container.exec.go | 11 +- container/container.go | 16 +- container/container.logs.go | 6 +- container/container.logs_test.go | 2 +- container/container.network.go | 38 ++-- container/container.run.go | 22 ++- container/container.run_test.go | 81 ++++----- container/container.start.go | 4 +- container/container.stop.go | 6 +- container/container.terminate.go | 21 +-- container/container_examples_test.go | 10 +- container/container_unit_test.go | 5 +- container/definition.go | 4 +- container/definition_test.go | 3 +- container/exec/processor.go | 10 +- container/exec/processor_test.go | 15 +- container/files.go | 20 ++- container/go.mod | 22 +-- container/go.sum | 105 +++-------- container/inspect.go | 25 ++- container/lifecycle.create.go | 73 ++++++-- container/lifecycle.create_test.go | 109 ++++++------ container/lifecycle.go | 11 +- container/options.go | 4 +- container/options_test.go | 4 +- container/ports.go | 32 ++-- container/ports_benchmarks_test.go | 7 +- container/udp_port_binding_test.go | 49 +++-- container/wait/exec_test.go | 11 +- container/wait/exit_test.go | 11 +- container/wait/file_test.go | 2 +- container/wait/health.go | 4 +- container/wait/health_test.go | 18 +- container/wait/host_port.go | 42 ++--- container/wait/host_port_test.go | 197 ++++++++++----------- container/wait/http.go | 35 ++-- container/wait/http_test.go | 174 +++++++++--------- container/wait/log_test.go | 2 +- container/wait/nop.go | 12 +- container/wait/sql.go | 16 +- container/wait/sql_test.go | 59 +++--- container/wait/strategytarget_mock_test.go | 45 +++-- container/wait/wait.go | 10 +- container/wait/wait_test.go | 18 +- context/go.mod | 4 +- context/go.sum | 4 +- go.work | 2 +- go.work.sum | 67 +++++++ image/README.md | 12 +- image/build.go | 14 +- image/build.log.go | 4 +- image/build.log_test.go | 19 +- image/build_examples_test.go | 12 +- image/build_test.go | 31 ++-- image/build_unit_test.go | 4 +- image/go.mod | 16 +- image/go.sum | 77 ++------ image/mocks_test.go | 31 ++-- image/options.go | 15 +- image/options_test.go | 4 +- image/pull.go | 7 +- image/pull_benchmark_test.go | 60 ++++--- image/pull_examples_test.go | 22 ++- image/pull_test.go | 4 +- image/pull_unit_test.go | 4 +- image/remove.go | 13 +- image/remove_test.go | 4 +- image/save.go | 2 +- legacyadapters/README.md | 2 +- legacyadapters/config/auth.go | 3 +- legacyadapters/config/auth_test.go | 27 +-- legacyadapters/go.mod | 4 +- legacyadapters/go.sum | 4 +- network/go.mod | 17 +- network/go.sum | 84 +-------- network/network.go | 6 +- network/network.inspect.go | 17 +- network/network.inspect_test.go | 14 +- network/network.list.go | 40 +++-- network/network.list_test.go | 6 +- network/network.terminate.go | 4 +- network/network_examples_test.go | 9 +- network/network_test.go | 13 +- network/options.go | 3 +- network/testing.go | 4 +- network/types.go | 7 +- volume/README.md | 4 +- volume/go.mod | 17 +- volume/go.sum | 84 +-------- volume/options.go | 11 +- volume/testing.go | 2 +- volume/types.go | 5 +- volume/volume.find.go | 18 +- volume/volume.find_test.go | 8 +- volume/volume.go | 7 +- volume/volume.terminate.go | 5 +- volume/volume_benchmark_test.go | 4 +- volume/volume_examples_test.go | 5 +- 122 files changed, 1191 insertions(+), 1339 deletions(-) diff --git a/client/client.container.go b/client/client.container.go index 25569776..17001d8e 100644 --- a/client/client.container.go +++ b/client/client.container.go @@ -5,19 +5,16 @@ import ( "fmt" "github.com/containerd/errdefs" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" - - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/api/types/network" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" ) // ContainerCreate creates a new container. -func (c *sdkClient) ContainerCreate(ctx context.Context, config *container.Config, hostConfig *container.HostConfig, networkingConfig *network.NetworkingConfig, platform *ocispec.Platform, name string) (container.CreateResponse, error) { +func (c *sdkClient) ContainerCreate(ctx context.Context, options client.ContainerCreateOptions) (client.ContainerCreateResult, error) { // Add the labels that identify this as a container created by the SDK. - AddSDKLabels(config.Labels) + AddSDKLabels(options.Config.Labels) - return c.APIClient.ContainerCreate(ctx, config, hostConfig, networkingConfig, platform, name) + return c.APIClient.ContainerCreate(ctx, options) } // FindContainerByName finds a container by name. The name filter uses a regex to find the containers. @@ -27,14 +24,16 @@ func (c *sdkClient) FindContainerByName(ctx context.Context, name string) (*cont } // Note that, 'name' filter will use regex to find the containers - filter := filters.NewArgs(filters.Arg("name", fmt.Sprintf("^%s$", name))) - containers, err := c.ContainerList(ctx, container.ListOptions{All: true, Filters: filter}) + containers, err := c.ContainerList(ctx, client.ContainerListOptions{ + All: true, + Filters: make(client.Filters).Add("name", "^"+name+"$"), + }) if err != nil { return nil, fmt.Errorf("container list: %w", err) } - if len(containers) > 0 { - return &containers[0], nil + if len(containers.Items) > 0 { + return &containers.Items[0], nil } return nil, errdefs.ErrNotFound.WithMessage(fmt.Sprintf("container %s not found", name)) diff --git a/client/client.container_benchmarks_test.go b/client/client.container_benchmarks_test.go index 38bf6c96..9c5002ef 100644 --- a/client/client.container_benchmarks_test.go +++ b/client/client.container_benchmarks_test.go @@ -7,9 +7,9 @@ import ( "sync" "testing" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/container" "github.com/docker/go-sdk/client" ) @@ -42,7 +42,7 @@ func BenchmarkContainerList(b *testing.B) { b.ReportAllocs() b.RunParallel(func(pb *testing.PB) { for pb.Next() { - _, err := dockerClient.ContainerList(context.Background(), container.ListOptions{All: true}) + _, err := dockerClient.ContainerList(context.Background(), dockerclient.ContainerListOptions{All: true}) require.NoError(b, err) } }) @@ -73,16 +73,16 @@ func BenchmarkContainerPause(b *testing.B) { createContainer(b, dockerClient, img, containerName) b.Run("container-pause-unpause", func(b *testing.B) { - err = dockerClient.ContainerStart(context.Background(), containerName, container.StartOptions{}) + _, err = dockerClient.ContainerStart(context.Background(), containerName, dockerclient.ContainerStartOptions{}) require.NoError(b, err) b.ResetTimer() b.ReportAllocs() for i := 0; i < b.N; i++ { - err := dockerClient.ContainerPause(context.Background(), containerName) + _, err := dockerClient.ContainerPause(context.Background(), containerName, dockerclient.ContainerPauseOptions{}) require.NoError(b, err) - err = dockerClient.ContainerUnpause(context.Background(), containerName) + _, err = dockerClient.ContainerUnpause(context.Background(), containerName, dockerclient.ContainerUnpauseOptions{}) require.NoError(b, err) } }) diff --git a/client/client.container_test.go b/client/client.container_test.go index cdc212c5..606a3a41 100644 --- a/client/client.container_test.go +++ b/client/client.container_test.go @@ -8,11 +8,11 @@ import ( "testing" "github.com/containerd/errdefs" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/image" - "github.com/docker/go-connections/nat" "github.com/docker/go-sdk/client" ) @@ -40,10 +40,10 @@ func TestContainerList(t *testing.T) { wg.Wait() - containers, err := dockerClient.ContainerList(context.Background(), container.ListOptions{All: true}) + containers, err := dockerClient.ContainerList(context.Background(), dockerclient.ContainerListOptions{All: true}) require.NoError(t, err) - require.NotEmpty(t, containers) - require.Len(t, containers, max) + require.NotEmpty(t, containers.Items) + require.Len(t, containers.Items, max) } func TestFindContainerByName(t *testing.T) { @@ -84,31 +84,34 @@ func TestContainerPause(t *testing.T) { pullImage(t, dockerClient, img) createContainer(t, dockerClient, img, "nginx-test-pause") - err = dockerClient.ContainerStart(context.Background(), "nginx-test-pause", container.StartOptions{}) + _, err = dockerClient.ContainerStart(context.Background(), "nginx-test-pause", dockerclient.ContainerStartOptions{}) require.NoError(t, err) - err = dockerClient.ContainerPause(context.Background(), "nginx-test-pause") + _, err = dockerClient.ContainerPause(context.Background(), "nginx-test-pause", dockerclient.ContainerPauseOptions{}) require.NoError(t, err) - err = dockerClient.ContainerUnpause(context.Background(), "nginx-test-pause") + _, err = dockerClient.ContainerUnpause(context.Background(), "nginx-test-pause", dockerclient.ContainerUnpauseOptions{}) require.NoError(t, err) } func createContainer(tb testing.TB, dockerClient client.SDKClient, img string, name string) { tb.Helper() - resp, err := dockerClient.ContainerCreate(context.Background(), &container.Config{ - Image: img, - ExposedPorts: nat.PortSet{ - "80/tcp": {}, + resp, err := dockerClient.ContainerCreate(context.Background(), dockerclient.ContainerCreateOptions{ + Config: &container.Config{ + Image: img, + ExposedPorts: network.PortSet{ + network.MustParsePort("80/tcp"): {}, + }, }, - }, nil, nil, nil, name) + Name: name, + }) require.NoError(tb, err) require.NotNil(tb, resp) require.NotEmpty(tb, resp.ID) tb.Cleanup(func() { - err := dockerClient.ContainerRemove(context.Background(), resp.ID, container.RemoveOptions{Force: true}) + _, err := dockerClient.ContainerRemove(context.Background(), resp.ID, dockerclient.ContainerRemoveOptions{Force: true}) require.NoError(tb, err) }) } @@ -116,7 +119,7 @@ func createContainer(tb testing.TB, dockerClient client.SDKClient, img string, n func pullImage(tb testing.TB, client client.SDKClient, img string) { tb.Helper() - r, err := client.ImagePull(context.Background(), img, image.PullOptions{}) + r, err := client.ImagePull(context.Background(), img, dockerclient.ImagePullOptions{}) require.NoError(tb, err) defer r.Close() diff --git a/client/client.go b/client/client.go index 761d85ea..cfe84dd9 100644 --- a/client/client.go +++ b/client/client.go @@ -9,7 +9,8 @@ import ( "path/filepath" "time" - "github.com/docker/docker/client" + "github.com/moby/moby/client" + dockercontext "github.com/docker/go-sdk/context" ) @@ -34,7 +35,7 @@ var ( return func(c SDKClient) error { var pingErr error for i := range 3 { - if _, pingErr = c.Ping(ctx); pingErr == nil { + if _, pingErr = c.Ping(ctx, client.PingOptions{}); pingErr == nil { return nil } select { @@ -135,7 +136,7 @@ func (c *sdkClient) init() error { opts = append(opts, client.WithHTTPHeaders(httpHeaders)) - api, err := client.NewClientWithOpts(opts...) + api, err := client.New(opts...) if err != nil { return fmt.Errorf("new client: %w", err) } diff --git a/client/client.image.go b/client/client.image.go index 6bea1177..30b7b227 100644 --- a/client/client.image.go +++ b/client/client.image.go @@ -4,11 +4,11 @@ import ( "context" "io" - "github.com/docker/docker/api/types/build" + "github.com/moby/moby/client" ) // ImageBuild builds an image from a build context and options. -func (c *sdkClient) ImageBuild(ctx context.Context, context io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) { +func (c *sdkClient) ImageBuild(ctx context.Context, context io.Reader, options client.ImageBuildOptions) (client.ImageBuildResult, error) { // Add client labels AddSDKLabels(options.Labels) diff --git a/client/client.network.go b/client/client.network.go index 8bc7a324..2320df0b 100644 --- a/client/client.network.go +++ b/client/client.network.go @@ -3,11 +3,11 @@ package client import ( "context" - "github.com/docker/docker/api/types/network" + "github.com/moby/moby/client" ) // NetworkCreate creates a new network -func (c *sdkClient) NetworkCreate(ctx context.Context, name string, options network.CreateOptions) (network.CreateResponse, error) { +func (c *sdkClient) NetworkCreate(ctx context.Context, name string, options client.NetworkCreateOptions) (client.NetworkCreateResult, error) { // Add the labels that identify this as a network created by the SDK. AddSDKLabels(options.Labels) diff --git a/client/client.volume.go b/client/client.volume.go index 948d0460..68329ab1 100644 --- a/client/client.volume.go +++ b/client/client.volume.go @@ -3,11 +3,11 @@ package client import ( "context" - "github.com/docker/docker/api/types/volume" + "github.com/moby/moby/client" ) // VolumeCreate creates a new volume. -func (c *sdkClient) VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error) { +func (c *sdkClient) VolumeCreate(ctx context.Context, options client.VolumeCreateOptions) (client.VolumeCreateResult, error) { // Add the labels that identify this as a volume created by the SDK. AddSDKLabels(options.Labels) diff --git a/client/client_benchmark_test.go b/client/client_benchmark_test.go index caf81827..53c14acf 100644 --- a/client/client_benchmark_test.go +++ b/client/client_benchmark_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - dockerclient "github.com/docker/docker/client" "github.com/docker/go-sdk/client" ) diff --git a/client/client_test.go b/client/client_test.go index 9563cb59..73e86383 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -5,9 +5,9 @@ import ( "path/filepath" "testing" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - dockerclient "github.com/docker/docker/client" "github.com/docker/go-sdk/client" dockercontext "github.com/docker/go-sdk/context" ) @@ -24,7 +24,7 @@ func TestNew(t *testing.T) { require.NoError(t, err) require.NotNil(t, cli) - info, err := cli.Info(context.Background()) + info, err := cli.Info(context.Background(), dockerclient.InfoOptions{}) require.NoError(t, err) require.NotNil(t, info) }) @@ -34,11 +34,11 @@ func TestNew(t *testing.T) { require.NoError(t, err) require.NotNil(t, cli) - info1, err := cli.Info(context.Background()) + info1, err := cli.Info(context.Background(), dockerclient.InfoOptions{}) require.NoError(t, err) require.NotNil(t, info1) - info2, err := cli.Info(context.Background()) + info2, err := cli.Info(context.Background(), dockerclient.InfoOptions{}) require.NoError(t, err) require.NotNil(t, info2) @@ -99,7 +99,7 @@ func TestNew(t *testing.T) { infoHealthCheck := func(ctx context.Context) func(c client.SDKClient) error { return func(c client.SDKClient) error { - _, err := c.Info(ctx) + _, err := c.Info(ctx, dockerclient.InfoOptions{}) return err } } diff --git a/client/daemon.go b/client/daemon.go index 169d94e6..cbb6f2d7 100644 --- a/client/daemon.go +++ b/client/daemon.go @@ -3,17 +3,18 @@ package client import ( "context" "errors" + "net/netip" "net/url" "os" - "github.com/docker/docker/api/types/network" + "github.com/moby/moby/client" ) // dockerEnvFile is the file that is created when running inside a container. // It's a variable to allow testing. var dockerEnvFile = "/.dockerenv" -// DaemonHost gets the host or ip of the Docker daemon where ports are exposed on +// DaemonHostWithContext gets the host or ip of the Docker daemon where ports are exposed on // Warning: this is based on your Docker host setting. Will fail if using an SSH tunnel func (c *sdkClient) DaemonHostWithContext(ctx context.Context) (string, error) { c.mtx.Lock() @@ -38,9 +39,10 @@ func (c *sdkClient) daemonHostLocked(ctx context.Context) (string, error) { if inAContainer(dockerEnvFile) { ip, err := c.getGatewayIP(ctx, "bridge") if err != nil { - ip = "localhost" + host = "localhost" + } else { + host = ip.String() } - host = ip } else { host = "localhost" } @@ -51,21 +53,21 @@ func (c *sdkClient) daemonHostLocked(ctx context.Context) (string, error) { return host, nil } -func (c *sdkClient) getGatewayIP(ctx context.Context, defaultNetwork string) (string, error) { - nw, err := c.NetworkInspect(ctx, defaultNetwork, network.InspectOptions{}) +func (c *sdkClient) getGatewayIP(ctx context.Context, defaultNetwork string) (netip.Addr, error) { + nw, err := c.NetworkInspect(ctx, defaultNetwork, client.NetworkInspectOptions{}) if err != nil { - return "", err + return netip.Addr{}, err } - var ip string - for _, cfg := range nw.IPAM.Config { - if cfg.Gateway != "" { + var ip netip.Addr + for _, cfg := range nw.Network.IPAM.Config { + if cfg.Gateway.IsValid() { ip = cfg.Gateway break } } - if ip == "" { - return "", errors.New("failed to get gateway IP from network settings") + if !ip.IsValid() { + return netip.Addr{}, errors.New("failed to get gateway IP from network settings") } return ip, nil diff --git a/client/examples_test.go b/client/examples_test.go index 997503a8..c2436c23 100644 --- a/client/examples_test.go +++ b/client/examples_test.go @@ -5,6 +5,8 @@ import ( "fmt" "log" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/client" ) @@ -15,13 +17,13 @@ func ExampleNew() { return } - info, err := cli.Info(context.Background()) + info, err := cli.Info(context.Background(), dockerclient.InfoOptions{}) if err != nil { log.Printf("error getting info: %s", err) return } - fmt.Println(info.OperatingSystem != "") + fmt.Println(info.Info.OperatingSystem != "") // Output: // true diff --git a/client/go.mod b/client/go.mod index 0a79941a..18db6bdc 100644 --- a/client/go.mod +++ b/client/go.mod @@ -1,6 +1,6 @@ module github.com/docker/go-sdk/client -go 1.24 +go 1.24.0 replace ( github.com/docker/go-sdk/config => ../config @@ -10,44 +10,33 @@ replace ( require ( github.com/caarlos0/env/v11 v11.3.1 github.com/containerd/errdefs v1.0.0 - github.com/docker/docker v28.3.2+incompatible - github.com/docker/go-connections v0.5.0 github.com/docker/go-sdk/context v0.1.0-alpha011 - github.com/opencontainers/image-spec v1.1.1 + github.com/moby/moby/api v1.52.0 + github.com/moby/moby/client v0.1.0 github.com/stretchr/testify v1.10.0 ) require ( github.com/Microsoft/go-winio v0.6.2 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect - github.com/containerd/log v0.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/reference v0.6.0 // indirect + github.com/docker/go-connections v0.6.0 // indirect github.com/docker/go-sdk/config v0.1.0-alpha011 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/sys/atomicwriter v0.1.0 // indirect - github.com/moby/term v0.5.2 // indirect - github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/pkg/errors v0.9.1 // indirect + github.com/opencontainers/image-spec v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/sdk v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect - go.opentelemetry.io/proto/otlp v1.7.0 // indirect golang.org/x/sys v0.33.0 // indirect - golang.org/x/time v0.11.0 // indirect - google.golang.org/grpc v1.73.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/client/go.sum b/client/go.sum index 218ed7eb..08a9ebae 100644 --- a/client/go.sum +++ b/client/go.sum @@ -1,25 +1,17 @@ -github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= -github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA= github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v28.3.2+incompatible h1:wn66NJ6pWB1vBZIilP8G3qQPqHy5XymfYn5vsqeA5oA= -github.com/docker/docker v28.3.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -29,56 +21,36 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= -github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= -github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= -github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= -github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= -github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= +github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= +github.com/moby/moby/client v0.1.0 h1:nt+hn6O9cyJQqq5UWnFGqsZRTS/JirUqzPjEl0Bdc/8= +github.com/moby/moby/client v0.1.0/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXXvf78e00EwY6Wp0YII8ww2JVWshZ20HfTlE11AM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ= go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= @@ -87,49 +59,8 @@ go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFw go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= -google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -137,3 +68,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/client/options.go b/client/options.go index d4da6988..ec574c42 100644 --- a/client/options.go +++ b/client/options.go @@ -5,7 +5,7 @@ import ( "errors" "log/slog" - "github.com/docker/docker/client" + "github.com/moby/moby/client" ) // ClientOption is a type that represents an option for configuring a client. diff --git a/client/types.go b/client/types.go index 2f9e5888..ca02d609 100644 --- a/client/types.go +++ b/client/types.go @@ -6,9 +6,8 @@ import ( "log/slog" "sync" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/system" - "github.com/docker/docker/client" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" ) // packagePath is the package path for the docker-go-sdk package. @@ -21,7 +20,7 @@ type SDKClient interface { // Logger returns the logger for the client. Logger() *slog.Logger - // DaemonHost gets the host or ip of the Docker daemon where ports are exposed on + // DaemonHostWithContext gets the host or ip of the Docker daemon where ports are exposed on DaemonHostWithContext(ctx context.Context) (string, error) // FindContainerByName finds a container by name. @@ -59,7 +58,7 @@ type sdkClient struct { extraHeaders map[string]string // cached docker info - dockerInfo system.Info + dockerInfo client.SystemInfoResult dockerInfoSet bool // healthCheck is a function that returns the health of the docker daemon. @@ -75,7 +74,7 @@ func (c *sdkClient) Logger() *slog.Logger { // Info returns information about the docker server. The result of Info is cached // and reused every time Info is called. // It will also print out the docker server info, and the resolved Docker paths, to the default logger. -func (c *sdkClient) Info(ctx context.Context) (system.Info, error) { +func (c *sdkClient) Info(ctx context.Context, options client.InfoOptions) (client.SystemInfoResult, error) { c.mtx.Lock() if c.dockerInfoSet { defer c.mtx.Unlock() @@ -83,9 +82,9 @@ func (c *sdkClient) Info(ctx context.Context) (system.Info, error) { } c.mtx.Unlock() - var info system.Info + var info client.SystemInfoResult - info, err := c.APIClient.Info(ctx) + info, err := c.APIClient.Info(ctx, options) if err != nil { return info, fmt.Errorf("docker info: %w", err) } @@ -93,20 +92,20 @@ func (c *sdkClient) Info(ctx context.Context) (system.Info, error) { c.dockerInfoSet = true infoLabels := "" - if len(c.dockerInfo.Labels) > 0 { + if len(c.dockerInfo.Info.Labels) > 0 { infoLabels = ` Labels:` - for _, lb := range c.dockerInfo.Labels { + for _, lb := range c.dockerInfo.Info.Labels { infoLabels += "\n " + lb } } c.log.Info("Connected to docker", "package", packagePath, - "server_version", c.dockerInfo.ServerVersion, + "server_version", c.dockerInfo.Info.ServerVersion, "client_version", c.ClientVersion(), - "operating_system", c.dockerInfo.OperatingSystem, - "mem_total", c.dockerInfo.MemTotal/1024/1024, + "operating_system", c.dockerInfo.Info.OperatingSystem, + "mem_total", c.dockerInfo.Info.MemTotal/1024/1024, "labels", infoLabels, "docker_context", c.dockerContext, "docker_host", c.dockerHost, diff --git a/config/auth.go b/config/auth.go index 2908a469..e74c02ee 100644 --- a/config/auth.go +++ b/config/auth.go @@ -3,7 +3,8 @@ package config import ( "fmt" - "github.com/docker/docker/api/types/registry" + "github.com/moby/moby/api/pkg/authconfig" + "github.com/moby/moby/api/types/registry" ) // This is used by the docker CLI in cases where an oauth identity token is used. @@ -38,5 +39,5 @@ func AuthConfigForHostname(hostname string) (registry.AuthConfig, error) { // EncodeBase64 encodes an AuthConfig into base64. func EncodeBase64(authConfig registry.AuthConfig) (string, error) { - return registry.EncodeAuthConfig(authConfig) + return authconfig.Encode(authConfig) } diff --git a/config/auth_test.go b/config/auth_test.go index 90acc634..cabbea84 100644 --- a/config/auth_test.go +++ b/config/auth_test.go @@ -9,9 +9,8 @@ import ( "strconv" "testing" + "github.com/moby/moby/api/types/registry" "github.com/stretchr/testify/require" - - "github.com/docker/docker/api/types/registry" ) func TestDecodeBase64Auth(t *testing.T) { diff --git a/config/config.go b/config/config.go index e5ef4cff..c56df075 100644 --- a/config/config.go +++ b/config/config.go @@ -12,7 +12,8 @@ import ( "sync" "time" - "github.com/docker/docker/api/types/registry" + "github.com/moby/moby/api/types/registry" + "github.com/docker/go-sdk/config/auth" ) diff --git a/config/config_benchmarks_test.go b/config/config_benchmarks_test.go index 9fc84e6a..0158e180 100644 --- a/config/config_benchmarks_test.go +++ b/config/config_benchmarks_test.go @@ -3,9 +3,8 @@ package config import ( "testing" + "github.com/moby/moby/api/types/registry" "github.com/stretchr/testify/require" - - "github.com/docker/docker/api/types/registry" ) func BenchmarkAuthConfigCaching(b *testing.B) { diff --git a/config/config_test.go b/config/config_test.go index 6c397131..90052133 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -6,9 +6,8 @@ import ( "sync" "testing" + "github.com/moby/moby/api/types/registry" "github.com/stretchr/testify/require" - - "github.com/docker/docker/api/types/registry" ) func TestConfig_AuthConfigsForImages(t *testing.T) { diff --git a/config/credentials_helpers.go b/config/credentials_helpers.go index c2883932..fe779b04 100644 --- a/config/credentials_helpers.go +++ b/config/credentials_helpers.go @@ -9,7 +9,7 @@ import ( "runtime" "strings" - "github.com/docker/docker/api/types/registry" + "github.com/moby/moby/api/types/registry" ) // Errors from credential helpers. diff --git a/config/go.mod b/config/go.mod index 675b67d7..94d935d8 100644 --- a/config/go.mod +++ b/config/go.mod @@ -1,16 +1,15 @@ module github.com/docker/go-sdk/config -go 1.24 +go 1.24.0 require ( github.com/distribution/reference v0.6.0 - github.com/docker/docker v28.3.2+incompatible + github.com/moby/moby/api v1.52.0 github.com/stretchr/testify v1.10.0 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/google/go-cmp v0.7.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect @@ -18,5 +17,4 @@ require ( github.com/rogpeppe/go-internal v1.13.1 // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - gotest.tools/v3 v3.5.2 // indirect ) diff --git a/config/go.sum b/config/go.sum index c916d080..7c65d1af 100644 --- a/config/go.sum +++ b/config/go.sum @@ -3,8 +3,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v28.3.2+incompatible h1:wn66NJ6pWB1vBZIilP8G3qQPqHy5XymfYn5vsqeA5oA= -github.com/docker/docker v28.3.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -14,6 +12,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= +github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= diff --git a/config/types.go b/config/types.go index bf2e2035..aeb67d05 100644 --- a/config/types.go +++ b/config/types.go @@ -3,7 +3,7 @@ package config import ( "sync/atomic" - "github.com/docker/docker/api/types/registry" + "github.com/moby/moby/api/types/registry" ) const ( diff --git a/container/container.exec.go b/container/container.exec.go index 0e188620..57a46b9b 100644 --- a/container/container.exec.go +++ b/container/container.exec.go @@ -6,7 +6,8 @@ import ( "io" "time" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/client" + "github.com/docker/go-sdk/container/exec" ) @@ -16,7 +17,7 @@ import ( // may result in unexpected bytes due to custom stream multiplexing headers. // Use [cexec.Multiplexed] option to read the combined output without the multiplexing headers. // Alternatively, to separate the stdout and stderr from [io.Reader] and interpret these headers properly, -// [github.com/docker/docker/pkg/stdcopy.StdCopy] from the Docker API should be used. +// [github.com/moby/moby/api/pkg/stdcopy.StdCopy] from the Docker API should be used. func (c *Container) Exec(ctx context.Context, cmd []string, options ...exec.ProcessOption) (int, io.Reader, error) { processOptions := exec.NewProcessOptions(cmd) @@ -26,12 +27,12 @@ func (c *Container) Exec(ctx context.Context, cmd []string, options ...exec.Proc o.Apply(processOptions) } - response, err := c.dockerClient.ContainerExecCreate(ctx, c.ID(), processOptions.ExecConfig) + response, err := c.dockerClient.ExecCreate(ctx, c.ID(), processOptions.ExecConfig) if err != nil { return 0, nil, fmt.Errorf("container exec create: %w", err) } - hijack, err := c.dockerClient.ContainerExecAttach(ctx, response.ID, container.ExecAttachOptions{}) + hijack, err := c.dockerClient.ExecAttach(ctx, response.ID, client.ExecAttachOptions{}) if err != nil { return 0, nil, fmt.Errorf("container exec attach: %w", err) } @@ -46,7 +47,7 @@ func (c *Container) Exec(ctx context.Context, cmd []string, options ...exec.Proc var exitCode int for { - execResp, err := c.dockerClient.ContainerExecInspect(ctx, response.ID) + execResp, err := c.dockerClient.ExecInspect(ctx, response.ID, client.ExecInspectOptions{}) if err != nil { return 0, nil, fmt.Errorf("container exec inspect: %w", err) } diff --git a/container/container.go b/container/container.go index fb83df9c..bc1ff034 100644 --- a/container/container.go +++ b/container/container.go @@ -5,8 +5,9 @@ import ( "fmt" "log/slog" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/api/types/container" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/container/wait" ) @@ -96,20 +97,23 @@ func FromID(ctx context.Context, dockerClient client.SDKClient, containerID stri dockerClient = sdk } - response, err := dockerClient.ContainerList(ctx, container.ListOptions{All: true, Filters: filters.NewArgs(filters.Arg("id", containerID))}) + response, err := dockerClient.ContainerList(ctx, dockerclient.ContainerListOptions{ + All: true, + Filters: make(dockerclient.Filters).Add("id", containerID), + }) if err != nil { return nil, fmt.Errorf("list containers: %w", err) } - if len(response) == 0 { + if len(response.Items) == 0 { return nil, fmt.Errorf("container %s not found", containerID) } - if len(response) > 1 { + if len(response.Items) > 1 { return nil, fmt.Errorf("multiple containers match ID %s", containerID) } - return FromResponse(ctx, dockerClient, response[0]) + return FromResponse(ctx, dockerClient, response.Items[0]) } // FromResponse builds a container struct from the response of the Docker API. diff --git a/container/container.logs.go b/container/container.logs.go index 911a69ea..b258f971 100644 --- a/container/container.logs.go +++ b/container/container.logs.go @@ -9,7 +9,7 @@ import ( "io" "log/slog" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/client" ) // Logger returns the logger for the container. @@ -20,7 +20,7 @@ func (c *Container) Logger() *slog.Logger { // Logs will fetch both STDOUT and STDERR from the current container. Returns a // ReadCloser and leaves it up to the caller to extract what it wants. func (c *Container) Logs(ctx context.Context) (io.ReadCloser, error) { - options := container.LogsOptions{ + options := client.ContainerLogsOptions{ ShowStdout: true, ShowStderr: true, } @@ -38,7 +38,7 @@ func (c *Container) Logs(ctx context.Context) (io.ReadCloser, error) { } // If TTY is enabled, logs are not multiplexed - return them directly - if inspect.Config.Tty { + if inspect.Container.Config.Tty { return rc, nil } diff --git a/container/container.logs_test.go b/container/container.logs_test.go index 959a445d..81c8a07d 100644 --- a/container/container.logs_test.go +++ b/container/container.logs_test.go @@ -11,9 +11,9 @@ import ( "testing" "time" + dockercontainer "github.com/moby/moby/api/types/container" "github.com/stretchr/testify/require" - dockercontainer "github.com/docker/docker/api/types/container" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/container" "github.com/docker/go-sdk/container/wait" diff --git a/container/container.network.go b/container/container.network.go index d3c5aa55..83229573 100644 --- a/container/container.network.go +++ b/container/container.network.go @@ -1,40 +1,38 @@ package container -import "context" +import ( + "context" + "net/netip" +) // ContainerIP gets the IP address of the primary network within the container. // If there are multiple networks, it returns an empty string. -func (c *Container) ContainerIP(ctx context.Context) (string, error) { +func (c *Container) ContainerIP(ctx context.Context) (netip.Addr, error) { inspect, err := c.Inspect(ctx) if err != nil { - return "", err + return netip.Addr{}, err } - ip := inspect.NetworkSettings.IPAddress - if ip == "" { - // use IP from "Networks" if only single network defined - networks := inspect.NetworkSettings.Networks - if len(networks) == 1 { - for _, v := range networks { - ip = v.IPAddress - } + // use IP from "Networks" if only single network defined + var ip netip.Addr + networks := inspect.Container.NetworkSettings.Networks + if len(networks) == 1 { + for _, v := range networks { + ip = v.IPAddress } } - return ip, nil } // ContainerIPs gets the IP addresses of all the networks within the container. -func (c *Container) ContainerIPs(ctx context.Context) ([]string, error) { - ips := make([]string, 0) - +func (c *Container) ContainerIPs(ctx context.Context) ([]netip.Addr, error) { inspect, err := c.Inspect(ctx) if err != nil { return nil, err } - networks := inspect.NetworkSettings.Networks - for _, nw := range networks { + ips := make([]netip.Addr, 0, len(inspect.Container.NetworkSettings.Networks)) + for _, nw := range inspect.Container.NetworkSettings.Networks { ips = append(ips, nw.IPAddress) } @@ -48,7 +46,7 @@ func (c *Container) NetworkAliases(ctx context.Context) (map[string][]string, er return map[string][]string{}, err } - networks := inspect.NetworkSettings.Networks + networks := inspect.Container.NetworkSettings.Networks a := map[string][]string{} @@ -66,9 +64,9 @@ func (c *Container) Networks(ctx context.Context) ([]string, error) { return []string{}, err } - networks := inspect.NetworkSettings.Networks + networks := inspect.Container.NetworkSettings.Networks - n := []string{} + var n []string for k := range networks { n = append(n, k) diff --git a/container/container.run.go b/container/container.run.go index 43dc809c..7c37afe9 100644 --- a/container/container.run.go +++ b/container/container.run.go @@ -5,8 +5,10 @@ import ( "errors" "fmt" - "github.com/docker/docker/api/types/container" - apinetwork "github.com/docker/docker/api/types/network" + "github.com/moby/moby/api/types/container" + apinetwork "github.com/moby/moby/api/types/network" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/client" ) @@ -112,7 +114,13 @@ func Run(ctx context.Context, opts ...ContainerCustomizer) (*Container, error) { // as it could have been overridden in there. dockerInput.Image = def.image - resp, err := def.dockerClient.ContainerCreate(ctx, dockerInput, hostConfig, networkingConfig, def.platform, def.name) + resp, err := def.dockerClient.ContainerCreate(ctx, dockerclient.ContainerCreateOptions{ + Config: dockerInput, + HostConfig: hostConfig, + NetworkingConfig: networkingConfig, + Platform: def.platform, + Name: def.name, + }) if err != nil { return nil, fmt.Errorf("container create: %w", err) } @@ -136,7 +144,7 @@ func Run(ctx context.Context, opts ...ContainerCustomizer) (*Container, error) { // If there is more than one network specified in the request attach newly created container to them one by one if len(def.networks) > 1 { for _, n := range def.networks[1:] { - nwInspect, err := ctr.dockerClient.NetworkInspect(ctx, n, apinetwork.InspectOptions{ + nwInspect, err := ctr.dockerClient.NetworkInspect(ctx, n, dockerclient.NetworkInspectOptions{ Verbose: true, }) if err != nil { @@ -146,8 +154,10 @@ func Run(ctx context.Context, opts ...ContainerCustomizer) (*Container, error) { endpointSetting := apinetwork.EndpointSettings{ Aliases: def.networkAliases[n], } - err = ctr.dockerClient.NetworkConnect(ctx, nwInspect.ID, resp.ID, &endpointSetting) - if err != nil { + if _, err = ctr.dockerClient.NetworkConnect(ctx, nwInspect.Network.ID, dockerclient.NetworkConnectOptions{ + Container: resp.ID, + EndpointConfig: &endpointSetting, + }); err != nil { return ctr, fmt.Errorf("network connect: %w", err) } } diff --git a/container/container.run_test.go b/container/container.run_test.go index 4e9e28f4..93982e97 100644 --- a/container/container.run_test.go +++ b/container/container.run_test.go @@ -15,10 +15,11 @@ import ( "time" "github.com/containerd/errdefs" + apicontainer "github.com/moby/moby/api/types/container" + apinetwork "github.com/moby/moby/api/types/network" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - apicontainer "github.com/docker/docker/api/types/container" - apinetwork "github.com/docker/docker/api/types/network" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/container" "github.com/docker/go-sdk/container/exec" @@ -185,9 +186,9 @@ echo "done" require.NoError(t, err) require.NotNil(t, inspect) - require.Contains(t, inspect.Config.Env, "ENV1=value1") - require.Contains(t, inspect.Config.Env, "ENV2=value2") - require.Equal(t, "test-hostname", inspect.Config.Hostname) + require.Contains(t, inspect.Container.Config.Env, "ENV1=value1") + require.Contains(t, inspect.Container.Config.Env, "ENV2=value2") + require.Equal(t, "test-hostname", inspect.Container.Config.Hostname) }) t.Run("with-host-config-modifier", func(t *testing.T) { @@ -205,7 +206,7 @@ echo "done" require.NoError(t, err) require.NotNil(t, inspect) - require.Contains(t, inspect.HostConfig.CapDrop, "CAP_NET_ADMIN") + require.Contains(t, inspect.Container.HostConfig.CapDrop, "CAP_NET_ADMIN") }) t.Run("with-endpoint-settings-modifier", func(t *testing.T) { @@ -228,9 +229,9 @@ echo "done" require.NoError(t, err) require.NotNil(t, inspect) - require.Contains(t, inspect.NetworkSettings.Networks, name) - require.Contains(t, inspect.NetworkSettings.Networks[name].Aliases, "alias1") - require.Contains(t, inspect.NetworkSettings.Networks[name].Aliases, "alias2") + require.Contains(t, inspect.Container.NetworkSettings.Networks, name) + require.Contains(t, inspect.Container.NetworkSettings.Networks[name].Aliases, "alias1") + require.Contains(t, inspect.Container.NetworkSettings.Networks[name].Aliases, "alias2") }) t.Run("with-startup-command", func(t *testing.T) { @@ -303,8 +304,8 @@ echo "done" require.NoError(t, err) require.NotNil(t, inspect) - require.Equal(t, ctr.ID(), inspect.ID) - require.Equal(t, ctr.Image(), inspect.Config.Image) + require.Equal(t, ctr.ID(), inspect.Container.ID) + require.Equal(t, ctr.Image(), inspect.Container.Config.Image) }) t.Run("endpoint", func(t *testing.T) { @@ -328,26 +329,26 @@ echo "done" }) t.Run("port-endpoint", func(t *testing.T) { - portEndpoint, err := ctr.PortEndpoint(context.Background(), "80/tcp", "tcp") + portEndpoint, err := ctr.PortEndpoint(context.Background(), apinetwork.MustParsePort("80/tcp"), "tcp") require.NoError(t, err) require.True(t, strings.HasPrefix(portEndpoint, "tcp://")) }) t.Run("port-endpoint-not-found", func(t *testing.T) { - portEndpoint, err := ctr.PortEndpoint(context.Background(), "3306/tcp", "tcp") + portEndpoint, err := ctr.PortEndpoint(context.Background(), apinetwork.MustParsePort("3306/tcp"), "tcp") require.ErrorIs(t, err, errdefs.ErrNotFound) require.Empty(t, portEndpoint) }) t.Run("mapped-port", func(t *testing.T) { - mappedPort, err := ctr.MappedPort(context.Background(), "80/tcp") + mappedPort, err := ctr.MappedPort(context.Background(), apinetwork.MustParsePort("80/tcp")) require.NoError(t, err) require.NotNil(t, mappedPort) - require.NotEqual(t, "80", mappedPort.Port()) + require.NotEqual(t, "80", mappedPort) }) t.Run("mapped-port-not-found", func(t *testing.T) { - mappedPort, err := ctr.MappedPort(context.Background(), "3306/tcp") + mappedPort, err := ctr.MappedPort(context.Background(), apinetwork.MustParsePort("3306/tcp")) require.ErrorIs(t, err, errdefs.ErrNotFound) require.Empty(t, mappedPort) }) @@ -366,7 +367,7 @@ echo "done" require.NoError(t, err) require.NotNil(t, state) - require.Equal(t, "running", state.Status) + require.Equal(t, apicontainer.StateRunning, state.Status) err = c.Stop(context.Background()) require.NoError(t, err) @@ -374,7 +375,7 @@ echo "done" state, err = c.State(context.Background()) require.NoError(t, err) require.NotNil(t, state) - require.Equal(t, "exited", state.Status) + require.Equal(t, apicontainer.StateExited, state.Status) err = c.Terminate(context.Background()) require.NoError(t, err) @@ -404,11 +405,11 @@ func TestRun_addSDKLabels(t *testing.T) { inspect, err := ctr.Inspect(context.Background()) require.NoError(t, err) - require.Contains(t, inspect.Config.Labels, client.LabelBase) - require.Contains(t, inspect.Config.Labels, client.LabelLang) - require.Contains(t, inspect.Config.Labels, client.LabelVersion) - require.Contains(t, inspect.Config.Labels, client.LabelBase+".container") - require.Equal(t, container.Version(), inspect.Config.Labels[client.LabelBase+".container"]) + require.Contains(t, inspect.Container.Config.Labels, client.LabelBase) + require.Contains(t, inspect.Container.Config.Labels, client.LabelLang) + require.Contains(t, inspect.Container.Config.Labels, client.LabelVersion) + require.Contains(t, inspect.Container.Config.Labels, client.LabelBase+".container") + require.Equal(t, container.Version(), inspect.Container.Config.Labels[client.LabelBase+".container"]) } //go:embed testdata/hello.sh @@ -657,7 +658,7 @@ func TestRunWithNetworks(t *testing.T) { return container.Run(context.Background(), opts...) } - testInspect := func(t *testing.T, ctr *container.Container) *apicontainer.InspectResponse { + testInspect := func(t *testing.T, ctr *container.Container) dockerclient.ContainerInspectResult { t.Helper() inspect, err := ctr.Inspect(context.Background()) @@ -685,8 +686,8 @@ func TestRunWithNetworks(t *testing.T) { require.NoError(t, runErr) inspect := testInspect(t, ctr) - require.Len(t, inspect.NetworkSettings.Networks, 1) - require.Equal(t, []string{"ctr1"}, inspect.NetworkSettings.Networks[nw.Name()].Aliases) + require.Len(t, inspect.Container.NetworkSettings.Networks, 1) + require.Equal(t, []string{"ctr1"}, inspect.Container.NetworkSettings.Networks[nw.Name()].Aliases) }) t.Run("with-bridge-network", func(t *testing.T) { @@ -704,8 +705,8 @@ func TestRunWithNetworks(t *testing.T) { require.NoError(t, runErr) inspect := testInspect(t, ctr) - require.Len(t, inspect.NetworkSettings.Networks, 1) - require.Empty(t, inspect.NetworkSettings.Networks["bridge"].Aliases) // Bridge network does not support aliases + require.Len(t, inspect.Container.NetworkSettings.Networks, 1) + require.Empty(t, inspect.Container.NetworkSettings.Networks["bridge"].Aliases) // Bridge network does not support aliases }) t.Run("with-new-network", func(t *testing.T) { @@ -720,7 +721,7 @@ func TestRunWithNetworks(t *testing.T) { // We need to clean up the network first, else it fails // because the network would have active endpoints (containers) inspect := testInspect(t, ctr) - for k := range inspect.NetworkSettings.Networks { + for k := range inspect.Container.NetworkSettings.Networks { network.CleanupByID(t, k) } @@ -730,7 +731,7 @@ func TestRunWithNetworks(t *testing.T) { require.NoError(t, runErr) require.NotNil(t, inspect) - require.Len(t, inspect.NetworkSettings.Networks, 1) + require.Len(t, inspect.Container.NetworkSettings.Networks, 1) }) t.Run("with-network-name", func(t *testing.T) { @@ -750,8 +751,8 @@ func TestRunWithNetworks(t *testing.T) { require.NotNil(t, ctr) inspect := testInspect(t, ctr) - require.Len(t, inspect.NetworkSettings.Networks, 1) - require.Equal(t, []string{"ctr1"}, inspect.NetworkSettings.Networks[newNetwork.Name()].Aliases) + require.Len(t, inspect.Container.NetworkSettings.Networks, 1) + require.Equal(t, []string{"ctr1"}, inspect.Container.NetworkSettings.Networks[newNetwork.Name()].Aliases) }) t.Run("with-multiple-networks", func(t *testing.T) { @@ -774,9 +775,9 @@ func TestRunWithNetworks(t *testing.T) { require.NoError(t, runErr) inspect := testInspect(t, ctr) - require.Len(t, inspect.NetworkSettings.Networks, 2) - require.Equal(t, []string{"ctr1"}, inspect.NetworkSettings.Networks[nw1.Name()].Aliases) - require.Equal(t, []string{"ctr2"}, inspect.NetworkSettings.Networks[nw2.Name()].Aliases) + require.Len(t, inspect.Container.NetworkSettings.Networks, 2) + require.Equal(t, []string{"ctr1"}, inspect.Container.NetworkSettings.Networks[nw1.Name()].Aliases) + require.Equal(t, []string{"ctr2"}, inspect.Container.NetworkSettings.Networks[nw2.Name()].Aliases) }) } @@ -809,11 +810,11 @@ func TestRunWithWaitStrategy(t *testing.T) { } t.Run("for-listening-port", func(t *testing.T) { - testRun(t, nginxAlpineImage, wait.ForListeningPort("80/tcp"), false) + testRun(t, nginxAlpineImage, wait.ForListeningPort(apinetwork.MustParsePort("80/tcp")), false) }) t.Run("for-mapped-port", func(t *testing.T) { - testRun(t, nginxAlpineImage, wait.ForMappedPort("80/tcp"), false) + testRun(t, nginxAlpineImage, wait.ForMappedPort(apinetwork.MustParsePort("80/tcp")), false) }) t.Run("for-exposed-port", func(t *testing.T) { @@ -874,7 +875,7 @@ func TestRunWithWaitStrategy(t *testing.T) { }) } -func testCreateNetwork(t *testing.T, networkName string) apinetwork.CreateResponse { +func testCreateNetwork(t *testing.T, networkName string) dockerclient.NetworkCreateResult { t.Helper() dockerClient, err := client.New(context.TODO()) @@ -883,11 +884,11 @@ func testCreateNetwork(t *testing.T, networkName string) apinetwork.CreateRespon require.NoError(t, dockerClient.Close()) }) - nw, err := dockerClient.NetworkCreate(context.Background(), networkName, apinetwork.CreateOptions{}) + nw, err := dockerClient.NetworkCreate(context.Background(), networkName, dockerclient.NetworkCreateOptions{}) require.NoError(t, err) t.Cleanup(func() { - err := dockerClient.NetworkRemove(context.Background(), nw.ID) + _, err := dockerClient.NetworkRemove(context.Background(), nw.ID, dockerclient.NetworkRemoveOptions{}) require.NoError(t, err) require.NoError(t, dockerClient.Close()) }) diff --git a/container/container.start.go b/container/container.start.go index d9040b7b..dda13c1d 100644 --- a/container/container.start.go +++ b/container/container.start.go @@ -4,7 +4,7 @@ import ( "context" "fmt" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/client" ) // Start will start an already created container @@ -14,7 +14,7 @@ func (c *Container) Start(ctx context.Context) error { return fmt.Errorf("starting hook: %w", err) } - if err := c.dockerClient.ContainerStart(ctx, c.ID(), container.StartOptions{}); err != nil { + if _, err := c.dockerClient.ContainerStart(ctx, c.ID(), client.ContainerStartOptions{}); err != nil { return fmt.Errorf("container start: %w", err) } defer c.dockerClient.Close() diff --git a/container/container.stop.go b/container/container.stop.go index 45b74859..2969ea86 100644 --- a/container/container.stop.go +++ b/container/container.stop.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/client" ) // StopOptions is a type that holds the options for stopping a container. @@ -70,12 +70,12 @@ func (c *Container) Stop(ctx context.Context, opts ...StopOption) error { return fmt.Errorf("stopping hook: %w", err) } - var options container.StopOptions + var options client.ContainerStopOptions timeoutSeconds := int(stopOptions.StopTimeout().Seconds()) options.Timeout = &timeoutSeconds - if err := c.dockerClient.ContainerStop(stopOptions.Context(), c.ID(), options); err != nil { + if _, err := c.dockerClient.ContainerStop(stopOptions.Context(), c.ID(), options); err != nil { return fmt.Errorf("container stop: %w", err) } diff --git a/container/container.terminate.go b/container/container.terminate.go index b3f02034..5ba7698c 100644 --- a/container/container.terminate.go +++ b/container/container.terminate.go @@ -7,7 +7,8 @@ import ( "reflect" "time" - "github.com/docker/docker/api/types/container" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/client" ) @@ -46,7 +47,7 @@ func (o *TerminateOptions) Cleanup(cli client.SDKClient) error { // Best effort to remove all volumes. var errs []error for _, volume := range o.volumes { - if errRemove := cli.VolumeRemove(o.ctx, volume, true); errRemove != nil { + if _, errRemove := cli.VolumeRemove(o.ctx, volume, dockerclient.VolumeRemoveOptions{Force: true}); errRemove != nil { errs = append(errs, fmt.Errorf("volume remove %q: %w", volume, errRemove)) } } @@ -121,14 +122,14 @@ func (c *Container) Terminate(ctx context.Context, opts ...TerminateOption) erro // TODO: Handle errors from ContainerRemove more correctly, e.g. should we // run the terminated hook? - errs := []error{ - c.terminatingHook(ctx), - c.dockerClient.ContainerRemove(ctx, c.ID(), container.RemoveOptions{ - RemoveVolumes: true, - Force: true, - }), - c.terminatedHook(ctx), - } + errs := make([]error, 0, 4) + errs = append(errs, c.terminatingHook(ctx)) + _, err = c.dockerClient.ContainerRemove(ctx, c.ID(), dockerclient.ContainerRemoveOptions{ + RemoveVolumes: true, + Force: true, + }) + errs = append(errs, err) + errs = append(errs, c.terminatedHook(ctx)) c.isRunning = false diff --git a/container/container_examples_test.go b/container/container_examples_test.go index 3cd591bc..11485dc5 100644 --- a/container/container_examples_test.go +++ b/container/container_examples_test.go @@ -7,7 +7,9 @@ import ( "io" "strings" - containertypes "github.com/docker/docker/api/types/container" + containertypes "github.com/moby/moby/api/types/container" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/container" "github.com/docker/go-sdk/container/exec" ) @@ -73,7 +75,7 @@ func ExampleContainer_Inspect() { inspect, err := ctr.Inspect(context.Background()) fmt.Println(err) - fmt.Println(inspect.ID != "") + fmt.Println(inspect.Container.ID != "") err = ctr.Terminate(context.Background()) fmt.Println(err) @@ -240,7 +242,7 @@ func ExampleFromResponse() { cli := ctr.Client() // List containers to get the Summary (this is what you'd typically get from the Docker API) - containers, err := cli.ContainerList(context.Background(), containertypes.ListOptions{All: true}) + containers, err := cli.ContainerList(context.Background(), dockerclient.ContainerListOptions{All: true}) if err != nil { fmt.Println(err) return @@ -248,7 +250,7 @@ func ExampleFromResponse() { // Find our container in the list var summary containertypes.Summary - for _, c := range containers { + for _, c := range containers.Items { if c.ID == ctr.ID() { summary = c break diff --git a/container/container_unit_test.go b/container/container_unit_test.go index 57600a2e..92c0e42f 100644 --- a/container/container_unit_test.go +++ b/container/container_unit_test.go @@ -4,9 +4,8 @@ import ( "context" "testing" + "github.com/moby/moby/api/types/container" "github.com/stretchr/testify/require" - - "github.com/docker/docker/api/types/container" ) func TestFromResponse(t *testing.T) { @@ -14,7 +13,7 @@ func TestFromResponse(t *testing.T) { ID: "1234567890abcdefgh", Image: "nginx:latest", State: "running", - Ports: []container.Port{ + Ports: []container.PortSummary{ {PublicPort: 80, Type: "tcp"}, {PublicPort: 8080, Type: "udp"}, }, diff --git a/container/definition.go b/container/definition.go index f8e2cb6c..25290772 100644 --- a/container/definition.go +++ b/container/definition.go @@ -6,9 +6,9 @@ import ( "strings" "github.com/containerd/platforms" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/network" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/container/wait" "github.com/docker/go-sdk/image" diff --git a/container/definition_test.go b/container/definition_test.go index 3945b424..0974ecd3 100644 --- a/container/definition_test.go +++ b/container/definition_test.go @@ -3,9 +3,8 @@ package container import ( "testing" + "github.com/moby/moby/api/types/container" "github.com/stretchr/testify/require" - - "github.com/docker/docker/api/types/container" ) func TestValidateMounts(t *testing.T) { diff --git a/container/exec/processor.go b/container/exec/processor.go index 48e775c8..8d5c2363 100644 --- a/container/exec/processor.go +++ b/container/exec/processor.go @@ -6,13 +6,13 @@ import ( "io" "sync" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/pkg/stdcopy" + "github.com/moby/moby/api/pkg/stdcopy" + "github.com/moby/moby/client" ) // ProcessOptions defines options applicable to the reader processor type ProcessOptions struct { - ExecConfig container.ExecOptions + ExecConfig client.ExecCreateOptions Reader io.Reader } @@ -23,7 +23,7 @@ type ProcessOptions struct { // - attach stderr: true func NewProcessOptions(cmd []string) *ProcessOptions { return &ProcessOptions{ - ExecConfig: container.ExecOptions{ + ExecConfig: client.ExecCreateOptions{ Cmd: cmd, AttachStdout: true, AttachStderr: true, @@ -69,7 +69,7 @@ func WithEnv(env []string) ProcessOption { // WithTTY sets the TTY for the exec command func WithTTY(tty bool) ProcessOption { return ProcessOptionFunc(func(opts *ProcessOptions) { - opts.ExecConfig.Tty = tty + opts.ExecConfig.TTY = tty }) } diff --git a/container/exec/processor_test.go b/container/exec/processor_test.go index e015504c..8b12551a 100644 --- a/container/exec/processor_test.go +++ b/container/exec/processor_test.go @@ -4,13 +4,10 @@ import ( "bytes" "errors" "io" - "strings" "sync" "testing" "github.com/stretchr/testify/require" - - "github.com/docker/docker/pkg/stdcopy" ) func TestSafeBuffer(t *testing.T) { @@ -110,7 +107,7 @@ func TestNewProcessOptions(t *testing.T) { require.Empty(t, opts.ExecConfig.User) require.Empty(t, opts.ExecConfig.WorkingDir) require.Empty(t, opts.ExecConfig.Env) - require.False(t, opts.ExecConfig.Tty) + require.False(t, opts.ExecConfig.TTY) require.Nil(t, opts.Reader) }) } @@ -138,7 +135,7 @@ func TestProcessOptions(t *testing.T) { t.Run("WithTTY", func(t *testing.T) { opts := NewProcessOptions([]string{"echo"}) WithTTY(true).Apply(opts) - require.True(t, opts.ExecConfig.Tty) + require.True(t, opts.ExecConfig.TTY) }) t.Run("multiple-options", func(t *testing.T) { @@ -154,7 +151,7 @@ func TestProcessOptions(t *testing.T) { require.Equal(t, "testuser", opts.ExecConfig.User) require.Equal(t, "/test/dir", opts.ExecConfig.WorkingDir) require.Equal(t, []string{"TEST=value"}, opts.ExecConfig.Env) - require.True(t, opts.ExecConfig.Tty) + require.True(t, opts.ExecConfig.TTY) }) t.Run("default-values-not-affected", func(t *testing.T) { @@ -197,6 +194,7 @@ func TestMultiplexed(t *testing.T) { require.Nil(t, opts.Reader, "Reader should remain nil when no reader is set") }) + /* FIXME(robmry) - NewStdWriter is now internal to moby t.Run("combines-stdout-and-stderr", func(t *testing.T) { var buf bytes.Buffer writer := stdcopy.NewStdWriter(&buf, stdcopy.Stdout) @@ -217,6 +215,7 @@ func TestMultiplexed(t *testing.T) { require.Contains(t, outputStr, "stdout output") require.Contains(t, outputStr, "stderr output") }) + */ t.Run("empty-output", func(t *testing.T) { opts := NewProcessOptions([]string{"echo"}) @@ -241,6 +240,7 @@ func TestMultiplexed(t *testing.T) { require.Contains(t, err.Error(), "copying output") }) + /* FIXME(robmry) - NewStdWriter is now internal to moby t.Run("partial-read", func(t *testing.T) { var buf bytes.Buffer writer := stdcopy.NewStdWriter(&buf, stdcopy.Stdout) @@ -270,7 +270,9 @@ func TestMultiplexed(t *testing.T) { require.Contains(t, outputStr, "stdout output") require.Contains(t, outputStr, "stderr output") }) + */ + /* FIXME(robmry) - NewStdWriter is now internal to moby t.Run("large-output", func(t *testing.T) { largeOutput := strings.Repeat("x", 1024*1024) // 1MB of data @@ -290,6 +292,7 @@ func TestMultiplexed(t *testing.T) { require.NoError(t, err) require.Len(t, output, len(largeOutput)*2) }) + */ } // errorReader is a reader that always returns an error diff --git a/container/files.go b/container/files.go index d3b59946..e7bcec5d 100644 --- a/container/files.go +++ b/container/files.go @@ -13,7 +13,7 @@ import ( "path/filepath" "strings" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/client" ) // File represents a file that will be copied when container starts @@ -66,12 +66,14 @@ func (fc *FileFromContainer) Close() error { // CopyFromContainer copies a file from the container to the local filesystem. func (c *Container) CopyFromContainer(ctx context.Context, containerFilePath string) (io.ReadCloser, error) { - r, _, err := c.dockerClient.CopyFromContainer(ctx, c.ID(), containerFilePath) + r, err := c.dockerClient.CopyFromContainer(ctx, c.ID(), client.CopyFromContainerOptions{ + SourcePath: containerFilePath, + }) if err != nil { return nil, err } - tarReader := tar.NewReader(r) + tarReader := tar.NewReader(r.Content) // if we got here we have exactly one file in the TAR-stream // so we advance the index by one so the next call to Read will start reading it @@ -81,7 +83,7 @@ func (c *Container) CopyFromContainer(ctx context.Context, containerFilePath str } ret := &FileFromContainer{ - underlying: &r, + underlying: &r.Content, tarreader: tarReader, } @@ -109,7 +111,10 @@ func (c *Container) CopyDirToContainer(ctx context.Context, hostDirPath string, // create the directory under its parent parent := filepath.Dir(containerFilePath) - err = c.dockerClient.CopyToContainer(ctx, c.ID(), parent, buffer, container.CopyToContainerOptions{}) + _, err = c.dockerClient.CopyToContainer(ctx, c.ID(), client.CopyToContainerOptions{ + DestinationPath: parent, + Content: buffer, + }) if err != nil { return fmt.Errorf("copy to container: %w", err) } @@ -129,7 +134,10 @@ func (c *Container) CopyToContainer(ctx context.Context, fileContent []byte, con return fmt.Errorf("tar file: %w", err) } - err = c.dockerClient.CopyToContainer(ctx, c.ID(), "/", buffer, container.CopyToContainerOptions{}) + _, err = c.dockerClient.CopyToContainer(ctx, c.ID(), client.CopyToContainerOptions{ + DestinationPath: "/", + Content: buffer, + }) if err != nil { return fmt.Errorf("copy to container: %w", err) } diff --git a/container/go.mod b/container/go.mod index 7a9a4bd8..18f37783 100644 --- a/container/go.mod +++ b/container/go.mod @@ -1,6 +1,6 @@ module github.com/docker/go-sdk/container -go 1.24 +go 1.24.0 replace ( github.com/docker/go-sdk/client => ../client @@ -14,14 +14,15 @@ require ( dario.cat/mergo v1.0.2 github.com/containerd/errdefs v1.0.0 github.com/containerd/platforms v0.2.1 - github.com/docker/docker v28.3.2+incompatible - github.com/docker/go-connections v0.5.0 + github.com/docker/go-connections v0.6.0 github.com/docker/go-sdk/client v0.1.0-alpha011 github.com/docker/go-sdk/config v0.1.0-alpha011 github.com/docker/go-sdk/image v0.1.0-alpha012 github.com/docker/go-sdk/network v0.1.0-alpha011 - github.com/stretchr/testify v1.10.0 - golang.org/x/sys v0.33.0 + github.com/moby/moby/api v1.52.0 + github.com/moby/moby/client v0.1.0 + github.com/stretchr/testify v1.11.1 + golang.org/x/sys v0.35.0 ) require ( @@ -38,7 +39,6 @@ require ( github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/google/uuid v1.6.0 // indirect github.com/klauspost/compress v1.18.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect @@ -48,17 +48,17 @@ require ( github.com/moby/sys/user v0.4.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect github.com/moby/term v0.5.2 // indirect - github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/stretchr/objx v0.5.2 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect - go.opentelemetry.io/otel v1.37.0 // indirect - go.opentelemetry.io/otel/metric v1.37.0 // indirect - go.opentelemetry.io/otel/trace v1.37.0 // indirect + go.opentelemetry.io/otel v1.38.0 // indirect + go.opentelemetry.io/otel/metric v1.38.0 // indirect + go.opentelemetry.io/otel/sdk v1.38.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect + go.opentelemetry.io/otel/trace v1.38.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/container/go.sum b/container/go.sum index 69a6485a..08373814 100644 --- a/container/go.sum +++ b/container/go.sum @@ -10,8 +10,6 @@ github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5m github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= @@ -20,17 +18,15 @@ github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= +github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v28.3.2+incompatible h1:wn66NJ6pWB1vBZIilP8G3qQPqHy5XymfYn5vsqeA5oA= -github.com/docker/docker v28.3.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -40,16 +36,10 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -60,10 +50,12 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ= github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo= +github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= +github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= +github.com/moby/moby/client v0.1.0 h1:nt+hn6O9cyJQqq5UWnFGqsZRTS/JirUqzPjEl0Bdc/8= +github.com/moby/moby/client v0.1.0/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= -github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= @@ -72,14 +64,10 @@ github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= @@ -90,73 +78,26 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= -go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= -go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXXvf78e00EwY6Wp0YII8ww2JVWshZ20HfTlE11AM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ= -go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= -go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= -go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= -go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg= -go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFwHX4dThiPis= -go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= -go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= -go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= -golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= -google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -165,3 +106,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/container/inspect.go b/container/inspect.go index 0a209fea..a9803685 100644 --- a/container/inspect.go +++ b/container/inspect.go @@ -3,17 +3,30 @@ package container import ( "context" - "github.com/docker/docker/api/types/container" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/client" ) // Inspect returns the container's raw info -func (c *Container) Inspect(ctx context.Context) (*container.InspectResponse, error) { - inspect, err := c.dockerClient.ContainerInspect(ctx, c.ID()) +func (c *Container) Inspect(ctx context.Context) (client.ContainerInspectResult, error) { + inspect, err := c.dockerClient.ContainerInspect(ctx, c.ID(), client.ContainerInspectOptions{}) if err != nil { - return nil, err + return client.ContainerInspectResult{}, err + } + + return inspect, nil +} + +// InspectWithOptions returns the container's raw info, passing custom options. +// +// This method may be deprecated in the near future, to be replaced by functional options for Inspect. +func (c *Container) InspectWithOptions(ctx context.Context, options client.ContainerInspectOptions) (client.ContainerInspectResult, error) { + inspect, err := c.dockerClient.ContainerInspect(ctx, c.ID(), options) + if err != nil { + return client.ContainerInspectResult{}, err } - return &inspect, nil + return inspect, nil } // State returns container's running state. @@ -23,5 +36,5 @@ func (c *Container) State(ctx context.Context) (*container.State, error) { return nil, err } - return inspect.State, nil + return inspect.Container.State, nil } diff --git a/container/lifecycle.create.go b/container/lifecycle.create.go index 66f6062b..d5c0fa4d 100644 --- a/container/lifecycle.create.go +++ b/container/lifecycle.create.go @@ -5,11 +5,13 @@ import ( "errors" "fmt" "io" + "net/netip" "os" - "strings" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/network" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-connections/nat" "github.com/docker/go-sdk/client" ) @@ -131,19 +133,23 @@ func (c *Container) createdHook(ctx context.Context) error { }) } -func mergePortBindings(configPortMap, exposedPortMap nat.PortMap, exposedPorts []string) nat.PortMap { +func mergePortBindings(configPortMap, exposedPortMap network.PortMap, exposedPorts []string) network.PortMap { if exposedPortMap == nil { - exposedPortMap = make(map[nat.Port][]nat.PortBinding) + exposedPortMap = make(network.PortMap) } - mappedPorts := make(map[string]struct{}, len(exposedPorts)) + mappedPorts := make(network.PortSet, len(exposedPorts)) for _, p := range exposedPorts { - p = strings.Split(p, "/")[0] - mappedPorts[p] = struct{}{} + port, err := network.ParsePort(p) + if err != nil { + // TODO(robmry) - handle/log? + continue + } + mappedPorts[port] = struct{}{} } for k, v := range configPortMap { - if _, ok := mappedPorts[k.Port()]; ok { + if _, ok := mappedPorts[k]; ok { exposedPortMap[k] = v } } @@ -171,20 +177,20 @@ func preCreateContainerHook(ctx context.Context, dockerClient client.SDKClient, if len(def.networks) > 0 { attachContainerTo := def.networks[0] - nwInspect, err := dockerClient.NetworkInspect(ctx, def.networks[0], network.InspectOptions{ + nwInspect, err := dockerClient.NetworkInspect(ctx, def.networks[0], dockerclient.NetworkInspectOptions{ Verbose: true, }) if err != nil { return fmt.Errorf("network inspect: %w", err) } - aliases := []string{} + var aliases []string if _, ok := def.networkAliases[attachContainerTo]; ok { aliases = def.networkAliases[attachContainerTo] } endpointSetting := network.EndpointSettings{ Aliases: aliases, - NetworkID: nwInspect.ID, + NetworkID: nwInspect.Network.ID, } endpointSettings[attachContainerTo] = &endpointSetting @@ -210,7 +216,7 @@ func preCreateContainerHook(ctx context.Context, dockerClient client.SDKClient, hostConfig.PublishAllPorts = true } - exposedPortSet, exposedPortMap, err := nat.ParsePortSpecs(exposedPorts) + exposedPortSet, exposedPortMap, err := parsePortSpecs(exposedPorts) if err != nil { return err } @@ -226,3 +232,44 @@ func preCreateContainerHook(ctx context.Context, dockerClient client.SDKClient, return nil } + +// TODO(robmry) - migrate away from nat.ParsePortSpecs +func parsePortSpecs(exposedPorts []string) (network.PortSet, network.PortMap, error) { + p, b, err := nat.ParsePortSpecs(exposedPorts) + if err != nil { + return nil, nil, err + } + + ports := network.PortSet{} + for portStr := range p { + port, err := network.ParsePort(string(portStr)) + if err != nil { + return nil, nil, err + } + ports[port] = struct{}{} + } + bindings := network.PortMap{} + for portStr, natBs := range b { + port, err := network.ParsePort(string(portStr)) + if err != nil { + return nil, nil, err + } + bs := make([]network.PortBinding, 0, len(natBs)) + for _, nb := range natBs { + var addr netip.Addr + if nb.HostIP != "" { + var err error + addr, err = netip.ParseAddr(nb.HostIP) + if err != nil { + return nil, nil, err + } + } + bs = append(bs, network.PortBinding{ + HostIP: addr, + HostPort: nb.HostPort, + }) + } + bindings[port] = bs + } + return ports, bindings, nil +} diff --git a/container/lifecycle.create_test.go b/container/lifecycle.create_test.go index 639e657e..d6e30b24 100644 --- a/container/lifecycle.create_test.go +++ b/container/lifecycle.create_test.go @@ -5,15 +5,16 @@ import ( "context" "io" "log/slog" + "net/netip" "regexp" "testing" "time" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/network" - "github.com/docker/go-connections/nat" "github.com/docker/go-sdk/client" ) @@ -21,14 +22,14 @@ const nginxAlpineImage = "nginx:alpine" func TestMergePortBindings(t *testing.T) { type arg struct { - configPortMap nat.PortMap - parsedPortMap nat.PortMap + configPortMap network.PortMap + parsedPortMap network.PortMap exposedPorts []string } cases := []struct { name string arg arg - expected nat.PortMap + expected network.PortMap }{ { name: "empty ports", @@ -37,65 +38,69 @@ func TestMergePortBindings(t *testing.T) { parsedPortMap: nil, exposedPorts: nil, }, - expected: map[nat.Port][]nat.PortBinding{}, + expected: map[network.Port][]network.PortBinding{}, }, { name: "config port map but not exposed", arg: arg{ - configPortMap: map[nat.Port][]nat.PortBinding{ - "80/tcp": {{HostIP: "1", HostPort: "2"}}, + configPortMap: map[network.Port][]network.PortBinding{ + network.MustParsePort("80/tcp"): {{HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "2"}}, }, parsedPortMap: nil, exposedPorts: nil, }, - expected: map[nat.Port][]nat.PortBinding{}, + expected: map[network.Port][]network.PortBinding{}, }, { name: "parsed port map without config", arg: arg{ configPortMap: nil, - parsedPortMap: map[nat.Port][]nat.PortBinding{ - "80/tcp": {{HostIP: "", HostPort: ""}}, + parsedPortMap: map[network.Port][]network.PortBinding{ + network.MustParsePort("80/tcp"): {{}}, }, exposedPorts: nil, }, - expected: map[nat.Port][]nat.PortBinding{ - "80/tcp": {{HostIP: "", HostPort: "0"}}, + expected: map[network.Port][]network.PortBinding{ + network.MustParsePort("80/tcp"): { + {HostPort: "0"}, + }, }, }, { name: "parsed and configured but not exposed", arg: arg{ - configPortMap: map[nat.Port][]nat.PortBinding{ - "80/tcp": {{HostIP: "1", HostPort: "2"}}, + configPortMap: map[network.Port][]network.PortBinding{ + network.MustParsePort("80/tcp"): {{HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "2"}}, }, - parsedPortMap: map[nat.Port][]nat.PortBinding{ - "80/tcp": {{HostIP: "", HostPort: ""}}, + parsedPortMap: map[network.Port][]network.PortBinding{ + network.MustParsePort("80/tcp"): {{}}, }, exposedPorts: nil, }, - expected: map[nat.Port][]nat.PortBinding{ - "80/tcp": {{HostIP: "", HostPort: "0"}}, + expected: map[network.Port][]network.PortBinding{ + network.MustParsePort("80/tcp"): { + {HostPort: "0"}, + }, }, }, { name: "merge both parsed and config", arg: arg{ - configPortMap: map[nat.Port][]nat.PortBinding{ - "60/tcp": {{HostIP: "1", HostPort: "2"}}, - "70/tcp": {{HostIP: "1", HostPort: "2"}}, - "80/tcp": {{HostIP: "1", HostPort: "2"}}, + configPortMap: map[network.Port][]network.PortBinding{ + network.MustParsePort("60/tcp"): {{HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "2"}}, + network.MustParsePort("70/tcp"): {{HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "2"}}, + network.MustParsePort("80/tcp"): {{HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "2"}}, }, - parsedPortMap: map[nat.Port][]nat.PortBinding{ - "80/tcp": {{HostIP: "", HostPort: ""}}, - "90/tcp": {{HostIP: "", HostPort: ""}}, + parsedPortMap: map[network.Port][]network.PortBinding{ + network.MustParsePort("80/tcp"): {{}}, + network.MustParsePort("90/tcp"): {{}}, }, exposedPorts: []string{"70", "80/tcp"}, }, - expected: map[nat.Port][]nat.PortBinding{ - "70/tcp": {{HostIP: "1", HostPort: "2"}}, - "80/tcp": {{HostIP: "1", HostPort: "2"}}, - "90/tcp": {{HostIP: "", HostPort: "0"}}, + expected: map[network.Port][]network.PortBinding{ + network.MustParsePort("70/tcp"): {{HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "2"}}, + network.MustParsePort("80/tcp"): {{HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "2"}}, + network.MustParsePort("90/tcp"): {{HostPort: "0"}}, }, }, } @@ -124,10 +129,10 @@ func TestPreCreateModifierHook(t *testing.T) { config.Env = []string{"a=b"} }, hostConfigModifier: func(hostConfig *container.HostConfig) { - hostConfig.PortBindings = nat.PortMap{ - "80/tcp": []nat.PortBinding{ + hostConfig.PortBindings = network.PortMap{ + network.MustParsePort("80/tcp"): []network.PortBinding{ { - HostIP: "1", + HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "2", }, }, @@ -178,10 +183,10 @@ func TestPreCreateModifierHook(t *testing.T) { def := &Definition{ image: nginxAlpineImage, // alpine image does expose port 80 hostConfigModifier: func(hostConfig *container.HostConfig) { - hostConfig.PortBindings = nat.PortMap{ - "80/tcp": []nat.PortBinding{ + hostConfig.PortBindings = network.PortMap{ + network.MustParsePort("80/tcp"): []network.PortBinding{ { - HostIP: "1", + HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "2", }, }, @@ -204,12 +209,12 @@ func TestPreCreateModifierHook(t *testing.T) { require.Equal( t, - nat.PortSet(nat.PortSet{}), + network.PortSet(network.PortSet{}), inputConfig.ExposedPorts, "Docker config's exposed ports should be empty", ) require.Equal(t, - nat.PortMap{}, + network.PortMap{}, inputHostConfig.PortBindings, "Host config's portBinding should be empty", ) @@ -291,10 +296,10 @@ func TestPreCreateModifierHook(t *testing.T) { def := &Definition{ image: nginxAlpineImage, // alpine image does expose port 80 hostConfigModifier: func(hostConfig *container.HostConfig) { - hostConfig.PortBindings = nat.PortMap{ - "80/tcp": []nat.PortBinding{ + hostConfig.PortBindings = network.PortMap{ + network.MustParsePort("80/tcp"): []network.PortBinding{ { - HostIP: "localhost", + HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "8080", }, }, @@ -314,18 +319,18 @@ func TestPreCreateModifierHook(t *testing.T) { require.NoError(t, err) // assertions - require.Equal(t, "localhost", inputHostConfig.PortBindings["80/tcp"][0].HostIP) - require.Equal(t, "8080", inputHostConfig.PortBindings["80/tcp"][0].HostPort) + require.Equal(t, netip.MustParseAddr("127.0.0.1"), inputHostConfig.PortBindings[network.MustParsePort("80/tcp")][0].HostIP) + require.Equal(t, "8080", inputHostConfig.PortBindings[network.MustParsePort("80/tcp")][0].HostPort) }) t.Run("definition-contains-exposed-port-modifiers-with-protocol", func(t *testing.T) { def := &Definition{ image: nginxAlpineImage, // alpine image does expose port 80 hostConfigModifier: func(hostConfig *container.HostConfig) { - hostConfig.PortBindings = nat.PortMap{ - "80/tcp": []nat.PortBinding{ + hostConfig.PortBindings = network.PortMap{ + network.MustParsePort("80/tcp"): []network.PortBinding{ { - HostIP: "localhost", + HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "8080", }, }, @@ -345,8 +350,8 @@ func TestPreCreateModifierHook(t *testing.T) { require.NoError(t, err) // assertions - require.Equal(t, "localhost", inputHostConfig.PortBindings["80/tcp"][0].HostIP) - require.Equal(t, "8080", inputHostConfig.PortBindings["80/tcp"][0].HostPort) + require.Equal(t, netip.MustParseAddr("127.0.0.1"), inputHostConfig.PortBindings[network.MustParsePort("80/tcp")][0].HostIP) + require.Equal(t, "8080", inputHostConfig.PortBindings[network.MustParsePort("80/tcp")][0].HostPort) }) } @@ -418,7 +423,7 @@ func TestLifecycleHooks_WithMultipleHooks(t *testing.T) { require.Len(t, regexp.MustCompile("Stopping container").FindAllString(log, -1), 6) } -func testCreateNetwork(t *testing.T, networkName string) network.CreateResponse { +func testCreateNetwork(t *testing.T, networkName string) dockerclient.NetworkCreateResult { t.Helper() dockerClient, err := client.New(context.TODO()) @@ -427,11 +432,11 @@ func testCreateNetwork(t *testing.T, networkName string) network.CreateResponse require.NoError(t, dockerClient.Close()) }) - nw, err := dockerClient.NetworkCreate(context.Background(), networkName, network.CreateOptions{}) + nw, err := dockerClient.NetworkCreate(context.Background(), networkName, dockerclient.NetworkCreateOptions{}) require.NoError(t, err) t.Cleanup(func() { - err := dockerClient.NetworkRemove(context.Background(), nw.ID) + _, err := dockerClient.NetworkRemove(context.Background(), nw.ID, dockerclient.NetworkRemoveOptions{}) require.NoError(t, err) require.NoError(t, dockerClient.Close()) }) diff --git a/container/lifecycle.go b/container/lifecycle.go index 979bd0bb..5200ae82 100644 --- a/container/lifecycle.go +++ b/container/lifecycle.go @@ -12,8 +12,8 @@ import ( "github.com/containerd/errdefs" "github.com/containerd/platforms" + dockerclient "github.com/moby/moby/client" - apiimage "github.com/docker/docker/api/types/image" "github.com/docker/go-sdk/container/exec" "github.com/docker/go-sdk/container/wait" "github.com/docker/go-sdk/image" @@ -308,8 +308,13 @@ var defaultPullHook = []DefinitionHook{ pullOpts = append(pullOpts, def.pullOptions...) // apply platform last - pullOpt := apiimage.PullOptions{ - Platform: def.imagePlatform, // may be empty + var pullOpt dockerclient.ImagePullOptions + if def.imagePlatform != "" { + p, err := platforms.Parse(def.imagePlatform) + if err != nil { + return fmt.Errorf("invalid platform %s: %w", def.imagePlatform, err) + } + pullOpt.Platforms = append(pullOpt.Platforms, p) } pullOpts = append(pullOpts, image.WithPullOptions(pullOpt)) diff --git a/container/options.go b/container/options.go index a4e2ba75..64054927 100644 --- a/container/options.go +++ b/container/options.go @@ -10,9 +10,9 @@ import ( "time" "dario.cat/mergo" + "github.com/moby/moby/api/types/container" + apinetwork "github.com/moby/moby/api/types/network" - "github.com/docker/docker/api/types/container" - apinetwork "github.com/docker/docker/api/types/network" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/container/exec" "github.com/docker/go-sdk/container/log" diff --git a/container/options_test.go b/container/options_test.go index d964d1c6..d9bb0cd7 100644 --- a/container/options_test.go +++ b/container/options_test.go @@ -7,10 +7,10 @@ import ( "testing" "time" + "github.com/moby/moby/api/types/container" + apinetwork "github.com/moby/moby/api/types/network" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/container" - apinetwork "github.com/docker/docker/api/types/network" "github.com/docker/go-sdk/container/exec" "github.com/docker/go-sdk/container/wait" ) diff --git a/container/ports.go b/container/ports.go index b16bdfe3..c2aef5e4 100644 --- a/container/ports.go +++ b/container/ports.go @@ -4,10 +4,10 @@ import ( "context" "fmt" "net" + "strconv" "github.com/containerd/errdefs" - - "github.com/docker/go-connections/nat" + "github.com/moby/moby/api/types/network" ) // Endpoint gets proto://host:port string for the lowest numbered exposed port @@ -18,14 +18,14 @@ func (c *Container) Endpoint(ctx context.Context, proto string) (string, error) return "", err } - if len(inspect.NetworkSettings.Ports) == 0 { + if len(inspect.Container.NetworkSettings.Ports) == 0 { return "", errdefs.ErrNotFound.WithMessage("no ports exposed") } // Get lowest numbered bound port. - var lowestPort nat.Port - for port := range inspect.NetworkSettings.Ports { - if lowestPort == "" || port.Int() < lowestPort.Int() { + var lowestPort network.Port + for port := range inspect.Container.NetworkSettings.Ports { + if lowestPort.IsZero() || port.Num() < lowestPort.Num() { lowestPort = port } } @@ -36,7 +36,9 @@ func (c *Container) Endpoint(ctx context.Context, proto string) (string, error) // PortEndpoint gets proto://host:port string for the given exposed port // It returns proto://host:port or proto://[IPv6host]:port string for the given exposed port. // It returns just host:port or [IPv6host]:port if proto is blank. -func (c *Container) PortEndpoint(ctx context.Context, port nat.Port, proto string) (string, error) { +// +// TODO(robmry) - remove proto and use port.Proto() +func (c *Container) PortEndpoint(ctx context.Context, port network.Port, proto string) (string, error) { host, err := c.Host(ctx) if err != nil { return "", err @@ -47,7 +49,7 @@ func (c *Container) PortEndpoint(ctx context.Context, port nat.Port, proto strin return "", err } - hostPort := net.JoinHostPort(host, outerPort.Port()) + hostPort := net.JoinHostPort(host, strconv.Itoa(int(outerPort.Num()))) if proto == "" { return hostPort, nil } @@ -56,19 +58,19 @@ func (c *Container) PortEndpoint(ctx context.Context, port nat.Port, proto strin } // MappedPort gets externally mapped port for a container port -func (c *Container) MappedPort(ctx context.Context, port nat.Port) (nat.Port, error) { +func (c *Container) MappedPort(ctx context.Context, port network.Port) (network.Port, error) { inspect, err := c.Inspect(ctx) if err != nil { - return "", fmt.Errorf("inspect: %w", err) + return network.Port{}, fmt.Errorf("inspect: %w", err) } - if inspect.HostConfig.NetworkMode == "host" { + if inspect.Container.HostConfig.NetworkMode == "host" { return port, nil } - ports := inspect.NetworkSettings.Ports + ports := inspect.Container.NetworkSettings.Ports for k, p := range ports { - if k.Port() != port.Port() { + if k != port { continue } if port.Proto() != "" && k.Proto() != port.Proto() { @@ -77,8 +79,8 @@ func (c *Container) MappedPort(ctx context.Context, port nat.Port) (nat.Port, er if len(p) == 0 { continue } - return nat.NewPort(k.Proto(), p[0].HostPort) + return network.ParsePort(p[0].HostPort + "/" + string(k.Proto())) } - return "", errdefs.ErrNotFound.WithMessage(fmt.Sprintf("port %q not found", port)) + return network.Port{}, errdefs.ErrNotFound.WithMessage(fmt.Sprintf("port %q not found", port)) } diff --git a/container/ports_benchmarks_test.go b/container/ports_benchmarks_test.go index a1dcab2c..b6907b39 100644 --- a/container/ports_benchmarks_test.go +++ b/container/ports_benchmarks_test.go @@ -4,6 +4,7 @@ import ( "context" "testing" + "github.com/moby/moby/api/types/network" "github.com/stretchr/testify/require" "github.com/docker/go-sdk/container" @@ -17,11 +18,13 @@ func BenchmarkPortEndpoint(b *testing.B) { require.NoError(b, err) require.NotNil(b, ctr) + port80 := network.MustParsePort("80/tcp") + b.Run("port-endpoint", func(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - _, err := ctr.PortEndpoint(context.Background(), "80/tcp", "tcp") + _, err := ctr.PortEndpoint(context.Background(), port80, "tcp") require.NoError(b, err) } }) @@ -30,7 +33,7 @@ func BenchmarkPortEndpoint(b *testing.B) { b.ReportAllocs() b.ResetTimer() for i := 0; i < b.N; i++ { - _, err := ctr.MappedPort(context.Background(), "80/tcp") + _, err := ctr.MappedPort(context.Background(), port80) require.NoError(b, err) } }) diff --git a/container/udp_port_binding_test.go b/container/udp_port_binding_test.go index 5f8344f8..128e5eba 100644 --- a/container/udp_port_binding_test.go +++ b/container/udp_port_binding_test.go @@ -3,9 +3,12 @@ package container import ( "context" "net" + "net/netip" + "strconv" "testing" "time" + "github.com/moby/moby/api/types/network" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -36,26 +39,22 @@ func TestUDPPortBinding(t *testing.T) { Cleanup(t, c) // Test MappedPort function - this was the bug - udpPort, err := nat.NewPort("udp", "8080") - require.NoError(t, err) + udpPort, ok := network.PortFrom(8080, "udp") + require.True(t, ok) mappedPort, err := c.MappedPort(ctx, udpPort) require.NoError(t, err) // Before fix: mappedPort.Port() would return "0" // After fix: mappedPort.Port() returns actual port like "55051" - assert.NotEqual(t, "0", mappedPort.Port(), "UDP port should not return '0'") - assert.Equal(t, "udp", mappedPort.Proto(), "Protocol should be UDP") - - portNum := mappedPort.Int() - assert.Positive(t, portNum, "Port number should be greater than 0") - assert.LessOrEqual(t, portNum, 65535, "Port number should be valid UDP port range") + require.NotEqual(t, 0, mappedPort.Num(), "UDP port should not return '0'") + require.Equal(t, network.UDP, mappedPort.Proto(), "Protocol should be UDP") // Verify the port is actually accessible (basic connectivity test) hostIP, err := c.Host(ctx) require.NoError(t, err) - address := net.JoinHostPort(hostIP, mappedPort.Port()) + address := net.JoinHostPort(hostIP, strconv.Itoa(int(mappedPort.Num()))) conn, err := net.DialTimeout("udp", address, 2*time.Second) require.NoError(t, err, "Should be able to connect to UDP port") conn.Close() @@ -70,17 +69,14 @@ func TestUDPPortBinding(t *testing.T) { require.NoError(t, err) Cleanup(t, c) - tcpPort, err := nat.NewPort("tcp", "80") - require.NoError(t, err) + tcpPort, ok := network.PortFrom(80, "tcp") + require.True(t, ok) mappedPort, err := c.MappedPort(ctx, tcpPort) require.NoError(t, err) - assert.NotEqual(t, "0", mappedPort.Port(), "TCP port should not return '0'") - assert.Equal(t, "tcp", mappedPort.Proto(), "Protocol should be TCP") - - portNum := mappedPort.Int() - assert.Positive(t, portNum, "Port number should be greater than 0") + assert.NotEqual(t, 0, mappedPort.Num(), "TCP port should not return '0'") + assert.Equal(t, network.TCP, mappedPort.Proto(), "Protocol should be TCP") }) } @@ -90,18 +86,19 @@ func TestPortBindingInternalLogic(t *testing.T) { t.Run("mergePortBindings fixes empty HostPort", func(t *testing.T) { // Test the core fix: empty HostPort should become "0" // This simulates what nat.ParsePortSpecs returns for "8080/udp" - exposedPortMap := nat.PortMap{ - "8080/udp": []nat.PortBinding{{HostIP: "", HostPort: ""}}, // Empty HostPort (the bug) + exposedPortMap := network.PortMap{ + network.MustParsePort("8080/udp"): []network.PortBinding{{}}, // Empty HostPort (the bug) } - configPortMap := nat.PortMap{} // No existing port bindings + configPortMap := network.PortMap{} // No existing port bindings exposedPorts := []string{"8080/udp"} // Call the function our fix modified result := mergePortBindings(configPortMap, exposedPortMap, exposedPorts) // Verify the fix worked - require.Contains(t, result, nat.Port("8080/udp")) - bindings := result["8080/udp"] + udp80 := network.MustParsePort("8080/udp") + require.Contains(t, result, udp80) + bindings := result[udp80] require.Len(t, bindings, 1) // THE KEY ASSERTION: Empty HostPort should become "0" @@ -112,20 +109,20 @@ func TestPortBindingInternalLogic(t *testing.T) { t.Run("mergePortBindings preserves existing HostPort", func(t *testing.T) { // Ensure we don't modify already-set HostPort values - exposedPortMap := nat.PortMap{ - "8080/udp": []nat.PortBinding{{HostIP: "127.0.0.1", HostPort: "9090"}}, + exposedPortMap := network.PortMap{ + network.MustParsePort("8080/udp"): []network.PortBinding{{HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "9090"}}, } - configPortMap := nat.PortMap{} + configPortMap := network.PortMap{} exposedPorts := []string{"8080/udp"} result := mergePortBindings(configPortMap, exposedPortMap, exposedPorts) - bindings := result["8080/udp"] + bindings := result[network.MustParsePort("8080/udp")] require.Len(t, bindings, 1) // Should preserve existing values assert.Equal(t, "9090", bindings[0].HostPort, "Existing HostPort should be preserved") - assert.Equal(t, "127.0.0.1", bindings[0].HostIP, "Existing HostIP should be preserved") + assert.Equal(t, "127.0.0.1", bindings[0].HostIP.String(), "Existing HostIP should be preserved") }) t.Run("nat.ParsePortSpecs behavior documentation", func(t *testing.T) { diff --git a/container/wait/exec_test.go b/container/wait/exec_test.go index e330763e..53ccec4a 100644 --- a/container/wait/exec_test.go +++ b/container/wait/exec_test.go @@ -9,10 +9,11 @@ import ( "testing" "time" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" "github.com/docker/go-sdk/container/exec" "github.com/docker/go-sdk/container/wait" ) @@ -29,11 +30,11 @@ func (st mockExecTarget) Host(_ context.Context) (string, error) { return "", errors.New("not implemented") } -func (st mockExecTarget) Inspect(_ context.Context) (*container.InspectResponse, error) { - return nil, errors.New("not implemented") +func (st mockExecTarget) Inspect(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{}, errors.New("not implemented") } -func (st mockExecTarget) MappedPort(_ context.Context, n nat.Port) (nat.Port, error) { +func (st mockExecTarget) MappedPort(_ context.Context, n network.Port) (network.Port, error) { return n, errors.New("not implemented") } diff --git a/container/wait/exit_test.go b/container/wait/exit_test.go index 4f4f2efa..ad311e2e 100644 --- a/container/wait/exit_test.go +++ b/container/wait/exit_test.go @@ -8,10 +8,11 @@ import ( "testing" "time" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" "github.com/docker/go-sdk/container/exec" ) @@ -23,11 +24,11 @@ func (st *exitStrategyTarget) Host(_ context.Context) (string, error) { return "", nil } -func (st *exitStrategyTarget) Inspect(_ context.Context) (*container.InspectResponse, error) { - return nil, nil +func (st *exitStrategyTarget) Inspect(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{}, nil } -func (st *exitStrategyTarget) MappedPort(_ context.Context, n nat.Port) (nat.Port, error) { +func (st *exitStrategyTarget) MappedPort(_ context.Context, n network.Port) (network.Port, error) { return n, nil } diff --git a/container/wait/file_test.go b/container/wait/file_test.go index fe73f5fe..e73a9866 100644 --- a/container/wait/file_test.go +++ b/container/wait/file_test.go @@ -10,10 +10,10 @@ import ( "time" "github.com/containerd/errdefs" + "github.com/moby/moby/api/types/container" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/container" "github.com/docker/go-sdk/container/wait" ) diff --git a/container/wait/health.go b/container/wait/health.go index 482f52c2..029e133f 100644 --- a/container/wait/health.go +++ b/container/wait/health.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/docker/docker/api/types" + "github.com/moby/moby/api/types/container" ) // Implement interface @@ -87,7 +87,7 @@ func (ws *HealthStrategy) WaitUntilReady(ctx context.Context, target StrategyTar if err := checkState(state); err != nil { return err } - if state.Health == nil || state.Health.Status != types.Healthy { + if state.Health == nil || state.Health.Status != container.Healthy { time.Sleep(ws.PollInterval) continue } diff --git a/container/wait/health_test.go b/container/wait/health_test.go index 557fac8e..f73bb76a 100644 --- a/container/wait/health_test.go +++ b/container/wait/health_test.go @@ -9,11 +9,11 @@ import ( "testing" "time" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" "github.com/docker/go-sdk/container/exec" ) @@ -26,11 +26,11 @@ func (st *healthStrategyTarget) Host(_ context.Context) (string, error) { return "", nil } -func (st *healthStrategyTarget) Inspect(_ context.Context) (*container.InspectResponse, error) { - return nil, nil +func (st *healthStrategyTarget) Inspect(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{}, nil } -func (st *healthStrategyTarget) MappedPort(_ context.Context, n nat.Port) (nat.Port, error) { +func (st *healthStrategyTarget) MappedPort(_ context.Context, n network.Port) (network.Port, error) { return n, nil } @@ -72,7 +72,7 @@ func TestWaitForHealthTimesOutForUnhealthy(t *testing.T) { target := &healthStrategyTarget{ state: &container.State{ Running: true, - Health: &container.Health{Status: types.Unhealthy}, + Health: &container.Health{Status: container.Unhealthy}, }, } wg := NewHealthStrategy().WithTimeout(100 * time.Millisecond) @@ -87,7 +87,7 @@ func TestWaitForHealthSucceeds(t *testing.T) { target := &healthStrategyTarget{ state: &container.State{ Running: true, - Health: &container.Health{Status: types.Healthy}, + Health: &container.Health{Status: container.Healthy}, }, } wg := NewHealthStrategy().WithTimeout(100 * time.Millisecond) @@ -113,7 +113,7 @@ func TestWaitForHealthWithNil(t *testing.T) { // wait a bit to simulate startup time and give check time to at least // try a few times with a nil Health time.Sleep(200 * time.Millisecond) - target.setState(&container.Health{Status: types.Healthy}) + target.setState(&container.Health{Status: container.Healthy}) }(target) err := wg.WaitUntilReady(context.Background(), target) diff --git a/container/wait/host_port.go b/container/wait/host_port.go index b2a061c1..6ffcdd09 100644 --- a/container/wait/host_port.go +++ b/container/wait/host_port.go @@ -9,7 +9,7 @@ import ( "strconv" "time" - "github.com/docker/go-connections/nat" + "github.com/moby/moby/api/types/network" ) const ( @@ -31,7 +31,7 @@ var ( type HostPortStrategy struct { // Port is a string containing port number and protocol in the format "80/tcp" // which - Port nat.Port + Port network.Port // all WaitStrategies should have a startupTimeout to avoid waiting infinitely timeout *time.Duration PollInterval time.Duration @@ -49,7 +49,7 @@ type HostPortStrategy struct { // NewHostPortStrategy constructs a default host port strategy that waits for the given // port to be exposed. The default startup timeout is 60 seconds. -func NewHostPortStrategy(port nat.Port) *HostPortStrategy { +func NewHostPortStrategy(port network.Port) *HostPortStrategy { return &HostPortStrategy{ Port: port, PollInterval: defaultPollInterval(), @@ -63,19 +63,19 @@ func NewHostPortStrategy(port nat.Port) *HostPortStrategy { // ForListeningPort returns a host port strategy that waits for the given port // to be exposed and bound internally the container. // Alias for `NewHostPortStrategy(port)`. -func ForListeningPort(port nat.Port) *HostPortStrategy { +func ForListeningPort(port network.Port) *HostPortStrategy { return NewHostPortStrategy(port) } // ForExposedPort returns a host port strategy that waits for the first port // to be exposed and bound internally the container. func ForExposedPort() *HostPortStrategy { - return NewHostPortStrategy("") + return NewHostPortStrategy(network.Port{}) } // ForMappedPort returns a host port strategy that waits for the given port // to be mapped without accessing the port itself. -func ForMappedPort(port nat.Port) *HostPortStrategy { +func ForMappedPort(port network.Port) *HostPortStrategy { return NewHostPortStrategy(port).SkipInternalCheck().SkipExternalCheck() } @@ -116,7 +116,7 @@ func (hp *HostPortStrategy) Timeout() *time.Duration { // String returns a human-readable description of the wait strategy. func (hp *HostPortStrategy) String() string { port := "first exposed port" - if hp.Port != "" { + if hp.Port.IsValid() { port = fmt.Sprintf("port %s", hp.Port) } @@ -138,15 +138,15 @@ func (hp *HostPortStrategy) String() string { // detectInternalPort returns the lowest internal port that is currently bound. // If no internal port is found, it returns the zero nat.Port value which // can be checked against an empty string. -func (hp *HostPortStrategy) detectInternalPort(ctx context.Context, target StrategyTarget) (nat.Port, error) { - var internalPort nat.Port +func (hp *HostPortStrategy) detectInternalPort(ctx context.Context, target StrategyTarget) (network.Port, error) { + var internalPort network.Port inspect, err := target.Inspect(ctx) if err != nil { return internalPort, fmt.Errorf("inspect: %w", err) } - for port := range inspect.NetworkSettings.Ports { - if internalPort == "" || port.Int() < internalPort.Int() { + for port := range inspect.Container.NetworkSettings.Ports { + if internalPort.IsZero() || port.Num() < internalPort.Num() { internalPort = port } } @@ -168,7 +168,7 @@ func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyT internalPort := hp.Port i := 0 - if internalPort == "" { + if internalPort.IsZero() { var err error // Port is not specified, so we need to detect it. internalPort, err = hp.detectInternalPort(ctx, target) @@ -176,7 +176,7 @@ func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyT return fmt.Errorf("detect internal port: %w", err) } - for internalPort == "" { + for internalPort.IsZero() { select { case <-ctx.Done(): return fmt.Errorf("detect internal port: retries: %d, last err: %w, ctx err: %w", i, err, ctx.Err()) @@ -196,7 +196,7 @@ func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyT port, err := target.MappedPort(ctx, internalPort) i = 0 - for port == "" { + for port.IsZero() { i++ select { @@ -244,10 +244,10 @@ func (hp *HostPortStrategy) WaitUntilReady(ctx context.Context, target StrategyT return nil } -func externalCheck(ctx context.Context, ipAddress string, port nat.Port, target StrategyTarget, waitInterval time.Duration) error { +func externalCheck(ctx context.Context, ipAddress string, port network.Port, target StrategyTarget, waitInterval time.Duration) error { proto := port.Proto() - portNumber := port.Int() - portString := strconv.Itoa(portNumber) + portNumber := port.Num() + portString := strconv.Itoa(int(portNumber)) dialer := net.Dialer{} address := net.JoinHostPort(ipAddress, portString) @@ -255,7 +255,7 @@ func externalCheck(ctx context.Context, ipAddress string, port nat.Port, target if err := checkTarget(ctx, target); err != nil { return fmt.Errorf("check target: retries: %d address: %s: %w", i, address, err) } - conn, err := dialer.DialContext(ctx, proto, address) + conn, err := dialer.DialContext(ctx, string(proto), address) if err != nil { var v *net.OpError if errors.As(err, &v) { @@ -275,8 +275,8 @@ func externalCheck(ctx context.Context, ipAddress string, port nat.Port, target } } -func internalCheck(ctx context.Context, internalPort nat.Port, target StrategyTarget) error { - command := buildInternalCheckCommand(internalPort.Int()) +func internalCheck(ctx context.Context, internalPort network.Port, target StrategyTarget) error { + command := buildInternalCheckCommand(internalPort.Num()) for { if ctx.Err() != nil { return ctx.Err() @@ -303,7 +303,7 @@ func internalCheck(ctx context.Context, internalPort nat.Port, target StrategyTa } } -func buildInternalCheckCommand(internalPort int) string { +func buildInternalCheckCommand(internalPort uint16) string { command := `( cat /proc/net/tcp* | awk '{print $2}' | grep -i :%04x || nc -vz -w 1 localhost %d || diff --git a/container/wait/host_port_test.go b/container/wait/host_port_test.go index 34395a91..0bc0fc3e 100644 --- a/container/wait/host_port_test.go +++ b/container/wait/host_port_test.go @@ -6,14 +6,15 @@ import ( "io" "log/slog" "net" - "strconv" + "net/netip" "testing" "time" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" "github.com/docker/go-sdk/container/exec" ) @@ -23,18 +24,18 @@ func TestWaitForListeningPortSucceeds(t *testing.T) { defer listener.Close() rawPort := listener.Addr().(*net.TCPAddr).Port - port, err := nat.NewPort("tcp", strconv.Itoa(rawPort)) - require.NoError(t, err) + port, ok := network.PortFrom(uint16(rawPort), "tcp") + require.True(t, ok) var mappedPortCount, execCount int target := &MockStrategyTarget{ HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", ErrPortNotFound + return network.Port{}, ErrPortNotFound } return port, nil }, @@ -53,7 +54,7 @@ func TestWaitForListeningPortSucceeds(t *testing.T) { LoggerImpl: slog.Default, } - wg := ForListeningPort("80"). + wg := ForListeningPort(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) @@ -62,24 +63,21 @@ func TestWaitForListeningPortSucceeds(t *testing.T) { } func TestWaitForListeningPortInternallySucceeds(t *testing.T) { - localPort, err := nat.NewPort("tcp", "80") - require.NoError(t, err) - - mappedPort, err := nat.NewPort("tcp", "8080") - require.NoError(t, err) + localPort := network.MustParsePort("80/tcp") + mappedPort := network.MustParsePort("8080/tcp") var mappedPortCount, execCount int target := &MockStrategyTarget{ HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, p nat.Port) (nat.Port, error) { - if p.Int() != localPort.Int() { - return "", ErrPortNotFound + MappedPortImpl: func(_ context.Context, p network.Port) (network.Port, error) { + if p.Num() != localPort.Num() { + return network.Port{}, ErrPortNotFound } defer func() { mappedPortCount++ }() if mappedPortCount <= 2 { - return "", ErrPortNotFound + return network.Port{}, ErrPortNotFound } return mappedPort, nil }, @@ -103,29 +101,26 @@ func TestWaitForListeningPortInternallySucceeds(t *testing.T) { WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) - err = wg.WaitUntilReady(context.Background(), target) + err := wg.WaitUntilReady(context.Background(), target) require.NoError(t, err) } func TestWaitForMappedPortSucceeds(t *testing.T) { - localPort, err := nat.NewPort("tcp", "80") - require.NoError(t, err) - - mappedPort, err := nat.NewPort("tcp", "8080") - require.NoError(t, err) + localPort := network.MustParsePort("80/tcp") + mappedPort := network.MustParsePort("8080/tcp") var mappedPortCount int target := &MockStrategyTarget{ HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, p nat.Port) (nat.Port, error) { - if p.Int() != localPort.Int() { - return "", ErrPortNotFound + MappedPortImpl: func(_ context.Context, p network.Port) (network.Port, error) { + if p.Num() != localPort.Num() { + return network.Port{}, ErrPortNotFound } defer func() { mappedPortCount++ }() if mappedPortCount <= 2 { - return "", ErrPortNotFound + return network.Port{}, ErrPortNotFound } return mappedPort, nil }, @@ -141,7 +136,7 @@ func TestWaitForMappedPortSucceeds(t *testing.T) { WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) - err = wg.WaitUntilReady(context.Background(), target) + err := wg.WaitUntilReady(context.Background(), target) require.NoError(t, err) } @@ -151,35 +146,35 @@ func TestWaitForExposedPortSkipChecksSucceeds(t *testing.T) { defer listener.Close() rawPort := listener.Addr().(*net.TCPAddr).Port - port, err := nat.NewPort("tcp", strconv.Itoa(rawPort)) - require.NoError(t, err) + port, ok := network.PortFrom(uint16(rawPort), "tcp") + require.True(t, ok) var inspectCount, mappedPortCount, execCount int target := &MockStrategyTarget{ HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { defer func() { inspectCount++ }() if inspectCount == 0 { // Simulate a container that hasn't bound any ports yet. - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{}, + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{}, }, }, }, nil } - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80": []nat.PortBinding{ + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{ + network.MustParsePort("80"): []network.PortBinding{ { - HostIP: "0.0.0.0", - HostPort: port.Port(), + HostIP: netip.IPv4Unspecified(), + HostPort: port.String(), }, }, }, @@ -187,10 +182,10 @@ func TestWaitForExposedPortSkipChecksSucceeds(t *testing.T) { }, }, nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", ErrPortNotFound + return network.Port{}, ErrPortNotFound } return port, nil }, @@ -223,12 +218,12 @@ func TestHostPortStrategyFailsWhileGettingPortDueToOOMKilledContainer(t *testing HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", ErrPortNotFound + return network.Port{}, ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -237,7 +232,7 @@ func TestHostPortStrategyFailsWhileGettingPortDueToOOMKilledContainer(t *testing }, } - wg := NewHostPortStrategy("80"). + wg := NewHostPortStrategy(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) @@ -253,12 +248,12 @@ func TestHostPortStrategyFailsWhileGettingPortDueToExitedContainer(t *testing.T) HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", ErrPortNotFound + return network.Port{}, ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -268,7 +263,7 @@ func TestHostPortStrategyFailsWhileGettingPortDueToExitedContainer(t *testing.T) }, } - wg := NewHostPortStrategy("80"). + wg := NewHostPortStrategy(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) @@ -284,12 +279,12 @@ func TestHostPortStrategyFailsWhileGettingPortDueToUnexpectedContainerStatus(t * HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", ErrPortNotFound + return network.Port{}, ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -298,7 +293,7 @@ func TestHostPortStrategyFailsWhileGettingPortDueToUnexpectedContainerStatus(t * }, } - wg := NewHostPortStrategy("80"). + wg := NewHostPortStrategy(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) @@ -313,8 +308,8 @@ func TestHostPortStrategyFailsWhileExternalCheckingDueToOOMKilledContainer(t *te HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { - return "49152", nil + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -323,7 +318,7 @@ func TestHostPortStrategyFailsWhileExternalCheckingDueToOOMKilledContainer(t *te }, } - wg := NewHostPortStrategy("80"). + wg := NewHostPortStrategy(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) @@ -338,8 +333,8 @@ func TestHostPortStrategyFailsWhileExternalCheckingDueToExitedContainer(t *testi HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { - return "49152", nil + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -349,7 +344,7 @@ func TestHostPortStrategyFailsWhileExternalCheckingDueToExitedContainer(t *testi }, } - wg := NewHostPortStrategy("80"). + wg := NewHostPortStrategy(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) @@ -364,8 +359,8 @@ func TestHostPortStrategyFailsWhileExternalCheckingDueToUnexpectedContainerStatu HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { - return "49152", nil + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -374,7 +369,7 @@ func TestHostPortStrategyFailsWhileExternalCheckingDueToUnexpectedContainerStatu }, } - wg := NewHostPortStrategy("80"). + wg := NewHostPortStrategy(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) @@ -390,15 +385,15 @@ func TestHostPortStrategyFailsWhileInternalCheckingDueToOOMKilledContainer(t *te defer listener.Close() rawPort := listener.Addr().(*net.TCPAddr).Port - port, err := nat.NewPort("tcp", strconv.Itoa(rawPort)) - require.NoError(t, err) + port, ok := network.PortFrom(uint16(rawPort), "tcp") + require.True(t, ok) var stateCount int target := &MockStrategyTarget{ HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { return port, nil }, StateImpl: func(_ context.Context) (*container.State, error) { @@ -414,7 +409,7 @@ func TestHostPortStrategyFailsWhileInternalCheckingDueToOOMKilledContainer(t *te }, } - wg := NewHostPortStrategy("80"). + wg := NewHostPortStrategy(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) @@ -430,15 +425,15 @@ func TestHostPortStrategyFailsWhileInternalCheckingDueToExitedContainer(t *testi defer listener.Close() rawPort := listener.Addr().(*net.TCPAddr).Port - port, err := nat.NewPort("tcp", strconv.Itoa(rawPort)) - require.NoError(t, err) + port, ok := network.PortFrom(uint16(rawPort), "tcp") + require.True(t, ok) var stateCount int target := &MockStrategyTarget{ HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { return port, nil }, StateImpl: func(_ context.Context) (*container.State, error) { @@ -455,7 +450,7 @@ func TestHostPortStrategyFailsWhileInternalCheckingDueToExitedContainer(t *testi }, } - wg := NewHostPortStrategy("80"). + wg := NewHostPortStrategy(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) @@ -471,15 +466,15 @@ func TestHostPortStrategyFailsWhileInternalCheckingDueToUnexpectedContainerStatu defer listener.Close() rawPort := listener.Addr().(*net.TCPAddr).Port - port, err := nat.NewPort("tcp", strconv.Itoa(rawPort)) - require.NoError(t, err) + port, ok := network.PortFrom(uint16(rawPort), "tcp") + require.True(t, ok) var stateCount int target := &MockStrategyTarget{ HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { return port, nil }, StateImpl: func(_ context.Context) (*container.State, error) { @@ -495,7 +490,7 @@ func TestHostPortStrategyFailsWhileInternalCheckingDueToUnexpectedContainerStatu }, } - wg := NewHostPortStrategy("80"). + wg := NewHostPortStrategy(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) @@ -511,8 +506,8 @@ func TestHostPortStrategySucceedsGivenShellIsNotInstalled(t *testing.T) { defer listener.Close() rawPort := listener.Addr().(*net.TCPAddr).Port - port, err := nat.NewPort("tcp", strconv.Itoa(rawPort)) - require.NoError(t, err) + port, ok := network.PortFrom(uint16(rawPort), "tcp") + require.True(t, ok) buf := &bytes.Buffer{} logger := slog.New(slog.NewTextHandler(buf, nil)) @@ -521,15 +516,15 @@ func TestHostPortStrategySucceedsGivenShellIsNotInstalled(t *testing.T) { HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80": []nat.PortBinding{ + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{ + network.MustParsePort("80"): []network.PortBinding{ { - HostIP: "0.0.0.0", - HostPort: port.Port(), + HostIP: netip.IPv4Unspecified(), + HostPort: port.String(), }, }, }, @@ -537,7 +532,7 @@ func TestHostPortStrategySucceedsGivenShellIsNotInstalled(t *testing.T) { }, }, nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { return port, nil }, StateImpl: func(_ context.Context) (*container.State, error) { @@ -554,7 +549,7 @@ func TestHostPortStrategySucceedsGivenShellIsNotInstalled(t *testing.T) { }, } - wg := NewHostPortStrategy("80"). + wg := NewHostPortStrategy(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) @@ -570,8 +565,8 @@ func TestHostPortStrategySucceedsGivenShellIsNotFound(t *testing.T) { defer listener.Close() rawPort := listener.Addr().(*net.TCPAddr).Port - port, err := nat.NewPort("tcp", strconv.Itoa(rawPort)) - require.NoError(t, err) + port, ok := network.PortFrom(uint16(rawPort), "tcp") + require.True(t, ok) bufLogger := &bytes.Buffer{} logger := slog.New(slog.NewTextHandler(bufLogger, nil)) @@ -580,15 +575,15 @@ func TestHostPortStrategySucceedsGivenShellIsNotFound(t *testing.T) { HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{ - "80": []nat.PortBinding{ + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{ + network.MustParsePort("80"): []network.PortBinding{ { - HostIP: "0.0.0.0", - HostPort: port.Port(), + HostIP: netip.IPv4Unspecified(), + HostPort: port.String(), }, }, }, @@ -596,7 +591,7 @@ func TestHostPortStrategySucceedsGivenShellIsNotFound(t *testing.T) { }, }, nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { return port, nil }, StateImpl: func(_ context.Context) (*container.State, error) { @@ -613,7 +608,7 @@ func TestHostPortStrategySucceedsGivenShellIsNotFound(t *testing.T) { }, } - wg := NewHostPortStrategy("80"). + wg := NewHostPortStrategy(network.MustParsePort("80")). WithTimeout(5 * time.Second). WithPollInterval(100 * time.Millisecond) diff --git a/container/wait/http.go b/container/wait/http.go index 83e74f52..773d3ca4 100644 --- a/container/wait/http.go +++ b/container/wait/http.go @@ -14,7 +14,7 @@ import ( "strings" "time" - "github.com/docker/go-connections/nat" + "github.com/moby/moby/api/types/network" ) // Implement interface @@ -28,7 +28,7 @@ type HTTPStrategy struct { timeout *time.Duration // additional properties - Port nat.Port + Port network.Port Path string StatusCodeMatcher func(status int) bool ResponseMatcher func(body io.Reader) bool @@ -44,10 +44,10 @@ type HTTPStrategy struct { ForceIPv4LocalHost bool } -// NewHTTPStrategy constructs a HTTP strategy waiting on port 80 and status code 200 +// NewHTTPStrategy constructs an HTTP strategy waiting on port 80 and status code 200 func NewHTTPStrategy(path string) *HTTPStrategy { return &HTTPStrategy{ - Port: "", + Port: network.Port{}, Path: path, StatusCodeMatcher: defaultStatusCodeMatcher, ResponseMatcher: func(_ io.Reader) bool { return true }, @@ -78,7 +78,7 @@ func (ws *HTTPStrategy) WithTimeout(timeout time.Duration) *HTTPStrategy { // WithPort set the port to wait for. // Default is the lowest numbered port. -func (ws *HTTPStrategy) WithPort(port nat.Port) *HTTPStrategy { +func (ws *HTTPStrategy) WithPort(port network.Port) *HTTPStrategy { ws.Port = port return ws } @@ -171,8 +171,8 @@ func (ws *HTTPStrategy) String() string { } port := "default" - if ws.Port != "" { - port = ws.Port.Port() + if ws.Port.IsValid() { + port = ws.Port.String() } return fmt.Sprintf("%s %s request on port %s path %q", proto, ws.Method, port, ws.Path) @@ -197,8 +197,8 @@ func (ws *HTTPStrategy) WaitUntilReady(ctx context.Context, target StrategyTarge ipAddress = strings.Replace(ipAddress, "localhost", "127.0.0.1", 1) } - var mappedPort nat.Port - if ws.Port == "" { + var mappedPort network.Port + if ws.Port.IsZero() { // We wait one polling interval before we grab the ports // otherwise they might not be bound yet on startup. select { @@ -218,28 +218,31 @@ func (ws *HTTPStrategy) WaitUntilReady(ctx context.Context, target StrategyTarge } // Find the lowest numbered exposed tcp port. - var lowestPort nat.Port + var lowestPort network.Port var hostPort string - for port, bindings := range inspect.NetworkSettings.Ports { + for port, bindings := range inspect.Container.NetworkSettings.Ports { if len(bindings) == 0 || port.Proto() != "tcp" { continue } - if lowestPort == "" || port.Int() < lowestPort.Int() { + if lowestPort.IsZero() || port.Num() < lowestPort.Num() { lowestPort = port hostPort = bindings[0].HostPort } } - if lowestPort == "" { + if lowestPort.IsZero() { return errors.New("no exposed tcp ports or mapped ports - cannot wait for status") } - mappedPort, _ = nat.NewPort(lowestPort.Proto(), hostPort) + mappedPort, err = network.ParsePort(hostPort + "/" + string(lowestPort.Proto())) + if err != nil { + return err + } } else { mappedPort, err = target.MappedPort(ctx, ws.Port) - for mappedPort == "" { + for mappedPort.IsZero() { select { case <-ctx.Done(): return fmt.Errorf("%w: %w", ctx.Err(), err) @@ -298,7 +301,7 @@ func (ws *HTTPStrategy) WaitUntilReady(ctx context.Context, target StrategyTarge } client := http.Client{Transport: tripper, Timeout: time.Second} - address := net.JoinHostPort(ipAddress, strconv.Itoa(mappedPort.Int())) + address := net.JoinHostPort(ipAddress, strconv.Itoa(int(mappedPort.Num()))) endpoint, err := url.Parse(ws.Path) if err != nil { diff --git a/container/wait/http_test.go b/container/wait/http_test.go index 7c2bb2f8..c6748f76 100644 --- a/container/wait/http_test.go +++ b/container/wait/http_test.go @@ -3,13 +3,15 @@ package wait_test import ( "context" _ "embed" + "net/netip" "testing" "time" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" "github.com/docker/go-sdk/container/wait" ) @@ -19,26 +21,26 @@ func TestHttpStrategyFailsWhileGettingPortDueToOOMKilledContainer(t *testing.T) HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", wait.ErrPortNotFound + return network.Port{}, wait.ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ OOMKilled: true, }, nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{ - "8080/tcp": []nat.PortBinding{ + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{ + network.MustParsePort("8080/tcp"): []network.PortBinding{ { - HostIP: "127.0.0.1", + HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "49152", }, }, @@ -64,12 +66,12 @@ func TestHttpStrategyFailsWhileGettingPortDueToExitedContainer(t *testing.T) { HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", wait.ErrPortNotFound + return network.Port{}, wait.ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -77,14 +79,14 @@ func TestHttpStrategyFailsWhileGettingPortDueToExitedContainer(t *testing.T) { ExitCode: 1, }, nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{ - "8080/tcp": []nat.PortBinding{ + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{ + network.MustParsePort("8080/tcp"): []network.PortBinding{ { - HostIP: "127.0.0.1", + HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "49152", }, }, @@ -110,26 +112,26 @@ func TestHttpStrategyFailsWhileGettingPortDueToUnexpectedContainerStatus(t *test HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", wait.ErrPortNotFound + return network.Port{}, wait.ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ Status: "dead", }, nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{ - "8080/tcp": []nat.PortBinding{ + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{ + network.MustParsePort("8080/tcp"): []network.PortBinding{ { - HostIP: "127.0.0.1", + HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "49152", }, }, @@ -154,22 +156,22 @@ func TestHTTPStrategyFailsWhileRequestSendingDueToOOMKilledContainer(t *testing. HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { - return "49152", nil + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ OOMKilled: true, }, nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{ - "8080/tcp": []nat.PortBinding{ + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{ + network.MustParsePort("8080/tcp"): []network.PortBinding{ { - HostIP: "127.0.0.1", + HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "49152", }, }, @@ -194,8 +196,8 @@ func TestHttpStrategyFailsWhileRequestSendingDueToExitedContainer(t *testing.T) HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { - return "49152", nil + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -203,14 +205,14 @@ func TestHttpStrategyFailsWhileRequestSendingDueToExitedContainer(t *testing.T) ExitCode: 1, }, nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{ - "8080/tcp": []nat.PortBinding{ + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{ + network.MustParsePort("8080/tcp"): []network.PortBinding{ { - HostIP: "127.0.0.1", + HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "49152", }, }, @@ -235,22 +237,22 @@ func TestHttpStrategyFailsWhileRequestSendingDueToUnexpectedContainerStatus(t *t HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { - return "49152", nil + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ Status: "dead", }, nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{ - "8080/tcp": []nat.PortBinding{ + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{ + network.MustParsePort("8080/tcp"): []network.PortBinding{ { - HostIP: "127.0.0.1", + HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "49152", }, }, @@ -276,12 +278,12 @@ func TestHttpStrategyFailsWhileGettingPortDueToNoExposedPorts(t *testing.T) { HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", wait.ErrPortNotFound + return network.Port{}, wait.ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -289,11 +291,11 @@ func TestHttpStrategyFailsWhileGettingPortDueToNoExposedPorts(t *testing.T) { Running: true, }, nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{}, + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{}, }, }, }, nil @@ -315,12 +317,12 @@ func TestHttpStrategyFailsWhileGettingPortDueToOnlyUDPPorts(t *testing.T) { HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", wait.ErrPortNotFound + return network.Port{}, wait.ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -328,14 +330,14 @@ func TestHttpStrategyFailsWhileGettingPortDueToOnlyUDPPorts(t *testing.T) { Status: "running", }, nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{ - "8080/udp": []nat.PortBinding{ + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{ + network.MustParsePort("8080/udp"): []network.PortBinding{ { - HostIP: "127.0.0.1", + HostIP: netip.MustParseAddr("127.0.0.1"), HostPort: "49152", }, }, @@ -361,12 +363,12 @@ func TestHttpStrategyFailsWhileGettingPortDueToExposedPortNoBindings(t *testing. HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", wait.ErrPortNotFound + return network.Port{}, wait.ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -374,12 +376,12 @@ func TestHttpStrategyFailsWhileGettingPortDueToExposedPortNoBindings(t *testing. Status: "running", }, nil }, - InspectImpl: func(_ context.Context) (*container.InspectResponse, error) { - return &container.InspectResponse{ - NetworkSettings: &container.NetworkSettings{ - NetworkSettingsBase: container.NetworkSettingsBase{ - Ports: nat.PortMap{ - "8080/tcp": []nat.PortBinding{}, + InspectImpl: func(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{ + Container: container.InspectResponse{ + NetworkSettings: &container.NetworkSettings{ + Ports: network.PortMap{ + network.MustParsePort("8080/tcp"): []network.PortBinding{}, }, }, }, diff --git a/container/wait/log_test.go b/container/wait/log_test.go index 8f20f01e..01e276df 100644 --- a/container/wait/log_test.go +++ b/container/wait/log_test.go @@ -8,9 +8,9 @@ import ( "testing" "time" + "github.com/moby/moby/api/types/container" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/container" "github.com/docker/go-sdk/container/wait" ) diff --git a/container/wait/nop.go b/container/wait/nop.go index 2cce3cd7..06e81f67 100644 --- a/container/wait/nop.go +++ b/container/wait/nop.go @@ -6,8 +6,10 @@ import ( "log/slog" "time" - "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/client" + "github.com/docker/go-sdk/container/exec" ) @@ -57,11 +59,11 @@ func (st *NopStrategyTarget) Host(_ context.Context) (string, error) { return "", nil } -func (st *NopStrategyTarget) Inspect(_ context.Context) (*container.InspectResponse, error) { - return nil, nil +func (st *NopStrategyTarget) Inspect(_ context.Context) (client.ContainerInspectResult, error) { + return client.ContainerInspectResult{}, nil } -func (st *NopStrategyTarget) MappedPort(_ context.Context, n nat.Port) (nat.Port, error) { +func (st *NopStrategyTarget) MappedPort(_ context.Context, n network.Port) (network.Port, error) { return n, nil } diff --git a/container/wait/sql.go b/container/wait/sql.go index 696cc00b..aaf98489 100644 --- a/container/wait/sql.go +++ b/container/wait/sql.go @@ -6,7 +6,7 @@ import ( "fmt" "time" - "github.com/docker/go-connections/nat" + "github.com/moby/moby/api/types/network" ) var ( @@ -17,7 +17,7 @@ var ( const defaultForSQLQuery = "SELECT 1" // ForSQL constructs a new waitForSql strategy for the given driver -func ForSQL(port nat.Port, driver string, url func(host string, port nat.Port) string) *waitForSQL { +func ForSQL(port network.Port, driver string, url func(host string, port network.Port) string) *waitForSQL { return &waitForSQL{ Port: port, URL: url, @@ -31,9 +31,9 @@ func ForSQL(port nat.Port, driver string, url func(host string, port nat.Port) s type waitForSQL struct { timeout *time.Duration - URL func(host string, port nat.Port) string + URL func(host string, port network.Port) string Driver string - Port nat.Port + Port network.Port startupTimeout time.Duration PollInterval time.Duration query string @@ -64,8 +64,8 @@ func (w *waitForSQL) Timeout() *time.Duration { // String returns a human-readable description of the wait strategy. func (w *waitForSQL) String() string { port := "default" - if w.Port != "" { - port = w.Port.Port() + if w.Port.IsValid() { + port = w.Port.String() } query := "" @@ -96,10 +96,10 @@ func (w *waitForSQL) WaitUntilReady(ctx context.Context, target StrategyTarget) ticker := time.NewTicker(w.PollInterval) defer ticker.Stop() - var port nat.Port + var port network.Port port, err = target.MappedPort(ctx, w.Port) - for port == "" { + for port.IsZero() { select { case <-ctx.Done(): return fmt.Errorf("%w: %w", ctx.Err(), err) diff --git a/container/wait/sql_test.go b/container/wait/sql_test.go index 92736270..79f017e9 100644 --- a/container/wait/sql_test.go +++ b/container/wait/sql_test.go @@ -7,15 +7,14 @@ import ( "testing" "time" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" "github.com/stretchr/testify/require" - - "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" ) func Test_waitForSql_WithQuery(t *testing.T) { t.Run("default query", func(t *testing.T) { - w := ForSQL("5432/tcp", "postgres", func(_ string, _ nat.Port) string { + w := ForSQL(network.MustParsePort("5432/tcp"), "postgres", func(_ string, _ network.Port) string { return "fake-url" }) @@ -24,7 +23,7 @@ func Test_waitForSql_WithQuery(t *testing.T) { t.Run("custom query", func(t *testing.T) { const q = "SELECT 100;" - w := ForSQL("5432/tcp", "postgres", func(_ string, _ nat.Port) string { + w := ForSQL(network.MustParsePort("5432/tcp"), "postgres", func(_ string, _ network.Port) string { return "fake-url" }).WithQuery(q) @@ -82,12 +81,12 @@ func TestWaitForSQLSucceeds(t *testing.T) { HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", ErrPortNotFound + return network.Port{}, ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -96,7 +95,7 @@ func TestWaitForSQLSucceeds(t *testing.T) { }, } - wg := ForSQL("3306", "mock", func(_ string, _ nat.Port) string { return "" }). + wg := ForSQL(network.MustParsePort("3306"), "mock", func(_ string, _ network.Port) string { return "" }). WithTimeout(500 * time.Millisecond). WithPollInterval(100 * time.Millisecond) @@ -110,12 +109,12 @@ func TestWaitForSQLFailsWhileGettingPortDueToOOMKilledContainer(t *testing.T) { HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", ErrPortNotFound + return network.Port{}, ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -124,7 +123,7 @@ func TestWaitForSQLFailsWhileGettingPortDueToOOMKilledContainer(t *testing.T) { }, } - wg := ForSQL("3306", "mock", func(_ string, _ nat.Port) string { return "" }). + wg := ForSQL(network.MustParsePort("3306"), "mock", func(_ string, _ network.Port) string { return "" }). WithTimeout(500 * time.Millisecond). WithPollInterval(100 * time.Millisecond) @@ -140,12 +139,12 @@ func TestWaitForSQLFailsWhileGettingPortDueToExitedContainer(t *testing.T) { HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", ErrPortNotFound + return network.Port{}, ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -155,7 +154,7 @@ func TestWaitForSQLFailsWhileGettingPortDueToExitedContainer(t *testing.T) { }, } - wg := ForSQL("3306", "mock", func(_ string, _ nat.Port) string { return "" }). + wg := ForSQL(network.MustParsePort("3306"), "mock", func(_ string, _ network.Port) string { return "" }). WithTimeout(500 * time.Millisecond). WithPollInterval(100 * time.Millisecond) @@ -171,12 +170,12 @@ func TestWaitForSQLFailsWhileGettingPortDueToUnexpectedContainerStatus(t *testin HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { defer func() { mappedPortCount++ }() if mappedPortCount == 0 { - return "", ErrPortNotFound + return network.Port{}, ErrPortNotFound } - return "49152", nil + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -185,7 +184,7 @@ func TestWaitForSQLFailsWhileGettingPortDueToUnexpectedContainerStatus(t *testin }, } - wg := ForSQL("3306", "mock", func(_ string, _ nat.Port) string { return "" }). + wg := ForSQL(network.MustParsePort("3306"), "mock", func(_ string, _ network.Port) string { return "" }). WithTimeout(500 * time.Millisecond). WithPollInterval(100 * time.Millisecond) @@ -200,8 +199,8 @@ func TestWaitForSQLFailsWhileQueryExecutingDueToOOMKilledContainer(t *testing.T) HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { - return "49152", nil + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -210,7 +209,7 @@ func TestWaitForSQLFailsWhileQueryExecutingDueToOOMKilledContainer(t *testing.T) }, } - wg := ForSQL("3306", "mock", func(_ string, _ nat.Port) string { return "" }). + wg := ForSQL(network.MustParsePort("3306"), "mock", func(_ string, _ network.Port) string { return "" }). WithTimeout(500 * time.Millisecond). WithPollInterval(100 * time.Millisecond) @@ -225,8 +224,8 @@ func TestWaitForSQLFailsWhileQueryExecutingDueToExitedContainer(t *testing.T) { HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { - return "49152", nil + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -236,7 +235,7 @@ func TestWaitForSQLFailsWhileQueryExecutingDueToExitedContainer(t *testing.T) { }, } - wg := ForSQL("3306", "mock", func(_ string, _ nat.Port) string { return "" }). + wg := ForSQL(network.MustParsePort("3306"), "mock", func(_ string, _ network.Port) string { return "" }). WithTimeout(500 * time.Millisecond). WithPollInterval(100 * time.Millisecond) @@ -251,8 +250,8 @@ func TestWaitForSQLFailsWhileQueryExecutingDueToUnexpectedContainerStatus(t *tes HostImpl: func(_ context.Context) (string, error) { return "localhost", nil }, - MappedPortImpl: func(_ context.Context, _ nat.Port) (nat.Port, error) { - return "49152", nil + MappedPortImpl: func(_ context.Context, _ network.Port) (network.Port, error) { + return network.MustParsePort("49152"), nil }, StateImpl: func(_ context.Context) (*container.State, error) { return &container.State{ @@ -261,7 +260,7 @@ func TestWaitForSQLFailsWhileQueryExecutingDueToUnexpectedContainerStatus(t *tes }, } - wg := ForSQL("3306", "mock", func(_ string, _ nat.Port) string { return "" }). + wg := ForSQL(network.MustParsePort("3306"), "mock", func(_ string, _ network.Port) string { return "" }). WithTimeout(500 * time.Millisecond). WithPollInterval(100 * time.Millisecond) diff --git a/container/wait/strategytarget_mock_test.go b/container/wait/strategytarget_mock_test.go index 89c6fe5a..e32a6f93 100644 --- a/container/wait/strategytarget_mock_test.go +++ b/container/wait/strategytarget_mock_test.go @@ -3,9 +3,10 @@ package wait_test import ( - context "context" + container "github.com/moby/moby/api/types/container" + client "github.com/moby/moby/client" - container "github.com/docker/docker/api/types/container" + context "context" exec "github.com/docker/go-sdk/container/exec" @@ -13,7 +14,7 @@ import ( mock "github.com/stretchr/testify/mock" - nat "github.com/docker/go-connections/nat" + network "github.com/moby/moby/api/types/network" slog "log/slog" ) @@ -228,24 +229,22 @@ func (_c *mockStrategyTarget_Host_Call) RunAndReturn(run func(context.Context) ( } // Inspect provides a mock function with given fields: _a0 -func (_m *mockStrategyTarget) Inspect(_a0 context.Context) (*container.InspectResponse, error) { +func (_m *mockStrategyTarget) Inspect(_a0 context.Context) (client.ContainerInspectResult, error) { ret := _m.Called(_a0) if len(ret) == 0 { panic("no return value specified for Inspect") } - var r0 *container.InspectResponse + var r0 client.ContainerInspectResult var r1 error - if rf, ok := ret.Get(0).(func(context.Context) (*container.InspectResponse, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context) (client.ContainerInspectResult, error)); ok { return rf(_a0) } - if rf, ok := ret.Get(0).(func(context.Context) *container.InspectResponse); ok { + if rf, ok := ret.Get(0).(func(context.Context) client.ContainerInspectResult); ok { r0 = rf(_a0) } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).(*container.InspectResponse) - } + r0 = ret.Get(0).(client.ContainerInspectResult) } if rf, ok := ret.Get(1).(func(context.Context) error); ok { @@ -275,12 +274,12 @@ func (_c *mockStrategyTarget_Inspect_Call) Run(run func(_a0 context.Context)) *m return _c } -func (_c *mockStrategyTarget_Inspect_Call) Return(_a0 *container.InspectResponse, _a1 error) *mockStrategyTarget_Inspect_Call { +func (_c *mockStrategyTarget_Inspect_Call) Return(_a0 client.ContainerInspectResult, _a1 error) *mockStrategyTarget_Inspect_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *mockStrategyTarget_Inspect_Call) RunAndReturn(run func(context.Context) (*container.InspectResponse, error)) *mockStrategyTarget_Inspect_Call { +func (_c *mockStrategyTarget_Inspect_Call) RunAndReturn(run func(context.Context) (client.ContainerInspectResult, error)) *mockStrategyTarget_Inspect_Call { _c.Call.Return(run) return _c } @@ -391,25 +390,25 @@ func (_c *mockStrategyTarget_Logs_Call) RunAndReturn(run func(context.Context) ( } // MappedPort provides a mock function with given fields: _a0, _a1 -func (_m *mockStrategyTarget) MappedPort(_a0 context.Context, _a1 nat.Port) (nat.Port, error) { +func (_m *mockStrategyTarget) MappedPort(_a0 context.Context, _a1 network.Port) (network.Port, error) { ret := _m.Called(_a0, _a1) if len(ret) == 0 { panic("no return value specified for MappedPort") } - var r0 nat.Port + var r0 network.Port var r1 error - if rf, ok := ret.Get(0).(func(context.Context, nat.Port) (nat.Port, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, network.Port) (network.Port, error)); ok { return rf(_a0, _a1) } - if rf, ok := ret.Get(0).(func(context.Context, nat.Port) nat.Port); ok { + if rf, ok := ret.Get(0).(func(context.Context, network.Port) network.Port); ok { r0 = rf(_a0, _a1) } else { - r0 = ret.Get(0).(nat.Port) + r0 = ret.Get(0).(network.Port) } - if rf, ok := ret.Get(1).(func(context.Context, nat.Port) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, network.Port) error); ok { r1 = rf(_a0, _a1) } else { r1 = ret.Error(1) @@ -425,24 +424,24 @@ type mockStrategyTarget_MappedPort_Call struct { // MappedPort is a helper method to define mock.On call // - _a0 context.Context -// - _a1 nat.Port +// - _a1 network.Port func (_e *mockStrategyTarget_Expecter) MappedPort(_a0 interface{}, _a1 interface{}) *mockStrategyTarget_MappedPort_Call { return &mockStrategyTarget_MappedPort_Call{Call: _e.mock.On("MappedPort", _a0, _a1)} } -func (_c *mockStrategyTarget_MappedPort_Call) Run(run func(_a0 context.Context, _a1 nat.Port)) *mockStrategyTarget_MappedPort_Call { +func (_c *mockStrategyTarget_MappedPort_Call) Run(run func(_a0 context.Context, _a1 network.Port)) *mockStrategyTarget_MappedPort_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(nat.Port)) + run(args[0].(context.Context), args[1].(network.Port)) }) return _c } -func (_c *mockStrategyTarget_MappedPort_Call) Return(_a0 nat.Port, _a1 error) *mockStrategyTarget_MappedPort_Call { +func (_c *mockStrategyTarget_MappedPort_Call) Return(_a0 network.Port, _a1 error) *mockStrategyTarget_MappedPort_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *mockStrategyTarget_MappedPort_Call) RunAndReturn(run func(context.Context, nat.Port) (nat.Port, error)) *mockStrategyTarget_MappedPort_Call { +func (_c *mockStrategyTarget_MappedPort_Call) RunAndReturn(run func(context.Context, network.Port) (network.Port, error)) *mockStrategyTarget_MappedPort_Call { _c.Call.Return(run) return _c } diff --git a/container/wait/wait.go b/container/wait/wait.go index 8db6d14a..d07c1e74 100644 --- a/container/wait/wait.go +++ b/container/wait/wait.go @@ -8,8 +8,10 @@ import ( "log/slog" "time" - "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/container/exec" ) @@ -25,8 +27,8 @@ type StrategyTimeout interface { type StrategyTarget interface { Host(context.Context) (string, error) - Inspect(context.Context) (*container.InspectResponse, error) - MappedPort(context.Context, nat.Port) (nat.Port, error) + Inspect(context.Context) (dockerclient.ContainerInspectResult, error) + MappedPort(context.Context, network.Port) (network.Port, error) Logs(context.Context) (io.ReadCloser, error) Exec(context.Context, []string, ...exec.ProcessOption) (int, io.Reader, error) State(context.Context) (*container.State, error) diff --git a/container/wait/wait_test.go b/container/wait/wait_test.go index 3d7cd7c3..369a1ddb 100644 --- a/container/wait/wait_test.go +++ b/container/wait/wait_test.go @@ -4,10 +4,12 @@ import ( "context" "errors" "io" - slog "log/slog" + "log/slog" + + "github.com/moby/moby/api/types/container" + "github.com/moby/moby/api/types/network" + "github.com/moby/moby/client" - "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" "github.com/docker/go-sdk/container/exec" ) @@ -15,9 +17,9 @@ var ErrPortNotFound = errors.New("port not found") type MockStrategyTarget struct { HostImpl func(context.Context) (string, error) - InspectImpl func(context.Context) (*container.InspectResponse, error) - PortsImpl func(context.Context) (nat.PortMap, error) - MappedPortImpl func(context.Context, nat.Port) (nat.Port, error) + InspectImpl func(context.Context) (client.ContainerInspectResult, error) + PortsImpl func(context.Context) (network.PortMap, error) + MappedPortImpl func(context.Context, network.Port) (network.Port, error) LogsImpl func(context.Context) (io.ReadCloser, error) ExecImpl func(context.Context, []string, ...exec.ProcessOption) (int, io.Reader, error) StateImpl func(context.Context) (*container.State, error) @@ -29,11 +31,11 @@ func (st *MockStrategyTarget) Host(ctx context.Context) (string, error) { return st.HostImpl(ctx) } -func (st *MockStrategyTarget) Inspect(ctx context.Context) (*container.InspectResponse, error) { +func (st *MockStrategyTarget) Inspect(ctx context.Context) (client.ContainerInspectResult, error) { return st.InspectImpl(ctx) } -func (st *MockStrategyTarget) MappedPort(ctx context.Context, port nat.Port) (nat.Port, error) { +func (st *MockStrategyTarget) MappedPort(ctx context.Context, port network.Port) (network.Port, error) { return st.MappedPortImpl(ctx, port) } diff --git a/context/go.mod b/context/go.mod index 142c6260..8685cee5 100644 --- a/context/go.mod +++ b/context/go.mod @@ -1,6 +1,6 @@ module github.com/docker/go-sdk/context -go 1.24 +go 1.24.0 replace github.com/docker/go-sdk/config => ../config @@ -13,8 +13,8 @@ require ( require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/docker v28.3.2+incompatible // indirect github.com/kr/text v0.2.0 // indirect + github.com/moby/moby/api v1.52.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/context/go.sum b/context/go.sum index 15726ca6..b7afa7ae 100644 --- a/context/go.sum +++ b/context/go.sum @@ -3,14 +3,14 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v28.3.2+incompatible h1:wn66NJ6pWB1vBZIilP8G3qQPqHy5XymfYn5vsqeA5oA= -github.com/docker/docker v28.3.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= +github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= diff --git a/go.work b/go.work index deabaee5..44cb13f7 100644 --- a/go.work +++ b/go.work @@ -1,4 +1,4 @@ -go 1.24 +go 1.24.0 use ( ./client diff --git a/go.work.sum b/go.work.sum index a266c1d1..59cf7aa1 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,10 +1,16 @@ cel.dev/expr v0.20.0/go.mod h1:MrpN08Q+lEBs+bGYdLxxHkZoUSsCp0nSKTs0nTymJgw= cel.dev/expr v0.23.0 h1:wUb94w6OYQS4uXraxo9U+wUAs9jT47Xvl4iPgAwM2ss= cel.dev/expr v0.23.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= +cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.6.0 h1:A6hENjEsCDtC1k8byVsgwvVcioamEHvZ4j01OwKxG9I= cloud.google.com/go/compute/metadata v0.6.0/go.mod h1:FjyFAW1MW0C203CEOMDTu3Dk1FlqW3Rga40jzHL4hfg= +cloud.google.com/go/compute/metadata v0.7.0/go.mod h1:j5MvL9PprKL39t166CoB1uVHfQMs4tFQZZcKwksXUjo= +codeberg.org/go-fonts/liberation v0.5.0/go.mod h1:zS/2e1354/mJ4pGzIIaEtm/59VFCFnYC7YV6YdGl5GU= +codeberg.org/go-latex/latex v0.1.0/go.mod h1:LA0q/AyWIYrqVd+A9Upkgsb+IqPcmSTKc9Dny04MHMw= +codeberg.org/go-pdf/fpdf v0.10.0/go.mod h1:Y0DGRAdZ0OmnZPvjbMp/1bYxmIPxm0ws4tfoPOc4LjU= dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +git.sr.ht/~sbinet/gg v0.6.0/go.mod h1:uucygbfC9wVPQIfrmwM2et0imr8L7KQWywX0xpFMm94= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.1/go.mod h1:zGqV2R4Cr/k8Uye5w+dgQ06WJtEcbQG/8J7BB6hnCr4= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2/go.mod h1:SqINnQ9lVVdRlyC8cd1lCI0SdX4n2paeABd2K8ggfnE= @@ -13,20 +19,27 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83 github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0/go.mod h1:2bIszWvQRlJVmJLiuLhukLImRjKPcYdzzsx6darK02A= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0 h1:ErKg/3iS1AKcTkf3yixlZ54f9U1rljCkQyEXWUnIUxc= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.27.0/go.mod h1:yAZHSGnqScoU556rBOVkwLze6WP5N+U11RHuWaGVxwY= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.29.0/go.mod h1:Cz6ft6Dkn3Et6l2v2a9/RpN7epQ1GtDlO6lj8bEcOvw= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.21/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f h1:C5bqEmzEPLsHm9Mv73lSE9e9bKV23aB1vxOsmZrkl3k= github.com/cncf/xds/go v0.0.0-20250326154945-ae57f3c0d45f/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20250501225837-2ac532fd4443/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/containerd/typeurl/v2 v2.2.0 h1:6NBDbQzr7I5LHgp34xAXYF5DOTQDn05X58lsPEmzLso= github.com/containerd/typeurl/v2 v2.2.0/go.mod h1:8XOOxnyatxSWuG8OfsZXVnAF4iZfedjS/8UHSPJnX4g= github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/danieljoos/wincred v1.2.2 h1:774zMFJrqaeYCK2W57BgAem/MLi6mtSE47MB6BOJ0i0= github.com/danieljoos/wincred v1.2.2/go.mod h1:w7w4Utbrz8lqeMbDAK0lkNJUv5sAOkFi7nd/ogr0Uh8= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docker/go-sdk/client v0.1.0-alpha001/go.mod h1:riIX1X9he2Oxx0Wra35V/3BOfoIZf/tMZ7B6Z7zQU48= github.com/docker/go-sdk/config v0.1.0-alpha001/go.mod h1:eygQMlGzqLYetN/Qkc+lkHZJ9KJOMMCLy73OXn1rvzc= github.com/docker/go-sdk/context v0.1.0-alpha001/go.mod h1:VY14aL5Z7Vk31IumcHtxGwam3+f6UrXlhP96w1ysEnk= @@ -43,13 +56,20 @@ github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2T github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= +github.com/go-jose/go-jose/v4 v4.1.1/go.mod h1:BdsZGqgdO3b6tTc6LSE56wcDbMMLuPsw5d4ZD5f94kA= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/goccmack/gocc v0.0.0-20230228185258-2292f9e40198/go.mod h1:DTh/Y2+NbnOVVoypCCQrovMPDKUGp4yZpSbWg5D0XIM= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.5/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/keybase/go-keychain v0.0.1 h1:way+bWYa6lDppZoZcgMbYsvC7GxljxrskdNInRtuthU= @@ -60,6 +80,17 @@ github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6K github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lyft/protoc-gen-star/v2 v2.0.4-0.20230330145011-496ad1ac90a4/go.mod h1:amey7yeodaJhXSbf/TlLvWiqQfLOSpEk//mLlc+axEk= +github.com/moby/moby/api v0.0.0-20251022164246-00abc3a9d5c6/go.mod h1:/ou52HkRydg4+odrUR3vFsGgjIyHvprrpEQEkweL10s= +github.com/moby/moby/api v0.0.0-20251026152250-0a134ecc1623/go.mod h1:/ou52HkRydg4+odrUR3vFsGgjIyHvprrpEQEkweL10s= +github.com/moby/moby/api v0.0.0-20251029225139-7a97e1cb401f h1:jvrxd76X6jryoJNPOxvicvq/qnToY/vw5Xgi4tAvbeE= +github.com/moby/moby/api v0.0.0-20251029225139-7a97e1cb401f/go.mod h1:v0K/motq8oWmx+rtApG1rBTIpQ8KUONUjpf+U73gags= +github.com/moby/moby/api v1.52.0-rc.1 h1:yiNz/QzD4Jr1gyKl2iMo7OCZwwY+Xb3BltKv1xipwXo= +github.com/moby/moby/api v1.52.0-rc.1/go.mod h1:v0K/motq8oWmx+rtApG1rBTIpQ8KUONUjpf+U73gags= +github.com/moby/moby/client v0.0.0-20251022164246-00abc3a9d5c6/go.mod h1:sxVfwGqVgh7n+tdxA4gFToQ/lf+bM7zATnvQjVnsKT4= +github.com/moby/moby/client v0.0.0-20251029225139-7a97e1cb401f h1:itouVus9BFfARHQdPfLF64/jIr45iISNmwhr3r4s7gQ= +github.com/moby/moby/client v0.0.0-20251029225139-7a97e1cb401f/go.mod h1:1YrJTvhL771Q4xiwwe72NSS17lgsCF67xu8fEfSd77g= +github.com/moby/moby/client v0.1.0-rc.1 h1:NfuQec3HvQkPf4EvVkoFGPsBvlAc8CCyQN1m1kGSEX8= +github.com/moby/moby/client v0.1.0-rc.1/go.mod h1:qYzoKHz8qu4Ie1j41CWYhfNRHo8uhs5ay7cfx309Aqc= github.com/moby/sys/mount v0.3.4 h1:yn5jq4STPztkkzSKpZkLcmjue+bZJ0u2AuQY1iNI1Ww= github.com/moby/sys/mount v0.3.4/go.mod h1:KcQJMbQdJHPlq5lcYT+/CjatWM4PuxKe+XLSVS4J6Os= github.com/moby/sys/mountinfo v0.7.2 h1:1shs6aH5s4o5H2zQLn796ADW1wMrIwHsyJ2v9KouLrg= @@ -73,6 +104,8 @@ github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjL github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= @@ -80,9 +113,11 @@ github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3V github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= @@ -90,19 +125,26 @@ github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtC go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo= go.opentelemetry.io/contrib/detectors/gcp v1.35.0 h1:bGvFt68+KTiAKFlacHW6AhA56GF2rS0bdD3aJYEnmzA= go.opentelemetry.io/contrib/detectors/gcp v1.35.0/go.mod h1:qGWP8/+ILwMRIUf9uIVLloR1uo5ZYAslM4O6OqUi1DA= +go.opentelemetry.io/contrib/detectors/gcp v1.36.0/go.mod h1:IbBN8uAIIx734PTonTPxAxnjc2pQTxWNkwfstZ+6H2k= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ= go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y= +go.opentelemetry.io/otel v1.36.0/go.mod h1:/TcFMXYjyRNh8khOAO9ybYkqaDBb/70aVwkNML4pP8E= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE= +go.opentelemetry.io/otel/metric v1.36.0/go.mod h1:zC7Ks+yeyJt4xig9DEw9kuUFe5C3zLbVjV2PzT6qzbs= go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg= +go.opentelemetry.io/otel/sdk v1.36.0/go.mod h1:+lC+mTgD+MUWfjJubi2vvXWcVxyr9rmlshZni72pXeY= go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w= go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w= +go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps= go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc= +go.opentelemetry.io/otel/trace v1.36.0/go.mod h1:gQ+OnDZzrybY4k4seLzPAWNwVBBVlF2szhehOBB/tGA= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= @@ -110,14 +152,21 @@ golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZv golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w= golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= +golang.org/x/mod v0.26.0/go.mod h1:/j6NAhSk8iQ723BGAUyoAcn7SlD7s15Dp9Nd/SfeaFQ= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= +golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8= golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= @@ -132,28 +181,45 @@ golang.org/x/sync v0.14.0 h1:woo0S4Yywslg6hp4eUFjTVOyKt0RookbpAHG4c1HmhQ= golang.org/x/sync v0.14.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8= golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.34.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= +golang.org/x/telemetry v0.0.0-20250710130107-8d8967aff50b/go.mod h1:4ZwOYna0/zsOKwuR5X/m0QFOJpSZvAxFfkQT+Erd9D4= golang.org/x/term v0.32.0 h1:DR4lr0TjUs3epypdhTOkMmuF5CDFJ/8pOnbzMZPQ7bg= golang.org/x/term v0.32.0/go.mod h1:uZG1FhGx848Sqfsq4/DlJr3xGGsYMu/L5GW4abiaEPQ= +golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw= golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8 h1:vVKdlvoWBphwdxWKrFZEuM0kGgGLxUOYcY4U/2Vjg44= golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc= golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI= +golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg= +golang.org/x/tools v0.35.0/go.mod h1:NKdj5HkL/73byiZSJjqJgKn3ep7KjFkBOkR/Hps3VPw= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= +gonum.org/v1/plot v0.15.2/go.mod h1:DX+x+DWso3LTha+AdkJEv5Txvi+Tql3KAGkehP0/Ubg= google.golang.org/genproto/googleapis/api v0.0.0-20250218202821-56aae31c358a/go.mod h1:3kWAYMk1I75K4vykHtKt2ycnOgpA6974V7bREqbsenU= google.golang.org/genproto/googleapis/api v0.0.0-20250324211829-b45e905df463/go.mod h1:U90ffi8eUL9MwPcrJylN5+Mk2v3vuPDptd5yyNUiRR8= +google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:kXqgZtrWaf6qS3jZOCnCH7WYfrvFjkC51bM8fz3RsCA= google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ= google.golang.org/genproto/googleapis/rpc v0.0.0-20250324211829-b45e905df463/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= google.golang.org/genproto/googleapis/rpc v0.0.0-20250519155744-55703ea1f237/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250818200422-3122310a409c/go.mod h1:gw1tLEfykwDz2ET4a12jcXt4couGAm7IwsVaTy0Sflo= google.golang.org/grpc v1.64.1/go.mod h1:hiQF4LFZelK2WKaP6W0L92zGHtiQdZxk8CrSdvyjeP0= google.golang.org/grpc v1.67.0/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec= @@ -162,3 +228,4 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/image/README.md b/image/README.md index 659e8a85..91290bf3 100644 --- a/image/README.md +++ b/image/README.md @@ -24,7 +24,7 @@ if err != nil { The Pull operation can be customized using functional options. The following options are available: - `WithPullClient(cli client.SDKClient) image.PullOption`: The client to use to pull the image. If not provided, the default client will be used. -- `WithPullOptions(options apiimage.PullOptions) image.PullOption`: The options to use to pull the image. The type of the options is "github.com/docker/docker/api/types/image". +- `WithPullOptions(options apiimage.PullOptions) image.PullOption`: The options to use to pull the image. The type of the options is "github.com/moby/moby/api/types/image". - `WithPullHandler(pullHandler func(r io.ReadCloser) error) image.PullOption`: The handler to use to pull the image, which acts as a callback to the pull operation. First, you need to import the following packages: @@ -33,7 +33,7 @@ First, you need to import the following packages: import ( "context" - apiimage "github.com/docker/docker/api/types/image" + apiimage "github.com/moby/moby/api/types/image" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/image" ) @@ -79,7 +79,7 @@ if err != nil { The Remove operation can be customized using functional options. The following options are available: - `WithRemoveClient(cli client.SDKClient) image.RemoveOption`: The client to use to remove the image. If not provided, the default client will be used. -- `WithRemoveOptions(options dockerimage.RemoveOptions) image.RemoveOption`: The options to use to remove the image. The type of the options is "github.com/docker/docker/api/types/image". +- `WithRemoveOptions(options dockerimage.RemoveOptions) image.RemoveOption`: The options to use to remove the image. The type of the options is "github.com/moby/moby/api/types/image". First, you need to import the following packages: @@ -87,7 +87,7 @@ First, you need to import the following packages: import ( "context" - dockerimage "github.com/docker/docker/api/types/image" + dockerimage "github.com/moby/moby/api/types/image" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/image" ) @@ -172,7 +172,7 @@ The Build operation can be customized using functional options. The following op - `WithBuildClient(cli client.SDKClient) image.BuildOption`: The client to use to build the image. If not provided, the default client will be used. - `WithLogWriter(writer io.Writer) image.BuildOption`: The writer to use to write the build output. If not provided, the build output will be written to the standard output. -- `WithBuildOptions(options build.ImageBuildOptions) image.BuildOption`: The options to use to build the image. The type of the options is "github.com/docker/docker/api/types/build". If set, the tag and context reader will be overridden with the arguments passed to the `Build` function. +- `WithBuildOptions(options build.ImageBuildOptions) image.BuildOption`: The options to use to build the image. The type of the options is "github.com/moby/moby/api/types/build". If set, the tag and context reader will be overridden with the arguments passed to the `Build` function. First, you need to import the following packages: @@ -180,7 +180,7 @@ First, you need to import the following packages: import ( "context" - "github.com/docker/docker/api/types/build" + "github.com/moby/moby/api/types/build" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/image" ) diff --git a/image/build.go b/image/build.go index 60689844..1a765751 100644 --- a/image/build.go +++ b/image/build.go @@ -11,10 +11,10 @@ import ( "github.com/cenkalti/backoff/v4" "github.com/moby/go-archive" "github.com/moby/go-archive/compression" + dockerclient "github.com/moby/moby/client" + "github.com/moby/moby/client/pkg/jsonmessage" "github.com/moby/term" - "github.com/docker/docker/api/types/build" - "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/go-sdk/client" ) @@ -63,7 +63,7 @@ func BuildFromDir(ctx context.Context, dir string, dockerfile string, tag string return "", fmt.Errorf("archive build context: %w", err) } - buildOpts := build.ImageBuildOptions{ + buildOpts := dockerclient.ImageBuildOptions{ Dockerfile: dockerfile, } @@ -83,7 +83,7 @@ func Build(ctx context.Context, contextReader io.Reader, tag string, opts ...Bui } buildOpts := &buildOptions{ - opts: build.ImageBuildOptions{ + opts: dockerclient.ImageBuildOptions{ Dockerfile: "Dockerfile", }, } @@ -127,15 +127,15 @@ func Build(ctx context.Context, contextReader io.Reader, tag string, opts ...Bui defer tryClose(contextReader) resp, err := backoff.RetryNotifyWithData( - func() (build.ImageBuildResponse, error) { + func() (dockerclient.ImageBuildResult, error) { var err error resp, err := buildOpts.client.ImageBuild(ctx, contextReader, buildOpts.opts) if err != nil { if client.IsPermanentClientError(err) { - return build.ImageBuildResponse{}, backoff.Permanent(fmt.Errorf("build image: %w", err)) + return dockerclient.ImageBuildResult{}, backoff.Permanent(fmt.Errorf("build image: %w", err)) } - return build.ImageBuildResponse{}, err + return dockerclient.ImageBuildResult{}, err } return resp, nil diff --git a/image/build.log.go b/image/build.log.go index 1551fe12..5497864e 100644 --- a/image/build.log.go +++ b/image/build.log.go @@ -5,7 +5,7 @@ import ( "log/slog" "strings" - "github.com/docker/docker/pkg/jsonmessage" + "github.com/moby/moby/api/types/jsonstream" ) // loggerWriter is a custom writer that forwards to the slog.Logger @@ -16,7 +16,7 @@ type loggerWriter struct { // Write writes the message to the logger. func (lw *loggerWriter) Write(p []byte) (int, error) { // Try to parse as JSON message first - var msg jsonmessage.JSONMessage + var msg jsonstream.Message if err := json.Unmarshal(p, &msg); err == nil { // It's a JSON message, log it structured and there is no default case because // empty JSON messages should not be logged, to avoid noise. diff --git a/image/build.log_test.go b/image/build.log_test.go index 99e21b65..02f9c70f 100644 --- a/image/build.log_test.go +++ b/image/build.log_test.go @@ -7,9 +7,8 @@ import ( "strings" "testing" + "github.com/moby/moby/api/types/jsonstream" "github.com/stretchr/testify/require" - - "github.com/docker/docker/pkg/jsonmessage" ) func TestLoggerWriter_Write(t *testing.T) { @@ -55,8 +54,8 @@ func testLoggerWriterWithJSONError(t *testing.T) { logger := slog.New(slog.NewTextHandler(buf, nil)) writer := &loggerWriter{logger: logger} - errorMsg := jsonmessage.JSONMessage{ - Error: &jsonmessage.JSONError{ + errorMsg := jsonstream.Message{ + Error: &jsonstream.Error{ Message: "build failed", }, } @@ -80,7 +79,7 @@ func testLoggerWriterWithJSONStream(t *testing.T) { logger := slog.New(slog.NewTextHandler(buf, nil)) writer := &loggerWriter{logger: logger} - streamMsg := jsonmessage.JSONMessage{ + streamMsg := jsonstream.Message{ Stream: "Step 1/3 : FROM ubuntu:latest", } jsonData, err := json.Marshal(streamMsg) @@ -102,7 +101,7 @@ func testLoggerWriterWithJSONStatus(t *testing.T) { logger := slog.New(slog.NewTextHandler(buf, nil)) writer := &loggerWriter{logger: logger} - statusMsg := jsonmessage.JSONMessage{ + statusMsg := jsonstream.Message{ Status: "Downloading", ID: "abc123", } @@ -177,7 +176,7 @@ func testLoggerWriterStreamWithNewline(t *testing.T) { logger := slog.New(slog.NewTextHandler(buf, nil)) writer := &loggerWriter{logger: logger} - streamMsg := jsonmessage.JSONMessage{ + streamMsg := jsonstream.Message{ Stream: "Step 1/3 : FROM ubuntu:latest\n", } jsonData, err := json.Marshal(streamMsg) @@ -200,10 +199,10 @@ func testLoggerWriterStatusWithProgress(t *testing.T) { logger := slog.New(slog.NewTextHandler(buf, nil)) writer := &loggerWriter{logger: logger} - statusMsg := jsonmessage.JSONMessage{ + statusMsg := jsonstream.Message{ Status: "Downloading", ID: "abc123", - Progress: &jsonmessage.JSONProgress{Current: 1024, Total: 2048}, + Progress: &jsonstream.Progress{Current: 1024, Total: 2048}, } jsonData, err := json.Marshal(statusMsg) require.NoError(t, err) @@ -275,7 +274,7 @@ func testLoggerWriterWithEmptyJSONFields(t *testing.T) { logger := slog.New(slog.NewTextHandler(buf, nil)) writer := &loggerWriter{logger: logger} - emptyMsg := jsonmessage.JSONMessage{ + emptyMsg := jsonstream.Message{ Stream: "", Status: "", ID: "", diff --git a/image/build_examples_test.go b/image/build_examples_test.go index a7593537..d2fee927 100644 --- a/image/build_examples_test.go +++ b/image/build_examples_test.go @@ -8,8 +8,8 @@ import ( "log/slog" "path" - "github.com/docker/docker/api/types/build" - dockerimage "github.com/docker/docker/api/types/image" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/image" ) @@ -41,7 +41,7 @@ func ExampleBuild() { tag, err := image.Build( context.Background(), contextArchive, "example:test", - image.WithBuildOptions(build.ImageBuildOptions{ + image.WithBuildOptions(dockerclient.ImageBuildOptions{ Dockerfile: "Dockerfile", }), ) @@ -50,7 +50,7 @@ func ExampleBuild() { return } defer func() { - _, err = image.Remove(context.Background(), tag, image.WithRemoveOptions(dockerimage.RemoveOptions{ + _, err = image.Remove(context.Background(), tag, image.WithRemoveOptions(dockerclient.ImageRemoveOptions{ Force: true, PruneChildren: true, })) @@ -86,7 +86,7 @@ func ExampleBuildFromDir() { tag, err := image.BuildFromDir( context.Background(), buildPath, "Dockerfile", "example:test", - image.WithBuildOptions(build.ImageBuildOptions{ + image.WithBuildOptions(dockerclient.ImageBuildOptions{ Dockerfile: "Dockerfile", }), ) @@ -95,7 +95,7 @@ func ExampleBuildFromDir() { return } defer func() { - _, err = image.Remove(context.Background(), tag, image.WithRemoveOptions(dockerimage.RemoveOptions{ + _, err = image.Remove(context.Background(), tag, image.WithRemoveOptions(dockerclient.ImageRemoveOptions{ Force: true, PruneChildren: true, })) diff --git a/image/build_test.go b/image/build_test.go index fadcdbfc..b887eb93 100644 --- a/image/build_test.go +++ b/image/build_test.go @@ -4,18 +4,14 @@ import ( "bytes" "context" "errors" - "fmt" "io" "log/slog" "path" "testing" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/build" - "github.com/docker/docker/api/types/container" - "github.com/docker/docker/api/types/filters" - dockerimage "github.com/docker/docker/api/types/image" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/image" ) @@ -116,9 +112,11 @@ func TestBuildFromDir(t *testing.T) { }) t.Run("with-dockerfile/options-are-overridden", func(t *testing.T) { - tag, err := image.BuildFromDir(context.Background(), buildPath, "Dockerfile", "test:test", image.WithBuildOptions(build.ImageBuildOptions{ - Dockerfile: "Dockerfile.custom", - })) + tag, err := image.BuildFromDir(context.Background(), buildPath, "Dockerfile", "test:test", + image.WithBuildOptions(dockerclient.ImageBuildOptions{ + Dockerfile: "Dockerfile.custom", + }), + ) t.Cleanup(func() { cleanup(t, tag) }) @@ -163,7 +161,7 @@ func testBuild(tb testing.TB, b *testBuildInfo, opts ...image.BuildOption) { require.NoError(tb, cli.Close()) }) - buildOpts := build.ImageBuildOptions{ + buildOpts := dockerclient.ImageBuildOptions{ // Used as a marker to identify the containers created by the test // so it's possible to clean them up after the tests. Labels: map[string]string{ @@ -203,20 +201,23 @@ func cleanup(tb testing.TB, tag string) { require.NoError(tb, cli.Close()) }) - _, err = image.Remove(context.Background(), tag, image.WithRemoveOptions(dockerimage.RemoveOptions{ + _, err = image.Remove(context.Background(), tag, image.WithRemoveOptions(dockerclient.ImageRemoveOptions{ Force: true, PruneChildren: true, })) require.NoError(tb, err) - containers, err := cli.ContainerList(context.Background(), container.ListOptions{ - Filters: filters.NewArgs(filters.Arg("status", "created"), filters.Arg("label", fmt.Sprintf("%s=%s", labelImageBuildTestKey, labelImageBuildTestValue))), - All: true, + containers, err := cli.ContainerList(context.Background(), dockerclient.ContainerListOptions{ + Filters: make(dockerclient.Filters). + Add("status", "created"). + Add("label", labelImageBuildTestKey+"="+labelImageBuildTestValue), + All: true, }) require.NoError(tb, err) // force the removal of the intermediate containers, if any - for _, ctr := range containers { - require.NoError(tb, cli.ContainerRemove(context.Background(), ctr.ID, container.RemoveOptions{Force: true})) + for _, ctr := range containers.Items { + _, err := cli.ContainerRemove(context.Background(), ctr.ID, dockerclient.ContainerRemoveOptions{Force: true}) + require.NoError(tb, err) } } diff --git a/image/build_unit_test.go b/image/build_unit_test.go index 7fd115d7..0467bc3d 100644 --- a/image/build_unit_test.go +++ b/image/build_unit_test.go @@ -10,9 +10,9 @@ import ( "time" "github.com/containerd/errdefs" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/build" "github.com/docker/go-sdk/client" ) @@ -36,7 +36,7 @@ func TestBuild_withRetries(t *testing.T) { tag, err := Build( ctx, contextArchive, "test", WithBuildClient(sdk), - WithBuildOptions(build.ImageBuildOptions{ + WithBuildOptions(dockerclient.ImageBuildOptions{ Dockerfile: "Dockerfile", }), ) diff --git a/image/go.mod b/image/go.mod index da2849af..304c2920 100644 --- a/image/go.mod +++ b/image/go.mod @@ -1,6 +1,6 @@ module github.com/docker/go-sdk/image -go 1.24 +go 1.24.0 replace ( github.com/docker/go-sdk/client => ../client @@ -11,10 +11,11 @@ replace ( require ( github.com/cenkalti/backoff/v4 v4.2.1 github.com/containerd/errdefs v1.0.0 - github.com/docker/docker v28.3.2+incompatible github.com/docker/go-sdk/client v0.1.0-alpha011 github.com/docker/go-sdk/config v0.1.0-alpha011 github.com/moby/go-archive v0.1.0 + github.com/moby/moby/api v1.52.0 + github.com/moby/moby/client v0.1.0 github.com/moby/patternmatcher v0.6.0 github.com/moby/term v0.5.2 github.com/opencontainers/image-spec v1.1.1 @@ -25,26 +26,22 @@ require ( github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/caarlos0/env/v11 v11.3.1 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/containerd/log v0.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-connections v0.6.0 // indirect github.com/docker/go-sdk/context v0.1.0-alpha011 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/klauspost/compress v1.18.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/moby/sys/sequential v0.6.0 // indirect github.com/moby/sys/user v0.4.0 // indirect github.com/moby/sys/userns v0.1.0 // indirect - github.com/morikuni/aec v1.0.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/sirupsen/logrus v1.9.3 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect @@ -52,11 +49,6 @@ require ( go.opentelemetry.io/otel v1.37.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect - golang.org/x/net v0.40.0 // indirect golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.26.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/image/go.sum b/image/go.sum index 2059f8da..e609b3f6 100644 --- a/image/go.sum +++ b/image/go.sum @@ -8,25 +8,21 @@ github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5m github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/creack/pty v1.1.24 h1:bJrF4RRfyJnbTJqzRLHzcGaZK1NeM5kTC9jGgovnR1s= +github.com/creack/pty v1.1.24/go.mod h1:08sCNb52WyoAwi2QDyzUCTgcvVFhUzewun7wtTfvcwE= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v28.3.2+incompatible h1:wn66NJ6pWB1vBZIilP8G3qQPqHy5XymfYn5vsqeA5oA= -github.com/docker/docker v28.3.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -36,16 +32,10 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -56,10 +46,12 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/go-archive v0.1.0 h1:Kk/5rdW/g+H8NHdJW2gsXyZ7UnzvJNOy6VKJqueWdcQ= github.com/moby/go-archive v0.1.0/go.mod h1:G9B+YoujNohJmrIYFBpSd54GTUB4lt9S+xVQvsJyFuo= +github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= +github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= +github.com/moby/moby/client v0.1.0 h1:nt+hn6O9cyJQqq5UWnFGqsZRTS/JirUqzPjEl0Bdc/8= +github.com/moby/moby/client v0.1.0/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE= github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= -github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= @@ -68,14 +60,10 @@ github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= @@ -86,18 +74,12 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXXvf78e00EwY6Wp0YII8ww2JVWshZ20HfTlE11AM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ= go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= @@ -106,51 +88,10 @@ go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFw go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= -google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -159,3 +100,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/image/mocks_test.go b/image/mocks_test.go index c98ac8c9..f0bac465 100644 --- a/image/mocks_test.go +++ b/image/mocks_test.go @@ -4,11 +4,10 @@ import ( "bytes" "context" "io" + "iter" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/build" - "github.com/docker/docker/api/types/image" - "github.com/docker/docker/client" + "github.com/moby/moby/api/types/jsonstream" + "github.com/moby/moby/client" ) // errMockCli is a mock implementation of client.APIClient, which is handy for simulating @@ -21,11 +20,11 @@ type errMockCli struct { imagePullCount int } -func (f *errMockCli) Ping(_ context.Context) (types.Ping, error) { - return types.Ping{}, nil +func (f *errMockCli) Ping(_ context.Context, _ client.PingOptions) (client.PingResult, error) { + return client.PingResult{}, nil } -func (f *errMockCli) ImageBuild(_ context.Context, _ io.Reader, _ build.ImageBuildOptions) (build.ImageBuildResponse, error) { +func (f *errMockCli) ImageBuild(_ context.Context, _ io.Reader, _ client.ImageBuildOptions) (client.ImageBuildResult, error) { f.imageBuildCount++ // In real Docker API, the response body contains JSON build messages, not the build context @@ -34,18 +33,30 @@ func (f *errMockCli) ImageBuild(_ context.Context, _ io.Reader, _ build.ImageBui {"stream":"Successfully built abc123"} ` responseBody := io.NopCloser(bytes.NewBufferString(mockBuildOutput)) - return build.ImageBuildResponse{Body: responseBody}, f.err + return client.ImageBuildResult{Body: responseBody}, f.err } -func (f *errMockCli) ImagePull(_ context.Context, _ string, _ image.PullOptions) (io.ReadCloser, error) { +func (f *errMockCli) ImagePull(_ context.Context, _ string, _ client.ImagePullOptions) (client.ImagePullResponse, error) { f.imagePullCount++ // Return mock JSON messages similar to real Docker pull output mockPullOutput := `{"status":"Pulling from library/nginx","id":"latest"} {"status":"Pull complete","id":"abc123"} ` - return io.NopCloser(bytes.NewBufferString(mockPullOutput)), f.err + return errMockImagePullResponse{ReadCloser: io.NopCloser(bytes.NewBufferString(mockPullOutput))}, f.err } func (f *errMockCli) Close() error { return nil } + +type errMockImagePullResponse struct { + io.ReadCloser +} + +func (f errMockImagePullResponse) JSONMessages(_ context.Context) iter.Seq2[jsonstream.Message, error] { + return nil +} + +func (f errMockImagePullResponse) Wait(_ context.Context) error { + return nil +} diff --git a/image/options.go b/image/options.go index f5e4b971..27bf8015 100644 --- a/image/options.go +++ b/image/options.go @@ -5,10 +5,9 @@ import ( "fmt" "io" + dockerclient "github.com/moby/moby/client" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/docker/docker/api/types/build" - "github.com/docker/docker/api/types/image" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/config" ) @@ -18,7 +17,7 @@ type BuildOption func(*buildOptions) error type buildOptions struct { client client.SDKClient - opts build.ImageBuildOptions + opts dockerclient.ImageBuildOptions } // WithBuildClient sets the build client used to build the image. @@ -31,7 +30,7 @@ func WithBuildClient(buildClient client.SDKClient) BuildOption { // WithBuildOptions sets the build options used to build the image. // If set, the tag and context reader will be ignored. -func WithBuildOptions(options build.ImageBuildOptions) BuildOption { +func WithBuildOptions(options dockerclient.ImageBuildOptions) BuildOption { return func(opts *buildOptions) error { opts.opts = options return nil @@ -43,7 +42,7 @@ type PullOption func(*pullOptions) error type pullOptions struct { client client.SDKClient - pullOptions image.PullOptions + pullOptions dockerclient.ImagePullOptions pullHandler func(r io.ReadCloser) error credentialsFn func(string) (string, string, error) } @@ -86,7 +85,7 @@ func WithPullClient(pullClient client.SDKClient) PullOption { } // WithPullOptions sets the pull options used to pull the image. -func WithPullOptions(imagePullOptions image.PullOptions) PullOption { +func WithPullOptions(imagePullOptions dockerclient.ImagePullOptions) PullOption { return func(opts *pullOptions) error { opts.pullOptions = imagePullOptions return nil @@ -111,7 +110,7 @@ type RemoveOption func(*removeOptions) error type removeOptions struct { client client.SDKClient - removeOptions image.RemoveOptions + removeOptions dockerclient.ImageRemoveOptions } // WithRemoveClient sets the remove client used to remove the image. @@ -123,7 +122,7 @@ func WithRemoveClient(removeClient client.SDKClient) RemoveOption { } // WithRemoveOptions sets the remove options used to remove the image. -func WithRemoveOptions(options image.RemoveOptions) RemoveOption { +func WithRemoveOptions(options dockerclient.ImageRemoveOptions) RemoveOption { return func(opts *removeOptions) error { opts.removeOptions = options return nil diff --git a/image/options_test.go b/image/options_test.go index 047b610e..fdffb41a 100644 --- a/image/options_test.go +++ b/image/options_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/image" "github.com/docker/go-sdk/client" ) @@ -22,7 +22,7 @@ func TestWithOptions(t *testing.T) { }) t.Run("with-pull-options", func(t *testing.T) { - opts := image.PullOptions{} + opts := dockerclient.ImagePullOptions{} pullOpts := &pullOptions{} err := WithPullOptions(opts)(pullOpts) require.NoError(t, err) diff --git a/image/pull.go b/image/pull.go index fb4ee919..d312a29d 100644 --- a/image/pull.go +++ b/image/pull.go @@ -9,10 +9,11 @@ import ( "time" "github.com/cenkalti/backoff/v4" + "github.com/moby/moby/api/pkg/authconfig" + "github.com/moby/moby/api/types/registry" + "github.com/moby/moby/client/pkg/jsonmessage" "github.com/moby/term" - "github.com/docker/docker/api/types/registry" - "github.com/docker/docker/pkg/jsonmessage" "github.com/docker/go-sdk/client" ) @@ -85,7 +86,7 @@ func Pull(ctx context.Context, imageName string, opts ...PullOption) error { Password: password, } - pullOpts.pullOptions.RegistryAuth, err = registry.EncodeAuthConfig(authConfig) + pullOpts.pullOptions.RegistryAuth, err = authconfig.Encode(authConfig) if err != nil { pullOpts.client.Logger().Warn("failed to encode image auth, setting empty credentials for the image", "image", imageName, "error", err) } diff --git a/image/pull_benchmark_test.go b/image/pull_benchmark_test.go index 2250cafc..1580982e 100644 --- a/image/pull_benchmark_test.go +++ b/image/pull_benchmark_test.go @@ -4,14 +4,14 @@ import ( "context" "errors" "io" + "iter" "log/slog" "testing" + "github.com/moby/moby/api/types/jsonstream" + "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/image" - "github.com/docker/docker/client" sdkclient "github.com/docker/go-sdk/client" ) @@ -19,19 +19,19 @@ import ( type mockImagePullClient struct { client.APIClient *testLogger - pullFunc func(ctx context.Context, image string, options image.PullOptions) (io.ReadCloser, error) + pullFunc func(ctx context.Context, image string, options client.ImagePullOptions) (client.ImagePullResponse, error) } func (m *mockImagePullClient) Close() error { return nil } -func (m *mockImagePullClient) ImagePull(ctx context.Context, image string, options image.PullOptions) (io.ReadCloser, error) { +func (m *mockImagePullClient) ImagePull(ctx context.Context, image string, options client.ImagePullOptions) (client.ImagePullResponse, error) { return m.pullFunc(ctx, image, options) } -func (m *mockImagePullClient) Ping(_ context.Context) (types.Ping, error) { - return types.Ping{}, nil +func (m *mockImagePullClient) Ping(_ context.Context, _ client.PingOptions) (client.PingResult, error) { + return client.PingResult{}, nil } func setupPullBenchmark(b *testing.B) *mockImagePullClient { @@ -39,23 +39,35 @@ func setupPullBenchmark(b *testing.B) *mockImagePullClient { return &mockImagePullClient{ testLogger: newTestLogger(b), - pullFunc: func(_ context.Context, _ string, _ image.PullOptions) (io.ReadCloser, error) { - return io.NopCloser(io.Reader(io.MultiReader())), nil + pullFunc: func(_ context.Context, _ string, _ client.ImagePullOptions) (client.ImagePullResponse, error) { + return mockImagePullResponse{io.NopCloser(io.MultiReader())}, nil }, } } +type mockImagePullResponse struct { + io.ReadCloser +} + +func (f mockImagePullResponse) JSONMessages(_ context.Context) iter.Seq2[jsonstream.Message, error] { + return nil +} + +func (f mockImagePullResponse) Wait(_ context.Context) error { + return nil +} + func BenchmarkPull(b *testing.B) { ctx := context.Background() imageName := "test/image:latest" - pullOpt := image.PullOptions{} + pullOpt := client.ImagePullOptions{} b.Run("pull-without-auth", func(b *testing.B) { - client := setupPullBenchmark(b) + c := setupPullBenchmark(b) b.ResetTimer() b.ReportAllocs() - sdk, err := sdkclient.New(context.TODO(), sdkclient.WithDockerAPI(client)) + sdk, err := sdkclient.New(context.TODO(), sdkclient.WithDockerAPI(c)) require.NoError(b, err) for range b.N { @@ -67,16 +79,16 @@ func BenchmarkPull(b *testing.B) { }) b.Run("pull-with-auth", func(b *testing.B) { - client := setupPullBenchmark(b) + c := setupPullBenchmark(b) // Mock registry credentials - client.pullFunc = func(_ context.Context, _ string, options image.PullOptions) (io.ReadCloser, error) { + c.pullFunc = func(_ context.Context, _ string, options client.ImagePullOptions) (client.ImagePullResponse, error) { require.NotEmpty(b, options.RegistryAuth) - return io.NopCloser(io.Reader(io.MultiReader())), nil + return mockImagePullResponse{io.NopCloser(io.MultiReader())}, nil } b.ResetTimer() b.ReportAllocs() - sdk, err := sdkclient.New(context.TODO(), sdkclient.WithDockerAPI(client)) + sdk, err := sdkclient.New(context.TODO(), sdkclient.WithDockerAPI(c)) require.NoError(b, err) for range b.N { @@ -88,19 +100,19 @@ func BenchmarkPull(b *testing.B) { }) b.Run("pull-with-retries", func(b *testing.B) { - client := setupPullBenchmark(b) + c := setupPullBenchmark(b) attempts := 0 - client.pullFunc = func(_ context.Context, _ string, _ image.PullOptions) (io.ReadCloser, error) { + c.pullFunc = func(_ context.Context, _ string, _ client.ImagePullOptions) (client.ImagePullResponse, error) { attempts++ if attempts < 3 { return nil, errors.New("temporary error") } - return io.NopCloser(io.Reader(io.MultiReader())), nil + return mockImagePullResponse{io.NopCloser(io.MultiReader())}, nil } b.ResetTimer() b.ReportAllocs() - sdk, err := sdkclient.New(context.TODO(), sdkclient.WithDockerAPI(client)) + sdk, err := sdkclient.New(context.TODO(), sdkclient.WithDockerAPI(c)) require.NoError(b, err) // Use a custom pull handler that discards output to avoid measuring display performance @@ -119,16 +131,16 @@ func BenchmarkPull(b *testing.B) { }) b.Run("with-pull-handler", func(b *testing.B) { - client := setupPullBenchmark(b) + c := setupPullBenchmark(b) // Mock registry credentials - client.pullFunc = func(_ context.Context, _ string, options image.PullOptions) (io.ReadCloser, error) { + c.pullFunc = func(_ context.Context, _ string, options client.ImagePullOptions) (client.ImagePullResponse, error) { require.NotEmpty(b, options.RegistryAuth) - return io.NopCloser(io.Reader(io.MultiReader())), nil + return mockImagePullResponse{io.NopCloser(io.MultiReader())}, nil } b.ResetTimer() b.ReportAllocs() - sdk, err := sdkclient.New(context.TODO(), sdkclient.WithDockerAPI(client)) + sdk, err := sdkclient.New(context.TODO(), sdkclient.WithDockerAPI(c)) require.NoError(b, err) for range b.N { diff --git a/image/pull_examples_test.go b/image/pull_examples_test.go index d120af56..d0889b34 100644 --- a/image/pull_examples_test.go +++ b/image/pull_examples_test.go @@ -8,7 +8,9 @@ import ( "log" "strings" - apiimage "github.com/docker/docker/api/types/image" + dockerclient "github.com/moby/moby/client" + v1 "github.com/opencontainers/image-spec/specs-go/v1" + "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/image" ) @@ -39,9 +41,12 @@ func ExamplePull_withClient() { } func ExamplePull_withPullOptions() { - opts := apiimage.PullOptions{ - Platform: "linux/amd64", - } + opts := dockerclient.ImagePullOptions{Platforms: []v1.Platform{ + { + OS: "linux", + Architecture: "amd64", + }, + }} err := image.Pull(context.Background(), "alpine:3.22", image.WithPullOptions(opts)) @@ -52,9 +57,12 @@ func ExamplePull_withPullOptions() { } func ExamplePull_withPullHandler() { - opts := apiimage.PullOptions{ - Platform: "linux/amd64", - } + opts := dockerclient.ImagePullOptions{Platforms: []v1.Platform{ + { + OS: "linux", + Architecture: "amd64", + }, + }} buff := &bytes.Buffer{} diff --git a/image/pull_test.go b/image/pull_test.go index bf2977c1..618997d1 100644 --- a/image/pull_test.go +++ b/image/pull_test.go @@ -7,9 +7,9 @@ import ( "io" "testing" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - apiimage "github.com/docker/docker/api/types/image" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/image" ) @@ -23,7 +23,7 @@ func TestPull(t *testing.T) { t.Helper() opts = append(opts, image.WithPullClient(dockerClient)) - opts = append(opts, image.WithPullOptions(apiimage.PullOptions{})) + opts = append(opts, image.WithPullOptions(dockerclient.ImagePullOptions{})) ctx := context.Background() diff --git a/image/pull_unit_test.go b/image/pull_unit_test.go index 732943d4..f3a98fde 100644 --- a/image/pull_unit_test.go +++ b/image/pull_unit_test.go @@ -9,14 +9,14 @@ import ( "time" "github.com/containerd/errdefs" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/image" sdkclient "github.com/docker/go-sdk/client" ) func TestPull(t *testing.T) { - defaultPullOpts := []PullOption{WithPullOptions(image.PullOptions{})} + defaultPullOpts := []PullOption{WithPullOptions(dockerclient.ImagePullOptions{})} testPull := func(t *testing.T, imageName string, pullOpts []PullOption, mockCli *errMockCli, shouldRetry bool) string { t.Helper() diff --git a/image/remove.go b/image/remove.go index bf860837..f51ad66d 100644 --- a/image/remove.go +++ b/image/remove.go @@ -5,34 +5,35 @@ import ( "errors" "fmt" - "github.com/docker/docker/api/types/image" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/client" ) // Remove removes an image from the local repository. -func Remove(ctx context.Context, image string, opts ...RemoveOption) ([]image.DeleteResponse, error) { +func Remove(ctx context.Context, image string, opts ...RemoveOption) (dockerclient.ImageRemoveResult, error) { removeOpts := &removeOptions{} for _, opt := range opts { if err := opt(removeOpts); err != nil { - return nil, fmt.Errorf("apply remove option: %w", err) + return dockerclient.ImageRemoveResult{}, fmt.Errorf("apply remove option: %w", err) } } if image == "" { - return nil, errors.New("image is required") + return dockerclient.ImageRemoveResult{}, errors.New("image is required") } if removeOpts.client == nil { sdk, err := client.New(ctx) if err != nil { - return nil, err + return dockerclient.ImageRemoveResult{}, err } removeOpts.client = sdk } resp, err := removeOpts.client.ImageRemove(ctx, image, removeOpts.removeOptions) if err != nil { - return nil, fmt.Errorf("remove image: %w", err) + return dockerclient.ImageRemoveResult{}, fmt.Errorf("remove image: %w", err) } return resp, nil diff --git a/image/remove_test.go b/image/remove_test.go index 0ad76838..6eaa3188 100644 --- a/image/remove_test.go +++ b/image/remove_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - dockerimage "github.com/docker/docker/api/types/image" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/image" ) @@ -36,7 +36,7 @@ func TestRemove(t *testing.T) { t.Run("success/with-options", func(t *testing.T) { pullImage(t, img) - resp, err := image.Remove(context.Background(), img, image.WithRemoveOptions(dockerimage.RemoveOptions{ + resp, err := image.Remove(context.Background(), img, image.WithRemoveOptions(dockerclient.ImageRemoveOptions{ Force: true, PruneChildren: true, })) diff --git a/image/save.go b/image/save.go index 19f2f844..93080fcb 100644 --- a/image/save.go +++ b/image/save.go @@ -6,9 +6,9 @@ import ( "fmt" "os" + dockerclient "github.com/moby/moby/client" ocispec "github.com/opencontainers/image-spec/specs-go/v1" - dockerclient "github.com/docker/docker/client" "github.com/docker/go-sdk/client" ) diff --git a/legacyadapters/README.md b/legacyadapters/README.md index f7fb5a57..fab410bc 100644 --- a/legacyadapters/README.md +++ b/legacyadapters/README.md @@ -23,7 +23,7 @@ Convert SDK auth config to Docker Engine API format: ```go import ( - "github.com/docker/docker/api/types/registry" + "github.com/moby/moby/api/types/registry" "github.com/docker/go-sdk/config" legacyconfig "github.com/docker/go-sdk/legacyadapters/config" ) diff --git a/legacyadapters/config/auth.go b/legacyadapters/config/auth.go index ee0ecec9..7bb9ecc3 100644 --- a/legacyadapters/config/auth.go +++ b/legacyadapters/config/auth.go @@ -7,9 +7,10 @@ package config import ( + "github.com/moby/moby/api/types/registry" + "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/types" - "github.com/docker/docker/api/types/registry" "github.com/docker/go-sdk/config" ) diff --git a/legacyadapters/config/auth_test.go b/legacyadapters/config/auth_test.go index fc1bf46c..6148863b 100644 --- a/legacyadapters/config/auth_test.go +++ b/legacyadapters/config/auth_test.go @@ -3,11 +3,11 @@ package config import ( "testing" + "github.com/moby/moby/api/types/registry" "github.com/stretchr/testify/require" "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/config/types" - "github.com/docker/docker/api/types/registry" "github.com/docker/go-sdk/config" ) @@ -18,11 +18,9 @@ func TestToRegistryAuthConfig(t *testing.T) { expected registry.AuthConfig }{ { - name: "empty config", - input: registry.AuthConfig{}, - expected: registry.AuthConfig{ - Email: "", - }, + name: "empty config", + input: registry.AuthConfig{}, + expected: registry.AuthConfig{}, }, { name: "basic username and password", @@ -33,7 +31,6 @@ func TestToRegistryAuthConfig(t *testing.T) { expected: registry.AuthConfig{ Username: "testuser", Password: "testpass", - Email: "", }, }, { @@ -47,7 +44,6 @@ func TestToRegistryAuthConfig(t *testing.T) { Username: "user", Password: "pass", Auth: "dXNlcjpwYXNz", - Email: "", }, }, { @@ -60,7 +56,6 @@ func TestToRegistryAuthConfig(t *testing.T) { expected: registry.AuthConfig{ Username: "user", Password: "pass", - Email: "", ServerAddress: "registry.example.com", }, }, @@ -72,7 +67,6 @@ func TestToRegistryAuthConfig(t *testing.T) { }, expected: registry.AuthConfig{ Username: "user", - Email: "", IdentityToken: "identity-token-123", }, }, @@ -84,7 +78,6 @@ func TestToRegistryAuthConfig(t *testing.T) { }, expected: registry.AuthConfig{ Username: "user", - Email: "", RegistryToken: "registry-token-456", }, }, @@ -102,7 +95,6 @@ func TestToRegistryAuthConfig(t *testing.T) { Username: "testuser", Password: "testpass", Auth: "dGVzdHVzZXI6dGVzdHBhc3M=", - Email: "", ServerAddress: "registry.example.com", IdentityToken: "identity-token-123", RegistryToken: "registry-token-456", @@ -118,17 +110,6 @@ func TestToRegistryAuthConfig(t *testing.T) { } } -func TestToRegistryAuthConfig_EmailAlwaysEmpty(t *testing.T) { - // Test that Email field is always set to empty string, regardless of input - input := registry.AuthConfig{ - Username: "user", - Password: "pass", - } - - result := ToRegistryAuthConfig(input) - require.Empty(t, result.Email, "Email field should always be empty") -} - func TestConfigToConfigFile(t *testing.T) { t.Helper() tests := []struct { diff --git a/legacyadapters/go.mod b/legacyadapters/go.mod index cd219032..6e33b822 100644 --- a/legacyadapters/go.mod +++ b/legacyadapters/go.mod @@ -1,13 +1,13 @@ module github.com/docker/go-sdk/legacyadapters -go 1.24 +go 1.24.0 replace github.com/docker/go-sdk/config => ../config require ( github.com/docker/cli v28.3.2+incompatible - github.com/docker/docker v28.3.2+incompatible github.com/docker/go-sdk/config v0.1.0-alpha011 + github.com/moby/moby/api v1.52.0 github.com/stretchr/testify v1.10.0 ) diff --git a/legacyadapters/go.sum b/legacyadapters/go.sum index 78881b54..5ae51887 100644 --- a/legacyadapters/go.sum +++ b/legacyadapters/go.sum @@ -6,8 +6,6 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/cli v28.3.2+incompatible h1:mOt9fcLE7zaACbxW1GeS65RI67wIJrTnqS3hP2huFsY= github.com/docker/cli v28.3.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/docker v28.3.2+incompatible h1:wn66NJ6pWB1vBZIilP8G3qQPqHy5XymfYn5vsqeA5oA= -github.com/docker/docker v28.3.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.9.3 h1:gAm/VtF9wgqJMoxzT3Gj5p4AqIjCBS4wrsOh9yRqcz8= github.com/docker/docker-credential-helpers v0.9.3/go.mod h1:x+4Gbw9aGmChi3qTLZj8Dfn0TD20M/fuWy0E5+WDeCo= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= @@ -16,6 +14,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= +github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= diff --git a/network/go.mod b/network/go.mod index 6e54b7a1..e1e9ed72 100644 --- a/network/go.mod +++ b/network/go.mod @@ -1,6 +1,6 @@ module github.com/docker/go-sdk/network -go 1.24 +go 1.24.0 replace ( github.com/docker/go-sdk/client => ../client @@ -10,44 +10,35 @@ replace ( require ( github.com/containerd/errdefs v1.0.0 - github.com/docker/docker v28.3.2+incompatible github.com/docker/go-sdk/client v0.1.0-alpha011 github.com/google/uuid v1.6.0 + github.com/moby/moby/api v1.52.0 + github.com/moby/moby/client v0.1.0 github.com/stretchr/testify v1.10.0 ) require ( - github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/caarlos0/env/v11 v11.3.1 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-connections v0.6.0 // indirect github.com/docker/go-sdk/config v0.1.0-alpha011 // indirect github.com/docker/go-sdk/context v0.1.0-alpha011 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/sys/sequential v0.6.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect go.opentelemetry.io/otel v1.37.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect - golang.org/x/net v0.40.0 // indirect golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.26.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/network/go.sum b/network/go.sum index 1c8658ec..08a9ebae 100644 --- a/network/go.sum +++ b/network/go.sum @@ -1,25 +1,17 @@ -github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= -github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA= github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v28.3.2+incompatible h1:wn66NJ6pWB1vBZIilP8G3qQPqHy5XymfYn5vsqeA5oA= -github.com/docker/docker v28.3.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -29,56 +21,36 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= -github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= -github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= -github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= -github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= -github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= +github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= +github.com/moby/moby/client v0.1.0 h1:nt+hn6O9cyJQqq5UWnFGqsZRTS/JirUqzPjEl0Bdc/8= +github.com/moby/moby/client v0.1.0/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXXvf78e00EwY6Wp0YII8ww2JVWshZ20HfTlE11AM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ= go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= @@ -87,50 +59,8 @@ go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFw go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= -google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -138,3 +68,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/network/network.go b/network/network.go index b6636858..173baaca 100644 --- a/network/network.go +++ b/network/network.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/google/uuid" + dockerclient "github.com/moby/moby/client" - "github.com/docker/docker/api/types/network" "github.com/docker/go-sdk/client" ) @@ -36,7 +36,7 @@ func New(ctx context.Context, opts ...Option) (*Network, error) { networkOptions.labels[moduleLabel] = Version() - nc := network.CreateOptions{ + nc := dockerclient.NetworkCreateOptions{ Driver: networkOptions.driver, Internal: networkOptions.internal, EnableIPv6: &networkOptions.enableIPv6, @@ -50,7 +50,7 @@ func New(ctx context.Context, opts ...Option) (*Network, error) { return nil, fmt.Errorf("create network: %w", err) } - if resp.Warning != "" { + if len(resp.Warning) > 0 { networkOptions.client.Logger().Warn("warning creating network", "message", resp.Warning) } diff --git a/network/network.inspect.go b/network/network.inspect.go index 4a41bbfa..3305b4b5 100644 --- a/network/network.inspect.go +++ b/network/network.inspect.go @@ -4,12 +4,12 @@ import ( "context" "errors" - "github.com/docker/docker/api/types/network" + "github.com/moby/moby/client" ) type inspectOptions struct { cache bool - options network.InspectOptions + options client.NetworkInspectOptions } // InspectOptions is a function that modifies the inspect options. @@ -26,7 +26,7 @@ func WithNoCache() InspectOptions { } // WithInspectOptions returns an InspectOptions that sets the inspect options. -func WithInspectOptions(opts network.InspectOptions) InspectOptions { +func WithInspectOptions(opts client.NetworkInspectOptions) InspectOptions { return func(o *inspectOptions) error { o.options = opts return nil @@ -34,10 +34,9 @@ func WithInspectOptions(opts network.InspectOptions) InspectOptions { } // Inspect inspects the network, caching the results. -func (n *Network) Inspect(ctx context.Context, opts ...InspectOptions) (network.Inspect, error) { - var zero network.Inspect +func (n *Network) Inspect(ctx context.Context, opts ...InspectOptions) (client.NetworkInspectResult, error) { if n.dockerClient == nil { - return zero, errors.New("docker client is not initialized") + return client.NetworkInspectResult{}, errors.New("docker client is not initialized") } inspectOptions := &inspectOptions{ @@ -45,13 +44,13 @@ func (n *Network) Inspect(ctx context.Context, opts ...InspectOptions) (network. } for _, opt := range opts { if err := opt(inspectOptions); err != nil { - return zero, err + return client.NetworkInspectResult{}, err } } if inspectOptions.cache { // if the result was already cached, return it - if n.inspect.ID != "" { + if n.inspect.Network.ID != "" { return n.inspect, nil } @@ -61,7 +60,7 @@ func (n *Network) Inspect(ctx context.Context, opts ...InspectOptions) (network. inspect, err := n.dockerClient.NetworkInspect(ctx, n.ID(), inspectOptions.options) if err != nil { - return zero, err + return client.NetworkInspectResult{}, err } // cache the result for subsequent calls diff --git a/network/network.inspect_test.go b/network/network.inspect_test.go index 1fc78cc8..be394cc0 100644 --- a/network/network.inspect_test.go +++ b/network/network.inspect_test.go @@ -7,9 +7,9 @@ import ( "strings" "testing" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - apinetwork "github.com/docker/docker/api/types/network" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/network" ) @@ -24,11 +24,11 @@ func TestInspect(t *testing.T) { require.NoError(t, err) require.NotNil(t, inspect) - require.Contains(t, inspect.Labels, client.LabelBase) - require.Contains(t, inspect.Labels, client.LabelLang) - require.Contains(t, inspect.Labels, client.LabelVersion) - require.Contains(t, inspect.Labels, client.LabelBase+".network") - require.Equal(t, network.Version(), inspect.Labels[client.LabelBase+".network"]) + require.Contains(t, inspect.Network.Labels, client.LabelBase) + require.Contains(t, inspect.Network.Labels, client.LabelLang) + require.Contains(t, inspect.Network.Labels, client.LabelVersion) + require.Contains(t, inspect.Network.Labels, client.LabelBase+".network") + require.Equal(t, network.Version(), inspect.Network.Labels[client.LabelBase+".network"]) }) t.Run("network-does-not-exist", func(t *testing.T) { @@ -49,7 +49,7 @@ func TestInspect(t *testing.T) { require.NoError(t, err) // Create an invalid inspect option that will cause an error - invalidOption := network.WithInspectOptions(apinetwork.InspectOptions{ + invalidOption := network.WithInspectOptions(dockerclient.NetworkInspectOptions{ Scope: "invalid-scope", // Using an invalid scope value }) diff --git a/network/network.list.go b/network/network.list.go index 558e3b76..09851748 100644 --- a/network/network.list.go +++ b/network/network.list.go @@ -4,9 +4,11 @@ import ( "context" "errors" "fmt" + "maps" + + "github.com/moby/moby/api/types/network" + dockerclient "github.com/moby/moby/client" - "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/api/types/network" "github.com/docker/go-sdk/client" ) @@ -20,7 +22,7 @@ const ( type listOptions struct { client client.SDKClient - filters filters.Args + filters dockerclient.Filters } type ListOptions func(opts *listOptions) error @@ -34,47 +36,47 @@ func WithListClient(client client.SDKClient) ListOptions { } // WithFilters sets the filters to be used to filter the networks. -func WithFilters(filters filters.Args) ListOptions { +func WithFilters(filters dockerclient.Filters) ListOptions { return func(opts *listOptions) error { - opts.filters = filters + opts.filters = maps.Clone(filters) return nil } } // FindByID returns a network by its ID. -func FindByID(ctx context.Context, id string, opts ...ListOptions) (network.Inspect, error) { - opts = append(opts, WithFilters(filters.NewArgs(filters.Arg(filterByID, id)))) +func FindByID(ctx context.Context, id string, opts ...ListOptions) (network.Summary, error) { + opts = append(opts, WithFilters(make(dockerclient.Filters).Add(filterByID, id))) nws, err := list(ctx, opts...) if err != nil { - return network.Inspect{}, err + return network.Summary{}, err } return nws[0], nil } // FindByName returns a network by its name. -func FindByName(ctx context.Context, name string, opts ...ListOptions) (network.Inspect, error) { - opts = append(opts, WithFilters(filters.NewArgs(filters.Arg(filterByName, name)))) +func FindByName(ctx context.Context, name string, opts ...ListOptions) (network.Summary, error) { + opts = append(opts, WithFilters(make(dockerclient.Filters).Add(filterByName, name))) nws, err := list(ctx, opts...) if err != nil { - return network.Inspect{}, err + return network.Summary{}, err } return nws[0], nil } // List returns a list of networks. -func List(ctx context.Context, opts ...ListOptions) ([]network.Inspect, error) { +func List(ctx context.Context, opts ...ListOptions) ([]network.Summary, error) { return list(ctx, opts...) } -func list(ctx context.Context, opts ...ListOptions) ([]network.Inspect, error) { - var nws []network.Inspect // initialize to the zero value +func list(ctx context.Context, opts ...ListOptions) ([]network.Summary, error) { + var nws []network.Summary // initialize to the zero value initialOpts := &listOptions{ - filters: filters.NewArgs(), + filters: make(dockerclient.Filters), } for _, opt := range opts { if err := opt(initialOpts); err != nil { @@ -82,8 +84,8 @@ func list(ctx context.Context, opts ...ListOptions) ([]network.Inspect, error) { } } - nwOpts := network.ListOptions{} - if initialOpts.filters.Len() > 0 { + nwOpts := dockerclient.NetworkListOptions{} + if len(initialOpts.filters) > 0 { nwOpts.Filters = initialOpts.filters } @@ -100,11 +102,11 @@ func list(ctx context.Context, opts ...ListOptions) ([]network.Inspect, error) { return nws, fmt.Errorf("failed to list networks: %w", err) } - if len(list) == 0 { + if len(list.Items) == 0 { return nws, errors.New("no networks found") } - nws = append(nws, list...) + nws = append(nws, list.Items...) return nws, nil } diff --git a/network/network.list_test.go b/network/network.list_test.go index a164dc8a..761ba12f 100644 --- a/network/network.list_test.go +++ b/network/network.list_test.go @@ -4,9 +4,9 @@ import ( "context" "testing" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/filters" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/network" ) @@ -58,7 +58,9 @@ func TestList(t *testing.T) { }) t.Run("with-filters", func(t *testing.T) { - nws, err = network.List(context.Background(), network.WithFilters(filters.NewArgs(filters.Arg("driver", "bridge")))) + nws, err = network.List(context.Background(), + network.WithFilters(make(dockerclient.Filters).Add("driver", "bridge")), + ) require.NoError(t, err) require.Len(t, nws, 1) }) diff --git a/network/network.terminate.go b/network/network.terminate.go index c7ee7617..407bb8a3 100644 --- a/network/network.terminate.go +++ b/network/network.terminate.go @@ -5,6 +5,8 @@ import ( "errors" "fmt" "reflect" + + "github.com/moby/moby/client" ) // TerminableNetwork is a network that can be terminated. @@ -18,7 +20,7 @@ func (n *Network) Terminate(ctx context.Context) error { return errors.New("docker client is not initialized") } - if err := n.dockerClient.NetworkRemove(ctx, n.ID()); err != nil { + if _, err := n.dockerClient.NetworkRemove(ctx, n.ID(), client.NetworkRemoveOptions{}); err != nil { return fmt.Errorf("terminate network: %w", err) } diff --git a/network/network_examples_test.go b/network/network_examples_test.go index 318199ae..fc25093b 100644 --- a/network/network_examples_test.go +++ b/network/network_examples_test.go @@ -5,7 +5,8 @@ import ( "fmt" "runtime" - apinetwork "github.com/docker/docker/api/types/network" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/network" ) @@ -79,7 +80,7 @@ func ExampleNetwork_Inspect() { inspect, err := nw.Inspect(context.Background()) fmt.Println(err) - fmt.Println(inspect.Name) + fmt.Println(inspect.Network.Name) err = nw.Terminate(context.Background()) fmt.Println(err) @@ -99,13 +100,13 @@ func ExampleNetwork_Inspect_withOptions() { inspect, err := nw.Inspect( context.Background(), network.WithNoCache(), - network.WithInspectOptions(apinetwork.InspectOptions{ + network.WithInspectOptions(dockerclient.NetworkInspectOptions{ Verbose: true, Scope: "local", }), ) fmt.Println(err) - fmt.Println(inspect.Name) + fmt.Println(inspect.Network.Name) err = nw.Terminate(context.Background()) fmt.Println(err) diff --git a/network/network_test.go b/network/network_test.go index 2919fcf1..2665a731 100644 --- a/network/network_test.go +++ b/network/network_test.go @@ -2,12 +2,13 @@ package network_test import ( "context" + "net/netip" "runtime" "testing" + apinetwork "github.com/moby/moby/api/types/network" "github.com/stretchr/testify/require" - apinetwork "github.com/docker/docker/api/types/network" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/network" ) @@ -66,8 +67,8 @@ func newNetworkSuite(t *testing.T, dockerClient client.SDKClient) { Driver: "default", Config: []apinetwork.IPAMConfig{ { - Subnet: "10.1.1.0/24", - Gateway: "10.1.1.254", + Subnet: netip.MustParsePrefix("10.1.1.0/24"), + Gateway: netip.MustParseAddr("10.1.1.254"), }, }, Options: map[string]string{ @@ -134,9 +135,9 @@ func newNetworkSuite(t *testing.T, dockerClient client.SDKClient) { require.NoError(t, err) require.NotNil(t, inspect) - require.Contains(t, inspect.Labels, client.LabelBase) - require.Contains(t, inspect.Labels, client.LabelLang) - require.Contains(t, inspect.Labels, client.LabelVersion) + require.Contains(t, inspect.Network.Labels, client.LabelBase) + require.Contains(t, inspect.Network.Labels, client.LabelLang) + require.Contains(t, inspect.Network.Labels, client.LabelVersion) }) } diff --git a/network/options.go b/network/options.go index a197fd8a..8d06d7ad 100644 --- a/network/options.go +++ b/network/options.go @@ -3,7 +3,8 @@ package network import ( "errors" - "github.com/docker/docker/api/types/network" + "github.com/moby/moby/api/types/network" + "github.com/docker/go-sdk/client" ) diff --git a/network/testing.go b/network/testing.go index 527017a5..49da24db 100644 --- a/network/testing.go +++ b/network/testing.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/containerd/errdefs" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/network" "github.com/docker/go-sdk/client" ) @@ -61,7 +61,7 @@ func CleanupByID(tb testing.TB, id string) { // synthetic network using a new docker client. nw := &Network{ - response: network.CreateResponse{ + response: dockerclient.NetworkCreateResult{ ID: id, }, dockerClient: dockerClient, diff --git a/network/types.go b/network/types.go index d4afbff0..3cef355c 100644 --- a/network/types.go +++ b/network/types.go @@ -1,14 +1,15 @@ package network import ( - "github.com/docker/docker/api/types/network" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/client" ) // Network represents a Docker network. type Network struct { - response network.CreateResponse - inspect network.Inspect + response dockerclient.NetworkCreateResult + inspect dockerclient.NetworkInspectResult dockerClient client.SDKClient opts *options name string diff --git a/volume/README.md b/volume/README.md index d0fa158f..724c2ca6 100644 --- a/volume/README.md +++ b/volume/README.md @@ -30,7 +30,7 @@ if err != nil { } fmt.Printf("volume: %+v", vol) -vols, err := volume.List(context.Background(), volume.WithFilters(filters.NewArgs(filters.Arg("label", "volume.type=example-test")))) +vols, err := volume.List(context.Background(), make(client.Filters).Add("label", "volume.type=example-test")) if err != nil { log.Println(err) return @@ -62,4 +62,4 @@ When terminating a volume, the `Terminate` function can be customized using func When finding a volume, the `FindByID` and `List` functions can be customized using functional options. The following options are available: - `WithFindClient(client *client.Client) volume.FindOptions`: The client to use to find the volume. If not provided, the default client will be used. -- `WithFilters(filters filters.Args) volume.FindOptions`: The filters to use to find the volume. In the case of the `FindByID` function, this option is ignored. +- `WithFilters(filters client.Filters) volume.FindOptions`: The filters to use to find the volume. In the case of the `FindByID` function, this option is ignored. diff --git a/volume/go.mod b/volume/go.mod index eef01979..6d9c8bce 100644 --- a/volume/go.mod +++ b/volume/go.mod @@ -1,6 +1,6 @@ module github.com/docker/go-sdk/volume -go 1.24 +go 1.24.0 replace ( github.com/docker/go-sdk/client => ../client @@ -10,43 +10,34 @@ replace ( require ( github.com/containerd/errdefs v1.0.0 - github.com/docker/docker v28.3.2+incompatible github.com/docker/go-sdk/client v0.1.0-alpha011 + github.com/moby/moby/api v1.52.0 + github.com/moby/moby/client v0.1.0 github.com/stretchr/testify v1.10.0 ) require ( - github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/caarlos0/env/v11 v11.3.1 // indirect - github.com/cenkalti/backoff/v5 v5.0.2 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/go-connections v0.5.0 // indirect + github.com/docker/go-connections v0.6.0 // indirect github.com/docker/go-sdk/config v0.1.0-alpha011 // indirect github.com/docker/go-sdk/context v0.1.0-alpha011 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/sys/sequential v0.6.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect go.opentelemetry.io/otel v1.37.0 // indirect go.opentelemetry.io/otel/metric v1.37.0 // indirect go.opentelemetry.io/otel/trace v1.37.0 // indirect - golang.org/x/net v0.40.0 // indirect golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.26.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 // indirect - google.golang.org/protobuf v1.36.6 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/volume/go.sum b/volume/go.sum index 1c8658ec..08a9ebae 100644 --- a/volume/go.sum +++ b/volume/go.sum @@ -1,25 +1,17 @@ -github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= -github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/caarlos0/env/v11 v11.3.1 h1:cArPWC15hWmEt+gWk7YBi7lEXTXCvpaSdCiZE2X5mCA= github.com/caarlos0/env/v11 v11.3.1/go.mod h1:qupehSf/Y0TUTsxKywqRt/vJjN5nz6vauiYEUUr8P4U= -github.com/cenkalti/backoff/v5 v5.0.2 h1:rIfFVxEf1QsI7E1ZHfp/B4DF/6QBAUhmgkxc0H7Zss8= -github.com/cenkalti/backoff/v5 v5.0.2/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v28.3.2+incompatible h1:wn66NJ6pWB1vBZIilP8G3qQPqHy5XymfYn5vsqeA5oA= -github.com/docker/docker v28.3.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= -github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -29,56 +21,36 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1/go.mod h1:Zanoh4+gvIgluNqcfMVTJueD4wSS5hT7zTt4Mrutd90= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/sys/atomicwriter v0.1.0 h1:kw5D/EqkBwsBFi0ss9v1VG3wIkVhzGvLklJ+w3A14Sw= -github.com/moby/sys/atomicwriter v0.1.0/go.mod h1:Ul8oqv2ZMNHOceF643P6FKPXeCmYtlQMvpizfsSoaWs= -github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= -github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= -github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= -github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= -github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg= +github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc= +github.com/moby/moby/client v0.1.0 h1:nt+hn6O9cyJQqq5UWnFGqsZRTS/JirUqzPjEl0Bdc/8= +github.com/moby/moby/client v0.1.0/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= -github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 h1:F7Jx+6hwnZ41NSFTO5q4LYDtJRXBf2PD0rNBkeB/lus= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0/go.mod h1:UHB22Z8QsdRDrnAtX4PntOl36ajSxcdUMt1sF7Y6E7Q= go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ= go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0 h1:nRVXXvf78e00EwY6Wp0YII8ww2JVWshZ20HfTlE11AM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.36.0/go.mod h1:r49hO7CgrxY9Voaj3Xe8pANWtr0Oq916d0XAmOoCZAQ= go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE= go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E= go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI= @@ -87,50 +59,8 @@ go.opentelemetry.io/otel/sdk/metric v1.36.0 h1:r0ntwwGosWGaa0CrSt8cuNuTcccMXERFw go.opentelemetry.io/otel/sdk/metric v1.36.0/go.mod h1:qTNOhFDfKRwX0yXOqJYegL5WRaW376QbB7P4Pb0qva4= go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4= go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0= -go.opentelemetry.io/proto/otlp v1.7.0 h1:jX1VolD6nHuFzOYso2E73H85i92Mv8JQYk0K9vz09os= -go.opentelemetry.io/proto/otlp v1.7.0/go.mod h1:fSKjH6YJ7HDlwzltzyMj036AJ3ejJLCgCSHGj4efDDo= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw= golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= -golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= -golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= -golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822 h1:oWVWY3NzT7KJppx2UKhKmzPq4SRe0LdCijVRwvGeikY= -google.golang.org/genproto/googleapis/api v0.0.0-20250603155806-513f23925822/go.mod h1:h3c4v36UTKzUiuaOKQ6gr3S+0hovBtUrXzTG/i3+XEc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822 h1:fc6jSaCT0vBduLYZHYrBBNY4dsWuvgyff9noRNDdBeE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250603155806-513f23925822/go.mod h1:qQ0YXyHHx3XkvlzUtpXDkS29lDSafHMZBAZDc03LQ3A= -google.golang.org/grpc v1.73.0 h1:VIWSmpI2MegBtTuFt5/JWy2oXxtjJ/e89Z70ImfD2ok= -google.golang.org/grpc v1.73.0/go.mod h1:50sbHOUqWoCQGI8V2HQLJM0B+LMlIUjNSZmow7EVBQc= -google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY= -google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -138,3 +68,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= diff --git a/volume/options.go b/volume/options.go index b94b779d..c5504d5c 100644 --- a/volume/options.go +++ b/volume/options.go @@ -1,7 +1,10 @@ package volume import ( - "github.com/docker/docker/api/types/filters" + "maps" + + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/client" ) @@ -54,7 +57,7 @@ func WithForce() TerminateOption { type findOptions struct { client client.SDKClient - filters filters.Args + filters dockerclient.Filters } // FindOptions is a function that modifies the find options @@ -70,9 +73,9 @@ func WithFindClient(dockerClient client.SDKClient) FindOptions { } // WithFilters sets the filters to be used to filter the volumes. -func WithFilters(filters filters.Args) FindOptions { +func WithFilters(filters dockerclient.Filters) FindOptions { return func(opts *findOptions) error { - opts.filters = filters + opts.filters = maps.Clone(filters) return nil } } diff --git a/volume/testing.go b/volume/testing.go index 3b03d7bc..89436097 100644 --- a/volume/testing.go +++ b/volume/testing.go @@ -7,9 +7,9 @@ import ( "testing" "github.com/containerd/errdefs" + "github.com/moby/moby/api/types/volume" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/volume" "github.com/docker/go-sdk/client" ) diff --git a/volume/types.go b/volume/types.go index 357091ef..70856b18 100644 --- a/volume/types.go +++ b/volume/types.go @@ -1,13 +1,14 @@ package volume import ( - "github.com/docker/docker/api/types/volume" + dockervolume "github.com/moby/moby/api/types/volume" + "github.com/docker/go-sdk/client" ) // Volume represents a Docker volume. type Volume struct { - *volume.Volume + *dockervolume.Volume dockerClient client.SDKClient } diff --git a/volume/volume.find.go b/volume/volume.find.go index 699c2b59..0f075bf9 100644 --- a/volume/volume.find.go +++ b/volume/volume.find.go @@ -3,8 +3,8 @@ package volume import ( "context" - "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/api/types/volume" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/client" ) @@ -25,13 +25,13 @@ func FindByID(ctx context.Context, volumeID string, opts ...FindOptions) (*Volum findOpts.client = sdk } - v, err := findOpts.client.VolumeInspect(ctx, volumeID) + v, err := findOpts.client.VolumeInspect(ctx, volumeID, dockerclient.VolumeInspectOptions{}) if err != nil { return nil, err } return &Volume{ - Volume: &v, + Volume: &v.Volume, dockerClient: findOpts.client, }, nil } @@ -39,7 +39,7 @@ func FindByID(ctx context.Context, volumeID string, opts ...FindOptions) (*Volum // List lists volumes. func List(ctx context.Context, opts ...FindOptions) ([]Volume, error) { findOpts := &findOptions{ - filters: filters.NewArgs(), + filters: dockerclient.Filters{}, } for _, opt := range opts { if err := opt(findOpts); err != nil { @@ -55,17 +55,17 @@ func List(ctx context.Context, opts ...FindOptions) ([]Volume, error) { findOpts.client = sdk } - response, err := findOpts.client.VolumeList(ctx, volume.ListOptions{ + response, err := findOpts.client.VolumeList(ctx, dockerclient.VolumeListOptions{ Filters: findOpts.filters, }) if err != nil { return nil, err } - volumes := make([]Volume, len(response.Volumes)) - for i, v := range response.Volumes { + volumes := make([]Volume, len(response.Items)) + for i, v := range response.Items { volumes[i] = Volume{ - Volume: v, + Volume: &v, dockerClient: findOpts.client, } } diff --git a/volume/volume.find_test.go b/volume/volume.find_test.go index 4bbaaf5f..774a0b5f 100644 --- a/volume/volume.find_test.go +++ b/volume/volume.find_test.go @@ -6,9 +6,9 @@ import ( "testing" "github.com/containerd/errdefs" + dockerclient "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/filters" "github.com/docker/go-sdk/client" "github.com/docker/go-sdk/volume" ) @@ -58,7 +58,7 @@ func TestList(t *testing.T) { volume.Cleanup(t, v) require.NoError(t, err) - vols, err := volume.List(context.Background(), volume.WithFilters(filters.NewArgs(filters.Arg("name", v.Name)))) + vols, err := volume.List(context.Background(), volume.WithFilters(make(dockerclient.Filters).Add("name", v.Name))) require.NoError(t, err) require.Len(t, vols, 1) require.Equal(t, v.Name, vols[0].Name) @@ -95,14 +95,14 @@ func TestList(t *testing.T) { volume.Cleanup(t, v) require.NoError(t, err) - vols, err := volume.List(context.Background(), volume.WithFilters(filters.NewArgs(filters.Arg("label", "volume.type=test")))) + vols, err := volume.List(context.Background(), volume.WithFilters(make(dockerclient.Filters).Add("label", "volume.type=test"))) require.NoError(t, err) require.Len(t, vols, 1) require.Equal(t, v.Name, vols[0].Name) }) t.Run("EMPTY", func(t *testing.T) { - vols, err := volume.List(context.Background(), volume.WithFilters(filters.NewArgs(filters.Arg("label", "volume.type=FOO")))) + vols, err := volume.List(context.Background(), volume.WithFilters(make(dockerclient.Filters).Add("label", "volume.type=FOO"))) require.NoError(t, err) require.Empty(t, vols) }) diff --git a/volume/volume.go b/volume/volume.go index 08742e12..bda0bc36 100644 --- a/volume/volume.go +++ b/volume/volume.go @@ -4,7 +4,8 @@ import ( "context" "fmt" - "github.com/docker/docker/api/types/volume" + dockerclient "github.com/moby/moby/client" + "github.com/docker/go-sdk/client" ) @@ -32,7 +33,7 @@ func New(ctx context.Context, opts ...Option) (*Volume, error) { volumeOptions.labels[moduleLabel] = Version() - v, err := volumeOptions.client.VolumeCreate(ctx, volume.CreateOptions{ + v, err := volumeOptions.client.VolumeCreate(ctx, dockerclient.VolumeCreateOptions{ Name: volumeOptions.name, Labels: volumeOptions.labels, }) @@ -41,7 +42,7 @@ func New(ctx context.Context, opts ...Option) (*Volume, error) { } return &Volume{ - Volume: &v, + Volume: &v.Volume, dockerClient: volumeOptions.client, }, nil } diff --git a/volume/volume.terminate.go b/volume/volume.terminate.go index ea451f8a..bd1037c6 100644 --- a/volume/volume.terminate.go +++ b/volume/volume.terminate.go @@ -3,6 +3,8 @@ package volume import ( "context" "fmt" + + "github.com/moby/moby/client" ) // TerminableVolume is a volume that can be terminated. @@ -19,5 +21,6 @@ func (v *Volume) Terminate(ctx context.Context, opts ...TerminateOption) error { } } - return v.dockerClient.VolumeRemove(ctx, v.Name, terminateOptions.force) + _, err := v.dockerClient.VolumeRemove(ctx, v.Name, client.VolumeRemoveOptions{Force: terminateOptions.force}) + return err } diff --git a/volume/volume_benchmark_test.go b/volume/volume_benchmark_test.go index fca3e8e9..6cad127e 100644 --- a/volume/volume_benchmark_test.go +++ b/volume/volume_benchmark_test.go @@ -5,9 +5,9 @@ import ( "fmt" "testing" + "github.com/moby/moby/client" "github.com/stretchr/testify/require" - "github.com/docker/docker/api/types/filters" "github.com/docker/go-sdk/volume" ) @@ -82,7 +82,7 @@ func BenchmarkVolumeOperations(b *testing.B) { b.ReportAllocs() b.ResetTimer() for range b.N { - _, err := volume.List(context.Background(), volume.WithFilters(filters.NewArgs(filters.Arg("label", "volume.type=test")))) + _, err := volume.List(context.Background(), volume.WithFilters(make(client.Filters).Add("label", "volume.type=test"))) require.NoError(b, err) } }) diff --git a/volume/volume_examples_test.go b/volume/volume_examples_test.go index f05ecc1a..709e51ec 100644 --- a/volume/volume_examples_test.go +++ b/volume/volume_examples_test.go @@ -5,7 +5,8 @@ import ( "fmt" "log" - "github.com/docker/docker/api/types/filters" + "github.com/moby/moby/client" + "github.com/docker/go-sdk/volume" ) @@ -67,7 +68,7 @@ func ExampleList() { } }() - vols, err := volume.List(context.Background(), volume.WithFilters(filters.NewArgs(filters.Arg("label", "volume.type=example-test")))) + vols, err := volume.List(context.Background(), volume.WithFilters(make(client.Filters).Add("label", "volume.type=example-test"))) if err != nil { log.Println(err) return