Explorar o código

go.mod: bump github.com/moby/moby/api v1.53.0, moby/client v0.2.2

Also update TestDefaultNetworkSettings:
Test that the network with the highest priority is returned as
"primary" network, and other networks as extra networks.

Signed-off-by: Sebastiaan van Stijn <[email protected]>
Sebastiaan van Stijn hai 7 meses
pai
achega
bfb5511d0d
Modificáronse 71 ficheiros con 1822 adicións e 1925 borrados
  1. 1 1
      Makefile
  2. 2 2
      cmd/compose/bridge.go
  3. 0 11
      cmd/compose/compose.go
  4. 1 1
      cmd/compose/images.go
  5. 30 7
      cmd/compose/list.go
  6. 1 1
      cmd/compose/ps.go
  7. 6 7
      cmd/compose/stats.go
  8. 14 7
      cmd/formatter/container.go
  9. 1 1
      cmd/formatter/logs.go
  10. 30 31
      go.mod
  11. 135 209
      go.sum
  12. 1 1
      internal/sync/tar.go
  13. 1 1
      internal/tracing/attributes.go
  14. 5 4
      pkg/api/api.go
  15. 17 11
      pkg/bridge/convert.go
  16. 21 17
      pkg/bridge/transformers.go
  17. 8 7
      pkg/compose/attach.go
  18. 2 2
      pkg/compose/build_bake.go
  19. 12 10
      pkg/compose/build_classic.go
  20. 3 3
      pkg/compose/commit.go
  21. 13 15
      pkg/compose/compose.go
  22. 3 3
      pkg/compose/container.go
  23. 16 18
      pkg/compose/containers.go
  24. 27 41
      pkg/compose/convergence.go
  25. 140 208
      pkg/compose/convergence_test.go
  26. 2 11
      pkg/compose/convert.go
  27. 35 13
      pkg/compose/cp.go
  28. 228 121
      pkg/compose/create.go
  29. 26 20
      pkg/compose/create_test.go
  30. 4 2
      pkg/compose/desktop.go
  31. 17 16
      pkg/compose/down.go
  32. 148 144
      pkg/compose/down_test.go
  33. 6 8
      pkg/compose/events.go
  34. 1 1
      pkg/compose/exec.go
  35. 2 1
      pkg/compose/export.go
  36. 13 17
      pkg/compose/filters.go
  37. 17 22
      pkg/compose/generate.go
  38. 14 10
      pkg/compose/hook.go
  39. 12 17
      pkg/compose/image_pruner.go
  40. 7 8
      pkg/compose/images.go
  41. 17 15
      pkg/compose/images_test.go
  42. 5 2
      pkg/compose/kill.go
  43. 43 35
      pkg/compose/kill_test.go
  44. 9 8
      pkg/compose/logs.go
  45. 31 23
      pkg/compose/logs_test.go
  46. 6 6
      pkg/compose/ls.go
  47. 1 1
      pkg/compose/ls_test.go
  48. 11 16
      pkg/compose/monitor.go
  49. 4 3
      pkg/compose/pause.go
  50. 2 2
      pkg/compose/port.go
  51. 14 8
      pkg/compose/ps.go
  52. 19 19
      pkg/compose/ps_test.go
  53. 22 9
      pkg/compose/pull.go
  54. 8 7
      pkg/compose/push.go
  55. 5 4
      pkg/compose/remove.go
  56. 4 3
      pkg/compose/restart.go
  57. 5 4
      pkg/compose/run.go
  58. 6 3
      pkg/compose/secrets.go
  59. 1 1
      pkg/compose/shellout.go
  60. 5 9
      pkg/compose/start.go
  61. 17 17
      pkg/compose/stop_test.go
  62. 4 1
      pkg/compose/top.go
  63. 4 3
      pkg/compose/up.go
  64. 11 12
      pkg/compose/volumes.go
  65. 15 17
      pkg/compose/volumes_test.go
  66. 4 5
      pkg/compose/wait.go
  67. 27 27
      pkg/compose/watch.go
  68. 18 15
      pkg/compose/watch_test.go
  69. 230 272
      pkg/dryrun/dryrunclient.go
  70. 251 329
      pkg/mocks/mock_docker_api.go
  71. 1 19
      pkg/mocks/mock_docker_cli.go

+ 1 - 1
Makefile

@@ -95,7 +95,7 @@ example-provider: ## build example provider for e2e tests
 mocks:
 	mockgen --version >/dev/null 2>&1 || go install go.uber.org/mock/[email protected]
 	mockgen -destination pkg/mocks/mock_docker_cli.go -package mocks github.com/docker/cli/cli/command Cli
-	mockgen -destination pkg/mocks/mock_docker_api.go -package mocks github.com/docker/docker/client APIClient
+	mockgen -destination pkg/mocks/mock_docker_api.go -package mocks github.com/moby/moby/client APIClient
 	mockgen -destination pkg/mocks/mock_docker_compose_api.go -package mocks -source=./pkg/api/api.go Service
 
 .PHONY: e2e

+ 2 - 2
cmd/compose/bridge.go

@@ -23,9 +23,9 @@ import (
 
 	"github.com/distribution/reference"
 	"github.com/docker/cli/cli/command"
-	"github.com/docker/docker/api/types/image"
-	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/go-units"
+	"github.com/moby/moby/api/types/image"
+	"github.com/moby/moby/client/pkg/stringid"
 	"github.com/spf13/cobra"
 
 	"github.com/docker/compose/v5/cmd/formatter"

+ 0 - 11
cmd/compose/compose.go

@@ -35,7 +35,6 @@ import (
 	composepaths "github.com/compose-spec/compose-go/v2/paths"
 	"github.com/compose-spec/compose-go/v2/types"
 	composegoutils "github.com/compose-spec/compose-go/v2/utils"
-	"github.com/docker/buildx/util/logutil"
 	dockercli "github.com/docker/cli/cli"
 	"github.com/docker/cli/cli-plugins/metadata"
 	"github.com/docker/cli/cli/command"
@@ -423,16 +422,6 @@ func (o *BackendOptions) Add(option compose.Option) {
 
 // RootCommand returns the compose command with its child commands
 func RootCommand(dockerCli command.Cli, backendOptions *BackendOptions) *cobra.Command { //nolint:gocyclo
-	// filter out useless commandConn.CloseWrite warning message that can occur
-	// when using a remote context that is unreachable: "commandConn.CloseWrite: commandconn: failed to wait: signal: killed"
-	// https://github.com/docker/cli/blob/e1f24d3c93df6752d3c27c8d61d18260f141310c/cli/connhelper/commandconn/commandconn.go#L203-L215
-	logrus.AddHook(logutil.NewFilter([]logrus.Level{
-		logrus.WarnLevel,
-	},
-		"commandConn.CloseWrite:",
-		"commandConn.CloseRead:",
-	))
-
 	opts := ProjectOptions{}
 	var (
 		ansi     string

+ 1 - 1
cmd/compose/images.go

@@ -27,8 +27,8 @@ import (
 
 	"github.com/containerd/platforms"
 	"github.com/docker/cli/cli/command"
-	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/go-units"
+	"github.com/moby/moby/client/pkg/stringid"
 	"github.com/spf13/cobra"
 
 	"github.com/docker/compose/v5/cmd/formatter"

+ 30 - 7
cmd/compose/list.go

@@ -18,12 +18,15 @@ package compose
 
 import (
 	"context"
+	"errors"
 	"fmt"
 	"io"
+	"regexp"
 	"strings"
 
 	"github.com/docker/cli/cli/command"
 	"github.com/docker/cli/opts"
+	"github.com/moby/moby/client"
 	"github.com/spf13/cobra"
 
 	"github.com/docker/compose/v5/cmd/formatter"
@@ -61,11 +64,32 @@ var acceptedListFilters = map[string]bool{
 	"name": true,
 }
 
+// match returns true if any of the values at key match the source string
+func match(filters client.Filters, field, source string) bool {
+	if f, ok := filters[field]; ok && f[source] {
+		return true
+	}
+
+	fieldValues := filters[field]
+	for name2match := range fieldValues {
+		isMatch, err := regexp.MatchString(name2match, source)
+		if err != nil {
+			continue
+		}
+		if isMatch {
+			return true
+		}
+	}
+	return false
+}
+
 func runList(ctx context.Context, dockerCli command.Cli, backendOptions *BackendOptions, lsOpts lsOptions) error {
 	filters := lsOpts.Filter.Value()
-	err := filters.Validate(acceptedListFilters)
-	if err != nil {
-		return err
+
+	for filter := range filters {
+		if _, ok := acceptedListFilters[filter]; !ok {
+			return errors.New("invalid filter '" + filter + "'")
+		}
 	}
 
 	backend, err := compose.NewComposeService(dockerCli, backendOptions.Options...)
@@ -77,13 +101,12 @@ func runList(ctx context.Context, dockerCli command.Cli, backendOptions *Backend
 		return err
 	}
 
-	if filters.Len() > 0 {
+	if len(filters) > 0 {
 		var filtered []api.Stack
 		for _, s := range stackList {
-			if filters.Contains("name") && !filters.Match("name", s.Name) {
-				continue
+			if match(filters, "name", s.Name) {
+				filtered = append(filtered, s)
 			}
-			filtered = append(filtered, s)
 		}
 		stackList = filtered
 	}

+ 1 - 1
cmd/compose/ps.go

@@ -176,7 +176,7 @@ func filterByStatus(containers []api.ContainerSummary, statuses []string) []api.
 
 func hasStatus(c api.ContainerSummary, statuses []string) bool {
 	for _, status := range statuses {
-		if c.State == status {
+		if string(c.State) == status {
 			return true
 		}
 	}

+ 6 - 7
cmd/compose/stats.go

@@ -22,7 +22,7 @@ import (
 
 	"github.com/docker/cli/cli/command"
 	"github.com/docker/cli/cli/command/container"
-	"github.com/docker/docker/api/types/filters"
+	"github.com/moby/moby/client"
 	"github.com/spf13/cobra"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -67,18 +67,17 @@ func runStats(ctx context.Context, dockerCli command.Cli, opts statsOptions, ser
 	if err != nil {
 		return err
 	}
-	filter := []filters.KeyValuePair{
-		filters.Arg("label", fmt.Sprintf("%s=%s", api.ProjectLabel, name)),
-	}
+	f := client.Filters{}
+	f.Add("label", fmt.Sprintf("%s=%s", api.ProjectLabel, name))
+
 	if len(service) > 0 {
-		filter = append(filter, filters.Arg("label", fmt.Sprintf("%s=%s", api.ServiceLabel, service[0])))
+		f.Add("label", fmt.Sprintf("%s=%s", api.ServiceLabel, service[0]))
 	}
-	args := filters.NewArgs(filter...)
 	return container.RunStats(ctx, dockerCli, &container.StatsOptions{
 		All:      opts.all,
 		NoStream: opts.noStream,
 		NoTrunc:  opts.noTrunc,
 		Format:   opts.format,
-		Filters:  &args,
+		Filters:  f,
 	})
 }

+ 14 - 7
cmd/formatter/container.go

@@ -18,14 +18,15 @@ package formatter
 
 import (
 	"fmt"
+	"net/netip"
 	"strconv"
 	"strings"
 	"time"
 
 	"github.com/docker/cli/cli/command/formatter"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/pkg/stringid"
 	"github.com/docker/go-units"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client/pkg/stringid"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
@@ -197,7 +198,7 @@ func (c *ContainerContext) ExitCode() int {
 }
 
 func (c *ContainerContext) State() string {
-	return c.c.State
+	return string(c.c.State)
 }
 
 func (c *ContainerContext) Status() string {
@@ -205,7 +206,7 @@ func (c *ContainerContext) Status() string {
 }
 
 func (c *ContainerContext) Health() string {
-	return c.c.Health
+	return string(c.c.Health)
 }
 
 func (c *ContainerContext) Publishers() api.PortPublishers {
@@ -213,10 +214,16 @@ func (c *ContainerContext) Publishers() api.PortPublishers {
 }
 
 func (c *ContainerContext) Ports() string {
-	var ports []container.Port
+	var ports []container.PortSummary
 	for _, publisher := range c.c.Publishers {
-		ports = append(ports, container.Port{
-			IP:          publisher.URL,
+		var pIP netip.Addr
+		if publisher.URL != "" {
+			if p, err := netip.ParseAddr(publisher.URL); err == nil {
+				pIP = p
+			}
+		}
+		ports = append(ports, container.PortSummary{
+			IP:          pIP,
 			PrivatePort: uint16(publisher.TargetPort),
 			PublicPort:  uint16(publisher.PublishedPort),
 			Type:        publisher.Protocol,

+ 1 - 1
cmd/formatter/logs.go

@@ -26,7 +26,7 @@ import (
 	"time"
 
 	"github.com/buger/goterm"
-	"github.com/docker/docker/pkg/jsonmessage"
+	"github.com/moby/moby/client/pkg/jsonmessage"
 
 	"github.com/docker/compose/v5/pkg/api"
 )

+ 30 - 31
go.mod

@@ -1,6 +1,6 @@
 module github.com/docker/compose/v5
 
-go 1.24.3
+go 1.25.0
 
 require (
 	github.com/AlecAivazis/survey/v2 v2.3.7
@@ -14,8 +14,8 @@ require (
 	github.com/containerd/errdefs v1.0.0
 	github.com/containerd/platforms v1.0.0-rc.2
 	github.com/distribution/reference v0.6.0
-	github.com/docker/buildx v0.30.1
-	github.com/docker/cli v28.5.2+incompatible
+	github.com/docker/buildx v0.31.1
+	github.com/docker/cli v29.2.1+incompatible
 	github.com/docker/cli-docs-tool v0.11.0
 	github.com/docker/docker v28.5.2+incompatible
 	github.com/docker/go-connections v0.6.0
@@ -29,8 +29,10 @@ require (
 	github.com/jonboulle/clockwork v0.5.0
 	github.com/mattn/go-shellwords v1.0.12
 	github.com/mitchellh/go-ps v1.0.0
-	github.com/moby/buildkit v0.26.3
-	github.com/moby/go-archive v0.1.0
+	github.com/moby/buildkit v0.27.1
+	github.com/moby/go-archive v0.2.0
+	github.com/moby/moby/api v1.53.0
+	github.com/moby/moby/client v0.2.2
 	github.com/moby/patternmatcher v0.6.0
 	github.com/moby/sys/atomicwriter v0.1.0
 	github.com/morikuni/aec v1.1.0
@@ -62,9 +64,7 @@ require (
 
 require (
 	github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
-	github.com/beorn7/perks v1.0.1 // indirect
 	github.com/cenkalti/backoff/v5 v5.0.3 // indirect
-	github.com/cespare/xxhash/v2 v2.3.0 // indirect
 	github.com/containerd/containerd/api v1.10.0 // indirect
 	github.com/containerd/continuity v0.4.5 // indirect
 	github.com/containerd/errdefs/pkg v0.3.0 // indirect
@@ -74,9 +74,7 @@ require (
 	github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect
 	github.com/davecgh/go-spew v1.1.1 // indirect
 	github.com/docker/distribution v2.8.3+incompatible // indirect
-	github.com/docker/docker-credential-helpers v0.9.3 // indirect
-	github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c // indirect
-	github.com/docker/go-metrics v0.0.1 // indirect
+	github.com/docker/docker-credential-helpers v0.9.5 // indirect
 	github.com/felixge/httpsnoop v1.0.4 // indirect
 	github.com/fvbommel/sortorder v1.1.0 // indirect
 	github.com/go-logr/logr v1.4.3 // indirect
@@ -87,22 +85,19 @@ require (
 	github.com/golang/protobuf v1.5.4 // indirect
 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
 	github.com/gorilla/mux v1.8.1 // indirect
-	github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 // indirect
+	github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 // indirect
 	github.com/hashicorp/errwrap v1.1.0 // indirect
 	github.com/hashicorp/go-multierror v1.1.1 // indirect
 	github.com/in-toto/in-toto-golang v0.9.0 // indirect
 	github.com/inconshreveable/mousetrap v1.1.0 // indirect
 	github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf // indirect
 	github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
-	github.com/klauspost/compress v1.18.2 // indirect
-	github.com/magiconair/properties v1.8.9 // indirect
+	github.com/klauspost/compress v1.18.3 // indirect
 	github.com/mattn/go-colorable v0.1.14 // indirect
 	github.com/mattn/go-isatty v0.0.20 // indirect
 	github.com/mattn/go-runewidth v0.0.16 // indirect
 	github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
-	github.com/miekg/pkcs11 v1.1.1 // indirect
 	github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
-	github.com/mitchellh/mapstructure v1.5.0 // indirect
 	github.com/moby/docker-image-spec v1.3.1 // indirect
 	github.com/moby/locker v1.0.1 // indirect
 	github.com/moby/sys/capability v0.4.0 // indirect
@@ -112,24 +107,20 @@ 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/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
 	github.com/otiai10/mint v1.6.3 // indirect
 	github.com/pelletier/go-toml v1.9.5 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/prometheus/client_golang v1.23.2 // indirect
-	github.com/prometheus/client_model v0.6.2 // indirect
-	github.com/prometheus/common v0.66.1 // indirect
-	github.com/prometheus/procfs v0.16.1 // indirect
-	github.com/rivo/uniseg v0.2.0 // indirect
+	github.com/rivo/uniseg v0.4.7 // indirect
 	github.com/russross/blackfriday/v2 v2.1.0 // indirect
 	github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect
 	github.com/secure-systems-lab/go-securesystemslib v0.9.1 // indirect
 	github.com/shibumi/go-pathspec v1.3.0 // indirect
-	github.com/theupdateframework/notary v0.7.0 // indirect
+	github.com/sigstore/sigstore v1.10.0 // indirect
+	github.com/sigstore/sigstore-go v1.1.4-0.20251124094504-b5fe07a5a7d7 // indirect
 	github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 // indirect
-	github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f // indirect
+	github.com/tonistiigi/fsutil v0.0.0-20251211185533-a2aa163d723f // indirect
 	github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 // indirect
 	github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea // indirect
 	github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab // indirect
@@ -142,16 +133,24 @@ require (
 	go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.38.0 // indirect
 	go.opentelemetry.io/otel/sdk/metric v1.38.0 // indirect
 	go.opentelemetry.io/proto/otlp v1.7.1 // indirect
-	go.yaml.in/yaml/v2 v2.4.2 // indirect
 	go.yaml.in/yaml/v3 v3.0.4 // indirect
-	golang.org/x/crypto v0.45.0 // indirect
-	golang.org/x/net v0.47.0 // indirect
-	golang.org/x/term v0.37.0 // indirect
-	golang.org/x/text v0.31.0 // indirect
+	golang.org/x/crypto v0.46.0 // indirect
+	golang.org/x/net v0.48.0 // indirect
+	golang.org/x/term v0.38.0 // indirect
+	golang.org/x/text v0.32.0 // indirect
 	golang.org/x/time v0.14.0 // indirect
-	google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda // indirect
-	google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect
-	google.golang.org/protobuf v1.36.10 // indirect
+	google.golang.org/genproto/googleapis/api v0.0.0-20251103181224-f26f9409b101 // indirect
+	google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101 // indirect
+	google.golang.org/protobuf v1.36.11 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
+
+exclude (
+	// FIXME(thaJeztah): remove this once kubernetes updated their dependencies to no longer need this.
+	//
+	// For additional details, see this PR and links mentioned in that PR:
+	// https://github.com/kubernetes-sigs/kustomize/pull/5830#issuecomment-2569960859
+	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc
+	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2
+)

+ 135 - 209
go.sum

@@ -1,11 +1,11 @@
+cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8=
+cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc=
 github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8afgbRMd7mFxO99hRNu+6tazq8nFF9lIwo9JFroBk=
 github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
 github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ=
 github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo=
 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/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
-github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e h1:rd4bOvKmDIx0WeTv9Qz+hghsgyjikFiPrseXHlKepO0=
 github.com/DefangLabs/secret-detector v0.0.0-20250403165618-22662109213e/go.mod h1:blbwPQh4DTlCZEfk1BLU4oMIhLda2U+A840Uag9DsZw=
 github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
@@ -14,36 +14,22 @@ github.com/Microsoft/hcsshim v0.14.0-rc.1 h1:qAPXKwGOkVn8LlqgBN8GS0bxZ83hOJpcjxz
 github.com/Microsoft/hcsshim v0.14.0-rc.1/go.mod h1:hTKFGbnDtQb1wHiOWv4v0eN+7boSWAHyK/tNAaYZL0c=
 github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s=
 github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w=
-github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d h1:hi6J4K6DKrR4/ljxn6SF6nURyu785wKMuQcjt7H3VCQ=
-github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
 github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
 github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
-github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
-github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
-github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 h1:aM1rlcoLz8y5B2r4tTLMiVTrMtpfY0O8EScKJxaSaEc=
-github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA=
-github.com/beorn7/perks v0.0.0-20150223135152-b965b613227f/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
-github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/anchore/go-struct-converter v0.1.0 h1:2rDRssAl6mgKBSLNiVCMADgZRhoqtw9dedlWa0OhD30=
+github.com/anchore/go-struct-converter v0.1.0/go.mod h1:rYqSE9HbjzpHTI74vwPvae4ZVYZd1lue2ta6xHPdblA=
+github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
+github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
 github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
-github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw=
-github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA=
-github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
+github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
+github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 github.com/buger/goterm v1.0.4 h1:Z9YvGmOih81P0FbVtEYTFF6YsSgxSUKEhf/f9bTMXbY=
 github.com/buger/goterm v1.0.4/go.mod h1:HiFWV3xnkolgrBV3mY8m0X0Pumt4zg4QhbdOzQtB8tE=
-github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0 h1:s7+5BfS4WFJoVF9pnB8kBk03S7pZXRdKamnV0FOl5Sc=
-github.com/bugsnag/bugsnag-go v1.0.5-0.20150529004307-13fd6b8acda0/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
-github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b h1:otBG+dV+YK+Soembjv71DPz3uX/V/6MMlSyD9JBQ6kQ=
-github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
-github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0 h1:nvj0OLI3YqYXer/kZD8Ri1aaunCxIEsOst1BVJswV0o=
-github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
 github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM=
 github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
 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/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ=
-github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA=
 github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb h1:EDmT6Q9Zs+SbUoc7Ik9EfrFqcylYqgPZ9ANSbTAntnE=
 github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AXHbDs86ZSdt/osfBi5qfexBrKUdONk989Wnk4=
 github.com/compose-spec/compose-go/v2 v2.10.1 h1:mFbXobojGRFIVi1UknrvaDAZ+PkJfyjqkA1yseh+vAU=
@@ -66,8 +52,8 @@ github.com/containerd/fifo v1.1.0 h1:4I2mbh5stb1u6ycIABlBw9zgtlK8viPI9QkQNRQEEmY
 github.com/containerd/fifo v1.1.0/go.mod h1:bmC4NWMbXlt2EZ0Hc7Fx7QzTFxgPID13eH0Qu+MAb2o=
 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/nydus-snapshotter v0.15.4 h1:l59kGRVMtwMLDLh322HsWhEsBCkRKMkGWYV5vBeLYCE=
-github.com/containerd/nydus-snapshotter v0.15.4/go.mod h1:eRJqnxQDr48HNop15kZdLZpFF5B6vf6Q11Aq1K0E4Ms=
+github.com/containerd/nydus-snapshotter v0.15.10 h1:hphjuKOqSHLGznNJiAvmsOWkdu4qFXjf4DzGrWSuIsM=
+github.com/containerd/nydus-snapshotter v0.15.10/go.mod h1:EWRd/QJ0b6UKHAqYgiV5gHlqLC2qq5cQiSlXEdVovrA=
 github.com/containerd/platforms v1.0.0-rc.2 h1:0SPgaNZPVWGEi4grZdV8VRYQn78y+nm6acgLGv/QzE4=
 github.com/containerd/platforms v1.0.0-rc.2/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4=
 github.com/containerd/plugin v1.0.0 h1:c8Kf1TNl6+e2TtMHZt+39yAPDbouRH9WAToRjex483Y=
@@ -82,103 +68,123 @@ github.com/containerd/typeurl/v2 v2.2.3/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsx
 github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
 github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo=
 github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
-github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 github.com/creack/pty v1.1.17/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/cyphar/filepath-securejoin v0.5.1 h1:eYgfMq5yryL4fbWfkLpFFy2ukSELzaJOTaUTuh+oF48=
-github.com/cyphar/filepath-securejoin v0.5.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
+github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q=
+github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
+github.com/cyphar/filepath-securejoin v0.6.0 h1:BtGB77njd6SVO6VztOHfPxKitJvd/VPT+OFBFMOi1Is=
+github.com/cyphar/filepath-securejoin v0.6.0/go.mod h1:A8hd4EnAeyujCJRrICiOWqjS1AX0a9kM5XL+NwKoYSc=
 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/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
+github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 h1:ge14PCmCvPjpMQMIAH7uKg0lrtNSOdpYsRXlwk3QbaE=
+github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352/go.mod h1:SKVExuS+vpu2l9IoOc0RwqE7NYnb0JlcFHFnEJkVDzc=
+github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 h1:lxmTCgmHE1GUYL7P0MlNa00M67axePTq+9nBSGddR8I=
+github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7/go.mod h1:GvWntX9qiTlOud0WkQ6ewFm0LPy5JUR1Xo0Ngbd1w6Y=
 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/dlclark/regexp2 v1.11.0 h1:G/nrcoOa7ZXlpoa/91N3X7mM3r8eIlMBBJZvsz/mxKI=
 github.com/dlclark/regexp2 v1.11.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
-github.com/docker/buildx v0.30.1 h1:3vthfaTQOLt5QfN2nl7rKuPLUvx69nL5ZikFIXp//c8=
-github.com/docker/buildx v0.30.1/go.mod h1:8nwT0V6UNYNo9rXq6WO/BQd9KrJ0JYcY/QX6x0y1Oro=
-github.com/docker/cli v28.5.2+incompatible h1:XmG99IHcBmIAoC1PPg9eLBZPlTrNUAijsHLm8PjhBlg=
-github.com/docker/cli v28.5.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/buildx v0.31.1 h1:zbvbrb9nxBNVV8nnI33f2F+4aAZBA1gY+AmeBFflMqY=
+github.com/docker/buildx v0.31.1/go.mod h1:SD+jYLnt3S4SXqohVtV+8z+dihnOgwMJ8t+bLQvsaCk=
+github.com/docker/cli v29.2.1+incompatible h1:n3Jt0QVCN65eiVBoUTZQM9mcQICCJt3akW4pKAbKdJg=
+github.com/docker/cli v29.2.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 github.com/docker/cli-docs-tool v0.11.0 h1:7d8QARFb7QEobizqxmEM7fOteZEHwH/zWgHQtHZEcfE=
 github.com/docker/cli-docs-tool v0.11.0/go.mod h1:ma8BKiisUo8D6W05XEYIh3oa1UbgrZhi1nowyKFJa8Q=
-github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk=
 github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
 github.com/docker/docker v28.5.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/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0=
-github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c/go.mod h1:CADgU4DSXK5QUlFslkQu2yW2TKzFZcXq/leZfM0UH5Q=
-github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
+github.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY=
+github.com/docker/docker-credential-helpers v0.9.5/go.mod h1:v1S+hepowrQXITkEfw6o4+BMbGot02wiKpzWhGUZK6c=
 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-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
 github.com/docker/go-metrics v0.0.1 h1:AgB/0SvBxihN0X8OR4SjsblXkbMvalQ8cjmtKQ2rQV8=
 github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw=
 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/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
-github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
-github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM=
 github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203 h1:XBBHcIb256gUJtLmY22n99HaZTz+r2Z51xUPi01m3wg=
 github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203/go.mod h1:E1jcSv8FaEny+OP/5k9UxZVw9YFWGj7eI4KR/iOBqCg=
-github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
 github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
 github.com/fsnotify/fsevents v0.2.0 h1:BRlvlqjvNTfogHfeBOFvSC9N0Ddy+wzQCQukyoD7o/c=
 github.com/fsnotify/fsevents v0.2.0/go.mod h1:B3eEk39i4hz8y1zaWS/wPrAP4O6wkIl7HQwKBr1qH/w=
-github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fvbommel/sortorder v1.1.0 h1:fUmoe+HLsBTctBDoaBwpQo5N+nrCp8g/BjKb/6ZQmYw=
 github.com/fvbommel/sortorder v1.1.0/go.mod h1:uk88iVf1ovNn1iLfgUVU2F9o5eO30ui720w+kxuqRs0=
-github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
-github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
-github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 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/go-sql-driver/mysql v1.3.0 h1:pgwjLi/dvffoP9aabwkT3AKpXQM93QARkjFhDDqC1UE=
-github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
-github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
+github.com/go-openapi/analysis v0.24.1 h1:Xp+7Yn/KOnVWYG8d+hPksOYnCYImE3TieBa7rBOesYM=
+github.com/go-openapi/analysis v0.24.1/go.mod h1:dU+qxX7QGU1rl7IYhBC8bIfmWQdX4Buoea4TGtxXY84=
+github.com/go-openapi/errors v0.22.4 h1:oi2K9mHTOb5DPW2Zjdzs/NIvwi2N3fARKaTJLdNabaM=
+github.com/go-openapi/errors v0.22.4/go.mod h1:z9S8ASTUqx7+CP1Q8dD8ewGH/1JWFFLX/2PmAYNQLgk=
+github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk=
+github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM=
+github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc=
+github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4=
+github.com/go-openapi/loads v0.23.2 h1:rJXAcP7g1+lWyBHC7iTY+WAF0rprtM+pm8Jxv1uQJp4=
+github.com/go-openapi/loads v0.23.2/go.mod h1:IEVw1GfRt/P2Pplkelxzj9BYFajiWOtY2nHZNj4UnWY=
+github.com/go-openapi/runtime v0.29.2 h1:UmwSGWNmWQqKm1c2MGgXVpC2FTGwPDQeUsBMufc5Yj0=
+github.com/go-openapi/runtime v0.29.2/go.mod h1:biq5kJXRJKBJxTDJXAa00DOTa/anflQPhT0/wmjuy+0=
+github.com/go-openapi/spec v0.22.1 h1:beZMa5AVQzRspNjvhe5aG1/XyBSMeX1eEOs7dMoXh/k=
+github.com/go-openapi/spec v0.22.1/go.mod h1:c7aeIQT175dVowfp7FeCvXXnjN/MrpaONStibD2WtDA=
+github.com/go-openapi/strfmt v0.25.0 h1:7R0RX7mbKLa9EYCTHRcCuIPcaqlyQiWNPTXwClK0saQ=
+github.com/go-openapi/strfmt v0.25.0/go.mod h1:nNXct7OzbwrMY9+5tLX4I21pzcmE6ccMGXl3jFdPfn8=
+github.com/go-openapi/swag v0.25.3 h1:FAa5wJXyDtI7yUztKDfZxDrSx+8WTg31MfCQ9s3PV+s=
+github.com/go-openapi/swag v0.25.3/go.mod h1:tX9vI8Mj8Ny+uCEk39I1QADvIPI7lkndX4qCsEqhkS8=
+github.com/go-openapi/swag/cmdutils v0.25.3 h1:EIwGxN143JCThNHnqfqs85R8lJcJG06qjJRZp3VvjLI=
+github.com/go-openapi/swag/cmdutils v0.25.3/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0=
+github.com/go-openapi/swag/conv v0.25.3 h1:PcB18wwfba7MN5BVlBIV+VxvUUeC2kEuCEyJ2/t2X7E=
+github.com/go-openapi/swag/conv v0.25.3/go.mod h1:n4Ibfwhn8NJnPXNRhBO5Cqb9ez7alBR40JS4rbASUPU=
+github.com/go-openapi/swag/fileutils v0.25.3 h1:P52Uhd7GShkeU/a1cBOuqIcHMHBrA54Z2t5fLlE85SQ=
+github.com/go-openapi/swag/fileutils v0.25.3/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk=
+github.com/go-openapi/swag/jsonname v0.25.3 h1:U20VKDS74HiPaLV7UZkztpyVOw3JNVsit+w+gTXRj0A=
+github.com/go-openapi/swag/jsonname v0.25.3/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag=
+github.com/go-openapi/swag/jsonutils v0.25.3 h1:kV7wer79KXUM4Ea4tBdAVTU842Rg6tWstX3QbM4fGdw=
+github.com/go-openapi/swag/jsonutils v0.25.3/go.mod h1:ILcKqe4HC1VEZmJx51cVuZQ6MF8QvdfXsQfiaCs0z9o=
+github.com/go-openapi/swag/loading v0.25.3 h1:Nn65Zlzf4854MY6Ft0JdNrtnHh2bdcS/tXckpSnOb2Y=
+github.com/go-openapi/swag/loading v0.25.3/go.mod h1:xajJ5P4Ang+cwM5gKFrHBgkEDWfLcsAKepIuzTmOb/c=
+github.com/go-openapi/swag/mangling v0.25.3 h1:rGIrEzXaYWuUW1MkFmG3pcH+EIA0/CoUkQnIyB6TUyo=
+github.com/go-openapi/swag/mangling v0.25.3/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg=
+github.com/go-openapi/swag/netutils v0.25.3 h1:XWXHZfL/65ABiv8rvGp9dtE0C6QHTYkCrNV77jTl358=
+github.com/go-openapi/swag/netutils v0.25.3/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg=
+github.com/go-openapi/swag/stringutils v0.25.3 h1:nAmWq1fUTWl/XiaEPwALjp/8BPZJun70iDHRNq/sH6w=
+github.com/go-openapi/swag/stringutils v0.25.3/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0=
+github.com/go-openapi/swag/typeutils v0.25.3 h1:2w4mEEo7DQt3V4veWMZw0yTPQibiL3ri2fdDV4t2TQc=
+github.com/go-openapi/swag/typeutils v0.25.3/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE=
+github.com/go-openapi/swag/yamlutils v0.25.3 h1:LKTJjCn/W1ZfMec0XDL4Vxh8kyAnv1orH5F2OREDUrg=
+github.com/go-openapi/swag/yamlutils v0.25.3/go.mod h1:Y7QN6Wc5DOBXK14/xeo1cQlq0EA0wvLoSv13gDQoCao=
+github.com/go-openapi/validate v0.25.1 h1:sSACUI6Jcnbo5IWqbYHgjibrhhmt3vR6lCzKZnmAgBw=
+github.com/go-openapi/validate v0.25.1/go.mod h1:RMVyVFYte0gbSTaZ0N4KmTn6u/kClvAFp+mAVfS/DQc=
 github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
 github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
 github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
 github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
-github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
-github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
 github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
 github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
-github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
 github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ=
 github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
-github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
 github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
 github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
-github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93 h1:jc2UWq7CbdszqeH6qu1ougXMIUBfSy8Pbh/anURYbGI=
-github.com/google/certificate-transparency-go v1.0.10-0.20180222191210-5ab67e519c93/go.mod h1:QeJfpSbVSfYc7RgB3gJFj9cbuQMMchQxrWXz8Ruopmg=
-github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
+github.com/google/certificate-transparency-go v1.3.2 h1:9ahSNZF2o7SYMaKaXhAumVEzXB2QaayzII9C8rv7v+A=
+github.com/google/certificate-transparency-go v1.3.2/go.mod h1:H5FpMUaGa5Ab2+KCYsxg6sELw3Flkl7pGZzWdBoYLXs=
 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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/go-containerregistry v0.20.6 h1:cvWX87UxxLgaH76b4hIvya6Dzz9qHB31qAwjAohdSTU=
+github.com/google/go-containerregistry v0.20.6/go.mod h1:T0x8MuoAoKX/873bkeSfLD2FAkwCDf9/HZgsFJ02E2Y=
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
 github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
 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/gorilla/mux v1.7.0/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
 github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
 github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2 h1:8Tjv8EJ+pM1xP8mK6egEbD1OgnVTyacbefKhmbLhIhU=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.2/go.mod h1:pkJQ2tZHJ0aFOVEEot6oZmaVEZcRme73eIFmhiVuRWs=
-github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=
-github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3 h1:NmZ1PKzSTQbuGHw9DGPFomqkkLWMC+vZCkfs+FHv1Vg=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.3/go.mod h1:zQrxl1YP88HQlA6i9c63DSVPFklWpGX4OWAc9bFuaH4=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
 github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
 github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -188,47 +194,26 @@ github.com/hashicorp/go-version v1.8.0 h1:KAkNb1HAiZd1ukkxDFGmokVZe1Xy9HG6NUp+bP
 github.com/hashicorp/go-version v1.8.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
 github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec h1:qv2VnGeEQHchGaZ/u7lxST/RaJw+cv273q79D81Xbog=
 github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68=
-github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/in-toto/attestation v1.1.2 h1:MBFn6lsMq6dptQZJBhalXTcWMb/aJy3V+GX3VYj/V1E=
+github.com/in-toto/attestation v1.1.2/go.mod h1:gYFddHMZj3DiQ0b62ltNi1Vj5rC879bTmBbrv9CRHpM=
 github.com/in-toto/in-toto-golang v0.9.0 h1:tHny7ac4KgtsfrG6ybU8gVOZux2H8jN05AXJ9EBM1XU=
 github.com/in-toto/in-toto-golang v0.9.0/go.mod h1:xsBVrVsHNsB61++S6Dy2vWosKhuA3lUTQd+eF9HdeMo=
-github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
 github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s=
 github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4=
-github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8 h1:CZkYfurY6KGhVtlalI4QwQ6T0Cu6iuY3e0x5RLu96WE=
-github.com/jinzhu/gorm v0.0.0-20170222002820-5409931a1bb8/go.mod h1:Vla75njaFJ8clLU1W44h34PjIkijhjHIYnZxMqCdxqo=
-github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d h1:jRQLvyVGL+iVtDElaEIDdKwpPqUIZJfzkNLV34htpEc=
-github.com/jinzhu/inflection v0.0.0-20170102125226-1c35d901db3d/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
-github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
 github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I=
 github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60=
-github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
-github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U=
-github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
 github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
 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.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
-github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
-github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
-github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
-github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/klauspost/compress v1.18.3 h1:9PJRvfbmTabkOX8moIpXPbMMbYN60bWImDDU7L+/6zw=
+github.com/klauspost/compress v1.18.3/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
 github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
 github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
-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/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
-github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
-github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/magiconair/properties v1.5.3/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
-github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM=
-github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
 github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
 github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
@@ -239,28 +224,24 @@ github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6T
 github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
 github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
-github.com/mattn/go-sqlite3 v1.6.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
-github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
-github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
-github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU=
-github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
 github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc=
 github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg=
 github.com/mitchellh/hashstructure/v2 v2.0.2 h1:vGKWl0YJqUNxE8d+h8f6NJLcCJrgbhC4NcD46KavDd4=
 github.com/mitchellh/hashstructure/v2 v2.0.2/go.mod h1:MG3aRVU/N29oo/V/IhBX8GR/zz4kQkprJgF2EVszyDE=
-github.com/mitchellh/mapstructure v0.0.0-20150613213606-2caf8efc9366/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
-github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
-github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
-github.com/moby/buildkit v0.26.3 h1:D+ruZVAk/3ipRq5XRxBH9/DIFpRjSlTtMbghT5gQP9g=
-github.com/moby/buildkit v0.26.3/go.mod h1:4T4wJzQS4kYWIfFRjsbJry4QoxDBjK+UGOEOs1izL7w=
+github.com/moby/buildkit v0.27.1 h1:qlIWpnZzqCkrYiGkctM1gBD/YZPOJTjtUdRBlI0oBOU=
+github.com/moby/buildkit v0.27.1/go.mod h1:99qLrCrIAFgEOiFnCi9Y0Wwp6/qA7QvZ3uq/6wF0IsI=
 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/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/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8=
+github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU=
 github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg=
 github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc=
+github.com/moby/moby/api v1.53.0 h1:PihqG1ncw4W+8mZs69jlwGXdaYBeb5brF6BL7mPIS/w=
+github.com/moby/moby/api v1.53.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
+github.com/moby/moby/client v0.2.2 h1:Pt4hRMCAIlyjL3cr8M5TrXCwKzguebPAc2do2ur7dEM=
+github.com/moby/moby/client v0.2.2/go.mod h1:2EkIPVNCqR05CMIzL1mfA07t0HvVUUOl85pasRz/GmQ=
 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=
@@ -281,70 +262,43 @@ 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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
-github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
-github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/morikuni/aec v1.1.0 h1:vBBl0pUnvi/Je71dsRrhMBtreIqNMYErSAbEeb8jrXQ=
 github.com/morikuni/aec v1.1.0/go.mod h1:xDRgiq/iw5l+zkao76YTKzKttOp2cwPEne25HDkJnBw=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
-github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
-github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
-github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg=
-github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
-github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
+github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
+github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
 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.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 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/opencontainers/runtime-spec v1.3.0 h1:YZupQUdctfhpZy3TM39nN9Ika5CBWT5diQ8ibYCRkxg=
 github.com/opencontainers/runtime-spec v1.3.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
 github.com/opencontainers/selinux v1.13.1 h1:A8nNeceYngH9Ow++M+VVEwJVpdFmrlxsN22F+ISDCJE=
 github.com/opencontainers/selinux v1.13.1/go.mod h1:S10WXZ/osk2kWOYKy1x2f/eXF5ZHJoUs8UU/2caNRbg=
-github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
-github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
 github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
 github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
 github.com/otiai10/mint v1.6.3/go.mod h1:MJm72SBthJjz8qhefc4z1PYEieWmy8Bku7CjcAqyUSM=
 github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
 github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
-github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
-github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 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.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/prometheus/client_golang v0.9.0-pre1.0.20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
-github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
-github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
 github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
 github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
-github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
-github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
 github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
-github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
-github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
-github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
 github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs=
 github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA=
-github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
-github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
-github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
-github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
-github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
-github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
+github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0=
+github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw=
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
+github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
+github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
 github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
 github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
 github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
@@ -355,52 +309,53 @@ github.com/secure-systems-lab/go-securesystemslib v0.9.1 h1:nZZaNz4DiERIQguNy0cL
 github.com/secure-systems-lab/go-securesystemslib v0.9.1/go.mod h1:np53YzT0zXGMv6x4iEWc9Z59uR+x+ndLwCLqPYpLXVU=
 github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI=
 github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE=
-github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
-github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sigstore/protobuf-specs v0.5.0 h1:F8YTI65xOHw70NrvPwJ5PhAzsvTnuJMGLkA4FIkofAY=
+github.com/sigstore/protobuf-specs v0.5.0/go.mod h1:+gXR+38nIa2oEupqDdzg4qSBT0Os+sP7oYv6alWewWc=
+github.com/sigstore/rekor v1.4.3 h1:2+aw4Gbgumv8vYM/QVg6b+hvr4x4Cukur8stJrVPKU0=
+github.com/sigstore/rekor v1.4.3/go.mod h1:o0zgY087Q21YwohVvGwV9vK1/tliat5mfnPiVI3i75o=
+github.com/sigstore/rekor-tiles/v2 v2.0.1 h1:1Wfz15oSRNGF5Dzb0lWn5W8+lfO50ork4PGIfEKjZeo=
+github.com/sigstore/rekor-tiles/v2 v2.0.1/go.mod h1:Pjsbhzj5hc3MKY8FfVTYHBUHQEnP0ozC4huatu4x7OU=
+github.com/sigstore/sigstore v1.10.0 h1:lQrmdzqlR8p9SCfWIpFoGUqdXEzJSZT2X+lTXOMPaQI=
+github.com/sigstore/sigstore v1.10.0/go.mod h1:Ygq+L/y9Bm3YnjpJTlQrOk/gXyrjkpn3/AEJpmk1n9Y=
+github.com/sigstore/sigstore-go v1.1.4-0.20251124094504-b5fe07a5a7d7 h1:94NLPmq4bxvdmslzcG670IOkrlS98CGpmob8cjpFHuI=
+github.com/sigstore/sigstore-go v1.1.4-0.20251124094504-b5fe07a5a7d7/go.mod h1:4r/PNX0G7uzkLpc3PSdYs5E2k4bWEJNXTK6kwAyw9TM=
+github.com/sigstore/timestamp-authority/v2 v2.0.2 h1:WavlEeLh6HKt+osbmsHDg6/FaM/8Pz9iVUMh9pAsl/o=
+github.com/sigstore/timestamp-authority/v2 v2.0.2/go.mod h1:D+wbQg8ASQzKnwBhLo7rIJD+9Zev4Ppqd4myPe8k57E=
 github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
 github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
 github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
-github.com/spdx/tools-golang v0.5.5 h1:61c0KLfAcNqAjlg6UNMdkwpMernhw3zVRwDZ2x9XOmk=
-github.com/spdx/tools-golang v0.5.5/go.mod h1:MVIsXx8ZZzaRWNQpUDhC4Dud34edUYJYecciXgrw5vE=
-github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94 h1:JmfC365KywYwHB946TTiQWEb8kqPY+pybPLoGE9GgVk=
-github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg=
-github.com/spf13/cobra v0.0.1/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
+github.com/spdx/tools-golang v0.5.7 h1:+sWcKGnhwp3vLdMqPcLdA6QK679vd86cK9hQWH3AwCg=
+github.com/spdx/tools-golang v0.5.7/go.mod h1:jg7w0LOpoNAw6OxKEzCoqPC2GCTj45LyTlVmXubDsYw=
 github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
 github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
-github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431 h1:XTHrT015sxHyJ5FnQ0AeemSspZWaDq7DoTRW0EVsDCE=
-github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
-github.com/spf13/pflag v1.0.0/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
 github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
 github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c h1:2EejZtjFjKJGk71ANb+wtFK5EjUzUkEM3R0xnp559xg=
-github.com/spf13/viper v0.0.0-20150530192845-be5ff3e4840c/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
-github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
-github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
 github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
-github.com/theupdateframework/notary v0.7.0 h1:QyagRZ7wlSpjT5N2qQAh/pN+DVqgekv4DzbAiAiEL3c=
-github.com/theupdateframework/notary v0.7.0/go.mod h1:c9DRxcmhHmVLDay4/2fUYdISnHqbFDGRSlXPO0AhYWw=
+github.com/theupdateframework/go-tuf v0.7.0 h1:CqbQFrWo1ae3/I0UCblSbczevCCbS31Qvs5LdxRWqRI=
+github.com/theupdateframework/go-tuf/v2 v2.3.0 h1:gt3X8xT8qu/HT4w+n1jgv+p7koi5ad8XEkLXXZqG9AA=
+github.com/theupdateframework/go-tuf/v2 v2.3.0/go.mod h1:xW8yNvgXRncmovMLvBxKwrKpsOwJZu/8x+aB0KtFcdw=
 github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375 h1:QB54BJwA6x8QU9nHY3xJSZR2kX9bgpZekRKGkLTmEXA=
 github.com/tilt-dev/fsnotify v1.4.8-0.20220602155310-fff9c274a375/go.mod h1:xRroudyp5iVtxKqZCrA6n2TLFRBf8bmnjr1UD4x+z7g=
 github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323 h1:r0p7fK56l8WPequOaR3i9LBqfPtEdXIQbUTzT55iqT4=
 github.com/tonistiigi/dchapes-mode v0.0.0-20250318174251-73d941a28323/go.mod h1:3Iuxbr0P7D3zUzBMAZB+ois3h/et0shEz0qApgHYGpY=
-github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f h1:MoxeMfHAe5Qj/ySSBfL8A7l1V+hxuluj8owsIEEZipI=
-github.com/tonistiigi/fsutil v0.0.0-20250605211040-586307ad452f/go.mod h1:BKdcez7BiVtBvIcef90ZPc6ebqIWr4JWD7+EvLm6J98=
+github.com/tonistiigi/fsutil v0.0.0-20251211185533-a2aa163d723f h1:Z4NEQ86qFl1mHuCu9gwcE+EYCwDKfXAYXZbdIXyxmEA=
+github.com/tonistiigi/fsutil v0.0.0-20251211185533-a2aa163d723f/go.mod h1:BKdcez7BiVtBvIcef90ZPc6ebqIWr4JWD7+EvLm6J98=
 github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0 h1:2f304B10LaZdB8kkVEaoXvAMVan2tl9AiK4G0odjQtE=
 github.com/tonistiigi/go-csvvalue v0.0.0-20240814133006-030d3b2625d0/go.mod h1:278M4p8WsNh3n4a1eqiFcV2FGk7wE5fwUpUom9mK9lE=
 github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea h1:SXhTLE6pb6eld/v/cCndK0AMpt1wiVFb/YYmqB3/QG0=
 github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea/go.mod h1:WPnis/6cRcDZSUvVmezrxJPkiO87ThFYsoUiMwWNDJk=
 github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab h1:H6aJ0yKQ0gF49Qb2z5hI1UHxSQt4JMyxebFR15KnApw=
 github.com/tonistiigi/vt100 v0.0.0-20240514184818-90bafcd6abab/go.mod h1:ulncasL3N9uLrVann0m+CDlJKWsIAP34MPcOJF6VRvc=
+github.com/transparency-dev/formats v0.0.0-20251017110053-404c0d5b696c h1:5a2XDQ2LiAUV+/RjckMyq9sXudfrPSuCY4FuPC1NyAw=
+github.com/transparency-dev/formats v0.0.0-20251017110053-404c0d5b696c/go.mod h1:g85IafeFJZLxlzZCDRu4JLpfS7HKzR+Hw9qRh3bVzDI=
+github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4=
+github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A=
 github.com/vbatts/tar-split v0.12.2 h1:w/Y6tjxpeiFMR47yzZPlPj/FcPLpXbTUi/9H7d3CPa4=
 github.com/vbatts/tar-split v0.12.2/go.mod h1:eF6B6i6ftWQcDqEn3/iGFRFRo8cBIMSJVOpnNdfTMFA=
 github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc=
@@ -408,6 +363,8 @@ github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtX
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+go.mongodb.org/mongo-driver v1.17.6 h1:87JUG1wZfWsr6rIz3ZmpH90rL5tea7O3IHuSwHUpsss=
+go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ=
 go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0=
 go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
 go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
@@ -444,56 +401,40 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
 go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
 go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
 go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
-go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
-go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU=
+go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
+go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
 go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
 go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
 go.yaml.in/yaml/v4 v4.0.0-rc.4 h1:UP4+v6fFrBIb1l934bDl//mmnoIZEDK0idg1+AIvX5U=
 go.yaml.in/yaml/v4 v4.0.0-rc.4/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
-golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/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-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.45.0 h1:jMBrvKuj23MTlT0bQEOBcAE0mjg8mK9RXFhRH6nyF3Q=
-golang.org/x/crypto v0.45.0/go.mod h1:XTGrrkGJve7CYK7J8PEww4aY7gM3qMCElcJQ8n8JdX4=
+golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
+golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
 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/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA=
-golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w=
-golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
-golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/mod v0.31.0 h1:HaW9xtz0+kOcWKwli0ZXy79Ix+UW/vOfmWI5QVd2tgI=
+golang.org/x/mod v0.31.0/go.mod h1:43JraMp9cGx1Rx3AqioxrbrhNsLl2l/iNAvuBkrezpg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
-golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 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.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY=
-golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU=
-golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
+golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
 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/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
 golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
-golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/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-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -506,17 +447,16 @@ golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
 golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
-golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
-golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
+golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
+golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
 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.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
-golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
+golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
+golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
 golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
 golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -530,39 +470,25 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
 gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
-google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda h1:+2XxjfsAu6vqFxwGBRcHiMaDCuZiqXGDUDVWVtrFAnE=
-google.golang.org/genproto/googleapis/api v0.0.0-20251029180050-ab9386a59fda/go.mod h1:fDMmzKV90WSg1NbozdqrE64fkuTv6mlq2zxo9ad+3yo=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
-google.golang.org/grpc v1.0.5/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
+google.golang.org/genproto/googleapis/api v0.0.0-20251103181224-f26f9409b101 h1:vk5TfqZHNn0obhPIYeS+cxIFKFQgser/M2jnI+9c6MM=
+google.golang.org/genproto/googleapis/api v0.0.0-20251103181224-f26f9409b101/go.mod h1:E17fc4PDhkr22dE3RgnH2hEubUaky6ZwW4VhANxyspg=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101 h1:tRPGkdGHuewF4UisLzzHHr1spKw92qLM98nIzxbC0wY=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20251103181224-f26f9409b101/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
 google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc=
 google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U=
-google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
-google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
-gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U=
-gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
-gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII=
-gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU=
+google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
+google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/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=
-gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
-gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
 gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
 gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
-gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1 h1:d4KQkxAaAiRY2h5Zqis161Pv91A37uZyJOx73duwUwM=
-gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1/go.mod h1:WbjuEoo1oadwzQ4apSDU+JTvmllEHtsNHS6y7vFc7iw=
-gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
-gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
-gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 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=
 tags.cncf.io/container-device-interface v1.1.0 h1:RnxNhxF1JOu6CJUVpetTYvrXHdxw9j9jFYgZpI+anSY=
 tags.cncf.io/container-device-interface v1.1.0/go.mod h1:76Oj0Yqp9FwTx/pySDc8Bxjpg+VqXfDb50cKAXVJ34Q=

+ 1 - 1
internal/sync/tar.go

@@ -31,8 +31,8 @@ import (
 	"strings"
 	"sync"
 
-	"github.com/docker/docker/api/types/container"
 	"github.com/moby/go-archive"
+	"github.com/moby/moby/api/types/container"
 	"golang.org/x/sync/errgroup"
 )
 

+ 1 - 1
internal/tracing/attributes.go

@@ -25,7 +25,7 @@ import (
 	"time"
 
 	"github.com/compose-spec/compose-go/v2/types"
-	"github.com/docker/docker/api/types/container"
+	"github.com/moby/moby/api/types/container"
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/trace"
 )

+ 5 - 4
pkg/api/api.go

@@ -28,7 +28,8 @@ import (
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/containerd/platforms"
 	"github.com/docker/cli/opts"
-	"github.com/docker/docker/api/types/volume"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/volume"
 )
 
 // LoadListener receives events during project loading.
@@ -154,7 +155,7 @@ type VolumesOptions struct {
 	Services []string
 }
 
-type VolumesSummary = *volume.Volume
+type VolumesSummary = volume.Volume
 
 type ScaleOptions struct {
 	Services []string
@@ -544,9 +545,9 @@ type ContainerSummary struct {
 	Project      string
 	Service      string
 	Created      int64
-	State        string
+	State        container.ContainerState
 	Status       string
-	Health       string
+	Health       container.HealthStatus
 	ExitCode     int
 	Publishers   PortPublishers
 	Labels       map[string]string

+ 17 - 11
pkg/bridge/convert.go

@@ -30,11 +30,12 @@ import (
 	"github.com/containerd/errdefs"
 	"github.com/docker/cli/cli/command"
 	cli "github.com/docker/cli/cli/command/container"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/image"
-	"github.com/docker/docker/api/types/network"
-	"github.com/docker/docker/pkg/jsonmessage"
 	"github.com/docker/go-connections/nat"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/image"
+	"github.com/moby/moby/api/types/network"
+	"github.com/moby/moby/client"
+	"github.com/moby/moby/client/pkg/jsonmessage"
 	"github.com/sirupsen/logrus"
 	"go.yaml.in/yaml/v4"
 
@@ -138,10 +139,14 @@ func convert(ctx context.Context, dockerCli command.Cli, model map[string]any, o
 			}
 			containerConfig.User = usr.Uid
 		}
-		created, err := dockerCli.Client().ContainerCreate(ctx, containerConfig, &container.HostConfig{
-			AutoRemove: true,
-			Binds:      binds,
-		}, &network.NetworkingConfig{}, nil, "")
+		created, err := dockerCli.Client().ContainerCreate(ctx, client.ContainerCreateOptions{
+			Config: containerConfig,
+			HostConfig: &container.HostConfig{
+				Binds:      binds,
+				AutoRemove: true,
+			},
+			NetworkingConfig: &network.NetworkingConfig{},
+		})
 		if err != nil {
 			return err
 		}
@@ -218,13 +223,14 @@ func inspectWithPull(ctx context.Context, dockerCli command.Cli, imageName strin
 	inspect, err := dockerCli.Client().ImageInspect(ctx, imageName)
 	if errdefs.IsNotFound(err) {
 		var stream io.ReadCloser
-		stream, err = dockerCli.Client().ImagePull(ctx, imageName, image.PullOptions{})
+		stream, err = dockerCli.Client().ImagePull(ctx, imageName, client.ImagePullOptions{})
 		if err != nil {
 			return image.InspectResponse{}, err
 		}
 		defer func() { _ = stream.Close() }()
 
-		err = jsonmessage.DisplayJSONMessagesToStream(stream, dockerCli.Out(), nil)
+		out := dockerCli.Out()
+		err = jsonmessage.DisplayJSONMessagesStream(stream, out, out.FD(), out.IsTerminal(), nil)
 		if err != nil {
 			return image.InspectResponse{}, err
 		}
@@ -232,5 +238,5 @@ func inspectWithPull(ctx context.Context, dockerCli command.Cli, imageName strin
 			return image.InspectResponse{}, err
 		}
 	}
-	return inspect, err
+	return inspect.InspectResponse, err
 }

+ 21 - 17
pkg/bridge/transformers.go

@@ -23,11 +23,9 @@ import (
 	"path/filepath"
 
 	"github.com/docker/cli/cli/command"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/image"
-	"github.com/docker/docker/api/types/network"
 	"github.com/moby/go-archive"
+	"github.com/moby/moby/api/types/image"
+	"github.com/moby/moby/client"
 )
 
 const (
@@ -65,34 +63,39 @@ func CreateTransformer(ctx context.Context, dockerCli command.Cli, options Creat
 		return err
 	}
 
-	created, err := dockerCli.Client().ContainerCreate(ctx, &container.Config{
+	created, err := dockerCli.Client().ContainerCreate(ctx, client.ContainerCreateOptions{
 		Image: options.From,
-	}, &container.HostConfig{}, &network.NetworkingConfig{}, nil, "")
+	})
+
 	defer func() {
-		_ = dockerCli.Client().ContainerRemove(context.Background(), created.ID, container.RemoveOptions{Force: true})
+		_, _ = dockerCli.Client().ContainerRemove(context.Background(), created.ID, client.ContainerRemoveOptions{
+			Force: true,
+		})
 	}()
 
 	if err != nil {
 		return err
 	}
-	content, stat, err := dockerCli.Client().CopyFromContainer(ctx, created.ID, templatesPath)
+	resp, err := dockerCli.Client().CopyFromContainer(ctx, created.ID, client.CopyFromContainerOptions{
+		SourcePath: templatesPath,
+	})
 	if err != nil {
 		return err
 	}
 	defer func() {
-		_ = content.Close()
+		_ = resp.Content.Close()
 	}()
 
 	srcInfo := archive.CopyInfo{
 		Path:   templatesPath,
 		Exists: true,
-		IsDir:  stat.Mode.IsDir(),
+		IsDir:  resp.Stat.Mode.IsDir(),
 	}
 
-	preArchive := content
+	preArchive := resp.Content
 	if srcInfo.RebaseName != "" {
 		_, srcBase := archive.SplitPathDirEntry(srcInfo.Path)
-		preArchive = archive.RebaseArchiveEntries(content, srcBase, srcInfo.RebaseName)
+		preArchive = archive.RebaseArchiveEntries(resp.Content, srcBase, srcInfo.RebaseName)
 	}
 
 	if err := archive.CopyTo(preArchive, srcInfo, out); err != nil {
@@ -111,10 +114,11 @@ COPY templates /templates
 }
 
 func ListTransformers(ctx context.Context, dockerCli command.Cli) ([]image.Summary, error) {
-	api := dockerCli.Client()
-	return api.ImageList(ctx, image.ListOptions{
-		Filters: filters.NewArgs(
-			filters.Arg("label", fmt.Sprintf("%s=%s", TransformerLabel, "transformation")),
-		),
+	res, err := dockerCli.Client().ImageList(ctx, client.ImageListOptions{
+		Filters: make(client.Filters).Add("label", fmt.Sprintf("%s=%s", TransformerLabel, "transformation")),
 	})
+	if err != nil {
+		return nil, err
+	}
+	return res.Items, nil
 }

+ 8 - 7
pkg/compose/attach.go

@@ -24,8 +24,9 @@ import (
 	"strings"
 
 	"github.com/compose-spec/compose-go/v2/types"
-	containerType "github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/pkg/stdcopy"
+	"github.com/moby/moby/api/pkg/stdcopy"
+	containerType "github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"github.com/sirupsen/logrus"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -69,7 +70,7 @@ func (s *composeService) attachContainer(ctx context.Context, container containe
 }
 
 func (s *composeService) doAttachContainer(ctx context.Context, service, id, name string, listener api.ContainerEventListener) error {
-	inspect, err := s.apiClient().ContainerInspect(ctx, id)
+	inspect, err := s.apiClient().ContainerInspect(ctx, id, client.ContainerInspectOptions{})
 	if err != nil {
 		return err
 	}
@@ -93,7 +94,7 @@ func (s *composeService) doAttachContainer(ctx context.Context, service, id, nam
 		})
 	})
 
-	err = s.attachContainerStreams(ctx, id, inspect.Config.Tty, wOut, wErr)
+	err = s.attachContainerStreams(ctx, id, inspect.Container.Config.Tty, wOut, wErr)
 	if err != nil {
 		return err
 	}
@@ -136,7 +137,7 @@ func (s *composeService) attachContainerStreams(ctx context.Context, container s
 }
 
 func (s *composeService) getContainerStreams(ctx context.Context, container string) (io.ReadCloser, error) {
-	cnx, err := s.apiClient().ContainerAttach(ctx, container, containerType.AttachOptions{
+	cnx, err := s.apiClient().ContainerAttach(ctx, container, client.ContainerAttachOptions{
 		Stream: true,
 		Stdin:  false,
 		Stdout: true,
@@ -144,12 +145,12 @@ func (s *composeService) getContainerStreams(ctx context.Context, container stri
 		Logs:   false,
 	})
 	if err == nil {
-		stdout := ContainerStdout{HijackedResponse: cnx}
+		stdout := ContainerStdout{HijackedResponse: cnx.HijackedResponse}
 		return stdout, nil
 	}
 
 	// Fallback to logs API
-	logs, err := s.apiClient().ContainerLogs(ctx, container, containerType.LogsOptions{
+	logs, err := s.apiClient().ContainerLogs(ctx, container, client.ContainerLogsOptions{
 		ShowStdout: true,
 		ShowStderr: true,
 		Follow:     true,

+ 2 - 2
pkg/compose/build_bake.go

@@ -39,11 +39,11 @@ import (
 	"github.com/docker/cli/cli/command"
 	"github.com/docker/cli/cli/command/image/build"
 	"github.com/docker/cli/cli/streams"
-	"github.com/docker/docker/api/types/versions"
 	"github.com/google/uuid"
 	"github.com/moby/buildkit/client"
 	gitutil "github.com/moby/buildkit/frontend/dockerfile/dfgitutil"
 	"github.com/moby/buildkit/util/progress/progressui"
+	"github.com/moby/moby/client/pkg/versions"
 	"github.com/sirupsen/logrus"
 	"github.com/spf13/cobra"
 	"golang.org/x/sync/errgroup"
@@ -447,7 +447,7 @@ type _console struct {
 	*streams.Out
 }
 
-func (c _console) Read(p []byte) (n int, err error) {
+func (c _console) Read([]byte) (n int, err error) {
 	return 0, errors.New("not implemented")
 }
 

+ 12 - 10
pkg/compose/build_classic.go

@@ -29,13 +29,15 @@ import (
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/docker/cli/cli"
 	"github.com/docker/cli/cli/command/image/build"
-	buildtypes "github.com/docker/docker/api/types/build"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/registry"
-	"github.com/docker/docker/pkg/jsonmessage"
-	"github.com/docker/docker/pkg/progress"
-	"github.com/docker/docker/pkg/streamformatter"
 	"github.com/moby/go-archive"
+	buildtypes "github.com/moby/moby/api/types/build"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/jsonstream"
+	"github.com/moby/moby/api/types/registry"
+	"github.com/moby/moby/client"
+	"github.com/moby/moby/client/pkg/jsonmessage"
+	"github.com/moby/moby/client/pkg/progress"
+	"github.com/moby/moby/client/pkg/streamformatter"
 	"github.com/sirupsen/logrus"
 	"go.opentelemetry.io/otel/attribute"
 	"go.opentelemetry.io/otel/trace"
@@ -266,7 +268,7 @@ func (s *composeService) doBuildImage(ctx context.Context, project *types.Projec
 	defer response.Body.Close() //nolint:errcheck
 
 	imageID := ""
-	aux := func(msg jsonmessage.JSONMessage) {
+	aux := func(msg jsonstream.Message) {
 		var result buildtypes.Result
 		if err := json.Unmarshal(*msg.Aux, &result); err != nil {
 			logrus.Errorf("Failed to parse aux message: %s", err)
@@ -277,7 +279,7 @@ func (s *composeService) doBuildImage(ctx context.Context, project *types.Projec
 
 	err = jsonmessage.DisplayJSONMessagesStream(response.Body, buildBuff, progBuff.FD(), true, aux)
 	if err != nil {
-		var jerr *jsonmessage.JSONError
+		var jerr *jsonstream.Error
 		if errors.As(err, &jerr) {
 			// If no error code is set, default to 1
 			if jerr.Code == 0 {
@@ -291,9 +293,9 @@ func (s *composeService) doBuildImage(ctx context.Context, project *types.Projec
 	return imageID, nil
 }
 
-func imageBuildOptions(proxyConfigs map[string]string, project *types.Project, service types.ServiceConfig, options api.BuildOptions) buildtypes.ImageBuildOptions {
+func imageBuildOptions(proxyConfigs map[string]string, project *types.Project, service types.ServiceConfig, options api.BuildOptions) client.ImageBuildOptions {
 	config := service.Build
-	return buildtypes.ImageBuildOptions{
+	return client.ImageBuildOptions{
 		Version:     buildtypes.BuilderV1,
 		Tags:        config.Tags,
 		NoCache:     config.NoCache,

+ 3 - 3
pkg/compose/commit.go

@@ -21,7 +21,7 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/docker/docker/api/types/container"
+	"github.com/moby/moby/client"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
@@ -58,12 +58,12 @@ func (s *composeService) commit(ctx context.Context, projectName string, options
 		return nil
 	}
 
-	response, err := s.apiClient().ContainerCommit(ctx, ctr.ID, container.CommitOptions{
+	response, err := s.apiClient().ContainerCommit(ctx, ctr.ID, client.ContainerCommitOptions{
 		Reference: options.Reference,
 		Comment:   options.Comment,
 		Author:    options.Author,
 		Changes:   options.Changes.GetSlice(),
-		Pause:     options.Pause,
+		NoPause:   !options.Pause,
 	})
 	if err != nil {
 		return err

+ 13 - 15
pkg/compose/compose.go

@@ -31,13 +31,10 @@ import (
 	"github.com/docker/cli/cli/config/configfile"
 	"github.com/docker/cli/cli/flags"
 	"github.com/docker/cli/cli/streams"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/network"
-	"github.com/docker/docker/api/types/swarm"
-	"github.com/docker/docker/api/types/volume"
-	"github.com/docker/docker/client"
 	"github.com/jonboulle/clockwork"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/swarm"
+	"github.com/moby/moby/client"
 	"github.com/sirupsen/logrus"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -434,8 +431,8 @@ func increment(scale *int) *int {
 }
 
 func (s *composeService) actualVolumes(ctx context.Context, projectName string) (types.Volumes, error) {
-	opts := volume.ListOptions{
-		Filters: filters.NewArgs(projectFilter(projectName)),
+	opts := client.VolumeListOptions{
+		Filters: projectFilter(projectName),
 	}
 	volumes, err := s.apiClient().VolumeList(ctx, opts)
 	if err != nil {
@@ -443,7 +440,7 @@ func (s *composeService) actualVolumes(ctx context.Context, projectName string)
 	}
 
 	actual := types.Volumes{}
-	for _, vol := range volumes.Volumes {
+	for _, vol := range volumes.Items {
 		actual[vol.Labels[api.VolumeLabel]] = types.VolumeConfig{
 			Name:   vol.Name,
 			Driver: vol.Driver,
@@ -454,15 +451,15 @@ func (s *composeService) actualVolumes(ctx context.Context, projectName string)
 }
 
 func (s *composeService) actualNetworks(ctx context.Context, projectName string) (types.Networks, error) {
-	networks, err := s.apiClient().NetworkList(ctx, network.ListOptions{
-		Filters: filters.NewArgs(projectFilter(projectName)),
+	networks, err := s.apiClient().NetworkList(ctx, client.NetworkListOptions{
+		Filters: projectFilter(projectName),
 	})
 	if err != nil {
 		return nil, err
 	}
 
 	actual := types.Networks{}
-	for _, net := range networks {
+	for _, net := range networks.Items {
 		actual[net.Labels[api.NetworkLabel]] = types.NetworkConfig{
 			Name:   net.Name,
 			Driver: net.Driver,
@@ -480,11 +477,11 @@ var swarmEnabled = struct {
 
 func (s *composeService) isSwarmEnabled(ctx context.Context) (bool, error) {
 	swarmEnabled.once.Do(func() {
-		info, err := s.apiClient().Info(ctx)
+		res, err := s.apiClient().Info(ctx, client.InfoOptions{})
 		if err != nil {
 			swarmEnabled.err = err
 		}
-		switch info.Swarm.LocalNodeState {
+		switch res.Info.Swarm.LocalNodeState {
 		case swarm.LocalNodeStateInactive, swarm.LocalNodeStateLocked:
 			swarmEnabled.val = false
 		default:
@@ -503,8 +500,9 @@ type runtimeVersionCache struct {
 var runtimeVersion runtimeVersionCache
 
 func (s *composeService) RuntimeVersion(ctx context.Context) (string, error) {
+	// TODO(thaJeztah): this should use Client.ClientVersion), which has the negotiated version.
 	runtimeVersion.once.Do(func() {
-		version, err := s.apiClient().ServerVersion(ctx)
+		version, err := s.apiClient().ServerVersion(ctx, client.ServerVersionOptions{})
 		if err != nil {
 			runtimeVersion.err = err
 		}

+ 3 - 3
pkg/compose/container.go

@@ -19,14 +19,14 @@ package compose
 import (
 	"io"
 
-	moby "github.com/docker/docker/api/types"
+	"github.com/moby/moby/client"
 )
 
 var _ io.ReadCloser = ContainerStdout{}
 
 // ContainerStdout implement ReadCloser for moby.HijackedResponse
 type ContainerStdout struct {
-	moby.HijackedResponse
+	client.HijackedResponse
 }
 
 // Read implement io.ReadCloser
@@ -44,7 +44,7 @@ var _ io.WriteCloser = ContainerStdin{}
 
 // ContainerStdin implement WriteCloser for moby.HijackedResponse
 type ContainerStdin struct {
-	moby.HijackedResponse
+	client.HijackedResponse
 }
 
 // Write implement io.WriteCloser

+ 16 - 18
pkg/compose/containers.go

@@ -24,8 +24,8 @@ import (
 	"strconv"
 
 	"github.com/compose-spec/compose-go/v2/types"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
@@ -42,32 +42,31 @@ const (
 )
 
 func (s *composeService) getContainers(ctx context.Context, project string, oneOff oneOff, all bool, selectedServices ...string) (Containers, error) {
-	var containers Containers
-	f := getDefaultFilters(project, oneOff, selectedServices...)
-	containers, err := s.apiClient().ContainerList(ctx, container.ListOptions{
-		Filters: filters.NewArgs(f...),
+	res, err := s.apiClient().ContainerList(ctx, client.ContainerListOptions{
+		Filters: getDefaultFilters(project, oneOff, selectedServices...),
 		All:     all,
 	})
 	if err != nil {
 		return nil, err
 	}
+	containers := Containers(res.Items)
 	if len(selectedServices) > 1 {
 		containers = containers.filter(isService(selectedServices...))
 	}
 	return containers, nil
 }
 
-func getDefaultFilters(projectName string, oneOff oneOff, selectedServices ...string) []filters.KeyValuePair {
-	f := []filters.KeyValuePair{projectFilter(projectName)}
+func getDefaultFilters(projectName string, oneOff oneOff, selectedServices ...string) client.Filters {
+	f := projectFilter(projectName)
 	if len(selectedServices) == 1 {
-		f = append(f, serviceFilter(selectedServices[0]))
+		f.Add("label", serviceFilter(selectedServices[0]))
 	}
-	f = append(f, hasConfigHashLabel())
+	f.Add("label", hasConfigHashLabel())
 	switch oneOff {
 	case oneOffOnly:
-		f = append(f, oneOffFilter(true))
+		f.Add("label", oneOffFilter(true))
 	case oneOffExclude:
-		f = append(f, oneOffFilter(false))
+		f.Add("label", oneOffFilter(false))
 	case oneOffInclude:
 	}
 	return f
@@ -76,17 +75,16 @@ func getDefaultFilters(projectName string, oneOff oneOff, selectedServices ...st
 func (s *composeService) getSpecifiedContainer(ctx context.Context, projectName string, oneOff oneOff, all bool, serviceName string, containerIndex int) (container.Summary, error) {
 	defaultFilters := getDefaultFilters(projectName, oneOff, serviceName)
 	if containerIndex > 0 {
-		defaultFilters = append(defaultFilters, containerNumberFilter(containerIndex))
+		defaultFilters.Add("label", containerNumberFilter(containerIndex))
 	}
-	containers, err := s.apiClient().ContainerList(ctx, container.ListOptions{
-		Filters: filters.NewArgs(
-			defaultFilters...,
-		),
-		All: all,
+	res, err := s.apiClient().ContainerList(ctx, client.ContainerListOptions{
+		Filters: defaultFilters,
+		All:     all,
 	})
 	if err != nil {
 		return container.Summary{}, err
 	}
+	containers := res.Items
 	if len(containers) < 1 {
 		if containerIndex > 0 {
 			return container.Summary{}, fmt.Errorf("service %q is not running container #%d", serviceName, containerIndex)

+ 27 - 41
pkg/compose/convergence.go

@@ -30,9 +30,9 @@ import (
 
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/containerd/platforms"
-	"github.com/docker/docker/api/types/container"
-	mmount "github.com/docker/docker/api/types/mount"
-	"github.com/docker/docker/api/types/versions"
+	"github.com/moby/moby/api/types/container"
+	mmount "github.com/moby/moby/api/types/mount"
+	"github.com/moby/moby/client"
 	specs "github.com/opencontainers/image-spec/specs-go/v1"
 	"github.com/sirupsen/logrus"
 	"go.opentelemetry.io/otel/attribute"
@@ -657,17 +657,19 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P
 	}
 
 	timeoutInSecond := utils.DurationSecondToInt(timeout)
-	err = s.apiClient().ContainerStop(ctx, replaced.ID, container.StopOptions{Timeout: timeoutInSecond})
+	_, err = s.apiClient().ContainerStop(ctx, replaced.ID, client.ContainerStopOptions{Timeout: timeoutInSecond})
 	if err != nil {
 		return created, err
 	}
 
-	err = s.apiClient().ContainerRemove(ctx, replaced.ID, container.RemoveOptions{})
+	_, err = s.apiClient().ContainerRemove(ctx, replaced.ID, client.ContainerRemoveOptions{})
 	if err != nil {
 		return created, err
 	}
 
-	err = s.apiClient().ContainerRename(ctx, tmpName, name)
+	_, err = s.apiClient().ContainerRename(ctx, tmpName, client.ContainerRenameOptions{
+		NewName: name,
+	})
 	if err != nil {
 		return created, err
 	}
@@ -683,7 +685,7 @@ func (s *composeService) startContainer(ctx context.Context, ctr container.Summa
 	s.events.On(newEvent(getContainerProgressName(ctr), api.Working, "Restart"))
 	startMx.Lock()
 	defer startMx.Unlock()
-	err := s.apiClient().ContainerStart(ctx, ctr.ID, container.StartOptions{})
+	_, err := s.apiClient().ContainerStart(ctx, ctr.ID, client.ContainerStartOptions{})
 	if err != nil {
 		return err
 	}
@@ -713,7 +715,13 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types
 		plat = &p
 	}
 
-	response, err := s.apiClient().ContainerCreate(ctx, cfgs.Container, cfgs.Host, cfgs.Network, plat, name)
+	response, err := s.apiClient().ContainerCreate(ctx, client.ContainerCreateOptions{
+		Name:             name,
+		Platform:         plat,
+		Config:           cfgs.Container,
+		HostConfig:       cfgs.Host,
+		NetworkingConfig: cfgs.Network,
+	})
 	if err != nil {
 		return created, err
 	}
@@ -724,42 +732,19 @@ func (s *composeService) createMobyContainer(ctx context.Context, project *types
 			Text:   warning,
 		})
 	}
-	inspectedContainer, err := s.apiClient().ContainerInspect(ctx, response.ID)
+	res, err := s.apiClient().ContainerInspect(ctx, response.ID, client.ContainerInspectOptions{})
 	if err != nil {
 		return created, err
 	}
 	created = container.Summary{
-		ID:     inspectedContainer.ID,
-		Labels: inspectedContainer.Config.Labels,
-		Names:  []string{inspectedContainer.Name},
+		ID:     res.Container.ID,
+		Labels: res.Container.Config.Labels,
+		Names:  []string{res.Container.Name},
 		NetworkSettings: &container.NetworkSettingsSummary{
-			Networks: inspectedContainer.NetworkSettings.Networks,
+			Networks: res.Container.NetworkSettings.Networks,
 		},
 	}
 
-	apiVersion, err := s.RuntimeVersion(ctx)
-	if err != nil {
-		return created, err
-	}
-	// Starting API version 1.44, the ContainerCreate API call takes multiple networks
-	// so we include all the configurations there and can skip the one-by-one calls here
-	if versions.LessThan(apiVersion, APIVersion144) {
-		// the highest-priority network is the primary and is included in the ContainerCreate API
-		// call via container.NetworkMode & network.NetworkingConfig
-		// any remaining networks are connected one-by-one here after creation (but before start)
-		serviceNetworks := service.NetworksByPriority()
-		for _, networkKey := range serviceNetworks {
-			mobyNetworkName := project.Networks[networkKey].Name
-			if string(cfgs.Host.NetworkMode) == mobyNetworkName {
-				// primary network already configured as part of ContainerCreate
-				continue
-			}
-			epSettings := createEndpointSettings(project, service, number, networkKey, cfgs.Links, opts.UseNetworkAliases)
-			if err := s.apiClient().NetworkConnect(ctx, mobyNetworkName, created.ID, epSettings); err != nil {
-				return created, err
-			}
-		}
-	}
 	return created, nil
 }
 
@@ -820,10 +805,11 @@ func (s *composeService) getLinks(ctx context.Context, projectName string, servi
 
 func (s *composeService) isServiceHealthy(ctx context.Context, containers Containers, fallbackRunning bool) (bool, error) {
 	for _, c := range containers {
-		ctr, err := s.apiClient().ContainerInspect(ctx, c.ID)
+		res, err := s.apiClient().ContainerInspect(ctx, c.ID, client.ContainerInspectOptions{})
 		if err != nil {
 			return false, err
 		}
+		ctr := res.Container
 		name := ctr.Name[1:]
 
 		if ctr.State.Status == container.StateExited {
@@ -855,12 +841,12 @@ func (s *composeService) isServiceHealthy(ctx context.Context, containers Contai
 
 func (s *composeService) isServiceCompleted(ctx context.Context, containers Containers) (bool, int, error) {
 	for _, c := range containers {
-		ctr, err := s.apiClient().ContainerInspect(ctx, c.ID)
+		res, err := s.apiClient().ContainerInspect(ctx, c.ID, client.ContainerInspectOptions{})
 		if err != nil {
 			return false, 0, err
 		}
-		if ctr.State != nil && ctr.State.Status == container.StateExited {
-			return true, ctr.State.ExitCode, nil
+		if res.Container.State != nil && res.Container.State.Status == container.StateExited {
+			return true, res.Container.State.ExitCode, nil
 		}
 	}
 	return false, 0, nil
@@ -904,7 +890,7 @@ func (s *composeService) startService(ctx context.Context,
 
 		eventName := getContainerProgressName(ctr)
 		s.events.On(startingEvent(eventName))
-		err = s.apiClient().ContainerStart(ctx, ctr.ID, container.StartOptions{})
+		_, err = s.apiClient().ContainerStart(ctx, ctr.ID, client.ContainerStartOptions{})
 		if err != nil {
 			return err
 		}

+ 140 - 208
pkg/compose/convergence_test.go

@@ -17,18 +17,18 @@
 package compose
 
 import (
+	"context"
 	"fmt"
+	"net/netip"
 	"strings"
 	"testing"
 
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/docker/cli/cli/config/configfile"
-	moby "github.com/docker/docker/api/types"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/image"
-	"github.com/docker/docker/api/types/network"
-	"github.com/docker/go-connections/nat"
+	"github.com/google/go-cmp/cmp/cmpopts"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/network"
+	"github.com/moby/moby/client"
 	"go.uber.org/mock/gomock"
 	"gotest.tools/v3/assert"
 
@@ -69,9 +69,8 @@ func TestServiceLinks(t *testing.T) {
 		Scale: intPtr(1),
 	}
 
-	containerListOptions := container.ListOptions{
-		Filters: filters.NewArgs(
-			projectFilter(testProject),
+	containerListOptions := client.ContainerListOptions{
+		Filters: projectFilter(testProject).Add("label",
 			serviceFilter("db"),
 			oneOffFilter(false),
 			hasConfigHashLabel(),
@@ -92,7 +91,9 @@ func TestServiceLinks(t *testing.T) {
 		s.Links = []string{"db"}
 
 		c := testContainer("db", dbContainerName, false)
-		apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]container.Summary{c}, nil)
+		apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return(client.ContainerListResult{
+			Items: []container.Summary{c},
+		}, nil)
 
 		links, err := tested.(*composeService).getLinks(t.Context(), testProject, s, 1)
 		assert.NilError(t, err)
@@ -116,7 +117,9 @@ func TestServiceLinks(t *testing.T) {
 
 		c := testContainer("db", dbContainerName, false)
 
-		apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]container.Summary{c}, nil)
+		apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return(client.ContainerListResult{
+			Items: []container.Summary{c},
+		}, nil)
 		links, err := tested.(*composeService).getLinks(t.Context(), testProject, s, 1)
 		assert.NilError(t, err)
 
@@ -138,7 +141,9 @@ func TestServiceLinks(t *testing.T) {
 		s.Links = []string{"db:dbname"}
 
 		c := testContainer("db", dbContainerName, false)
-		apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]container.Summary{c}, nil)
+		apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return(client.ContainerListResult{
+			Items: []container.Summary{c},
+		}, nil)
 
 		links, err := tested.(*composeService).getLinks(t.Context(), testProject, s, 1)
 		assert.NilError(t, err)
@@ -162,7 +167,9 @@ func TestServiceLinks(t *testing.T) {
 		s.ExternalLinks = []string{"db1:db2"}
 
 		c := testContainer("db", dbContainerName, false)
-		apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]container.Summary{c}, nil)
+		apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return(client.ContainerListResult{
+			Items: []container.Summary{c},
+		}, nil)
 
 		links, err := tested.(*composeService).getLinks(t.Context(), testProject, s, 1)
 		assert.NilError(t, err)
@@ -190,16 +197,17 @@ func TestServiceLinks(t *testing.T) {
 		s.Labels = s.Labels.Add(api.OneoffLabel, "True")
 
 		c := testContainer("web", webContainerName, true)
-		containerListOptionsOneOff := container.ListOptions{
-			Filters: filters.NewArgs(
-				projectFilter(testProject),
+		containerListOptionsOneOff := client.ContainerListOptions{
+			Filters: projectFilter(testProject).Add("label",
 				serviceFilter("web"),
 				oneOffFilter(false),
 				hasConfigHashLabel(),
 			),
 			All: true,
 		}
-		apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptionsOneOff).Return([]container.Summary{c}, nil)
+		apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptionsOneOff).Return(client.ContainerListResult{
+			Items: []container.Summary{c},
+		}, nil)
 
 		links, err := tested.(*composeService).getLinks(t.Context(), testProject, s, 1)
 		assert.NilError(t, err)
@@ -268,15 +276,15 @@ func TestIsServiceHealthy(t *testing.T) {
 		}
 
 		// Container with disabled healthcheck (Test: ["NONE"])
-		apiClient.EXPECT().ContainerInspect(ctx, containerID).Return(container.InspectResponse{
-			ContainerJSONBase: &container.ContainerJSONBase{
+		apiClient.EXPECT().ContainerInspect(ctx, containerID, gomock.Any()).Return(client.ContainerInspectResult{
+			Container: container.InspectResponse{
 				ID:    containerID,
 				Name:  "test-container",
 				State: &container.State{Status: "running"},
-			},
-			Config: &container.Config{
-				Healthcheck: &container.HealthConfig{
-					Test: []string{"NONE"},
+				Config: &container.Config{
+					Healthcheck: &container.HealthConfig{
+						Test: []string{"NONE"},
+					},
 				},
 			},
 		}, nil)
@@ -293,15 +301,15 @@ func TestIsServiceHealthy(t *testing.T) {
 		}
 
 		// Container with disabled healthcheck (Test: ["NONE"]) but fallbackRunning=false
-		apiClient.EXPECT().ContainerInspect(ctx, containerID).Return(container.InspectResponse{
-			ContainerJSONBase: &container.ContainerJSONBase{
+		apiClient.EXPECT().ContainerInspect(ctx, containerID, gomock.Any()).Return(client.ContainerInspectResult{
+			Container: container.InspectResponse{
 				ID:    containerID,
 				Name:  "test-container",
 				State: &container.State{Status: "running"},
-			},
-			Config: &container.Config{
-				Healthcheck: &container.HealthConfig{
-					Test: []string{"NONE"},
+				Config: &container.Config{
+					Healthcheck: &container.HealthConfig{
+						Test: []string{"NONE"},
+					},
 				},
 			},
 		}, nil)
@@ -317,14 +325,14 @@ func TestIsServiceHealthy(t *testing.T) {
 		}
 
 		// Container with no healthcheck at all
-		apiClient.EXPECT().ContainerInspect(ctx, containerID).Return(container.InspectResponse{
-			ContainerJSONBase: &container.ContainerJSONBase{
+		apiClient.EXPECT().ContainerInspect(ctx, containerID, gomock.Any()).Return(client.ContainerInspectResult{
+			Container: container.InspectResponse{
 				ID:    containerID,
 				Name:  "test-container",
 				State: &container.State{Status: "running"},
-			},
-			Config: &container.Config{
-				Healthcheck: nil,
+				Config: &container.Config{
+					Healthcheck: nil,
+				},
 			},
 		}, nil)
 
@@ -340,18 +348,18 @@ func TestIsServiceHealthy(t *testing.T) {
 		}
 
 		// Container with disabled healthcheck but exited
-		apiClient.EXPECT().ContainerInspect(ctx, containerID).Return(container.InspectResponse{
-			ContainerJSONBase: &container.ContainerJSONBase{
+		apiClient.EXPECT().ContainerInspect(ctx, containerID, gomock.Any()).Return(client.ContainerInspectResult{
+			Container: container.InspectResponse{
 				ID:   containerID,
 				Name: "test-container",
 				State: &container.State{
 					Status:   "exited",
 					ExitCode: 1,
 				},
-			},
-			Config: &container.Config{
-				Healthcheck: &container.HealthConfig{
-					Test: []string{"NONE"},
+				Config: &container.Config{
+					Healthcheck: &container.HealthConfig{
+						Test: []string{"NONE"},
+					},
 				},
 			},
 		}, nil)
@@ -367,8 +375,8 @@ func TestIsServiceHealthy(t *testing.T) {
 		}
 
 		// Container with actual healthcheck that is healthy
-		apiClient.EXPECT().ContainerInspect(ctx, containerID).Return(container.InspectResponse{
-			ContainerJSONBase: &container.ContainerJSONBase{
+		apiClient.EXPECT().ContainerInspect(ctx, containerID, gomock.Any()).Return(client.ContainerInspectResult{
+			Container: container.InspectResponse{
 				ID:   containerID,
 				Name: "test-container",
 				State: &container.State{
@@ -377,10 +385,10 @@ func TestIsServiceHealthy(t *testing.T) {
 						Status: container.Healthy,
 					},
 				},
-			},
-			Config: &container.Config{
-				Healthcheck: &container.HealthConfig{
-					Test: []string{"CMD", "curl", "-f", "http://localhost"},
+				Config: &container.Config{
+					Healthcheck: &container.HealthConfig{
+						Test: []string{"CMD", "curl", "-f", "http://localhost"},
+					},
 				},
 			},
 		}, nil)
@@ -392,177 +400,101 @@ func TestIsServiceHealthy(t *testing.T) {
 }
 
 func TestCreateMobyContainer(t *testing.T) {
-	t.Run("connects container networks one by one if API <1.44", func(t *testing.T) {
-		mockCtrl := gomock.NewController(t)
-		defer mockCtrl.Finish()
-		apiClient := mocks.NewMockAPIClient(mockCtrl)
-		cli := mocks.NewMockCli(mockCtrl)
-		tested, err := NewComposeService(cli)
-		assert.NilError(t, err)
-		cli.EXPECT().Client().Return(apiClient).AnyTimes()
-		cli.EXPECT().ConfigFile().Return(&configfile.ConfigFile{}).AnyTimes()
-		apiClient.EXPECT().DaemonHost().Return("").AnyTimes()
-		apiClient.EXPECT().ImageInspect(gomock.Any(), gomock.Any()).Return(image.InspectResponse{}, nil).AnyTimes()
-		// force `RuntimeVersion` to fetch again
-		runtimeVersion = runtimeVersionCache{}
-		apiClient.EXPECT().ServerVersion(gomock.Any()).Return(moby.Version{
-			APIVersion: "1.43",
-		}, nil).AnyTimes()
-
-		service := types.ServiceConfig{
-			Name: "test",
-			Networks: map[string]*types.ServiceNetworkConfig{
-				"a": {
-					Priority: 10,
-				},
-				"b": {
-					Priority: 100,
-				},
+	mockCtrl := gomock.NewController(t)
+	defer mockCtrl.Finish()
+	apiClient := mocks.NewMockAPIClient(mockCtrl)
+	cli := mocks.NewMockCli(mockCtrl)
+	tested, err := NewComposeService(cli)
+	assert.NilError(t, err)
+	cli.EXPECT().Client().Return(apiClient).AnyTimes()
+	cli.EXPECT().ConfigFile().Return(&configfile.ConfigFile{}).AnyTimes()
+	apiClient.EXPECT().DaemonHost().Return("").AnyTimes()
+	apiClient.EXPECT().ImageInspect(anyCancellableContext(), gomock.Any()).Return(client.ImageInspectResult{}, nil).AnyTimes()
+
+	// force `RuntimeVersion` to fetch fresh version
+	runtimeVersion = runtimeVersionCache{}
+	apiClient.EXPECT().ServerVersion(gomock.Any(), gomock.Any()).Return(client.ServerVersionResult{
+		APIVersion: "1.44",
+	}, nil).AnyTimes()
+
+	service := types.ServiceConfig{
+		Name: "test",
+		Networks: map[string]*types.ServiceNetworkConfig{
+			"a": {
+				Priority: 10,
 			},
-		}
-		project := types.Project{
-			Name: "bork",
-			Services: types.Services{
-				"test": service,
+			"b": {
+				Priority: 100,
 			},
-			Networks: types.Networks{
-				"a": types.NetworkConfig{
-					Name: "a-moby-name",
-				},
-				"b": types.NetworkConfig{
-					Name: "b-moby-name",
-				},
+		},
+	}
+	project := types.Project{
+		Name: "bork",
+		Services: types.Services{
+			"test": service,
+		},
+		Networks: types.Networks{
+			"a": types.NetworkConfig{
+				Name: "a-moby-name",
 			},
-		}
+			"b": types.NetworkConfig{
+				Name: "b-moby-name",
+			},
+		},
+	}
 
-		var falseBool bool
-		apiClient.EXPECT().ContainerCreate(gomock.Any(), gomock.Any(), gomock.Eq(
-			&container.HostConfig{
-				PortBindings: nat.PortMap{},
-				ExtraHosts:   []string{},
-				Tmpfs:        map[string]string{},
-				Resources: container.Resources{
-					OomKillDisable: &falseBool,
-				},
-				NetworkMode: "b-moby-name",
-			}), gomock.Eq(
-			&network.NetworkingConfig{
-				EndpointsConfig: map[string]*network.EndpointSettings{
-					"b-moby-name": {
-						IPAMConfig: &network.EndpointIPAMConfig{},
-						Aliases:    []string{"bork-test-0"},
-					},
-				},
-			}), gomock.Any(), gomock.Any()).Times(1).Return(
-			container.CreateResponse{
-				ID: "an-id",
-			}, nil)
-
-		apiClient.EXPECT().ContainerInspect(gomock.Any(), gomock.Eq("an-id")).Times(1).Return(
-			container.InspectResponse{
-				ContainerJSONBase: &container.ContainerJSONBase{
-					ID:   "an-id",
-					Name: "a-name",
-				},
-				Config:          &container.Config{},
-				NetworkSettings: &container.NetworkSettings{},
-			}, nil)
-
-		apiClient.EXPECT().NetworkConnect(gomock.Any(), "a-moby-name", "an-id", gomock.Eq(
-			&network.EndpointSettings{
-				IPAMConfig: &network.EndpointIPAMConfig{},
-				Aliases:    []string{"bork-test-0"},
-			}))
-
-		_, err = tested.(*composeService).createMobyContainer(t.Context(), &project, service, "test", 0, nil, createOptions{
-			Labels: make(types.Labels),
-		})
-		assert.NilError(t, err)
+	var got client.ContainerCreateOptions
+	apiClient.EXPECT().ContainerCreate(gomock.Any(), gomock.Any()).DoAndReturn(func(_ context.Context, opts client.ContainerCreateOptions) (client.ContainerCreateResult, error) {
+		got = opts
+		return client.ContainerCreateResult{ID: "an-id"}, nil
 	})
 
-	t.Run("includes all container networks in ContainerCreate call if API >=1.44", func(t *testing.T) {
-		mockCtrl := gomock.NewController(t)
-		defer mockCtrl.Finish()
-		apiClient := mocks.NewMockAPIClient(mockCtrl)
-		cli := mocks.NewMockCli(mockCtrl)
-		tested, err := NewComposeService(cli)
-		assert.NilError(t, err)
-		cli.EXPECT().Client().Return(apiClient).AnyTimes()
-		cli.EXPECT().ConfigFile().Return(&configfile.ConfigFile{}).AnyTimes()
-		apiClient.EXPECT().DaemonHost().Return("").AnyTimes()
-		apiClient.EXPECT().ImageInspect(gomock.Any(), gomock.Any()).Return(image.InspectResponse{}, nil).AnyTimes()
-		// force `RuntimeVersion` to fetch fresh version
-		runtimeVersion = runtimeVersionCache{}
-		apiClient.EXPECT().ServerVersion(gomock.Any()).Return(moby.Version{
-			APIVersion: APIVersion144,
-		}, nil).AnyTimes()
-
-		service := types.ServiceConfig{
-			Name: "test",
-			Networks: map[string]*types.ServiceNetworkConfig{
-				"a": {
-					Priority: 10,
-				},
-				"b": {
-					Priority: 100,
-				},
+	apiClient.EXPECT().ContainerInspect(gomock.Any(), gomock.Eq("an-id"), gomock.Any()).Times(1).Return(client.ContainerInspectResult{
+		Container: container.InspectResponse{
+			ID:              "an-id",
+			Name:            "a-name",
+			Config:          &container.Config{},
+			NetworkSettings: &container.NetworkSettings{},
+		},
+	}, nil)
+
+	_, err = tested.(*composeService).createMobyContainer(t.Context(), &project, service, "test", 0, nil, createOptions{
+		Labels: make(types.Labels),
+	})
+	var falseBool bool
+	want := client.ContainerCreateOptions{
+		Config: &container.Config{
+			AttachStdout: true,
+			AttachStderr: true,
+			Image:        "bork-test",
+			Labels: map[string]string{
+				"com.docker.compose.config-hash": "8dbce408396f8986266bc5deba0c09cfebac63c95c2238e405c7bee5f1bd84b8",
+				"com.docker.compose.depends_on":  "",
 			},
-		}
-		project := types.Project{
-			Name: "bork",
-			Services: types.Services{
-				"test": service,
+		},
+		HostConfig: &container.HostConfig{
+			PortBindings: network.PortMap{},
+			ExtraHosts:   []string{},
+			Tmpfs:        map[string]string{},
+			Resources: container.Resources{
+				OomKillDisable: &falseBool,
 			},
-			Networks: types.Networks{
-				"a": types.NetworkConfig{
-					Name: "a-moby-name",
+			NetworkMode: "b-moby-name",
+		},
+		NetworkingConfig: &network.NetworkingConfig{
+			EndpointsConfig: map[string]*network.EndpointSettings{
+				"a-moby-name": {
+					IPAMConfig: &network.EndpointIPAMConfig{},
+					Aliases:    []string{"bork-test-0"},
 				},
-				"b": types.NetworkConfig{
-					Name: "b-moby-name",
+				"b-moby-name": {
+					IPAMConfig: &network.EndpointIPAMConfig{},
+					Aliases:    []string{"bork-test-0"},
 				},
 			},
-		}
-
-		var falseBool bool
-		apiClient.EXPECT().ContainerCreate(gomock.Any(), gomock.Any(), gomock.Eq(
-			&container.HostConfig{
-				PortBindings: nat.PortMap{},
-				ExtraHosts:   []string{},
-				Tmpfs:        map[string]string{},
-				Resources: container.Resources{
-					OomKillDisable: &falseBool,
-				},
-				NetworkMode: "b-moby-name",
-			}), gomock.Eq(
-			&network.NetworkingConfig{
-				EndpointsConfig: map[string]*network.EndpointSettings{
-					"a-moby-name": {
-						IPAMConfig: &network.EndpointIPAMConfig{},
-						Aliases:    []string{"bork-test-0"},
-					},
-					"b-moby-name": {
-						IPAMConfig: &network.EndpointIPAMConfig{},
-						Aliases:    []string{"bork-test-0"},
-					},
-				},
-			}), gomock.Any(), gomock.Any()).Times(1).Return(
-			container.CreateResponse{
-				ID: "an-id",
-			}, nil)
-
-		apiClient.EXPECT().ContainerInspect(gomock.Any(), gomock.Eq("an-id")).Times(1).Return(
-			container.InspectResponse{
-				ContainerJSONBase: &container.ContainerJSONBase{
-					ID:   "an-id",
-					Name: "a-name",
-				},
-				Config:          &container.Config{},
-				NetworkSettings: &container.NetworkSettings{},
-			}, nil)
-
-		_, err = tested.(*composeService).createMobyContainer(t.Context(), &project, service, "test", 0, nil, createOptions{
-			Labels: make(types.Labels),
-		})
-		assert.NilError(t, err)
-	})
+		},
+		Name: "test",
+	}
+	assert.DeepEqual(t, want, got, cmpopts.EquateComparable(netip.Addr{}), cmpopts.EquateEmpty())
+	assert.NilError(t, err)
 }

+ 2 - 11
pkg/compose/convert.go

@@ -23,8 +23,7 @@ import (
 	"time"
 
 	compose "github.com/compose-spec/compose-go/v2/types"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/versions"
+	"github.com/moby/moby/api/types/container"
 )
 
 // ToMobyEnv convert into []string
@@ -69,15 +68,7 @@ func (s *composeService) ToMobyHealthCheck(ctx context.Context, check *compose.H
 	}
 	var startInterval time.Duration
 	if check.StartInterval != nil {
-		version, err := s.RuntimeVersion(ctx)
-		if err != nil {
-			return nil, err
-		}
-		if versions.LessThan(version, APIVersion144) {
-			return nil, fmt.Errorf("can't set healthcheck.start_interval as feature require Docker Engine %s or later", DockerEngineV25)
-		} else {
-			startInterval = time.Duration(*check.StartInterval)
-		}
+		startInterval = time.Duration(*check.StartInterval)
 		if check.StartPeriod == nil {
 			// see https://github.com/moby/moby/issues/48874
 			return nil, errors.New("healthcheck.start_interval requires healthcheck.start_period to be set")

+ 35 - 13
pkg/compose/cp.go

@@ -26,8 +26,9 @@ import (
 	"strings"
 
 	"github.com/docker/cli/cli/command"
-	"github.com/docker/docker/api/types/container"
 	"github.com/moby/go-archive"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -153,7 +154,13 @@ func (s *composeService) copyToContainer(ctx context.Context, containerID string
 
 	// Prepare destination copy info by stat-ing the container path.
 	dstInfo := archive.CopyInfo{Path: dstPath}
-	dstStat, err := s.apiClient().ContainerStatPath(ctx, containerID, dstPath)
+	var dstStat container.PathStat
+	res, err := s.apiClient().ContainerStatPath(ctx, containerID, client.ContainerStatPathOptions{
+		Path: dstPath,
+	})
+	if err == nil {
+		dstStat = res.Stat
+	}
 
 	// If the destination is a symbolic link, we should evaluate it.
 	if err == nil && dstStat.Mode&os.ModeSymlink != 0 {
@@ -165,7 +172,12 @@ func (s *composeService) copyToContainer(ctx context.Context, containerID string
 		}
 
 		dstInfo.Path = linkTarget
-		dstStat, err = s.apiClient().ContainerStatPath(ctx, containerID, linkTarget)
+		res, err = s.apiClient().ContainerStatPath(ctx, containerID, client.ContainerStatPathOptions{
+			Path: linkTarget,
+		})
+		if err == nil {
+			dstStat = res.Stat
+		}
 	}
 
 	// Validate the destination path
@@ -232,11 +244,13 @@ func (s *composeService) copyToContainer(ctx context.Context, containerID string
 		}
 	}
 
-	options := container.CopyToContainerOptions{
+	_, err = s.apiClient().CopyToContainer(ctx, containerID, client.CopyToContainerOptions{
+		DestinationPath:           resolvedDstPath,
+		Content:                   content,
 		AllowOverwriteDirWithFile: false,
 		CopyUIDGID:                opts.CopyUIDGID,
-	}
-	return s.apiClient().CopyToContainer(ctx, containerID, resolvedDstPath, content, options)
+	})
+	return err
 }
 
 func (s *composeService) copyFromContainer(ctx context.Context, containerID, srcPath, dstPath string, opts api.CopyOptions) error {
@@ -256,7 +270,13 @@ func (s *composeService) copyFromContainer(ctx context.Context, containerID, src
 	// if client requests to follow symbol link, then must decide target file to be copied
 	var rebaseName string
 	if opts.FollowLink {
-		srcStat, err := s.apiClient().ContainerStatPath(ctx, containerID, srcPath)
+		var srcStat container.PathStat
+		res, err := s.apiClient().ContainerStatPath(ctx, containerID, client.ContainerStatPathOptions{
+			Path: srcPath,
+		})
+		if err == nil {
+			srcStat = res.Stat
+		}
 
 		// If the destination is a symbolic link, we should follow it.
 		if err == nil && srcStat.Mode&os.ModeSymlink != 0 {
@@ -272,28 +292,30 @@ func (s *composeService) copyFromContainer(ctx context.Context, containerID, src
 		}
 	}
 
-	content, stat, err := s.apiClient().CopyFromContainer(ctx, containerID, srcPath)
+	res, err := s.apiClient().CopyFromContainer(ctx, containerID, client.CopyFromContainerOptions{
+		SourcePath: srcPath,
+	})
 	if err != nil {
 		return err
 	}
-	defer content.Close() //nolint:errcheck
+	defer res.Content.Close() //nolint:errcheck
 
 	if dstPath == "-" {
-		_, err = io.Copy(s.stdout(), content)
+		_, err = io.Copy(s.stdout(), res.Content)
 		return err
 	}
 
 	srcInfo := archive.CopyInfo{
 		Path:       srcPath,
 		Exists:     true,
-		IsDir:      stat.Mode.IsDir(),
+		IsDir:      res.Stat.Mode.IsDir(),
 		RebaseName: rebaseName,
 	}
 
-	preArchive := content
+	preArchive := res.Content
 	if srcInfo.RebaseName != "" {
 		_, srcBase := archive.SplitPathDirEntry(srcInfo.Path)
-		preArchive = archive.RebaseArchiveEntries(content, srcBase, srcInfo.RebaseName)
+		preArchive = archive.RebaseArchiveEntries(res.Content, srcBase, srcInfo.RebaseName)
 	}
 
 	return archive.CopyTo(preArchive, srcInfo, dstPath)

+ 228 - 121
pkg/compose/create.go

@@ -22,6 +22,8 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
+	"net"
+	"net/netip"
 	"os"
 	"path/filepath"
 	"slices"
@@ -31,14 +33,12 @@ import (
 	"github.com/compose-spec/compose-go/v2/paths"
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/containerd/errdefs"
-	"github.com/docker/docker/api/types/blkiodev"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/mount"
-	"github.com/docker/docker/api/types/network"
-	"github.com/docker/docker/api/types/versions"
-	volumetypes "github.com/docker/docker/api/types/volume"
-	"github.com/docker/go-connections/nat"
+	"github.com/moby/moby/api/types/blkiodev"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/mount"
+	"github.com/moby/moby/api/types/network"
+	"github.com/moby/moby/client"
+	"github.com/moby/moby/client/pkg/versions"
 	"github.com/sirupsen/logrus"
 	cdi "tags.cncf.io/container-device-interface/pkg/parser"
 
@@ -201,8 +201,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
 		mainNw = service.Networks[mainNwName]
 	}
 
-	macAddress, err := s.prepareContainerMACAddress(ctx, service, mainNw, mainNwName)
-	if err != nil {
+	if err := s.prepareContainerMACAddress(service, mainNw, mainNwName); err != nil {
 		return createConfigs{}, err
 	}
 
@@ -211,7 +210,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
 		return createConfigs{}, err
 	}
 
-	exposed, err := buildContainerPorts(service)
+	exposedPorts, err := buildContainerPorts(service)
 	if err != nil {
 		return createConfigs{}, err
 	}
@@ -220,7 +219,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
 		Hostname:        service.Hostname,
 		Domainname:      service.DomainName,
 		User:            service.User,
-		ExposedPorts:    exposed,
+		ExposedPorts:    exposedPorts,
 		Tty:             tty,
 		OpenStdin:       stdinOpen,
 		StdinOnce:       opts.AttachStdin && stdinOpen,
@@ -232,7 +231,6 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
 		WorkingDir:      service.WorkingDir,
 		Entrypoint:      entrypoint,
 		NetworkDisabled: service.NetworkMode == "disabled",
-		MacAddress:      macAddress, // Field is deprecated since API v1.44, but kept for compatibility with older API versions.
 		Labels:          labels,
 		StopSignal:      service.StopSignal,
 		Env:             ToMobyEnv(env),
@@ -262,7 +260,10 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
 	if err != nil {
 		return createConfigs{}, err
 	}
-	portBindings := buildContainerPortBindingOptions(service)
+	portBindings, err := buildContainerPortBindingOptions(service)
+	if err != nil {
+		return createConfigs{}, err
+	}
 
 	// MISC
 	resources := getDeployResources(service)
@@ -278,6 +279,15 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
 		return createConfigs{}, err
 	}
 
+	var dnsIPs []netip.Addr
+	for _, d := range service.DNS {
+		dnsIP, err := netip.ParseAddr(d)
+		if err != nil {
+			return createConfigs{}, fmt.Errorf("invalid DNS address: %w", err)
+		}
+		dnsIPs = append(dnsIPs, dnsIP)
+	}
+
 	hostConfig := container.HostConfig{
 		AutoRemove:     opts.AutoRemove,
 		Annotations:    service.Annotations,
@@ -297,7 +307,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
 		Resources:      resources,
 		VolumeDriver:   service.VolumeDriver,
 		VolumesFrom:    service.VolumesFrom,
-		DNS:            service.DNS,
+		DNS:            dnsIPs,
 		DNSSearch:      service.DNSSearch,
 		DNSOptions:     service.DNSOpts,
 		ExtraHosts:     service.ExtraHosts.AsList(":"),
@@ -336,12 +346,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context,
 // passed mainNw to provide backward-compatibility whenever possible.
 //
 // It returns the container-wide MAC address, but this value will be kept empty for newer API versions.
-func (s *composeService) prepareContainerMACAddress(ctx context.Context, service types.ServiceConfig, mainNw *types.ServiceNetworkConfig, nwName string) (string, error) {
-	version, err := s.RuntimeVersion(ctx)
-	if err != nil {
-		return "", err
-	}
-
+func (s *composeService) prepareContainerMACAddress(service types.ServiceConfig, mainNw *types.ServiceNetworkConfig, nwName string) error {
 	// Engine API 1.44 added support for endpoint-specific MAC address and now returns a warning when a MAC address is
 	// set in container.Config. Thus, we have to jump through a number of hoops:
 	//
@@ -355,31 +360,12 @@ func (s *composeService) prepareContainerMACAddress(ctx context.Context, service
 	// there's no need to check for API version in defaultNetworkSettings.
 	macAddress := service.MacAddress
 	if macAddress != "" && mainNw != nil && mainNw.MacAddress != "" && mainNw.MacAddress != macAddress {
-		return "", fmt.Errorf("the service-level mac_address should have the same value as network %s", nwName)
-	}
-	if versions.GreaterThanOrEqualTo(version, APIVersion144) {
-		if mainNw != nil && mainNw.MacAddress == "" {
-			mainNw.MacAddress = macAddress
-		}
-		macAddress = ""
-	} else if len(service.Networks) > 0 {
-		var withMacAddress []string
-		for nwName, nw := range service.Networks {
-			if nw != nil && nw.MacAddress != "" {
-				withMacAddress = append(withMacAddress, nwName)
-			}
-		}
-
-		if len(withMacAddress) > 1 {
-			return "", fmt.Errorf("a MAC address is specified for multiple networks (%s), but this feature requires Docker Engine %s or later", strings.Join(withMacAddress, ", "), DockerEngineV25)
-		}
-
-		if mainNw != nil && mainNw.MacAddress != "" {
-			macAddress = mainNw.MacAddress
-		}
+		return fmt.Errorf("the service-level mac_address should have the same value as network %s", nwName)
 	}
-
-	return macAddress, nil
+	if mainNw != nil && mainNw.MacAddress == "" {
+		mainNw.MacAddress = macAddress
+	}
+	return nil
 }
 
 func getAliases(project *types.Project, service types.ServiceConfig, serviceIndex int, cfg *types.ServiceNetworkConfig, useNetworkAliases bool) []string {
@@ -393,25 +379,48 @@ func getAliases(project *types.Project, service types.ServiceConfig, serviceInde
 	return aliases
 }
 
-func createEndpointSettings(p *types.Project, service types.ServiceConfig, serviceIndex int, networkKey string, links []string, useNetworkAliases bool) *network.EndpointSettings {
+func createEndpointSettings(p *types.Project, service types.ServiceConfig, serviceIndex int, networkKey string, links []string, useNetworkAliases bool) (*network.EndpointSettings, error) {
 	const ifname = "com.docker.network.endpoint.ifname"
 
 	config := service.Networks[networkKey]
 	var ipam *network.EndpointIPAMConfig
 	var (
-		ipv4Address string
-		ipv6Address string
+		ipv4Address netip.Addr
+		ipv6Address netip.Addr
 		macAddress  string
 		driverOpts  types.Options
 		gwPriority  int
 	)
 	if config != nil {
-		ipv4Address = config.Ipv4Address
-		ipv6Address = config.Ipv6Address
+		var err error
+		if config.Ipv4Address != "" {
+			ipv4Address, err = netip.ParseAddr(config.Ipv4Address)
+			if err != nil {
+				return nil, fmt.Errorf("invalid IPv4 address: %w", err)
+			}
+		}
+		if config.Ipv6Address != "" {
+			ipv6Address, err = netip.ParseAddr(config.Ipv6Address)
+			if err != nil {
+				return nil, fmt.Errorf("invalid IPv6 address: %w", err)
+			}
+		}
+		var linkLocalIPs []netip.Addr
+		for _, link := range config.LinkLocalIPs {
+			if link == "" {
+				continue
+			}
+			llIP, err := netip.ParseAddr(link)
+			if err != nil {
+				return nil, fmt.Errorf("invalid link-local IP: %w", err)
+			}
+			linkLocalIPs = append(linkLocalIPs, llIP)
+		}
+
 		ipam = &network.EndpointIPAMConfig{
-			IPv4Address:  ipv4Address,
+			IPv4Address:  ipv4Address.Unmap(),
 			IPv6Address:  ipv6Address,
-			LinkLocalIPs: config.LinkLocalIPs,
+			LinkLocalIPs: linkLocalIPs,
 		}
 		macAddress = config.MacAddress
 		driverOpts = config.DriverOpts
@@ -426,16 +435,25 @@ func createEndpointSettings(p *types.Project, service types.ServiceConfig, servi
 		}
 		gwPriority = config.GatewayPriority
 	}
+	var ma network.HardwareAddr
+	if macAddress != "" {
+		var err error
+		ma, err = parseMACAddr(macAddress)
+		if err != nil {
+			return nil, err
+		}
+	}
+
 	return &network.EndpointSettings{
 		Aliases:     getAliases(p, service, serviceIndex, config, useNetworkAliases),
 		Links:       links,
 		IPAddress:   ipv4Address,
 		IPv6Gateway: ipv6Address,
 		IPAMConfig:  ipam,
-		MacAddress:  macAddress,
+		MacAddress:  ma,
 		DriverOpts:  driverOpts,
 		GwPriority:  gwPriority,
-	}
+	}, nil
 }
 
 // copy/pasted from https://github.com/docker/cli/blob/9de1b162f/cli/command/container/opts.go#L673-L697 + RelativePath
@@ -517,24 +535,32 @@ func defaultNetworkSettings(project *types.Project,
 		primaryNetworkKey = "default"
 	}
 	primaryNetworkMobyNetworkName := project.Networks[primaryNetworkKey].Name
-	primaryNetworkEndpoint := createEndpointSettings(project, service, serviceIndex, primaryNetworkKey, links, useNetworkAliases)
+	primaryNetworkEndpoint, err := createEndpointSettings(project, service, serviceIndex, primaryNetworkKey, links, useNetworkAliases)
+	if err != nil {
+		return "", nil, err
+	}
+
 	endpointsConfig := map[string]*network.EndpointSettings{}
 
 	// Starting from API version 1.44, the Engine will take several EndpointsConfigs
 	// so we can pass all the extra networks we want the container to be connected to
 	// in the network configuration instead of connecting the container to each extra
 	// network individually after creation.
-	if versions.GreaterThanOrEqualTo(version, APIVersion144) {
-		if len(service.Networks) > 1 {
-			serviceNetworks := service.NetworksByPriority()
-			for _, networkKey := range serviceNetworks[1:] {
-				mobyNetworkName := project.Networks[networkKey].Name
-				epSettings := createEndpointSettings(project, service, serviceIndex, networkKey, links, useNetworkAliases)
-				endpointsConfig[mobyNetworkName] = epSettings
+	if len(service.Networks) > 1 {
+		serviceNetworks := service.NetworksByPriority()
+		for _, networkKey := range serviceNetworks[1:] {
+			mobyNetworkName := project.Networks[networkKey].Name
+			epSettings, err := createEndpointSettings(project, service, serviceIndex, networkKey, links, useNetworkAliases)
+			if err != nil {
+				return "", nil, err
 			}
+			endpointsConfig[mobyNetworkName] = epSettings
 		}
-		if primaryNetworkEndpoint.MacAddress == "" {
-			primaryNetworkEndpoint.MacAddress = service.MacAddress
+	}
+	if primaryNetworkEndpoint.MacAddress.String() == "" {
+		primaryNetworkEndpoint.MacAddress, err = parseMACAddr(service.MacAddress)
+		if err != nil {
+			return "", nil, err
 		}
 	}
 
@@ -766,37 +792,55 @@ func setBlkio(blkio *types.BlkioConfig, resources *container.Resources) {
 	}
 }
 
-func buildContainerPorts(s types.ServiceConfig) (nat.PortSet, error) {
-	ports := nat.PortSet{}
-	for _, s := range s.Expose {
-		proto, port := nat.SplitProtoPort(s)
-		start, end, err := nat.ParsePortRange(port)
+func buildContainerPorts(s types.ServiceConfig) (network.PortSet, error) {
+	// Add published ports as exposed ports.
+	exposedPorts := network.PortSet{}
+	for _, p := range s.Ports {
+		np, err := network.ParsePort(fmt.Sprintf("%d/%s", p.Target, p.Protocol))
 		if err != nil {
 			return nil, err
 		}
-		for i := start; i <= end; i++ {
-			p := nat.Port(fmt.Sprintf("%d/%s", i, proto))
-			ports[p] = struct{}{}
-		}
+		exposedPorts[np] = struct{}{}
 	}
-	for _, p := range s.Ports {
-		p := nat.Port(fmt.Sprintf("%d/%s", p.Target, p.Protocol))
-		ports[p] = struct{}{}
+
+	// Merge in exposed ports to the map of published ports
+	for _, e := range s.Expose {
+		// support two formats for expose, original format <portnum>/[<proto>]
+		// or <startport-endport>/[<proto>]
+		pr, err := network.ParsePortRange(e)
+		if err != nil {
+			return nil, err
+		}
+		// parse the start and end port and create a sequence of ports to expose
+		// if expose a port, the start and end port are the same
+		for p := range pr.All() {
+			exposedPorts[p] = struct{}{}
+		}
 	}
-	return ports, nil
+	return exposedPorts, nil
 }
 
-func buildContainerPortBindingOptions(s types.ServiceConfig) nat.PortMap {
-	bindings := nat.PortMap{}
+func buildContainerPortBindingOptions(s types.ServiceConfig) (network.PortMap, error) {
+	bindings := network.PortMap{}
 	for _, port := range s.Ports {
-		p := nat.Port(fmt.Sprintf("%d/%s", port.Target, port.Protocol))
-		binding := nat.PortBinding{
-			HostIP:   port.HostIP,
-			HostPort: port.Published,
+		var err error
+		p, err := network.ParsePort(fmt.Sprintf("%d/%s", port.Target, port.Protocol))
+		if err != nil {
+			return nil, err
+		}
+		var hostIP netip.Addr
+		if port.HostIP != "" {
+			hostIP, err = netip.ParseAddr(port.HostIP)
+			if err != nil {
+				return nil, err
+			}
 		}
-		bindings[p] = append(bindings[p], binding)
+		bindings[p] = append(bindings[p], network.PortBinding{
+			HostIP:   hostIP,
+			HostPort: port.Published,
+		})
 	}
-	return bindings
+	return bindings, nil
 }
 
 func getDependentServiceFromMode(mode string) string {
@@ -1283,8 +1327,9 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, project *ty
 	var dangledContainers Containers
 
 	// First, try to find a unique network matching by name or ID
-	inspect, err := s.apiClient().NetworkInspect(ctx, n.Name, network.InspectOptions{})
+	res, err := s.apiClient().NetworkInspect(ctx, n.Name, client.NetworkInspectOptions{})
 	if err == nil {
+		inspect := res.Network
 		// NetworkInspect will match on ID prefix, so double check we get the expected one
 		// as looking for network named `db` we could erroneously match network ID `db9086999caf`
 		if inspect.Name == n.Name || inspect.ID == n.Name {
@@ -1324,22 +1369,22 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, project *ty
 	// ignore other errors. Typically, an ambiguous request by name results in some generic `invalidParameter` error
 
 	// Either not found, or name is ambiguous - use NetworkList to list by name
-	networks, err := s.apiClient().NetworkList(ctx, network.ListOptions{
-		Filters: filters.NewArgs(filters.Arg("name", n.Name)),
+	nwList, err := s.apiClient().NetworkList(ctx, client.NetworkListOptions{
+		Filters: make(client.Filters).Add("name", n.Name),
 	})
 	if err != nil {
 		return "", err
 	}
 
 	// NetworkList Matches all or part of a network name, so we have to filter for a strict match
-	networks = slices.DeleteFunc(networks, func(net network.Summary) bool {
+	networks := slices.DeleteFunc(nwList.Items, func(net network.Summary) bool {
 		return net.Name != n.Name
 	})
 
-	for _, net := range networks {
-		if net.Labels[api.ProjectLabel] == project.Name &&
-			net.Labels[api.NetworkLabel] == name {
-			return net.ID, nil
+	for _, nw := range networks {
+		if nw.Labels[api.ProjectLabel] == project.Name &&
+			nw.Labels[api.NetworkLabel] == name {
+			return nw.ID, nil
 		}
 	}
 
@@ -1356,12 +1401,11 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, project *ty
 	if n.Ipam.Config != nil {
 		var config []network.IPAMConfig
 		for _, pool := range n.Ipam.Config {
-			config = append(config, network.IPAMConfig{
-				Subnet:     pool.Subnet,
-				IPRange:    pool.IPRange,
-				Gateway:    pool.Gateway,
-				AuxAddress: pool.AuxiliaryAddresses,
-			})
+			c, err := parseIPAMPool(pool)
+			if err != nil {
+				return "", err
+			}
+			config = append(config, c)
 		}
 		ipam = &network.IPAM{
 			Driver: n.Ipam.Driver,
@@ -1373,7 +1417,7 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, project *ty
 		return "", err
 	}
 	n.CustomLabels = n.CustomLabels.Add(api.ConfigHashLabel, hash)
-	createOpts := network.CreateOptions{
+	createOpts := client.NetworkCreateOptions{
 		Labels:     mergeLabels(n.Labels, n.CustomLabels),
 		Driver:     n.Driver,
 		Options:    n.DriverOpts,
@@ -1393,13 +1437,11 @@ func (s *composeService) resolveOrCreateNetwork(ctx context.Context, project *ty
 	}
 
 	for _, ipamConfig := range n.Ipam.Config {
-		config := network.IPAMConfig{
-			Subnet:     ipamConfig.Subnet,
-			IPRange:    ipamConfig.IPRange,
-			Gateway:    ipamConfig.Gateway,
-			AuxAddress: ipamConfig.AuxiliaryAddresses,
+		c, err := parseIPAMPool(ipamConfig)
+		if err != nil {
+			return "", err
 		}
-		createOpts.IPAM.Config = append(createOpts.IPAM.Config, config)
+		createOpts.IPAM.Config = append(createOpts.IPAM.Config, c)
 	}
 
 	networkEventName := fmt.Sprintf("Network %s", n.Name)
@@ -1450,7 +1492,7 @@ func (s *composeService) removeDivergedNetwork(ctx context.Context, project *typ
 		return nil, err
 	}
 
-	err = s.apiClient().NetworkRemove(ctx, n.Name)
+	_, err = s.apiClient().NetworkRemove(ctx, n.Name, client.NetworkRemoveOptions{})
 	eventName := fmt.Sprintf("Network %s", n.Name)
 	s.events.On(removedEvent(eventName))
 	return containers, err
@@ -1462,7 +1504,10 @@ func (s *composeService) disconnectNetwork(
 	containers Containers,
 ) error {
 	for _, c := range containers {
-		err := s.apiClient().NetworkDisconnect(ctx, nwName, c.ID, true)
+		_, err := s.apiClient().NetworkDisconnect(ctx, nwName, client.NetworkDisconnectOptions{
+			Container: c.ID,
+			Force:     true,
+		})
 		if err != nil {
 			return err
 		}
@@ -1478,7 +1523,10 @@ func (s *composeService) connectNetwork(
 	config *network.EndpointSettings,
 ) error {
 	for _, c := range containers {
-		err := s.apiClient().NetworkConnect(ctx, nwName, c.ID, config)
+		_, err := s.apiClient().NetworkConnect(ctx, nwName, client.NetworkConnectOptions{
+			Container:      c.ID,
+			EndpointConfig: config,
+		})
 		if err != nil {
 			return err
 		}
@@ -1492,26 +1540,26 @@ func (s *composeService) resolveExternalNetwork(ctx context.Context, n *types.Ne
 	// filter is used to look for an exact match to prevent e.g. a network
 	// named `db` from getting erroneously matched to a network with an ID
 	// like `db9086999caf`
-	networks, err := s.apiClient().NetworkList(ctx, network.ListOptions{
-		Filters: filters.NewArgs(filters.Arg("name", n.Name)),
+	res, err := s.apiClient().NetworkList(ctx, client.NetworkListOptions{
+		Filters: make(client.Filters).Add("name", n.Name),
 	})
 	if err != nil {
 		return "", err
 	}
+	networks := res.Items
 
 	if len(networks) == 0 {
 		// in this instance, n.Name is really an ID
-		sn, err := s.apiClient().NetworkInspect(ctx, n.Name, network.InspectOptions{})
+		sn, err := s.apiClient().NetworkInspect(ctx, n.Name, client.NetworkInspectOptions{})
 		if err == nil {
-			networks = append(networks, sn)
+			networks = append(networks, network.Summary{Network: sn.Network.Network})
 		} else if !errdefs.IsNotFound(err) {
 			return "", err
 		}
-
 	}
 
 	// NetworkList API doesn't return the exact name match, so we can retrieve more than one network with a request
-	networks = slices.DeleteFunc(networks, func(net network.Inspect) bool {
+	networks = slices.DeleteFunc(networks, func(net network.Summary) bool {
 		// this function is called during the rebuild stage of `compose watch`.
 		// we still require just one network back, but we need to run the search on the ID
 		return net.Name != n.Name && net.ID != n.Name
@@ -1539,7 +1587,7 @@ func (s *composeService) resolveExternalNetwork(ctx context.Context, n *types.Ne
 }
 
 func (s *composeService) ensureVolume(ctx context.Context, name string, volume types.VolumeConfig, project *types.Project) (string, error) {
-	inspected, err := s.apiClient().VolumeInspect(ctx, volume.Name)
+	inspected, err := s.apiClient().VolumeInspect(ctx, volume.Name, client.VolumeInspectOptions{})
 	if err != nil {
 		if !errdefs.IsNotFound(err) {
 			return "", err
@@ -1556,7 +1604,7 @@ func (s *composeService) ensureVolume(ctx context.Context, name string, volume t
 	}
 
 	// Volume exists with name, but let's double-check this is the expected one
-	p, ok := inspected.Labels[api.ProjectLabel]
+	p, ok := inspected.Volume.Labels[api.ProjectLabel]
 	if !ok {
 		logrus.Warnf("volume %q already exists but was not created by Docker Compose. Use `external: true` to use an existing volume", volume.Name)
 	}
@@ -1568,7 +1616,7 @@ func (s *composeService) ensureVolume(ctx context.Context, name string, volume t
 	if err != nil {
 		return "", err
 	}
-	actual, ok := inspected.Labels[api.ConfigHashLabel]
+	actual, ok := inspected.Volume.Labels[api.ConfigHashLabel]
 	if ok && actual != expected {
 		msg := fmt.Sprintf("Volume %q exists but doesn't match configuration in compose file. Recreate (data will be lost)?", volume.Name)
 		confirm, err := s.prompt(msg, false)
@@ -1583,7 +1631,7 @@ func (s *composeService) ensureVolume(ctx context.Context, name string, volume t
 			return volume.Name, s.createVolume(ctx, volume)
 		}
 	}
-	return inspected.Name, nil
+	return inspected.Volume.Name, nil
 }
 
 func (s *composeService) removeDivergedVolume(ctx context.Context, name string, volume types.VolumeConfig, project *types.Project) error {
@@ -1623,7 +1671,10 @@ func (s *composeService) removeDivergedVolume(ctx context.Context, name string,
 		return err
 	}
 
-	return s.apiClient().VolumeRemove(ctx, volume.Name, true)
+	_, err = s.apiClient().VolumeRemove(ctx, volume.Name, client.VolumeRemoveOptions{
+		Force: true,
+	})
+	return err
 }
 
 func (s *composeService) createVolume(ctx context.Context, volume types.VolumeConfig) error {
@@ -1634,7 +1685,7 @@ func (s *composeService) createVolume(ctx context.Context, volume types.VolumeCo
 		return err
 	}
 	volume.CustomLabels.Add(api.ConfigHashLabel, hash)
-	_, err = s.apiClient().VolumeCreate(ctx, volumetypes.CreateOptions{
+	_, err = s.apiClient().VolumeCreate(ctx, client.VolumeCreateOptions{
 		Labels:     mergeLabels(volume.Labels, volume.CustomLabels),
 		Name:       volume.Name,
 		Driver:     volume.Driver,
@@ -1647,3 +1698,59 @@ func (s *composeService) createVolume(ctx context.Context, volume types.VolumeCo
 	s.events.On(createdEvent(eventName))
 	return nil
 }
+
+func parseIPAMPool(pool *types.IPAMPool) (network.IPAMConfig, error) {
+	var (
+		err        error
+		subNet     netip.Prefix
+		ipRange    netip.Prefix
+		gateway    netip.Addr
+		auxAddress map[string]netip.Addr
+	)
+	if pool.Subnet != "" {
+		subNet, err = netip.ParsePrefix(pool.Subnet)
+		if err != nil {
+			return network.IPAMConfig{}, fmt.Errorf("invalid subnet: %w", err)
+		}
+	}
+	if pool.IPRange != "" {
+		ipRange, err = netip.ParsePrefix(pool.IPRange)
+		if err != nil {
+			return network.IPAMConfig{}, fmt.Errorf("invalid ip-range: %w", err)
+		}
+	}
+	if pool.Gateway != "" {
+		gateway, err = netip.ParseAddr(pool.Gateway)
+		if err != nil {
+			return network.IPAMConfig{}, fmt.Errorf("invalid gateway address: %w", err)
+		}
+	}
+	if len(pool.AuxiliaryAddresses) > 0 {
+		auxAddress = make(map[string]netip.Addr, len(pool.AuxiliaryAddresses))
+		for auxName, addr := range pool.AuxiliaryAddresses {
+			auxAddr, err := netip.ParseAddr(addr)
+			if err != nil {
+				return network.IPAMConfig{}, fmt.Errorf("invalid auxiliary address: %w", err)
+			}
+			auxAddress[auxName] = auxAddr
+		}
+
+	}
+	return network.IPAMConfig{
+		Subnet:     subNet,
+		IPRange:    ipRange,
+		Gateway:    gateway,
+		AuxAddress: auxAddress,
+	}, nil
+}
+
+func parseMACAddr(macAddress string) (network.HardwareAddr, error) {
+	if macAddress == "" {
+		return nil, nil
+	}
+	m, err := net.ParseMAC(macAddress)
+	if err != nil {
+		return nil, fmt.Errorf("invalid MAC address: %w", err)
+	}
+	return network.HardwareAddr(m), nil
+}

+ 26 - 20
pkg/compose/create_test.go

@@ -17,6 +17,8 @@
 package compose
 
 import (
+	"net"
+	"net/netip"
 	"os"
 	"path/filepath"
 	"sort"
@@ -24,10 +26,11 @@ import (
 
 	composeloader "github.com/compose-spec/compose-go/v2/loader"
 	composetypes "github.com/compose-spec/compose-go/v2/types"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/image"
-	mountTypes "github.com/docker/docker/api/types/mount"
-	"github.com/docker/docker/api/types/network"
+	"github.com/google/go-cmp/cmp/cmpopts"
+	"github.com/moby/moby/api/types/container"
+	mountTypes "github.com/moby/moby/api/types/mount"
+	"github.com/moby/moby/api/types/network"
+	"github.com/moby/moby/client"
 	"go.uber.org/mock/gomock"
 	"gotest.tools/v3/assert"
 	"gotest.tools/v3/assert/cmp"
@@ -161,7 +164,7 @@ func TestBuildContainerMountOptions(t *testing.T) {
 	s := composeService{
 		dockerCli: cli,
 	}
-	mock.EXPECT().ImageInspect(gomock.Any(), "myProject-myService").AnyTimes().Return(image.InspectResponse{}, nil)
+	mock.EXPECT().ImageInspect(gomock.Any(), "myProject-myService").AnyTimes().Return(client.ImageInspectResult{}, nil)
 
 	mounts, err := s.buildContainerMountOptions(t.Context(), project, project.Services["myService"], inherit)
 	sort.Slice(mounts, func(i, j int) bool {
@@ -189,7 +192,7 @@ func TestBuildContainerMountOptions(t *testing.T) {
 }
 
 func TestDefaultNetworkSettings(t *testing.T) {
-	t.Run("returns the network with the highest priority when service has multiple networks", func(t *testing.T) {
+	t.Run("returns the network with the highest priority as primary when service has multiple networks", func(t *testing.T) {
 		service := composetypes.ServiceConfig{
 			Name: "myService",
 			Networks: map[string]*composetypes.ServiceNetworkConfig{
@@ -216,10 +219,11 @@ func TestDefaultNetworkSettings(t *testing.T) {
 			}),
 		}
 
-		networkMode, networkConfig, err := defaultNetworkSettings(&project, service, 1, nil, true, "1.43")
+		networkMode, networkConfig, err := defaultNetworkSettings(&project, service, 1, nil, true, "1.44")
 		assert.NilError(t, err)
 		assert.Equal(t, string(networkMode), "myProject_myNetwork2")
-		assert.Check(t, cmp.Len(networkConfig.EndpointsConfig, 1))
+		assert.Check(t, cmp.Len(networkConfig.EndpointsConfig, 2))
+		assert.Check(t, cmp.Contains(networkConfig.EndpointsConfig, "myProject_myNetwork1"))
 		assert.Check(t, cmp.Contains(networkConfig.EndpointsConfig, "myProject_myNetwork2"))
 	})
 
@@ -245,7 +249,7 @@ func TestDefaultNetworkSettings(t *testing.T) {
 			}),
 		}
 
-		networkMode, networkConfig, err := defaultNetworkSettings(&project, service, 1, nil, true, "1.43")
+		networkMode, networkConfig, err := defaultNetworkSettings(&project, service, 1, nil, true, "1.44")
 		assert.NilError(t, err)
 		assert.Equal(t, string(networkMode), "myProject_default")
 		assert.Check(t, cmp.Len(networkConfig.EndpointsConfig, 1))
@@ -263,7 +267,7 @@ func TestDefaultNetworkSettings(t *testing.T) {
 			},
 		}
 
-		networkMode, networkConfig, err := defaultNetworkSettings(&project, service, 1, nil, true, "1.43")
+		networkMode, networkConfig, err := defaultNetworkSettings(&project, service, 1, nil, true, "1.44")
 		assert.NilError(t, err)
 		assert.Equal(t, string(networkMode), "none")
 		assert.Check(t, cmp.Nil(networkConfig))
@@ -284,7 +288,7 @@ func TestDefaultNetworkSettings(t *testing.T) {
 			}),
 		}
 
-		networkMode, networkConfig, err := defaultNetworkSettings(&project, service, 1, nil, true, "1.43")
+		networkMode, networkConfig, err := defaultNetworkSettings(&project, service, 1, nil, true, "1.44")
 		assert.NilError(t, err)
 		assert.Equal(t, string(networkMode), "host")
 		assert.Check(t, cmp.Nil(networkConfig))
@@ -292,7 +296,7 @@ func TestDefaultNetworkSettings(t *testing.T) {
 }
 
 func TestCreateEndpointSettings(t *testing.T) {
-	eps := createEndpointSettings(&composetypes.Project{
+	eps, err := createEndpointSettings(&composetypes.Project{
 		Name: "projName",
 	}, composetypes.ServiceConfig{
 		Name:          "serviceName",
@@ -304,7 +308,7 @@ func TestCreateEndpointSettings(t *testing.T) {
 				Ipv4Address:  "10.16.17.18",
 				Ipv6Address:  "fdb4:7a7f:373a:3f0c::42",
 				LinkLocalIPs: []string{"169.254.10.20"},
-				MacAddress:   "10:00:00:00:01",
+				MacAddress:   "02:00:00:00:00:01",
 				DriverOpts: composetypes.Options{
 					"driverOpt1": "optval1",
 					"driverOpt2": "optval2",
@@ -312,15 +316,17 @@ func TestCreateEndpointSettings(t *testing.T) {
 			},
 		},
 	}, 0, "netName", []string{"link1", "link2"}, true)
+	assert.NilError(t, err)
+	macAddr, _ := net.ParseMAC("02:00:00:00:00:01")
 	assert.Check(t, cmp.DeepEqual(eps, &network.EndpointSettings{
 		IPAMConfig: &network.EndpointIPAMConfig{
-			IPv4Address:  "10.16.17.18",
-			IPv6Address:  "fdb4:7a7f:373a:3f0c::42",
-			LinkLocalIPs: []string{"169.254.10.20"},
+			IPv4Address:  netip.MustParseAddr("10.16.17.18").Unmap(),
+			IPv6Address:  netip.MustParseAddr("fdb4:7a7f:373a:3f0c::42"),
+			LinkLocalIPs: []netip.Addr{netip.MustParseAddr("169.254.10.20").Unmap()},
 		},
 		Links:      []string{"link1", "link2"},
 		Aliases:    []string{"containerName", "serviceName", "alias1", "alias2"},
-		MacAddress: "10:00:00:00:01",
+		MacAddress: network.HardwareAddr(macAddr),
 		DriverOpts: map[string]string{
 			"driverOpt1": "optval1",
 			"driverOpt2": "optval2",
@@ -330,9 +336,9 @@ func TestCreateEndpointSettings(t *testing.T) {
 		//  - The IPv6 address here is the container's address, not the gateway.
 		//  - Both fields will be cleared by the daemon, but they could be removed from
 		//    the request.
-		IPAddress:   "10.16.17.18",
-		IPv6Gateway: "fdb4:7a7f:373a:3f0c::42",
-	}))
+		IPAddress:   netip.MustParseAddr("10.16.17.18").Unmap(),
+		IPv6Gateway: netip.MustParseAddr("fdb4:7a7f:373a:3f0c::42"),
+	}, cmpopts.EquateComparable(netip.Addr{})))
 }
 
 func Test_buildContainerVolumes(t *testing.T) {

+ 4 - 2
pkg/compose/desktop.go

@@ -19,6 +19,8 @@ package compose
 import (
 	"context"
 	"strings"
+
+	"github.com/moby/moby/client"
 )
 
 // engineLabelDesktopAddress is used to detect that Compose is running with a
@@ -27,11 +29,11 @@ import (
 const engineLabelDesktopAddress = "com.docker.desktop.address"
 
 func (s *composeService) isDesktopIntegrationActive(ctx context.Context) (bool, error) {
-	info, err := s.apiClient().Info(ctx)
+	res, err := s.apiClient().Info(ctx, client.InfoOptions{})
 	if err != nil {
 		return false, err
 	}
-	for _, l := range info.Labels {
+	for _, l := range res.Info.Labels {
 		k, _, ok := strings.Cut(l, "=")
 		if ok && k == engineLabelDesktopAddress {
 			return true, nil

+ 17 - 16
pkg/compose/down.go

@@ -24,10 +24,8 @@ import (
 
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/containerd/errdefs"
-	containerType "github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	imageapi "github.com/docker/docker/api/types/image"
-	"github.com/docker/docker/api/types/network"
+	containerType "github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"github.com/sirupsen/logrus"
 	"golang.org/x/sync/errgroup"
 
@@ -196,14 +194,13 @@ func (s *composeService) ensureNetworksDown(ctx context.Context, project *types.
 }
 
 func (s *composeService) removeNetwork(ctx context.Context, composeNetworkName string, projectName string, name string) error {
-	networks, err := s.apiClient().NetworkList(ctx, network.ListOptions{
-		Filters: filters.NewArgs(
-			projectFilter(projectName),
-			networkFilter(composeNetworkName)),
+	res, err := s.apiClient().NetworkList(ctx, client.NetworkListOptions{
+		Filters: projectFilter(projectName).Add("label", networkFilter(composeNetworkName)),
 	})
 	if err != nil {
 		return fmt.Errorf("failed to list networks: %w", err)
 	}
+	networks := res.Items
 
 	if len(networks) == 0 {
 		return nil
@@ -217,7 +214,7 @@ func (s *composeService) removeNetwork(ctx context.Context, composeNetworkName s
 		if net.Name != name {
 			continue
 		}
-		nw, err := s.apiClient().NetworkInspect(ctx, net.ID, network.InspectOptions{})
+		nwInspect, err := s.apiClient().NetworkInspect(ctx, net.ID, client.NetworkInspectOptions{})
 		if errdefs.IsNotFound(err) {
 			s.events.On(newEvent(eventName, api.Warning, "No resource found to remove"))
 			return nil
@@ -225,13 +222,14 @@ func (s *composeService) removeNetwork(ctx context.Context, composeNetworkName s
 		if err != nil {
 			return err
 		}
+		nw := nwInspect.Network
 		if len(nw.Containers) > 0 {
 			s.events.On(newEvent(eventName, api.Warning, "Resource is still in use"))
 			found++
 			continue
 		}
 
-		if err := s.apiClient().NetworkRemove(ctx, net.ID); err != nil {
+		if _, err := s.apiClient().NetworkRemove(ctx, net.ID, client.NetworkRemoveOptions{}); err != nil {
 			if errdefs.IsNotFound(err) {
 				continue
 			}
@@ -255,7 +253,7 @@ func (s *composeService) removeNetwork(ctx context.Context, composeNetworkName s
 func (s *composeService) removeImage(ctx context.Context, image string) error {
 	id := fmt.Sprintf("Image %s", image)
 	s.events.On(newEvent(id, api.Working, "Removing"))
-	_, err := s.apiClient().ImageRemove(ctx, image, imageapi.RemoveOptions{})
+	_, err := s.apiClient().ImageRemove(ctx, image, client.ImageRemoveOptions{})
 	if err == nil {
 		s.events.On(newEvent(id, api.Done, "Removed"))
 		return nil
@@ -274,14 +272,16 @@ func (s *composeService) removeImage(ctx context.Context, image string) error {
 func (s *composeService) removeVolume(ctx context.Context, id string) error {
 	resource := fmt.Sprintf("Volume %s", id)
 
-	_, err := s.apiClient().VolumeInspect(ctx, id)
+	_, err := s.apiClient().VolumeInspect(ctx, id, client.VolumeInspectOptions{})
 	if errdefs.IsNotFound(err) {
 		// Already gone
 		return nil
 	}
 
 	s.events.On(newEvent(resource, api.Working, "Removing"))
-	err = s.apiClient().VolumeRemove(ctx, id, true)
+	_, err = s.apiClient().VolumeRemove(ctx, id, client.VolumeRemoveOptions{
+		Force: true,
+	})
 	if err == nil {
 		s.events.On(newEvent(resource, api.Done, "Removed"))
 		return nil
@@ -314,8 +314,9 @@ func (s *composeService) stopContainer(ctx context.Context, service *types.Servi
 		}
 	}
 
-	timeoutInSecond := utils.DurationSecondToInt(timeout)
-	err := s.apiClient().ContainerStop(ctx, ctr.ID, containerType.StopOptions{Timeout: timeoutInSecond})
+	_, err := s.apiClient().ContainerStop(ctx, ctr.ID, client.ContainerStopOptions{
+		Timeout: utils.DurationSecondToInt(timeout),
+	})
 	if err != nil {
 		s.events.On(errorEvent(eventName, "Error while Stopping"))
 		return err
@@ -355,7 +356,7 @@ func (s *composeService) stopAndRemoveContainer(ctx context.Context, ctr contain
 		return err
 	}
 	s.events.On(removingEvent(eventName))
-	err = s.apiClient().ContainerRemove(ctx, ctr.ID, containerType.RemoveOptions{
+	_, err = s.apiClient().ContainerRemove(ctx, ctr.ID, client.ContainerRemoveOptions{
 		Force:         true,
 		RemoveVolumes: volumes,
 	})

+ 148 - 144
pkg/compose/down_test.go

@@ -25,11 +25,11 @@ import (
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/containerd/errdefs"
 	"github.com/docker/cli/cli/streams"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/image"
-	"github.com/docker/docker/api/types/network"
-	"github.com/docker/docker/api/types/volume"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/image"
+	"github.com/moby/moby/api/types/network"
+	"github.com/moby/moby/api/types/volume"
+	"github.com/moby/moby/client"
 	"go.uber.org/mock/gomock"
 	"gotest.tools/v3/assert"
 
@@ -46,48 +46,50 @@ func TestDown(t *testing.T) {
 	assert.NilError(t, err)
 
 	api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return(
-		[]container.Summary{
+		client.ContainerListResult{Items: []container.Summary{
 			testContainer("service1", "123", false),
 			testContainer("service2", "456", false),
 			testContainer("service2", "789", false),
 			testContainer("service_orphan", "321", true),
-		}, nil)
+		}}, nil)
 	api.EXPECT().VolumeList(
 		gomock.Any(),
-		volume.ListOptions{
-			Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject))),
+		client.VolumeListOptions{
+			Filters: projectFilter(strings.ToLower(testProject)),
 		}).
-		Return(volume.ListResponse{}, nil)
+		Return(client.VolumeListResult{}, nil)
 
 	// network names are not guaranteed to be unique, ensure Compose handles
 	// cleanup properly if duplicates are inadvertently created
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
-		Return([]network.Summary{
-			{ID: "abc123", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}},
-			{ID: "def456", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}},
-		}, nil)
-
-	stopOptions := container.StopOptions{}
-	api.EXPECT().ContainerStop(gomock.Any(), "123", stopOptions).Return(nil)
-	api.EXPECT().ContainerStop(gomock.Any(), "456", stopOptions).Return(nil)
-	api.EXPECT().ContainerStop(gomock.Any(), "789", stopOptions).Return(nil)
-
-	api.EXPECT().ContainerRemove(gomock.Any(), "123", container.RemoveOptions{Force: true}).Return(nil)
-	api.EXPECT().ContainerRemove(gomock.Any(), "456", container.RemoveOptions{Force: true}).Return(nil)
-	api.EXPECT().ContainerRemove(gomock.Any(), "789", container.RemoveOptions{Force: true}).Return(nil)
-
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{
-		Filters: filters.NewArgs(
-			projectFilter(strings.ToLower(testProject)),
-			networkFilter("default")),
-	}).Return([]network.Summary{
-		{ID: "abc123", Name: "myProject_default"},
-		{ID: "def456", Name: "myProject_default"},
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{Filters: projectFilter(strings.ToLower(testProject))}).
+		Return(client.NetworkListResult{Items: []network.Summary{
+			{Network: network.Network{ID: "abc123", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}}},
+			{Network: network.Network{ID: "def456", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}}},
+		}}, nil)
+
+	stopOptions := client.ContainerStopOptions{}
+	api.EXPECT().ContainerStop(gomock.Any(), "123", stopOptions).Return(client.ContainerStopResult{}, nil)
+	api.EXPECT().ContainerStop(gomock.Any(), "456", stopOptions).Return(client.ContainerStopResult{}, nil)
+	api.EXPECT().ContainerStop(gomock.Any(), "789", stopOptions).Return(client.ContainerStopResult{}, nil)
+
+	api.EXPECT().ContainerRemove(gomock.Any(), "123", client.ContainerRemoveOptions{Force: true}).Return(client.ContainerRemoveResult{}, nil)
+	api.EXPECT().ContainerRemove(gomock.Any(), "456", client.ContainerRemoveOptions{Force: true}).Return(client.ContainerRemoveResult{}, nil)
+	api.EXPECT().ContainerRemove(gomock.Any(), "789", client.ContainerRemoveOptions{Force: true}).Return(client.ContainerRemoveResult{}, nil)
+
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{
+		Filters: projectFilter(strings.ToLower(testProject)).Add("label", networkFilter("default")),
+	}).Return(client.NetworkListResult{Items: []network.Summary{
+		{Network: network.Network{ID: "abc123", Name: "myProject_default"}},
+		{Network: network.Network{ID: "def456", Name: "myProject_default"}},
+	}}, nil)
+	api.EXPECT().NetworkInspect(gomock.Any(), "abc123", gomock.Any()).Return(client.NetworkInspectResult{
+		Network: network.Inspect{Network: network.Network{ID: "abc123"}},
+	}, nil)
+	api.EXPECT().NetworkInspect(gomock.Any(), "def456", gomock.Any()).Return(client.NetworkInspectResult{
+		Network: network.Inspect{Network: network.Network{ID: "def456"}},
 	}, nil)
-	api.EXPECT().NetworkInspect(gomock.Any(), "abc123", gomock.Any()).Return(network.Inspect{ID: "abc123"}, nil)
-	api.EXPECT().NetworkInspect(gomock.Any(), "def456", gomock.Any()).Return(network.Inspect{ID: "def456"}, nil)
-	api.EXPECT().NetworkRemove(gomock.Any(), "abc123").Return(nil)
-	api.EXPECT().NetworkRemove(gomock.Any(), "def456").Return(nil)
+	api.EXPECT().NetworkRemove(gomock.Any(), "abc123", gomock.Any()).Return(client.NetworkRemoveResult{}, nil)
+	api.EXPECT().NetworkRemove(gomock.Any(), "def456", gomock.Any()).Return(client.NetworkRemoveResult{}, nil)
 
 	err = tested.Down(t.Context(), strings.ToLower(testProject), compose.DownOptions{})
 	assert.NilError(t, err)
@@ -101,42 +103,40 @@ func TestDownWithGivenServices(t *testing.T) {
 	tested, err := NewComposeService(cli)
 	assert.NilError(t, err)
 
-	api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return(
-		[]container.Summary{
+	api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return(client.ContainerListResult{
+		Items: []container.Summary{
 			testContainer("service1", "123", false),
 			testContainer("service2", "456", false),
 			testContainer("service2", "789", false),
 			testContainer("service_orphan", "321", true),
-		}, nil)
+		},
+	}, nil)
 	api.EXPECT().VolumeList(
 		gomock.Any(),
-		volume.ListOptions{
-			Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject))),
+		client.VolumeListOptions{
+			Filters: projectFilter(strings.ToLower(testProject)),
 		}).
-		Return(volume.ListResponse{}, nil)
+		Return(client.VolumeListResult{}, nil)
 
 	// network names are not guaranteed to be unique, ensure Compose handles
 	// cleanup properly if duplicates are inadvertently created
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
-		Return([]network.Summary{
-			{ID: "abc123", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}},
-			{ID: "def456", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}},
-		}, nil)
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{Filters: projectFilter(strings.ToLower(testProject))}).
+		Return(client.NetworkListResult{Items: []network.Summary{
+			{Network: network.Network{ID: "abc123", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}}},
+			{Network: network.Network{ID: "def456", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}}},
+		}}, nil)
 
-	stopOptions := container.StopOptions{}
-	api.EXPECT().ContainerStop(gomock.Any(), "123", stopOptions).Return(nil)
+	api.EXPECT().ContainerStop(gomock.Any(), "123", client.ContainerStopOptions{}).Return(client.ContainerStopResult{}, nil)
 
-	api.EXPECT().ContainerRemove(gomock.Any(), "123", container.RemoveOptions{Force: true}).Return(nil)
+	api.EXPECT().ContainerRemove(gomock.Any(), "123", client.ContainerRemoveOptions{Force: true}).Return(client.ContainerRemoveResult{}, nil)
 
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{
-		Filters: filters.NewArgs(
-			projectFilter(strings.ToLower(testProject)),
-			networkFilter("default")),
-	}).Return([]network.Summary{
-		{ID: "abc123", Name: "myProject_default"},
-	}, nil)
-	api.EXPECT().NetworkInspect(gomock.Any(), "abc123", gomock.Any()).Return(network.Inspect{ID: "abc123"}, nil)
-	api.EXPECT().NetworkRemove(gomock.Any(), "abc123").Return(nil)
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{
+		Filters: projectFilter(strings.ToLower(testProject)).Add("label", networkFilter("default")),
+	}).Return(client.NetworkListResult{Items: []network.Summary{
+		{Network: network.Network{ID: "abc123", Name: "myProject_default"}},
+	}}, nil)
+	api.EXPECT().NetworkInspect(gomock.Any(), "abc123", gomock.Any()).Return(client.NetworkInspectResult{Network: network.Inspect{Network: network.Network{ID: "abc123"}}}, nil)
+	api.EXPECT().NetworkRemove(gomock.Any(), "abc123", gomock.Any()).Return(client.NetworkRemoveResult{}, nil)
 
 	err = tested.Down(t.Context(), strings.ToLower(testProject), compose.DownOptions{
 		Services: []string{"service1", "not-running-service"},
@@ -152,27 +152,28 @@ func TestDownWithSpecifiedServiceButTheServicesAreNotRunning(t *testing.T) {
 	tested, err := NewComposeService(cli)
 	assert.NilError(t, err)
 
-	api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return(
-		[]container.Summary{
+	api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return(client.ContainerListResult{
+		Items: []container.Summary{
 			testContainer("service1", "123", false),
 			testContainer("service2", "456", false),
 			testContainer("service2", "789", false),
 			testContainer("service_orphan", "321", true),
-		}, nil)
+		},
+	}, nil)
 	api.EXPECT().VolumeList(
 		gomock.Any(),
-		volume.ListOptions{
-			Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject))),
+		client.VolumeListOptions{
+			Filters: projectFilter(strings.ToLower(testProject)),
 		}).
-		Return(volume.ListResponse{}, nil)
+		Return(client.VolumeListResult{}, nil)
 
 	// network names are not guaranteed to be unique, ensure Compose handles
 	// cleanup properly if duplicates are inadvertently created
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
-		Return([]network.Summary{
-			{ID: "abc123", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}},
-			{ID: "def456", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}},
-		}, nil)
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{Filters: projectFilter(strings.ToLower(testProject))}).
+		Return(client.NetworkListResult{Items: []network.Summary{
+			{Network: network.Network{ID: "abc123", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}}},
+			{Network: network.Network{ID: "def456", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}}},
+		}}, nil)
 
 	err = tested.Down(t.Context(), strings.ToLower(testProject), compose.DownOptions{
 		Services: []string{"not-running-service1", "not-running-service2"},
@@ -189,42 +190,47 @@ func TestDownRemoveOrphans(t *testing.T) {
 	assert.NilError(t, err)
 
 	api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(true)).Return(
-		[]container.Summary{
-			testContainer("service1", "123", false),
-			testContainer("service2", "789", false),
-			testContainer("service_orphan", "321", true),
+		client.ContainerListResult{
+			Items: []container.Summary{
+				testContainer("service1", "123", false),
+				testContainer("service2", "789", false),
+				testContainer("service_orphan", "321", true),
+			},
 		}, nil)
 	api.EXPECT().VolumeList(
 		gomock.Any(),
-		volume.ListOptions{
-			Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject))),
+		client.VolumeListOptions{
+			Filters: projectFilter(strings.ToLower(testProject)),
 		}).
-		Return(volume.ListResponse{}, nil)
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
-		Return([]network.Summary{
-			{
-				Name:   "myProject_default",
-				Labels: map[string]string{compose.NetworkLabel: "default"},
-			},
+		Return(client.VolumeListResult{}, nil)
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{Filters: projectFilter(strings.ToLower(testProject))}).
+		Return(client.NetworkListResult{
+			Items: []network.Summary{{
+				Network: network.Network{
+					Name:   "myProject_default",
+					Labels: map[string]string{compose.NetworkLabel: "default"},
+				},
+			}},
 		}, nil)
 
-	stopOptions := container.StopOptions{}
-	api.EXPECT().ContainerStop(gomock.Any(), "123", stopOptions).Return(nil)
-	api.EXPECT().ContainerStop(gomock.Any(), "789", stopOptions).Return(nil)
-	api.EXPECT().ContainerStop(gomock.Any(), "321", stopOptions).Return(nil)
+	stopOptions := client.ContainerStopOptions{}
+	api.EXPECT().ContainerStop(gomock.Any(), "123", stopOptions).Return(client.ContainerStopResult{}, nil)
+	api.EXPECT().ContainerStop(gomock.Any(), "789", stopOptions).Return(client.ContainerStopResult{}, nil)
+	api.EXPECT().ContainerStop(gomock.Any(), "321", stopOptions).Return(client.ContainerStopResult{}, nil)
 
-	api.EXPECT().ContainerRemove(gomock.Any(), "123", container.RemoveOptions{Force: true}).Return(nil)
-	api.EXPECT().ContainerRemove(gomock.Any(), "789", container.RemoveOptions{Force: true}).Return(nil)
-	api.EXPECT().ContainerRemove(gomock.Any(), "321", container.RemoveOptions{Force: true}).Return(nil)
+	api.EXPECT().ContainerRemove(gomock.Any(), "123", client.ContainerRemoveOptions{Force: true}).Return(client.ContainerRemoveResult{}, nil)
+	api.EXPECT().ContainerRemove(gomock.Any(), "789", client.ContainerRemoveOptions{Force: true}).Return(client.ContainerRemoveResult{}, nil)
+	api.EXPECT().ContainerRemove(gomock.Any(), "321", client.ContainerRemoveOptions{Force: true}).Return(client.ContainerRemoveResult{}, nil)
 
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{
-		Filters: filters.NewArgs(
-			networkFilter("default"),
-			projectFilter(strings.ToLower(testProject)),
-		),
-	}).Return([]network.Summary{{ID: "abc123", Name: "myProject_default"}}, nil)
-	api.EXPECT().NetworkInspect(gomock.Any(), "abc123", gomock.Any()).Return(network.Inspect{ID: "abc123"}, nil)
-	api.EXPECT().NetworkRemove(gomock.Any(), "abc123").Return(nil)
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{
+		Filters: projectFilter(strings.ToLower(testProject)).Add("label", networkFilter("default")),
+	}).Return(client.NetworkListResult{
+		Items: []network.Summary{{Network: network.Network{ID: "abc123", Name: "myProject_default"}}},
+	}, nil)
+	api.EXPECT().NetworkInspect(gomock.Any(), "abc123", gomock.Any()).Return(client.NetworkInspectResult{
+		Network: network.Inspect{Network: network.Network{ID: "abc123"}},
+	}, nil)
+	api.EXPECT().NetworkRemove(gomock.Any(), "abc123", gomock.Any()).Return(client.NetworkRemoveResult{}, nil)
 
 	err = tested.Down(t.Context(), strings.ToLower(testProject), compose.DownOptions{RemoveOrphans: true})
 	assert.NilError(t, err)
@@ -239,24 +245,26 @@ func TestDownRemoveVolumes(t *testing.T) {
 	assert.NilError(t, err)
 
 	api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return(
-		[]container.Summary{testContainer("service1", "123", false)}, nil)
+		client.ContainerListResult{
+			Items: []container.Summary{testContainer("service1", "123", false)},
+		}, nil)
 	api.EXPECT().VolumeList(
 		gomock.Any(),
-		volume.ListOptions{
-			Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject))),
+		client.VolumeListOptions{
+			Filters: projectFilter(strings.ToLower(testProject)),
 		}).
-		Return(volume.ListResponse{
-			Volumes: []*volume.Volume{{Name: "myProject_volume"}},
+		Return(client.VolumeListResult{
+			Items: []volume.Volume{{Name: "myProject_volume"}},
 		}, nil)
-	api.EXPECT().VolumeInspect(gomock.Any(), "myProject_volume").
-		Return(volume.Volume{}, nil)
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
-		Return(nil, nil)
+	api.EXPECT().VolumeInspect(gomock.Any(), "myProject_volume", gomock.Any()).
+		Return(client.VolumeInspectResult{}, nil)
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{Filters: projectFilter(strings.ToLower(testProject))}).
+		Return(client.NetworkListResult{}, nil)
 
-	api.EXPECT().ContainerStop(gomock.Any(), "123", container.StopOptions{}).Return(nil)
-	api.EXPECT().ContainerRemove(gomock.Any(), "123", container.RemoveOptions{Force: true, RemoveVolumes: true}).Return(nil)
+	api.EXPECT().ContainerStop(gomock.Any(), "123", client.ContainerStopOptions{}).Return(client.ContainerStopResult{}, nil)
+	api.EXPECT().ContainerRemove(gomock.Any(), "123", client.ContainerRemoveOptions{Force: true, RemoveVolumes: true}).Return(client.ContainerRemoveResult{}, nil)
 
-	api.EXPECT().VolumeRemove(gomock.Any(), "myProject_volume", true).Return(nil)
+	api.EXPECT().VolumeRemove(gomock.Any(), "myProject_volume", client.VolumeRemoveOptions{Force: true}).Return(client.VolumeRemoveResult{}, nil)
 
 	err = tested.Down(t.Context(), strings.ToLower(testProject), compose.DownOptions{Volumes: true})
 	assert.NilError(t, err)
@@ -285,17 +293,16 @@ func TestDownRemoveImages(t *testing.T) {
 	assert.NilError(t, err)
 
 	api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).
-		Return([]container.Summary{
-			testContainer("service1", "123", false),
+		Return(client.ContainerListResult{
+			Items: []container.Summary{
+				testContainer("service1", "123", false),
+			},
 		}, nil).
 		AnyTimes()
 
-	api.EXPECT().ImageList(gomock.Any(), image.ListOptions{
-		Filters: filters.NewArgs(
-			projectFilter(strings.ToLower(testProject)),
-			filters.Arg("dangling", "false"),
-		),
-	}).Return([]image.Summary{
+	api.EXPECT().ImageList(gomock.Any(), client.ImageListOptions{
+		Filters: projectFilter(strings.ToLower(testProject)).Add("dangling", "false"),
+	}).Return(client.ImageListResult{Items: []image.Summary{
 		{
 			Labels:   types.Labels{compose.ServiceLabel: "local-anonymous"},
 			RepoTags: []string{"testproject-local-anonymous:latest"},
@@ -304,7 +311,7 @@ func TestDownRemoveImages(t *testing.T) {
 			Labels:   types.Labels{compose.ServiceLabel: "local-named"},
 			RepoTags: []string{"local-named-image:latest"},
 		},
-	}, nil).AnyTimes()
+	}}, nil).AnyTimes()
 
 	imagesToBeInspected := map[string]bool{
 		"testproject-local-anonymous":     true,
@@ -323,12 +330,12 @@ func TestDownRemoveImages(t *testing.T) {
 		}
 
 		api.EXPECT().ImageInspect(gomock.Any(), img).
-			Return(resp, err).
+			Return(client.ImageInspectResult{InspectResponse: resp}, err).
 			AnyTimes()
 	}
 
 	api.EXPECT().ImageInspect(gomock.Any(), "registry.example.com/remote-image-tagged:v1.0").
-		Return(image.InspectResponse{RepoTags: []string{"registry.example.com/remote-image-tagged:v1.0"}}, nil).
+		Return(client.ImageInspectResult{InspectResponse: image.InspectResponse{RepoTags: []string{"registry.example.com/remote-image-tagged:v1.0"}}}, nil).
 		AnyTimes()
 
 	localImagesToBeRemoved := []string{
@@ -338,8 +345,8 @@ func TestDownRemoveImages(t *testing.T) {
 	for _, img := range localImagesToBeRemoved {
 		// test calls down --rmi=local then down --rmi=all, so local images
 		// get "removed" 2x, while other images are only 1x
-		api.EXPECT().ImageRemove(gomock.Any(), img, image.RemoveOptions{}).
-			Return(nil, nil).
+		api.EXPECT().ImageRemove(gomock.Any(), img, client.ImageRemoveOptions{}).
+			Return(client.ImageRemoveResult{}, nil).
 			Times(2)
 	}
 
@@ -353,8 +360,8 @@ func TestDownRemoveImages(t *testing.T) {
 		"registry.example.com/remote-image-tagged:v1.0",
 	}
 	for _, img := range otherImagesToBeRemoved {
-		api.EXPECT().ImageRemove(gomock.Any(), img, image.RemoveOptions{}).
-			Return(nil, nil).
+		api.EXPECT().ImageRemove(gomock.Any(), img, client.ImageRemoveOptions{}).
+			Return(client.ImageRemoveResult{}, nil).
 			Times(1)
 	}
 
@@ -375,35 +382,32 @@ func TestDownRemoveImages_NoLabel(t *testing.T) {
 	ctr := testContainer("service1", "123", false)
 
 	api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return(
-		[]container.Summary{ctr}, nil)
+		client.ContainerListResult{
+			Items: []container.Summary{ctr},
+		}, nil)
 
 	api.EXPECT().VolumeList(
 		gomock.Any(),
-		volume.ListOptions{
-			Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject))),
+		client.VolumeListOptions{
+			Filters: projectFilter(strings.ToLower(testProject)),
 		}).
-		Return(volume.ListResponse{
-			Volumes: []*volume.Volume{{Name: "myProject_volume"}},
+		Return(client.VolumeListResult{
+			Items: []volume.Volume{{Name: "myProject_volume"}},
 		}, nil)
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
-		Return(nil, nil)
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{Filters: projectFilter(strings.ToLower(testProject))}).
+		Return(client.NetworkListResult{}, nil)
 
 	// ImageList returns no images for the project since they were unlabeled
 	// (created by an older version of Compose)
-	api.EXPECT().ImageList(gomock.Any(), image.ListOptions{
-		Filters: filters.NewArgs(
-			projectFilter(strings.ToLower(testProject)),
-			filters.Arg("dangling", "false"),
-		),
-	}).Return(nil, nil)
-
-	api.EXPECT().ImageInspect(gomock.Any(), "testproject-service1").
-		Return(image.InspectResponse{}, nil)
+	api.EXPECT().ImageList(gomock.Any(), client.ImageListOptions{
+		Filters: projectFilter(strings.ToLower(testProject)).Add("dangling", "false"),
+	}).Return(client.ImageListResult{}, nil)
 
-	api.EXPECT().ContainerStop(gomock.Any(), "123", container.StopOptions{}).Return(nil)
-	api.EXPECT().ContainerRemove(gomock.Any(), "123", container.RemoveOptions{Force: true}).Return(nil)
+	api.EXPECT().ImageInspect(gomock.Any(), "testproject-service1", gomock.Any()).Return(client.ImageInspectResult{}, nil)
+	api.EXPECT().ContainerStop(gomock.Any(), "123", client.ContainerStopOptions{}).Return(client.ContainerStopResult{}, nil)
+	api.EXPECT().ContainerRemove(gomock.Any(), "123", client.ContainerRemoveOptions{Force: true}).Return(client.ContainerRemoveResult{}, nil)
 
-	api.EXPECT().ImageRemove(gomock.Any(), "testproject-service1:latest", image.RemoveOptions{}).Return(nil, nil)
+	api.EXPECT().ImageRemove(gomock.Any(), "testproject-service1:latest", client.ImageRemoveOptions{}).Return(client.ImageRemoveResult{}, nil)
 
 	err = tested.Down(t.Context(), strings.ToLower(testProject), compose.DownOptions{Images: "local"})
 	assert.NilError(t, err)

+ 6 - 8
pkg/compose/events.go

@@ -22,29 +22,27 @@ import (
 	"strings"
 	"time"
 
-	"github.com/docker/docker/api/types/events"
-	"github.com/docker/docker/api/types/filters"
+	"github.com/moby/moby/client"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
 
 func (s *composeService) Events(ctx context.Context, projectName string, options api.EventsOptions) error {
 	projectName = strings.ToLower(projectName)
-	evts, errors := s.apiClient().Events(ctx, events.ListOptions{
-		Filters: filters.NewArgs(projectFilter(projectName)),
+	res := s.apiClient().Events(ctx, client.EventsListOptions{
+		Filters: projectFilter(projectName),
 		Since:   options.Since,
 		Until:   options.Until,
 	})
 	for {
 		select {
-		case event := <-evts:
+		case event := <-res.Messages:
 			// TODO: support other event types
 			if event.Type != "container" {
 				continue
 			}
 
-			oneOff := event.Actor.Attributes[api.OneoffLabel]
-			if oneOff == "True" {
+			if event.Actor.Attributes[api.OneoffLabel] == "True" {
 				// ignore
 				continue
 			}
@@ -76,7 +74,7 @@ func (s *composeService) Events(ctx context.Context, projectName string, options
 				return err
 			}
 
-		case err := <-errors:
+		case err := <-res.Err:
 			return err
 		}
 	}

+ 1 - 1
pkg/compose/exec.go

@@ -23,7 +23,7 @@ import (
 
 	"github.com/docker/cli/cli"
 	"github.com/docker/cli/cli/command/container"
-	containerType "github.com/docker/docker/api/types/container"
+	containerType "github.com/moby/moby/api/types/container"
 
 	"github.com/docker/compose/v5/pkg/api"
 )

+ 2 - 1
pkg/compose/export.go

@@ -23,6 +23,7 @@ import (
 	"strings"
 
 	"github.com/docker/cli/cli/command"
+	"github.com/moby/moby/client"
 	"github.com/moby/sys/atomicwriter"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -57,7 +58,7 @@ func (s *composeService) export(ctx context.Context, projectName string, options
 		Status: api.Working,
 	})
 
-	responseBody, err := s.apiClient().ContainerExport(ctx, container.ID)
+	responseBody, err := s.apiClient().ContainerExport(ctx, container.ID, client.ContainerExportOptions{})
 	if err != nil {
 		return err
 	}

+ 13 - 17
pkg/compose/filters.go

@@ -19,39 +19,35 @@ package compose
 import (
 	"fmt"
 
-	"github.com/docker/docker/api/types/filters"
+	"github.com/moby/moby/client"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
 
-func projectFilter(projectName string) filters.KeyValuePair {
-	return filters.Arg("label", fmt.Sprintf("%s=%s", api.ProjectLabel, projectName))
+func projectFilter(projectName string) client.Filters {
+	return make(client.Filters).Add("label", fmt.Sprintf("%s=%s", api.ProjectLabel, projectName))
 }
 
-func serviceFilter(serviceName string) filters.KeyValuePair {
-	return filters.Arg("label", fmt.Sprintf("%s=%s", api.ServiceLabel, serviceName))
+func serviceFilter(serviceName string) string {
+	return fmt.Sprintf("%s=%s", api.ServiceLabel, serviceName)
 }
 
-func networkFilter(name string) filters.KeyValuePair {
-	return filters.Arg("label", fmt.Sprintf("%s=%s", api.NetworkLabel, name))
+func networkFilter(name string) string {
+	return fmt.Sprintf("%s=%s", api.NetworkLabel, name)
 }
 
-func oneOffFilter(b bool) filters.KeyValuePair {
+func oneOffFilter(b bool) string {
 	v := "False"
 	if b {
 		v = "True"
 	}
-	return filters.Arg("label", fmt.Sprintf("%s=%s", api.OneoffLabel, v))
+	return fmt.Sprintf("%s=%s", api.OneoffLabel, v)
 }
 
-func containerNumberFilter(index int) filters.KeyValuePair {
-	return filters.Arg("label", fmt.Sprintf("%s=%d", api.ContainerNumberLabel, index))
+func containerNumberFilter(index int) string {
+	return fmt.Sprintf("%s=%d", api.ContainerNumberLabel, index)
 }
 
-func hasProjectLabelFilter() filters.KeyValuePair {
-	return filters.Arg("label", api.ProjectLabel)
-}
-
-func hasConfigHashLabel() filters.KeyValuePair {
-	return filters.Arg("label", api.ConfigHashLabel)
+func hasConfigHashLabel() string {
+	return api.ConfigHashLabel
 }

+ 17 - 22
pkg/compose/generate.go

@@ -24,38 +24,33 @@ import (
 	"strings"
 
 	"github.com/compose-spec/compose-go/v2/types"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/mount"
-	"github.com/docker/docker/api/types/network"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/mount"
+	"github.com/moby/moby/api/types/network"
+	"github.com/moby/moby/client"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
 
 func (s *composeService) Generate(ctx context.Context, options api.GenerateOptions) (*types.Project, error) {
-	filtersListNames := filters.NewArgs()
-	filtersListIDs := filters.NewArgs()
-	for _, containerName := range options.Containers {
-		filtersListNames.Add("name", containerName)
-		filtersListIDs.Add("id", containerName)
-	}
-	containers, err := s.apiClient().ContainerList(ctx, container.ListOptions{
-		Filters: filtersListNames,
+	res, err := s.apiClient().ContainerList(ctx, client.ContainerListOptions{
+		Filters: make(client.Filters).Add("name", options.Containers...),
 		All:     true,
 	})
 	if err != nil {
 		return nil, err
 	}
+	containers := res.Items
 
-	containersByIds, err := s.apiClient().ContainerList(ctx, container.ListOptions{
-		Filters: filtersListIDs,
+	containersByIds, err := s.apiClient().ContainerList(ctx, client.ContainerListOptions{
+		Filters: make(client.Filters).Add("id", options.Containers...),
 		All:     true,
 	})
 	if err != nil {
 		return nil, err
 	}
 
-	for _, ctr := range containersByIds {
+	for _, ctr := range containersByIds.Items {
 		if !slices.ContainsFunc(containers, func(summary container.Summary) bool {
 			return summary.ID == ctr.ID
 		}) {
@@ -97,12 +92,12 @@ func (s *composeService) createProjectFromContainers(containers []container.Summ
 		}
 		service.Scale = increment(service.Scale)
 
-		inspect, err := s.apiClient().ContainerInspect(context.Background(), c.ID)
+		inspect, err := s.apiClient().ContainerInspect(context.Background(), c.ID, client.ContainerInspectOptions{})
 		if err != nil {
 			services[serviceLabel] = service
 			continue
 		}
-		s.extractComposeConfiguration(&service, inspect, volumes, secrets, networks)
+		s.extractComposeConfiguration(&service, inspect.Container, volumes, secrets, networks)
 		service.Labels = cleanDockerPreviousLabels(service.Labels)
 		services[serviceLabel] = service
 	}
@@ -136,10 +131,10 @@ func (s *composeService) extractComposeConfiguration(service *types.ServiceConfi
 		for key, portBindings := range inspect.HostConfig.PortBindings {
 			for _, portBinding := range portBindings {
 				service.Ports = append(service.Ports, types.ServicePortConfig{
-					Target:    uint32(key.Int()),
+					Target:    uint32(key.Num()),
 					Published: portBinding.HostPort,
-					Protocol:  key.Proto(),
-					HostIP:    portBinding.HostIP,
+					Protocol:  string(key.Proto()),
+					HostIP:    portBinding.HostIP.String(),
 				})
 			}
 		}
@@ -222,12 +217,12 @@ func (s *composeService) toComposeNetwork(networks map[string]*network.EndpointS
 	serviceNetworkConfigs := make(map[string]*types.ServiceNetworkConfig)
 
 	for name, net := range networks {
-		inspect, err := s.apiClient().NetworkInspect(context.Background(), name, network.InspectOptions{})
+		inspect, err := s.apiClient().NetworkInspect(context.Background(), name, client.NetworkInspectOptions{})
 		if err != nil {
 			networkConfigs[name] = types.NetworkConfig{}
 		} else {
 			networkConfigs[name] = types.NetworkConfig{
-				Internal: inspect.Internal,
+				Internal: inspect.Network.Internal,
 			}
 		}
 		serviceNetworkConfigs[name] = &types.ServiceNetworkConfig{

+ 14 - 10
pkg/compose/hook.go

@@ -23,8 +23,9 @@ import (
 	"time"
 
 	"github.com/compose-spec/compose-go/v2/types"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/pkg/stdcopy"
+	"github.com/moby/moby/api/pkg/stdcopy"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 
 	"github.com/docker/compose/v5/pkg/api"
 	"github.com/docker/compose/v5/pkg/utils"
@@ -43,7 +44,7 @@ func (s composeService) runHook(ctx context.Context, ctr container.Summary, serv
 	defer wOut.Close() //nolint:errcheck
 
 	detached := listener == nil
-	exec, err := s.apiClient().ContainerExecCreate(ctx, ctr.ID, container.ExecOptions{
+	exec, err := s.apiClient().ExecCreate(ctx, ctr.ID, client.ExecCreateOptions{
 		User:         hook.User,
 		Privileged:   hook.Privileged,
 		Env:          ToMobyEnv(hook.Environment),
@@ -61,9 +62,12 @@ func (s composeService) runHook(ctx context.Context, ctr container.Summary, serv
 	}
 
 	height, width := s.stdout().GetTtySize()
-	consoleSize := &[2]uint{height, width}
-	attach, err := s.apiClient().ContainerExecAttach(ctx, exec.ID, container.ExecAttachOptions{
-		Tty:         service.Tty,
+	consoleSize := client.ConsoleSize{
+		Width:  width,
+		Height: height,
+	}
+	attach, err := s.apiClient().ExecAttach(ctx, exec.ID, client.ExecAttachOptions{
+		TTY:         service.Tty,
 		ConsoleSize: consoleSize,
 	})
 	if err != nil {
@@ -80,7 +84,7 @@ func (s composeService) runHook(ctx context.Context, ctr container.Summary, serv
 		return err
 	}
 
-	inspected, err := s.apiClient().ContainerExecInspect(ctx, exec.ID)
+	inspected, err := s.apiClient().ExecInspect(ctx, exec.ID, client.ExecInspectOptions{})
 	if err != nil {
 		return err
 	}
@@ -91,9 +95,9 @@ func (s composeService) runHook(ctx context.Context, ctr container.Summary, serv
 }
 
 func (s composeService) runWaitExec(ctx context.Context, execID string, service types.ServiceConfig, listener api.ContainerEventListener) error {
-	err := s.apiClient().ContainerExecStart(ctx, execID, container.ExecStartOptions{
+	_, err := s.apiClient().ExecStart(ctx, execID, client.ExecStartOptions{
 		Detach: listener == nil,
-		Tty:    service.Tty,
+		TTY:    service.Tty,
 	})
 	if err != nil {
 		return nil
@@ -106,7 +110,7 @@ func (s composeService) runWaitExec(ctx context.Context, execID string, service
 		case <-ctx.Done():
 			return nil
 		case <-tick.C:
-			inspect, err := s.apiClient().ContainerExecInspect(ctx, execID)
+			inspect, err := s.apiClient().ExecInspect(ctx, execID, client.ExecInspectOptions{})
 			if err != nil {
 				return nil
 			}

+ 12 - 17
pkg/compose/image_pruner.go

@@ -25,9 +25,8 @@ import (
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/containerd/errdefs"
 	"github.com/distribution/reference"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/image"
-	"github.com/docker/docker/client"
+	"github.com/moby/moby/api/types/image"
+	"github.com/moby/moby/client"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -150,23 +149,19 @@ func (p *ImagePruner) namedImages(ctx context.Context) ([]string, error) {
 // The image name could either have been defined by the user or implicitly
 // created from the project + service name.
 func (p *ImagePruner) labeledLocalImages(ctx context.Context) ([]image.Summary, error) {
-	imageListOpts := image.ListOptions{
-		Filters: filters.NewArgs(
-			projectFilter(p.project.Name),
-			// TODO(milas): we should really clean up the dangling images as
-			// well (historically we have NOT); need to refactor this to handle
-			// it gracefully without producing confusing CLI output, i.e. we
-			// do not want to print out a bunch of untagged/dangling image IDs,
-			// they should be grouped into a logical operation for the relevant
-			// service
-			filters.Arg("dangling", "false"),
-		),
-	}
-	projectImages, err := p.client.ImageList(ctx, imageListOpts)
+	res, err := p.client.ImageList(ctx, client.ImageListOptions{
+		// TODO(milas): we should really clean up the dangling images as
+		// well (historically we have NOT); need to refactor this to handle
+		// it gracefully without producing confusing CLI output, i.e. we
+		// do not want to print out a bunch of untagged/dangling image IDs,
+		// they should be grouped into a logical operation for the relevant
+		// service
+		Filters: projectFilter(p.project.Name).Add("dangling", "false"),
+	})
 	if err != nil {
 		return nil, err
 	}
-	return projectImages, nil
+	return res.Items, nil
 }
 
 // unlabeledLocalImages are images that match the implicit naming convention

+ 7 - 8
pkg/compose/images.go

@@ -27,10 +27,9 @@ import (
 	"github.com/containerd/errdefs"
 	"github.com/containerd/platforms"
 	"github.com/distribution/reference"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/versions"
-	"github.com/docker/docker/client"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
+	"github.com/moby/moby/client/pkg/versions"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -38,9 +37,9 @@ import (
 
 func (s *composeService) Images(ctx context.Context, projectName string, options api.ImagesOptions) (map[string]api.ImageSummary, error) {
 	projectName = strings.ToLower(projectName)
-	allContainers, err := s.apiClient().ContainerList(ctx, container.ListOptions{
+	allContainers, err := s.apiClient().ContainerList(ctx, client.ContainerListOptions{
 		All:     true,
-		Filters: filters.NewArgs(projectFilter(projectName)),
+		Filters: projectFilter(projectName),
 	})
 	if err != nil {
 		return nil, err
@@ -48,13 +47,13 @@ func (s *composeService) Images(ctx context.Context, projectName string, options
 	var containers []container.Summary
 	if len(options.Services) > 0 {
 		// filter service containers
-		for _, c := range allContainers {
+		for _, c := range allContainers.Items {
 			if slices.Contains(options.Services, c.Labels[api.ServiceLabel]) {
 				containers = append(containers, c)
 			}
 		}
 	} else {
-		containers = allContainers
+		containers = allContainers.Items
 	}
 
 	version, err := s.RuntimeVersion(ctx)

+ 17 - 15
pkg/compose/images_test.go

@@ -17,14 +17,14 @@
 package compose
 
 import (
+	"net/netip"
 	"strings"
 	"testing"
 	"time"
 
-	"github.com/docker/docker/api/types"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/image"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/image"
+	"github.com/moby/moby/client"
 	"go.uber.org/mock/gomock"
 	"gotest.tools/v3/assert"
 
@@ -39,22 +39,24 @@ func TestImages(t *testing.T) {
 	tested, err := NewComposeService(cli)
 	assert.NilError(t, err)
 
-	args := filters.NewArgs(projectFilter(strings.ToLower(testProject)))
-	listOpts := container.ListOptions{All: true, Filters: args}
-	api.EXPECT().ServerVersion(gomock.Any()).Return(types.Version{APIVersion: "1.96"}, nil).AnyTimes()
+	args := projectFilter(strings.ToLower(testProject))
+	listOpts := client.ContainerListOptions{All: true, Filters: args}
+	api.EXPECT().ServerVersion(gomock.Any(), gomock.Any()).Return(client.ServerVersionResult{APIVersion: "1.96"}, nil).AnyTimes()
 	timeStr1 := "2025-06-06T06:06:06.000000000Z"
 	created1, _ := time.Parse(time.RFC3339Nano, timeStr1)
 	timeStr2 := "2025-03-03T03:03:03.000000000Z"
 	created2, _ := time.Parse(time.RFC3339Nano, timeStr2)
 	image1 := imageInspect("image1", "foo:1", 12345, timeStr1)
 	image2 := imageInspect("image2", "bar:2", 67890, timeStr2)
-	api.EXPECT().ImageInspect(anyCancellableContext(), "foo:1").Return(image1, nil).MaxTimes(2)
-	api.EXPECT().ImageInspect(anyCancellableContext(), "bar:2").Return(image2, nil)
-	c1 := containerDetail("service1", "123", "running", "foo:1")
-	c2 := containerDetail("service1", "456", "running", "bar:2")
-	c2.Ports = []container.Port{{PublicPort: 80, PrivatePort: 90, IP: "localhost"}}
-	c3 := containerDetail("service2", "789", "exited", "foo:1")
-	api.EXPECT().ContainerList(t.Context(), listOpts).Return([]container.Summary{c1, c2, c3}, nil)
+	api.EXPECT().ImageInspect(anyCancellableContext(), "foo:1").Return(client.ImageInspectResult{InspectResponse: image1}, nil).MaxTimes(2)
+	api.EXPECT().ImageInspect(anyCancellableContext(), "bar:2").Return(client.ImageInspectResult{InspectResponse: image2}, nil)
+	c1 := containerDetail("service1", "123", container.StateRunning, "foo:1")
+	c2 := containerDetail("service1", "456", container.StateRunning, "bar:2")
+	c2.Ports = []container.PortSummary{{PublicPort: 80, PrivatePort: 90, IP: netip.MustParseAddr("127.0.0.1")}}
+	c3 := containerDetail("service2", "789", container.StateExited, "foo:1")
+	api.EXPECT().ContainerList(t.Context(), listOpts).Return(client.ContainerListResult{
+		Items: []container.Summary{c1, c2, c3},
+	}, nil)
 
 	images, err := tested.Images(t.Context(), strings.ToLower(testProject), compose.ImagesOptions{})
 
@@ -97,7 +99,7 @@ func imageInspect(id string, imageReference string, size int64, created string)
 	}
 }
 
-func containerDetail(service string, id string, status string, imageName string) container.Summary {
+func containerDetail(service string, id string, status container.ContainerState, imageName string) container.Summary {
 	return container.Summary{
 		ID:     id,
 		Names:  []string{"/" + id},

+ 5 - 2
pkg/compose/kill.go

@@ -20,7 +20,8 @@ import (
 	"context"
 	"strings"
 
-	"github.com/docker/docker/api/types/container"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -61,7 +62,9 @@ func (s *composeService) kill(ctx context.Context, projectName string, options a
 		eg.Go(func() error {
 			eventName := getContainerProgressName(ctr)
 			s.events.On(killingEvent(eventName))
-			err := s.apiClient().ContainerKill(ctx, ctr.ID, options.Signal)
+			_, err := s.apiClient().ContainerKill(ctx, ctr.ID, client.ContainerKillOptions{
+				Signal: options.Signal,
+			})
 			if err != nil {
 				s.events.On(errorEvent(eventName, "Error while Killing"))
 				return err

+ 43 - 35
pkg/compose/kill_test.go

@@ -18,15 +18,13 @@ package compose
 
 import (
 	"context"
-	"fmt"
 	"path/filepath"
 	"strings"
 	"testing"
 
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/network"
-	"github.com/docker/docker/api/types/volume"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/network"
+	"github.com/moby/moby/client"
 	"go.uber.org/mock/gomock"
 	"gotest.tools/v3/assert"
 
@@ -45,23 +43,30 @@ func TestKillAll(t *testing.T) {
 
 	name := strings.ToLower(testProject)
 
-	api.EXPECT().ContainerList(t.Context(), container.ListOptions{
-		Filters: filters.NewArgs(projectFilter(name), hasConfigHashLabel()),
-	}).Return(
-		[]container.Summary{testContainer("service1", "123", false), testContainer("service1", "456", false), testContainer("service2", "789", false)}, nil)
+	api.EXPECT().ContainerList(t.Context(), client.ContainerListOptions{
+		Filters: projectFilter(name).Add("label", hasConfigHashLabel()),
+	}).Return(client.ContainerListResult{
+		Items: []container.Summary{
+			testContainer("service1", "123", false),
+			testContainer("service1", "456", false),
+			testContainer("service2", "789", false),
+		},
+	}, nil)
 	api.EXPECT().VolumeList(
 		gomock.Any(),
-		volume.ListOptions{
-			Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject))),
+		client.VolumeListOptions{
+			Filters: projectFilter(strings.ToLower(testProject)),
 		}).
-		Return(volume.ListResponse{}, nil)
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
-		Return([]network.Summary{
-			{ID: "abc123", Name: "testProject_default"},
+		Return(client.VolumeListResult{}, nil)
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{Filters: projectFilter(strings.ToLower(testProject))}).
+		Return(client.NetworkListResult{
+			Items: []network.Summary{{
+				Network: network.Network{ID: "abc123", Name: "testProject_default"},
+			}},
 		}, nil)
-	api.EXPECT().ContainerKill(anyCancellableContext(), "123", "").Return(nil)
-	api.EXPECT().ContainerKill(anyCancellableContext(), "456", "").Return(nil)
-	api.EXPECT().ContainerKill(anyCancellableContext(), "789", "").Return(nil)
+	api.EXPECT().ContainerKill(anyCancellableContext(), "123", client.ContainerKillOptions{}).Return(client.ContainerKillResult{}, nil)
+	api.EXPECT().ContainerKill(anyCancellableContext(), "456", client.ContainerKillOptions{}).Return(client.ContainerKillResult{}, nil)
+	api.EXPECT().ContainerKill(anyCancellableContext(), "789", client.ContainerKillOptions{}).Return(client.ContainerKillResult{}, nil)
 
 	err = tested.Kill(t.Context(), name, compose.KillOptions{})
 	assert.NilError(t, err)
@@ -77,22 +82,28 @@ func TestKillSignal(t *testing.T) {
 	assert.NilError(t, err)
 
 	name := strings.ToLower(testProject)
-	listOptions := container.ListOptions{
-		Filters: filters.NewArgs(projectFilter(name), serviceFilter(serviceName), hasConfigHashLabel()),
+	listOptions := client.ContainerListOptions{
+		Filters: projectFilter(name).Add("label", serviceFilter(serviceName), hasConfigHashLabel()),
 	}
 
-	api.EXPECT().ContainerList(t.Context(), listOptions).Return([]container.Summary{testContainer(serviceName, "123", false)}, nil)
+	api.EXPECT().ContainerList(t.Context(), listOptions).Return(client.ContainerListResult{
+		Items: []container.Summary{testContainer(serviceName, "123", false)},
+	}, nil)
 	api.EXPECT().VolumeList(
 		gomock.Any(),
-		volume.ListOptions{
-			Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject))),
+		client.VolumeListOptions{
+			Filters: projectFilter(strings.ToLower(testProject)),
 		}).
-		Return(volume.ListResponse{}, nil)
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
-		Return([]network.Summary{
-			{ID: "abc123", Name: "testProject_default"},
+		Return(client.VolumeListResult{}, nil)
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{Filters: projectFilter(strings.ToLower(testProject))}).
+		Return(client.NetworkListResult{
+			Items: []network.Summary{{
+				Network: network.Network{ID: "abc123", Name: "testProject_default"},
+			}},
 		}, nil)
-	api.EXPECT().ContainerKill(anyCancellableContext(), "123", "SIGTERM").Return(nil)
+	api.EXPECT().ContainerKill(anyCancellableContext(), "123", client.ContainerKillOptions{
+		Signal: "SIGTERM",
+	}).Return(client.ContainerKillResult{}, nil)
 
 	err = tested.Kill(t.Context(), name, compose.KillOptions{Services: []string{serviceName}, Signal: "SIGTERM"})
 	assert.NilError(t, err)
@@ -133,15 +144,12 @@ func anyCancellableContext() gomock.Matcher {
 	return gomock.AssignableToTypeOf(ctxWithCancel)
 }
 
-func projectFilterListOpt(withOneOff bool) container.ListOptions {
-	filter := filters.NewArgs(
-		projectFilter(strings.ToLower(testProject)),
-		hasConfigHashLabel(),
-	)
+func projectFilterListOpt(withOneOff bool) client.ContainerListOptions {
+	filter := projectFilter(strings.ToLower(testProject)).Add("label", hasConfigHashLabel())
 	if !withOneOff {
-		filter.Add("label", fmt.Sprintf("%s=False", compose.OneoffLabel))
+		filter.Add("label", oneOffFilter(false))
 	}
-	return container.ListOptions{
+	return client.ContainerListOptions{
 		Filters: filter,
 		All:     true,
 	}

+ 9 - 8
pkg/compose/logs.go

@@ -21,8 +21,9 @@ import (
 	"io"
 
 	"github.com/containerd/errdefs"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/pkg/stdcopy"
+	"github.com/moby/moby/api/pkg/stdcopy"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"github.com/sirupsen/logrus"
 	"golang.org/x/sync/errgroup"
 
@@ -83,14 +84,14 @@ func (s *composeService) Logs(
 		monitor.withListener(func(event api.ContainerEvent) {
 			if event.Type == api.ContainerEventStarted {
 				eg.Go(func() error {
-					ctr, err := s.apiClient().ContainerInspect(ctx, event.ID)
+					res, err := s.apiClient().ContainerInspect(ctx, event.ID, client.ContainerInspectOptions{})
 					if err != nil {
 						return err
 					}
 
-					err = s.doLogContainer(ctx, consumer, event.Source, ctr, api.LogOptions{
+					err = s.doLogContainer(ctx, consumer, event.Source, res.Container, api.LogOptions{
 						Follow:     options.Follow,
-						Since:      ctr.State.StartedAt,
+						Since:      res.Container.State.StartedAt,
 						Until:      options.Until,
 						Tail:       options.Tail,
 						Timestamps: options.Timestamps,
@@ -113,16 +114,16 @@ func (s *composeService) Logs(
 }
 
 func (s *composeService) logContainer(ctx context.Context, consumer api.LogConsumer, c container.Summary, options api.LogOptions) error {
-	ctr, err := s.apiClient().ContainerInspect(ctx, c.ID)
+	res, err := s.apiClient().ContainerInspect(ctx, c.ID, client.ContainerInspectOptions{})
 	if err != nil {
 		return err
 	}
 	name := getContainerNameWithoutProject(c)
-	return s.doLogContainer(ctx, consumer, name, ctr, options)
+	return s.doLogContainer(ctx, consumer, name, res.Container, options)
 }
 
 func (s *composeService) doLogContainer(ctx context.Context, consumer api.LogConsumer, name string, ctr container.InspectResponse, options api.LogOptions) error {
-	r, err := s.apiClient().ContainerLogs(ctx, ctr.ID, container.LogsOptions{
+	r, err := s.apiClient().ContainerLogs(ctx, ctr.ID, client.ContainerLogsOptions{
 		ShowStdout: true,
 		ShowStderr: true,
 		Follow:     options.Follow,

+ 31 - 23
pkg/compose/logs_test.go

@@ -23,9 +23,9 @@ import (
 	"testing"
 
 	"github.com/compose-spec/compose-go/v2/types"
-	containerType "github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
 	"github.com/docker/docker/pkg/stdcopy"
+	containerType "github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 	"go.uber.org/mock/gomock"
@@ -43,21 +43,25 @@ func TestComposeService_Logs_Demux(t *testing.T) {
 
 	name := strings.ToLower(testProject)
 
-	api.EXPECT().ContainerList(t.Context(), containerType.ListOptions{
+	api.EXPECT().ContainerList(t.Context(), client.ContainerListOptions{
 		All:     true,
-		Filters: filters.NewArgs(oneOffFilter(false), projectFilter(name), hasConfigHashLabel()),
+		Filters: projectFilter(name).Add("label", oneOffFilter(false), hasConfigHashLabel()),
 	}).Return(
-		[]containerType.Summary{
-			testContainer("service", "c", false),
+		client.ContainerListResult{
+			Items: []containerType.Summary{
+				testContainer("service", "c", false),
+			},
 		},
 		nil,
 	)
 
 	api.EXPECT().
-		ContainerInspect(anyCancellableContext(), "c").
-		Return(containerType.InspectResponse{
-			ContainerJSONBase: &containerType.ContainerJSONBase{ID: "c"},
-			Config:            &containerType.Config{Tty: false},
+		ContainerInspect(anyCancellableContext(), "c", gomock.Any()).
+		Return(client.ContainerInspectResult{
+			Container: containerType.InspectResponse{
+				ID:     "c",
+				Config: &containerType.Config{Tty: false},
+			},
 		}, nil)
 	c1Reader, c1Writer := io.Pipe()
 	t.Cleanup(func() {
@@ -112,28 +116,32 @@ func TestComposeService_Logs_ServiceFiltering(t *testing.T) {
 
 	name := strings.ToLower(testProject)
 
-	api.EXPECT().ContainerList(t.Context(), containerType.ListOptions{
+	api.EXPECT().ContainerList(t.Context(), client.ContainerListOptions{
 		All:     true,
-		Filters: filters.NewArgs(oneOffFilter(false), projectFilter(name), hasConfigHashLabel()),
+		Filters: projectFilter(name).Add("label", oneOffFilter(false), hasConfigHashLabel()),
 	}).Return(
-		[]containerType.Summary{
-			testContainer("serviceA", "c1", false),
-			testContainer("serviceA", "c2", false),
-			// serviceB will be filtered out by the project definition to
-			// ensure we ignore "orphan" containers
-			testContainer("serviceB", "c3", false),
-			testContainer("serviceC", "c4", false),
+		client.ContainerListResult{
+			Items: []containerType.Summary{
+				testContainer("serviceA", "c1", false),
+				testContainer("serviceA", "c2", false),
+				// serviceB will be filtered out by the project definition to
+				// ensure we ignore "orphan" containers
+				testContainer("serviceB", "c3", false),
+				testContainer("serviceC", "c4", false),
+			},
 		},
 		nil,
 	)
 
 	for _, id := range []string{"c1", "c2", "c4"} {
 		api.EXPECT().
-			ContainerInspect(anyCancellableContext(), id).
+			ContainerInspect(anyCancellableContext(), id, gomock.Any()).
 			Return(
-				containerType.InspectResponse{
-					ContainerJSONBase: &containerType.ContainerJSONBase{ID: id},
-					Config:            &containerType.Config{Tty: true},
+				client.ContainerInspectResult{
+					Container: containerType.InspectResponse{
+						ID:     id,
+						Config: &containerType.Config{Tty: true},
+					},
 				},
 				nil,
 			)

+ 6 - 6
pkg/compose/ls.go

@@ -23,23 +23,23 @@ import (
 	"sort"
 	"strings"
 
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"github.com/sirupsen/logrus"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
 
 func (s *composeService) List(ctx context.Context, opts api.ListOptions) ([]api.Stack, error) {
-	list, err := s.apiClient().ContainerList(ctx, container.ListOptions{
-		Filters: filters.NewArgs(hasProjectLabelFilter(), hasConfigHashLabel()),
+	list, err := s.apiClient().ContainerList(ctx, client.ContainerListOptions{
+		Filters: make(client.Filters).Add("label", api.ProjectLabel).Add("label", api.ConfigHashLabel),
 		All:     opts.All,
 	})
 	if err != nil {
 		return nil, err
 	}
 
-	return containersToStacks(list)
+	return containersToStacks(list.Items)
 }
 
 func containersToStacks(containers []container.Summary) ([]api.Stack, error) {
@@ -87,7 +87,7 @@ func combinedConfigFiles(containers []container.Summary) (string, error) {
 func containerToState(containers []container.Summary) []string {
 	statuses := []string{}
 	for _, c := range containers {
-		statuses = append(statuses, c.State)
+		statuses = append(statuses, string(c.State))
 	}
 	return statuses
 }

+ 1 - 1
pkg/compose/ls_test.go

@@ -20,7 +20,7 @@ import (
 	"fmt"
 	"testing"
 
-	"github.com/docker/docker/api/types/container"
+	"github.com/moby/moby/api/types/container"
 	"gotest.tools/v3/assert"
 
 	"github.com/docker/compose/v5/pkg/api"

+ 11 - 16
pkg/compose/monitor.go

@@ -21,10 +21,8 @@ import (
 	"strconv"
 
 	"github.com/containerd/errdefs"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/events"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/client"
+	"github.com/moby/moby/api/types/events"
+	"github.com/moby/moby/client"
 	"github.com/sirupsen/logrus"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -58,10 +56,9 @@ func (c *monitor) withServices(services []string) {
 //nolint:gocyclo
 func (c *monitor) Start(ctx context.Context) error {
 	// collect initial application container
-	initialState, err := c.apiClient.ContainerList(ctx, container.ListOptions{
+	initialState, err := c.apiClient.ContainerList(ctx, client.ContainerListOptions{
 		All: true,
-		Filters: filters.NewArgs(
-			projectFilter(c.project),
+		Filters: projectFilter(c.project).Add("label",
 			oneOffFilter(false),
 			hasConfigHashLabel(),
 		),
@@ -72,17 +69,15 @@ func (c *monitor) Start(ctx context.Context) error {
 
 	// containers is the set if container IDs the application is based on
 	containers := utils.Set[string]{}
-	for _, ctr := range initialState {
+	for _, ctr := range initialState.Items {
 		if len(c.services) == 0 || c.services[ctr.Labels[api.ServiceLabel]] {
 			containers.Add(ctr.ID)
 		}
 	}
 	restarting := utils.Set[string]{}
 
-	evtCh, errCh := c.apiClient.Events(ctx, events.ListOptions{
-		Filters: filters.NewArgs(
-			filters.Arg("type", "container"),
-			projectFilter(c.project)),
+	res := c.apiClient.Events(ctx, client.EventsListOptions{
+		Filters: projectFilter(c.project).Add("type", "container"),
 	})
 	for {
 		if len(containers) == 0 {
@@ -91,9 +86,9 @@ func (c *monitor) Start(ctx context.Context) error {
 		select {
 		case <-ctx.Done():
 			return nil
-		case err := <-errCh:
+		case err := <-res.Err:
 			return err
-		case event := <-evtCh:
+		case event := <-res.Messages:
 			if len(c.services) > 0 && !c.services[event.Actor.Attributes[api.ServiceLabel]] {
 				continue
 			}
@@ -140,14 +135,14 @@ func (c *monitor) Start(ctx context.Context) error {
 				logrus.Debugf("container %s restarted", ctr.Name)
 			case events.ActionDie:
 				logrus.Debugf("container %s exited with code %d", ctr.Name, ctr.ExitCode)
-				inspect, err := c.apiClient.ContainerInspect(ctx, event.Actor.ID)
+				inspect, err := c.apiClient.ContainerInspect(ctx, event.Actor.ID, client.ContainerInspectOptions{})
 				if errdefs.IsNotFound(err) {
 					// Source is already removed
 				} else if err != nil {
 					return err
 				}
 
-				if inspect.State != nil && (inspect.State.Restarting || inspect.State.Running) {
+				if inspect.Container.State != nil && (inspect.Container.State.Restarting || inspect.Container.State.Running) {
 					// State.Restarting is set by engine when container is configured to restart on exit
 					// on ContainerRestart it doesn't (see https://github.com/moby/moby/issues/45538)
 					// container state still is reported as "running"

+ 4 - 3
pkg/compose/pause.go

@@ -20,7 +20,8 @@ import (
 	"context"
 	"strings"
 
-	"github.com/docker/docker/api/types/container"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -45,7 +46,7 @@ func (s *composeService) pause(ctx context.Context, projectName string, options
 	eg, ctx := errgroup.WithContext(ctx)
 	containers.forEach(func(container container.Summary) {
 		eg.Go(func() error {
-			err := s.apiClient().ContainerPause(ctx, container.ID)
+			_, err := s.apiClient().ContainerPause(ctx, container.ID, client.ContainerPauseOptions{})
 			if err == nil {
 				eventName := getContainerProgressName(container)
 				s.events.On(newEvent(eventName, api.Done, "Paused"))
@@ -75,7 +76,7 @@ func (s *composeService) unPause(ctx context.Context, projectName string, option
 	eg, ctx := errgroup.WithContext(ctx)
 	containers.forEach(func(ctr container.Summary) {
 		eg.Go(func() error {
-			err = s.apiClient().ContainerUnpause(ctx, ctr.ID)
+			_, err = s.apiClient().ContainerUnpause(ctx, ctr.ID, client.ContainerUnpauseOptions{})
 			if err == nil {
 				eventName := getContainerProgressName(ctr)
 				s.events.On(newEvent(eventName, api.Done, "Unpaused"))

+ 2 - 2
pkg/compose/port.go

@@ -21,7 +21,7 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/docker/docker/api/types/container"
+	"github.com/moby/moby/api/types/container"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
@@ -34,7 +34,7 @@ func (s *composeService) Port(ctx context.Context, projectName string, service s
 	}
 	for _, p := range ctr.Ports {
 		if p.PrivatePort == port && p.Type == options.Protocol {
-			return p.IP, int(p.PublicPort), nil
+			return p.IP.String(), int(p.PublicPort), nil
 		}
 	}
 	return "", 0, portNotFoundError(options.Protocol, port, ctr)

+ 14 - 8
pkg/compose/ps.go

@@ -21,12 +21,14 @@ import (
 	"sort"
 	"strings"
 
-	"github.com/docker/docker/api/types/container"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
 
+//nolint:gocyclo
 func (s *composeService) Ps(ctx context.Context, projectName string, options api.PsOptions) ([]api.ContainerSummary, error) {
 	projectName = strings.ToLower(projectName)
 	oneOff := oneOffExclude
@@ -50,15 +52,19 @@ func (s *composeService) Ps(ctx context.Context, projectName string, options api
 				return ctr.Ports[i].PrivatePort < ctr.Ports[j].PrivatePort
 			})
 			for i, p := range ctr.Ports {
+				var url string
+				if p.IP.IsValid() {
+					url = p.IP.String()
+				}
 				publishers[i] = api.PortPublisher{
-					URL:           p.IP,
+					URL:           url, // TODO(thaJeztah); change this to a netip.Addr ??
 					TargetPort:    int(p.PrivatePort),
 					PublishedPort: int(p.PublicPort),
 					Protocol:      p.Type,
 				}
 			}
 
-			inspect, err := s.apiClient().ContainerInspect(ctx, ctr.ID)
+			inspect, err := s.apiClient().ContainerInspect(ctx, ctr.ID, client.ContainerInspectOptions{})
 			if err != nil {
 				return err
 			}
@@ -67,14 +73,14 @@ func (s *composeService) Ps(ctx context.Context, projectName string, options api
 				health   container.HealthStatus
 				exitCode int
 			)
-			if inspect.State != nil {
-				switch inspect.State.Status {
+			if inspect.Container.State != nil {
+				switch inspect.Container.State.Status {
 				case container.StateRunning:
-					if inspect.State.Health != nil {
-						health = inspect.State.Health.Status
+					if inspect.Container.State.Health != nil {
+						health = inspect.Container.State.Health.Status
 					}
 				case container.StateExited, container.StateDead:
-					exitCode = inspect.State.ExitCode
+					exitCode = inspect.Container.State.ExitCode
 				}
 			}
 

+ 19 - 19
pkg/compose/ps_test.go

@@ -17,11 +17,12 @@
 package compose
 
 import (
+	"net/netip"
 	"strings"
 	"testing"
 
-	containerType "github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
+	containerType "github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"go.uber.org/mock/gomock"
 	"gotest.tools/v3/assert"
 
@@ -36,17 +37,20 @@ func TestPs(t *testing.T) {
 	tested, err := NewComposeService(cli)
 	assert.NilError(t, err)
 
-	args := filters.NewArgs(projectFilter(strings.ToLower(testProject)), hasConfigHashLabel())
-	args.Add("label", "com.docker.compose.oneoff=False")
-	listOpts := containerType.ListOptions{Filters: args, All: false}
+	listOpts := client.ContainerListOptions{
+		Filters: projectFilter(strings.ToLower(testProject)).Add("label", hasConfigHashLabel(), oneOffFilter(false)),
+		All:     false,
+	}
 	c1, inspect1 := containerDetails("service1", "123", containerType.StateRunning, containerType.Healthy, 0)
 	c2, inspect2 := containerDetails("service1", "456", containerType.StateRunning, "", 0)
-	c2.Ports = []containerType.Port{{PublicPort: 80, PrivatePort: 90, IP: "localhost"}}
+	c2.Ports = []containerType.PortSummary{{PublicPort: 80, PrivatePort: 90, IP: netip.MustParseAddr("127.0.0.1")}}
 	c3, inspect3 := containerDetails("service2", "789", containerType.StateExited, "", 130)
-	api.EXPECT().ContainerList(t.Context(), listOpts).Return([]containerType.Summary{c1, c2, c3}, nil)
-	api.EXPECT().ContainerInspect(anyCancellableContext(), "123").Return(inspect1, nil)
-	api.EXPECT().ContainerInspect(anyCancellableContext(), "456").Return(inspect2, nil)
-	api.EXPECT().ContainerInspect(anyCancellableContext(), "789").Return(inspect3, nil)
+	api.EXPECT().ContainerList(t.Context(), listOpts).Return(client.ContainerListResult{
+		Items: []containerType.Summary{c1, c2, c3},
+	}, nil)
+	api.EXPECT().ContainerInspect(anyCancellableContext(), "123", gomock.Any()).Return(client.ContainerInspectResult{Container: inspect1}, nil)
+	api.EXPECT().ContainerInspect(anyCancellableContext(), "456", gomock.Any()).Return(client.ContainerInspectResult{Container: inspect2}, nil)
+	api.EXPECT().ContainerInspect(anyCancellableContext(), "789", gomock.Any()).Return(client.ContainerInspectResult{Container: inspect3}, nil)
 
 	containers, err := tested.Ps(t.Context(), strings.ToLower(testProject), compose.PsOptions{})
 
@@ -66,8 +70,7 @@ func TestPs(t *testing.T) {
 		{
 			ID: "456", Name: "456", Names: []string{"/456"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service1",
 			State:      containerType.StateRunning,
-			Health:     "",
-			Publishers: []compose.PortPublisher{{URL: "localhost", TargetPort: 90, PublishedPort: 80}},
+			Publishers: []compose.PortPublisher{{URL: "127.0.0.1", TargetPort: 90, PublishedPort: 80}},
 			Labels: map[string]string{
 				compose.ProjectLabel:     strings.ToLower(testProject),
 				compose.ConfigFilesLabel: "/src/pkg/compose/testdata/compose.yaml",
@@ -78,7 +81,6 @@ func TestPs(t *testing.T) {
 		{
 			ID: "789", Name: "789", Names: []string{"/789"}, Image: "foo", Project: strings.ToLower(testProject), Service: "service2",
 			State:      containerType.StateExited,
-			Health:     "",
 			ExitCode:   130,
 			Publishers: []compose.PortPublisher{},
 			Labels: map[string]string{
@@ -102,12 +104,10 @@ func containerDetails(service string, id string, status containerType.ContainerS
 		State:  status,
 	}
 	inspect := containerType.InspectResponse{
-		ContainerJSONBase: &containerType.ContainerJSONBase{
-			State: &containerType.State{
-				Status:   status,
-				Health:   &containerType.Health{Status: health},
-				ExitCode: exitCode,
-			},
+		State: &containerType.State{
+			Status:   status,
+			Health:   &containerType.Health{Status: health},
+			ExitCode: exitCode,
 		},
 	}
 	return ctr, inspect

+ 22 - 9
pkg/compose/pull.go

@@ -28,13 +28,14 @@ import (
 	"time"
 
 	"github.com/compose-spec/compose-go/v2/types"
+	"github.com/containerd/platforms"
 	"github.com/distribution/reference"
 	"github.com/docker/cli/cli/config/configfile"
 	clitypes "github.com/docker/cli/cli/config/types"
-	"github.com/docker/docker/api/types/image"
-	"github.com/docker/docker/client"
-	"github.com/docker/docker/pkg/jsonmessage"
+	"github.com/moby/moby/api/types/jsonstream"
+	"github.com/moby/moby/client"
 	"github.com/opencontainers/go-digest"
+	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
 	"github.com/sirupsen/logrus"
 	"golang.org/x/sync/errgroup"
 
@@ -189,9 +190,18 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
 		platform = defaultPlatform
 	}
 
-	stream, err := s.apiClient().ImagePull(ctx, service.Image, image.PullOptions{
+	var ociPlatforms []ocispec.Platform
+	if platform != "" {
+		p, err := platforms.Parse(platform)
+		if err != nil {
+			return "", err
+		}
+		ociPlatforms = append(ociPlatforms, p)
+	}
+
+	stream, err := s.apiClient().ImagePull(ctx, service.Image, client.ImagePullOptions{
 		RegistryAuth: encodedAuth,
-		Platform:     platform,
+		Platforms:    ociPlatforms,
 	})
 
 	if ctx.Err() != nil {
@@ -221,7 +231,7 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser
 
 	dec := json.NewDecoder(stream)
 	for {
-		var jm jsonmessage.JSONMessage
+		var jm jsonstream.Message
 		if err := dec.Decode(&jm); err != nil {
 			if errors.Is(err, io.EOF) {
 				break
@@ -251,7 +261,9 @@ func ImageDigestResolver(ctx context.Context, file *configfile.ConfigFile, apiCl
 		if err != nil {
 			return "", err
 		}
-		inspect, err := apiClient.DistributionInspect(ctx, named.String(), auth)
+		inspect, err := apiClient.DistributionInspect(ctx, named.String(), client.DistributionInspectOptions{
+			EncodedRegistryAuth: auth,
+		})
 		if err != nil {
 			return "",
 				fmt.Errorf("failed to resolve digest for %s: %w", named.String(), err)
@@ -396,7 +408,7 @@ const (
 	PullCompletePhase      = "Pull complete"
 )
 
-func toPullProgressEvent(parent string, jm jsonmessage.JSONMessage, events api.EventProcessor) {
+func toPullProgressEvent(parent string, jm jsonstream.Message, events api.EventProcessor) {
 	if jm.ID == "" || jm.Progress == nil {
 		return
 	}
@@ -409,7 +421,8 @@ func toPullProgressEvent(parent string, jm jsonmessage.JSONMessage, events api.E
 		status   = api.Working
 	)
 
-	progress = jm.Progress.String()
+	// FIXME(thaJeztah): what's the replacement for Progress.String()?
+	// progress = jm.Progress.String()
 
 	switch jm.Status {
 	case PreparingPhase, WaitingPhase, PullingFsPhase:

+ 8 - 7
pkg/compose/push.go

@@ -27,8 +27,8 @@ import (
 
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/distribution/reference"
-	"github.com/docker/docker/api/types/image"
-	"github.com/docker/docker/pkg/jsonmessage"
+	"github.com/moby/moby/api/types/jsonstream"
+	"github.com/moby/moby/client"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose/v5/internal/registry"
@@ -101,7 +101,7 @@ func (s *composeService) pushServiceImage(ctx context.Context, tag string, quiet
 		return err
 	}
 
-	stream, err := s.apiClient().ImagePush(ctx, tag, image.PushOptions{
+	stream, err := s.apiClient().ImagePush(ctx, tag, client.ImagePushOptions{
 		RegistryAuth: base64.URLEncoding.EncodeToString(buf),
 	})
 	if err != nil {
@@ -109,7 +109,7 @@ func (s *composeService) pushServiceImage(ctx context.Context, tag string, quiet
 	}
 	dec := json.NewDecoder(stream)
 	for {
-		var jm jsonmessage.JSONMessage
+		var jm jsonstream.Message
 		if err := dec.Decode(&jm); err != nil {
 			if errors.Is(err, io.EOF) {
 				break
@@ -128,7 +128,7 @@ func (s *composeService) pushServiceImage(ctx context.Context, tag string, quiet
 	return nil
 }
 
-func toPushProgressEvent(prefix string, jm jsonmessage.JSONMessage, events api.EventProcessor) {
+func toPushProgressEvent(prefix string, jm jsonstream.Message, events api.EventProcessor) {
 	if jm.ID == "" {
 		// skipped
 		return
@@ -149,7 +149,8 @@ func toPushProgressEvent(prefix string, jm jsonmessage.JSONMessage, events api.E
 		text = jm.Error.Message
 	}
 	if jm.Progress != nil {
-		text = jm.Progress.String()
+		// FIXME(thaJeztah): what's the replacement for Progress.String()?
+		// text = jm.Progress.String()
 		if jm.Progress.Total != 0 {
 			current = jm.Progress.Current
 			total = jm.Progress.Total
@@ -173,7 +174,7 @@ func toPushProgressEvent(prefix string, jm jsonmessage.JSONMessage, events api.E
 	})
 }
 
-func isDone(msg jsonmessage.JSONMessage) bool {
+func isDone(msg jsonstream.Message) bool {
 	// TODO there should be a better way to detect push is done than such a status message check
 	switch strings.ToLower(msg.Status) {
 	case "pushed", "layer already exists":

+ 5 - 4
pkg/compose/remove.go

@@ -21,7 +21,8 @@ import (
 	"fmt"
 	"strings"
 
-	"github.com/docker/docker/api/types/container"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -56,7 +57,7 @@ func (s *composeService) Remove(ctx context.Context, projectName string, options
 	var stoppedContainers Containers
 	for _, ctr := range containers {
 		// We have to inspect containers, as State reported by getContainers suffers a race condition
-		inspected, err := s.apiClient().ContainerInspect(ctx, ctr.ID)
+		inspected, err := s.apiClient().ContainerInspect(ctx, ctr.ID, client.ContainerInspectOptions{})
 		if api.IsNotFoundError(err) {
 			// Already removed. Maybe configured with auto-remove
 			continue
@@ -64,7 +65,7 @@ func (s *composeService) Remove(ctx context.Context, projectName string, options
 		if err != nil {
 			return err
 		}
-		if !inspected.State.Running || (options.Stop && s.dryRun) {
+		if !inspected.Container.State.Running || (options.Stop && s.dryRun) {
 			stoppedContainers = append(stoppedContainers, ctr)
 		}
 	}
@@ -101,7 +102,7 @@ func (s *composeService) remove(ctx context.Context, containers Containers, opti
 		eg.Go(func() error {
 			eventName := getContainerProgressName(ctr)
 			s.events.On(removingEvent(eventName))
-			err := s.apiClient().ContainerRemove(ctx, ctr.ID, container.RemoveOptions{
+			_, err := s.apiClient().ContainerRemove(ctx, ctr.ID, client.ContainerRemoveOptions{
 				RemoveVolumes: options.Volumes,
 				Force:         options.Force,
 			})

+ 4 - 3
pkg/compose/restart.go

@@ -21,7 +21,7 @@ import (
 	"strings"
 
 	"github.com/compose-spec/compose-go/v2/types"
-	"github.com/docker/docker/api/types/container"
+	"github.com/moby/moby/client"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -94,8 +94,9 @@ func (s *composeService) restart(ctx context.Context, projectName string, option
 				}
 				eventName := getContainerProgressName(ctr)
 				s.events.On(restartingEvent(eventName))
-				timeout := utils.DurationSecondToInt(options.Timeout)
-				err = s.apiClient().ContainerRestart(ctx, ctr.ID, container.StopOptions{Timeout: timeout})
+				_, err = s.apiClient().ContainerRestart(ctx, ctr.ID, client.ContainerRestartOptions{
+					Timeout: utils.DurationSecondToInt(options.Timeout),
+				})
 				if err != nil {
 					return err
 				}

+ 5 - 4
pkg/compose/run.go

@@ -27,7 +27,8 @@ import (
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/docker/cli/cli"
 	cmd "github.com/docker/cli/cli/command/container"
-	"github.com/docker/docker/pkg/stringid"
+	"github.com/moby/moby/client"
+	"github.com/moby/moby/client/pkg/stringid"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
@@ -136,17 +137,17 @@ func (s *composeService) prepareRun(ctx context.Context, project *types.Project,
 		return "", err
 	}
 
-	ctr, err := s.apiClient().ContainerInspect(ctx, created.ID)
+	inspect, err := s.apiClient().ContainerInspect(ctx, created.ID, client.ContainerInspectOptions{})
 	if err != nil {
 		return "", err
 	}
 
-	err = s.injectSecrets(ctx, project, service, ctr.ID)
+	err = s.injectSecrets(ctx, project, service, inspect.Container.ID)
 	if err != nil {
 		return created.ID, err
 	}
 
-	err = s.injectConfigs(ctx, project, service, ctr.ID)
+	err = s.injectConfigs(ctx, project, service, inspect.Container.ID)
 	return created.ID, err
 }
 

+ 6 - 3
pkg/compose/secrets.go

@@ -25,7 +25,7 @@ import (
 	"time"
 
 	"github.com/compose-spec/compose-go/v2/types"
-	"github.com/docker/docker/api/types/container"
+	"github.com/moby/moby/client"
 )
 
 type mountType string
@@ -128,9 +128,12 @@ func (s *composeService) copyFileToContainer(ctx context.Context, id, content st
 		return err
 	}
 
-	return s.apiClient().CopyToContainer(ctx, id, "/", &b, container.CopyToContainerOptions{
-		CopyUIDGID: file.UID != "" || file.GID != "",
+	_, err = s.apiClient().CopyToContainer(ctx, id, client.CopyToContainerOptions{
+		DestinationPath: "/",
+		Content:         &b,
+		CopyUIDGID:      file.UID != "" || file.GID != "",
 	})
+	return err
 }
 
 func createTar(env string, config types.FileReferenceConfig) (bytes.Buffer, error) {

+ 1 - 1
pkg/compose/shellout.go

@@ -26,7 +26,7 @@ import (
 	"github.com/docker/cli/cli-plugins/metadata"
 	"github.com/docker/cli/cli/command"
 	"github.com/docker/cli/cli/flags"
-	"github.com/docker/docker/client"
+	"github.com/moby/moby/client"
 	"go.opentelemetry.io/otel"
 	"go.opentelemetry.io/otel/propagation"
 

+ 5 - 9
pkg/compose/start.go

@@ -23,8 +23,7 @@ import (
 	"strings"
 
 	"github.com/compose-spec/compose-go/v2/types"
-	containerType "github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
+	"github.com/moby/moby/client"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
@@ -50,17 +49,14 @@ func (s *composeService) start(ctx context.Context, projectName string, options
 		}
 	}
 
-	var containers Containers
-	containers, err := s.apiClient().ContainerList(ctx, containerType.ListOptions{
-		Filters: filters.NewArgs(
-			projectFilter(project.Name),
-			oneOffFilter(false),
-		),
-		All: true,
+	res, err := s.apiClient().ContainerList(ctx, client.ContainerListOptions{
+		Filters: projectFilter(project.Name).Add("label", oneOffFilter(false)),
+		All:     true,
 	})
 	if err != nil {
 		return err
 	}
+	containers := Containers(res.Items)
 
 	err = InDependencyOrder(ctx, project, func(c context.Context, name string) error {
 		service, err := project.GetService(name)

+ 17 - 17
pkg/compose/stop_test.go

@@ -21,10 +21,8 @@ import (
 	"testing"
 	"time"
 
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/network"
-	"github.com/docker/docker/api/types/volume"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"go.uber.org/mock/gomock"
 	"gotest.tools/v3/assert"
 
@@ -41,25 +39,27 @@ func TestStopTimeout(t *testing.T) {
 	assert.NilError(t, err)
 
 	api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return(
-		[]container.Summary{
-			testContainer("service1", "123", false),
-			testContainer("service1", "456", false),
-			testContainer("service2", "789", false),
+		client.ContainerListResult{
+			Items: []container.Summary{
+				testContainer("service1", "123", false),
+				testContainer("service1", "456", false),
+				testContainer("service2", "789", false),
+			},
 		}, nil)
 	api.EXPECT().VolumeList(
 		gomock.Any(),
-		volume.ListOptions{
-			Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject))),
+		client.VolumeListOptions{
+			Filters: projectFilter(strings.ToLower(testProject)),
 		}).
-		Return(volume.ListResponse{}, nil)
-	api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}).
-		Return([]network.Summary{}, nil)
+		Return(client.VolumeListResult{}, nil)
+	api.EXPECT().NetworkList(gomock.Any(), client.NetworkListOptions{Filters: projectFilter(strings.ToLower(testProject))}).
+		Return(client.NetworkListResult{}, nil)
 
 	timeout := 2 * time.Second
-	stopConfig := container.StopOptions{Timeout: utils.DurationSecondToInt(&timeout)}
-	api.EXPECT().ContainerStop(gomock.Any(), "123", stopConfig).Return(nil)
-	api.EXPECT().ContainerStop(gomock.Any(), "456", stopConfig).Return(nil)
-	api.EXPECT().ContainerStop(gomock.Any(), "789", stopConfig).Return(nil)
+	stopConfig := client.ContainerStopOptions{Timeout: utils.DurationSecondToInt(&timeout)}
+	api.EXPECT().ContainerStop(gomock.Any(), "123", stopConfig).Return(client.ContainerStopResult{}, nil)
+	api.EXPECT().ContainerStop(gomock.Any(), "456", stopConfig).Return(client.ContainerStopResult{}, nil)
+	api.EXPECT().ContainerStop(gomock.Any(), "789", stopConfig).Return(client.ContainerStopResult{}, nil)
 
 	err = tested.Stop(t.Context(), strings.ToLower(testProject), compose.StopOptions{
 		Timeout: &timeout,

+ 4 - 1
pkg/compose/top.go

@@ -20,6 +20,7 @@ import (
 	"context"
 	"strings"
 
+	"github.com/moby/moby/client"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -39,7 +40,9 @@ func (s *composeService) Top(ctx context.Context, projectName string, services [
 	eg, ctx := errgroup.WithContext(ctx)
 	for i, ctr := range containers {
 		eg.Go(func() error {
-			topContent, err := s.apiClient().ContainerTop(ctx, ctr.ID, []string{})
+			topContent, err := s.apiClient().ContainerTop(ctx, ctr.ID, client.ContainerTopOptions{
+				Arguments: []string{},
+			})
 			if err != nil {
 				return err
 			}

+ 4 - 3
pkg/compose/up.go

@@ -31,6 +31,7 @@ import (
 	"github.com/containerd/errdefs"
 	"github.com/docker/cli/cli"
 	"github.com/eiannone/keyboard"
+	"github.com/moby/moby/client"
 	"github.com/sirupsen/logrus"
 	"golang.org/x/sync/errgroup"
 
@@ -252,15 +253,15 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
 			return
 		}
 		eg.Go(func() error {
-			ctr, err := s.apiClient().ContainerInspect(globalCtx, event.ID)
+			res, err := s.apiClient().ContainerInspect(globalCtx, event.ID, client.ContainerInspectOptions{})
 			if err != nil {
 				appendErr(err)
 				return nil
 			}
 
-			err = s.doLogContainer(globalCtx, options.Start.Attach, event.Source, ctr, api.LogOptions{
+			err = s.doLogContainer(globalCtx, options.Start.Attach, event.Source, res.Container, api.LogOptions{
 				Follow: true,
-				Since:  ctr.State.StartedAt,
+				Since:  res.Container.State.StartedAt,
 			})
 			if errdefs.IsNotImplemented(err) {
 				// container may be configured with logging_driver: none

+ 11 - 12
pkg/compose/volumes.go

@@ -20,16 +20,15 @@ import (
 	"context"
 	"slices"
 
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/volume"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 
 	"github.com/docker/compose/v5/pkg/api"
 )
 
 func (s *composeService) Volumes(ctx context.Context, project string, options api.VolumesOptions) ([]api.VolumesSummary, error) {
-	allContainers, err := s.apiClient().ContainerList(ctx, container.ListOptions{
-		Filters: filters.NewArgs(projectFilter(project)),
+	allContainers, err := s.apiClient().ContainerList(ctx, client.ContainerListOptions{
+		Filters: projectFilter(project),
 	})
 	if err != nil {
 		return nil, err
@@ -39,23 +38,23 @@ func (s *composeService) Volumes(ctx context.Context, project string, options ap
 
 	if len(options.Services) > 0 {
 		// filter service containers
-		for _, c := range allContainers {
+		for _, c := range allContainers.Items {
 			if slices.Contains(options.Services, c.Labels[api.ServiceLabel]) {
 				containers = append(containers, c)
 			}
 		}
 	} else {
-		containers = allContainers
+		containers = allContainers.Items
 	}
 
-	volumesResponse, err := s.apiClient().VolumeList(ctx, volume.ListOptions{
-		Filters: filters.NewArgs(projectFilter(project)),
+	volumesResponse, err := s.apiClient().VolumeList(ctx, client.VolumeListOptions{
+		Filters: projectFilter(project),
 	})
 	if err != nil {
 		return nil, err
 	}
 
-	projectVolumes := volumesResponse.Volumes
+	projectVolumes := volumesResponse.Items
 
 	if len(options.Services) == 0 {
 		return projectVolumes, nil
@@ -66,8 +65,8 @@ func (s *composeService) Volumes(ctx context.Context, project string, options ap
 	// create a name lookup of volumes used by containers
 	serviceVolumes := make(map[string]bool)
 
-	for _, container := range containers {
-		for _, mount := range container.Mounts {
+	for _, ctr := range containers {
+		for _, mount := range ctr.Mounts {
 			serviceVolumes[mount.Name] = true
 		}
 	}

+ 15 - 17
pkg/compose/volumes_test.go

@@ -19,9 +19,9 @@ package compose
 import (
 	"testing"
 
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/volume"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/volume"
+	"github.com/moby/moby/client"
 	"go.uber.org/mock/gomock"
 	"gotest.tools/v3/assert"
 
@@ -38,9 +38,9 @@ func TestVolumes(t *testing.T) {
 	}
 
 	// Create test volumes
-	vol1 := &volume.Volume{Name: testProject + "_vol1"}
-	vol2 := &volume.Volume{Name: testProject + "_vol2"}
-	vol3 := &volume.Volume{Name: testProject + "_vol3"}
+	vol1 := volume.Volume{Name: testProject + "_vol1"}
+	vol2 := volume.Volume{Name: testProject + "_vol2"}
+	vol3 := volume.Volume{Name: testProject + "_vol3"}
 
 	// Create test containers with volume mounts
 	c1 := container.Summary{
@@ -57,28 +57,26 @@ func TestVolumes(t *testing.T) {
 		},
 	}
 
-	args := filters.NewArgs(projectFilter(testProject))
-	listOpts := container.ListOptions{Filters: args}
-	volumeListArgs := filters.NewArgs(projectFilter(testProject))
-	volumeListOpts := volume.ListOptions{Filters: volumeListArgs}
-	volumeReturn := volume.ListResponse{
-		Volumes: []*volume.Volume{vol1, vol2, vol3},
+	listOpts := client.ContainerListOptions{Filters: projectFilter(testProject)}
+	volumeListOpts := client.VolumeListOptions{Filters: projectFilter(testProject)}
+	volumeReturn := client.VolumeListResult{
+		Items: []volume.Volume{vol1, vol2, vol3},
+	}
+	containerReturn := client.ContainerListResult{
+		Items: []container.Summary{c1, c2},
 	}
-	containerReturn := []container.Summary{c1, c2}
 
 	mockApi.EXPECT().ContainerList(t.Context(), listOpts).Times(2).Return(containerReturn, nil)
 	mockApi.EXPECT().VolumeList(t.Context(), volumeListOpts).Times(2).Return(volumeReturn, nil)
 
 	// Test without service filter - should return all project volumes
-	volumeOptions := api.VolumesOptions{}
-	volumes, err := tested.Volumes(t.Context(), testProject, volumeOptions)
+	volumes, err := tested.Volumes(t.Context(), testProject, api.VolumesOptions{})
 	expected := []api.VolumesSummary{vol1, vol2, vol3}
 	assert.NilError(t, err)
 	assert.DeepEqual(t, volumes, expected)
 
 	// Test with service filter - should only return volumes used by service1
-	volumeOptions = api.VolumesOptions{Services: []string{"service1"}}
-	volumes, err = tested.Volumes(t.Context(), testProject, volumeOptions)
+	volumes, err = tested.Volumes(t.Context(), testProject, api.VolumesOptions{Services: []string{"service1"}})
 	expected = []api.VolumesSummary{vol1, vol2}
 	assert.NilError(t, err)
 	assert.DeepEqual(t, volumes, expected)

+ 4 - 5
pkg/compose/wait.go

@@ -20,6 +20,7 @@ import (
 	"context"
 	"fmt"
 
+	"github.com/moby/moby/client"
 	"golang.org/x/sync/errgroup"
 
 	"github.com/docker/compose/v5/pkg/api"
@@ -39,15 +40,13 @@ func (s *composeService) Wait(ctx context.Context, projectName string, options a
 	for _, ctr := range containers {
 		eg.Go(func() error {
 			var err error
-			resultC, errC := s.apiClient().ContainerWait(waitCtx, ctr.ID, "")
-
+			res := s.apiClient().ContainerWait(waitCtx, ctr.ID, client.ContainerWaitOptions{})
 			select {
-			case result := <-resultC:
+			case result := <-res.Result:
 				_, _ = fmt.Fprintf(s.stdout(), "container %q exited with status code %d\n", ctr.ID, result.StatusCode)
 				statusCode = result.StatusCode
-			case err = <-errC:
+			case err = <-res.Error:
 			}
-
 			return err
 		})
 	}

+ 27 - 27
pkg/compose/watch.go

@@ -32,11 +32,10 @@ import (
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/compose-spec/compose-go/v2/utils"
 	ccli "github.com/docker/cli/cli/command/container"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/image"
 	"github.com/go-viper/mapstructure/v2"
 	"github.com/moby/buildkit/util/progress/progressui"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/client"
 	"github.com/sirupsen/logrus"
 	"golang.org/x/sync/errgroup"
 
@@ -459,20 +458,20 @@ func (t tarDockerClient) ContainersForService(ctx context.Context, projectName s
 }
 
 func (t tarDockerClient) Exec(ctx context.Context, containerID string, cmd []string, in io.Reader) error {
-	execCfg := container.ExecOptions{
+	execCreateResp, err := t.s.apiClient().ExecCreate(ctx, containerID, client.ExecCreateOptions{
 		Cmd:          cmd,
 		AttachStdout: false,
 		AttachStderr: true,
 		AttachStdin:  in != nil,
-		Tty:          false,
-	}
-	execCreateResp, err := t.s.apiClient().ContainerExecCreate(ctx, containerID, execCfg)
+		TTY:          false,
+	})
 	if err != nil {
 		return err
 	}
 
-	startCheck := container.ExecStartOptions{Tty: false, Detach: false}
-	conn, err := t.s.apiClient().ContainerExecAttach(ctx, execCreateResp.ID, startCheck)
+	conn, err := t.s.apiClient().ExecAttach(ctx, execCreateResp.ID, client.ExecAttachOptions{
+		TTY: false,
+	})
 	if err != nil {
 		return err
 	}
@@ -493,7 +492,10 @@ func (t tarDockerClient) Exec(ctx context.Context, containerID string, cmd []str
 		return err
 	})
 
-	err = t.s.apiClient().ContainerExecStart(ctx, execCreateResp.ID, startCheck)
+	_, err = t.s.apiClient().ExecStart(ctx, execCreateResp.ID, client.ExecStartOptions{
+		TTY:    false,
+		Detach: false,
+	})
 	if err != nil {
 		return err
 	}
@@ -505,7 +507,7 @@ func (t tarDockerClient) Exec(ctx context.Context, containerID string, cmd []str
 		return err
 	}
 
-	execResult, err := t.s.apiClient().ContainerExecInspect(ctx, execCreateResp.ID)
+	execResult, err := t.s.apiClient().ExecInspect(ctx, execCreateResp.ID, client.ExecInspectOptions{})
 	if err != nil {
 		return err
 	}
@@ -519,9 +521,12 @@ func (t tarDockerClient) Exec(ctx context.Context, containerID string, cmd []str
 }
 
 func (t tarDockerClient) Untar(ctx context.Context, id string, archive io.ReadCloser) error {
-	return t.s.apiClient().CopyToContainer(ctx, id, "/", archive, container.CopyToContainerOptions{
-		CopyUIDGID: true,
+	_, err := t.s.apiClient().CopyToContainer(ctx, id, client.CopyToContainerOptions{
+		DestinationPath: "/",
+		Content:         archive,
+		CopyUIDGID:      true,
 	})
+	return err
 }
 
 //nolint:gocyclo
@@ -705,20 +710,17 @@ func writeWatchSyncMessage(log api.LogConsumer, serviceName string, pathMappings
 }
 
 func (s *composeService) pruneDanglingImagesOnRebuild(ctx context.Context, projectName string, imageNameToIdMap map[string]string) {
-	images, err := s.apiClient().ImageList(ctx, image.ListOptions{
-		Filters: filters.NewArgs(
-			filters.Arg("dangling", "true"),
-			filters.Arg("label", api.ProjectLabel+"="+projectName),
-		),
+	images, err := s.apiClient().ImageList(ctx, client.ImageListOptions{
+		Filters: projectFilter(projectName).Add("dangling", "true"),
 	})
 	if err != nil {
 		logrus.Debugf("Failed to list images: %v", err)
 		return
 	}
 
-	for _, img := range images {
+	for _, img := range images.Items {
 		if _, ok := imageNameToIdMap[img.ID]; !ok {
-			_, err := s.apiClient().ImageRemove(ctx, img.ID, image.RemoveOptions{})
+			_, err := s.apiClient().ImageRemove(ctx, img.ID, client.ImageRemoveOptions{})
 			if err != nil {
 				logrus.Debugf("Failed to remove image %s: %v", img.ID, err)
 			}
@@ -832,20 +834,18 @@ func shouldIgnore(name string, ignore watch.PathMatcher) bool {
 
 // gets the image creation time for a service
 func (s *composeService) imageCreatedTime(ctx context.Context, project *types.Project, serviceName string) (time.Time, error) {
-	containers, err := s.apiClient().ContainerList(ctx, container.ListOptions{
-		All: true,
-		Filters: filters.NewArgs(
-			filters.Arg("label", fmt.Sprintf("%s=%s", api.ProjectLabel, project.Name)),
-			filters.Arg("label", fmt.Sprintf("%s=%s", api.ServiceLabel, serviceName))),
+	res, err := s.apiClient().ContainerList(ctx, client.ContainerListOptions{
+		All:     true,
+		Filters: projectFilter(project.Name).Add("label", serviceFilter(serviceName)),
 	})
 	if err != nil {
 		return time.Now(), err
 	}
-	if len(containers) == 0 {
+	if len(res.Items) == 0 {
 		return time.Now(), fmt.Errorf("could not get created time for service's image")
 	}
 
-	img, err := s.apiClient().ImageInspect(ctx, containers[0].ImageID)
+	img, err := s.apiClient().ImageInspect(ctx, res.Items[0].ImageID)
 	if err != nil {
 		return time.Now(), err
 	}

+ 18 - 15
pkg/compose/watch_test.go

@@ -23,10 +23,10 @@ import (
 
 	"github.com/compose-spec/compose-go/v2/types"
 	"github.com/docker/cli/cli/streams"
-	"github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/image"
 	"github.com/jonboulle/clockwork"
+	"github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/image"
+	"github.com/moby/moby/client"
 	"github.com/stretchr/testify/require"
 	"go.uber.org/mock/gomock"
 	"gotest.tools/v3/assert"
@@ -77,21 +77,24 @@ func TestWatch_Sync(t *testing.T) {
 	cli := mocks.NewMockCli(mockCtrl)
 	cli.EXPECT().Err().Return(streams.NewOut(os.Stderr)).AnyTimes()
 	apiClient := mocks.NewMockAPIClient(mockCtrl)
-	apiClient.EXPECT().ContainerList(gomock.Any(), gomock.Any()).Return([]container.Summary{
-		testContainer("test", "123", false),
+	apiClient.EXPECT().ContainerList(gomock.Any(), gomock.Any()).Return(client.ContainerListResult{
+		Items: []container.Summary{
+			testContainer("test", "123", false),
+		},
 	}, nil).AnyTimes()
 	// we expect the image to be pruned
-	apiClient.EXPECT().ImageList(gomock.Any(), image.ListOptions{
-		Filters: filters.NewArgs(
-			filters.Arg("dangling", "true"),
-			filters.Arg("label", api.ProjectLabel+"=myProjectName"),
-		),
-	}).Return([]image.Summary{
-		{ID: "123"},
-		{ID: "456"},
+	apiClient.EXPECT().ImageList(gomock.Any(), client.ImageListOptions{
+		Filters: make(client.Filters).
+			Add("dangling", "true").
+			Add("label", api.ProjectLabel+"=myProjectName"),
+	}).Return(client.ImageListResult{
+		Items: []image.Summary{
+			{ID: "123"},
+			{ID: "456"},
+		},
 	}, nil).Times(1)
-	apiClient.EXPECT().ImageRemove(gomock.Any(), "123", image.RemoveOptions{}).Times(1)
-	apiClient.EXPECT().ImageRemove(gomock.Any(), "456", image.RemoveOptions{}).Times(1)
+	apiClient.EXPECT().ImageRemove(gomock.Any(), "123", client.ImageRemoveOptions{}).Times(1)
+	apiClient.EXPECT().ImageRemove(gomock.Any(), "456", client.ImageRemoveOptions{}).Times(1)
 	//
 	cli.EXPECT().Client().Return(apiClient).AnyTimes()
 

+ 230 - 272
pkg/dryrun/dryrunclient.go

@@ -33,21 +33,11 @@ import (
 	"github.com/docker/buildx/builder"
 	"github.com/docker/buildx/util/imagetools"
 	"github.com/docker/cli/cli/command"
-	moby "github.com/docker/docker/api/types"
-	"github.com/docker/docker/api/types/build"
-	"github.com/docker/docker/api/types/checkpoint"
-	containerType "github.com/docker/docker/api/types/container"
-	"github.com/docker/docker/api/types/events"
-	"github.com/docker/docker/api/types/filters"
-	"github.com/docker/docker/api/types/image"
-	"github.com/docker/docker/api/types/network"
-	"github.com/docker/docker/api/types/registry"
-	"github.com/docker/docker/api/types/swarm"
-	"github.com/docker/docker/api/types/system"
-	"github.com/docker/docker/api/types/volume"
-	"github.com/docker/docker/client"
-	"github.com/docker/docker/pkg/jsonmessage"
-	specs "github.com/opencontainers/image-spec/specs-go/v1"
+	containerType "github.com/moby/moby/api/types/container"
+	"github.com/moby/moby/api/types/image"
+	"github.com/moby/moby/api/types/jsonstream"
+	"github.com/moby/moby/api/types/volume"
+	"github.com/moby/moby/client"
 )
 
 var _ client.APIClient = &DryRunClient{}
@@ -65,6 +55,14 @@ type execDetails struct {
 	command   []string
 }
 
+type fakeStreamResult struct {
+	io.ReadCloser
+	client.ImagePushResponse // same interface as [client.ImagePullResponse]
+}
+
+func (e fakeStreamResult) Read(p []byte) (int, error) { return e.ReadCloser.Read(p) }
+func (e fakeStreamResult) Close() error               { return e.ReadCloser.Close() }
+
 // NewDryRunClient produces a DryRunClient
 func NewDryRunClient(apiClient client.APIClient, cli command.Cli) (*DryRunClient, error) {
 	b, err := builder.New(cli, builder.WithSkippedValidation())
@@ -91,27 +89,25 @@ func getCallingFunction() string {
 
 // All methods and functions which need to be overridden for dry run.
 
-func (d *DryRunClient) ContainerAttach(ctx context.Context, container string, options containerType.AttachOptions) (moby.HijackedResponse, error) {
-	return moby.HijackedResponse{}, errors.New("interactive run is not supported in dry-run mode")
+func (d *DryRunClient) ContainerAttach(ctx context.Context, container string, options client.ContainerAttachOptions) (client.ContainerAttachResult, error) {
+	return client.ContainerAttachResult{}, errors.New("interactive run is not supported in dry-run mode")
 }
 
-func (d *DryRunClient) ContainerCreate(ctx context.Context, config *containerType.Config, hostConfig *containerType.HostConfig,
-	networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string,
-) (containerType.CreateResponse, error) {
+func (d *DryRunClient) ContainerCreate(ctx context.Context, options client.ContainerCreateOptions) (client.ContainerCreateResult, error) {
 	d.containers = append(d.containers, containerType.Summary{
-		ID:     containerName,
-		Names:  []string{containerName},
-		Labels: config.Labels,
+		ID:     options.Name,
+		Names:  []string{options.Name},
+		Labels: options.Config.Labels,
 		HostConfig: struct {
 			NetworkMode string            `json:",omitempty"`
 			Annotations map[string]string `json:",omitempty"`
 		}{},
 	})
-	return containerType.CreateResponse{ID: containerName}, nil
+	return client.ContainerCreateResult{ID: options.Name}, nil
 }
 
-func (d *DryRunClient) ContainerInspect(ctx context.Context, container string) (containerType.InspectResponse, error) {
-	containerJSON, err := d.apiClient.ContainerInspect(ctx, container)
+func (d *DryRunClient) ContainerInspect(ctx context.Context, container string, options client.ContainerInspectOptions) (client.ContainerInspectResult, error) {
+	containerJSON, err := d.apiClient.ContainerInspect(ctx, container, options)
 	if err != nil {
 		id := "dryRunId"
 		for _, c := range d.containers {
@@ -119,8 +115,8 @@ func (d *DryRunClient) ContainerInspect(ctx context.Context, container string) (
 				id = container
 			}
 		}
-		return containerType.InspectResponse{
-			ContainerJSONBase: &containerType.ContainerJSONBase{
+		return client.ContainerInspectResult{
+			Container: containerType.InspectResponse{
 				ID:   id,
 				Name: container,
 				State: &containerType.State{
@@ -129,117 +125,111 @@ func (d *DryRunClient) ContainerInspect(ctx context.Context, container string) (
 						Status: containerType.Healthy, // needed for healthcheck control
 					},
 				},
+				Mounts:          nil,
+				Config:          &containerType.Config{},
+				NetworkSettings: &containerType.NetworkSettings{},
 			},
-			Mounts:          nil,
-			Config:          &containerType.Config{},
-			NetworkSettings: &containerType.NetworkSettings{},
 		}, nil
 	}
 	return containerJSON, err
 }
 
-func (d *DryRunClient) ContainerKill(ctx context.Context, container, signal string) error {
-	return nil
+func (d *DryRunClient) ContainerKill(ctx context.Context, container string, options client.ContainerKillOptions) (client.ContainerKillResult, error) {
+	return client.ContainerKillResult{}, nil
 }
 
-func (d *DryRunClient) ContainerList(ctx context.Context, options containerType.ListOptions) ([]containerType.Summary, error) {
+func (d *DryRunClient) ContainerList(ctx context.Context, options client.ContainerListOptions) (client.ContainerListResult, error) {
 	caller := getCallingFunction()
 	switch caller {
 	case "start":
-		return d.containers, nil
+		return client.ContainerListResult{
+			Items: d.containers,
+		}, nil
 	case "getContainers":
 		if len(d.containers) == 0 {
-			var err error
-			d.containers, err = d.apiClient.ContainerList(ctx, options)
-			return d.containers, err
+			res, err := d.apiClient.ContainerList(ctx, options)
+			if err == nil {
+				d.containers = res.Items
+			}
+			return client.ContainerListResult{
+				Items: d.containers,
+			}, err
 		}
 	}
 	return d.apiClient.ContainerList(ctx, options)
 }
 
-func (d *DryRunClient) ContainerPause(ctx context.Context, container string) error {
-	return nil
+func (d *DryRunClient) ContainerPause(ctx context.Context, container string, options client.ContainerPauseOptions) (client.ContainerPauseResult, error) {
+	return client.ContainerPauseResult{}, nil
 }
 
-func (d *DryRunClient) ContainerRemove(ctx context.Context, container string, options containerType.RemoveOptions) error {
-	return nil
+func (d *DryRunClient) ContainerRemove(ctx context.Context, container string, options client.ContainerRemoveOptions) (client.ContainerRemoveResult, error) {
+	return client.ContainerRemoveResult{}, nil
 }
 
-func (d *DryRunClient) ContainerRename(ctx context.Context, container, newContainerName string) error {
-	return nil
+func (d *DryRunClient) ContainerRename(ctx context.Context, container string, options client.ContainerRenameOptions) (client.ContainerRenameResult, error) {
+	return client.ContainerRenameResult{}, nil
 }
 
-func (d *DryRunClient) ContainerRestart(ctx context.Context, container string, options containerType.StopOptions) error {
-	return nil
+func (d *DryRunClient) ContainerRestart(ctx context.Context, container string, options client.ContainerRestartOptions) (client.ContainerRestartResult, error) {
+	return client.ContainerRestartResult{}, nil
 }
 
-func (d *DryRunClient) ContainerStart(ctx context.Context, container string, options containerType.StartOptions) error {
-	return nil
+func (d *DryRunClient) ContainerStart(ctx context.Context, container string, options client.ContainerStartOptions) (client.ContainerStartResult, error) {
+	return client.ContainerStartResult{}, nil
 }
 
-func (d *DryRunClient) ContainerStop(ctx context.Context, container string, options containerType.StopOptions) error {
-	return nil
+func (d *DryRunClient) ContainerStop(ctx context.Context, container string, options client.ContainerStopOptions) (client.ContainerStopResult, error) {
+	return client.ContainerStopResult{}, nil
 }
 
-func (d *DryRunClient) ContainerUnpause(ctx context.Context, container string) error {
-	return nil
+func (d *DryRunClient) ContainerUnpause(ctx context.Context, container string, options client.ContainerUnpauseOptions) (client.ContainerUnpauseResult, error) {
+	return client.ContainerUnpauseResult{}, nil
 }
 
-func (d *DryRunClient) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, containerType.PathStat, error) {
-	rc := io.NopCloser(strings.NewReader(""))
-	if _, err := d.ContainerStatPath(ctx, container, srcPath); err != nil {
-		return rc, containerType.PathStat{}, fmt.Errorf("could not find the file %s in container %s", srcPath, container)
+func (d *DryRunClient) CopyFromContainer(ctx context.Context, container string, options client.CopyFromContainerOptions) (client.CopyFromContainerResult, error) {
+	if _, err := d.ContainerStatPath(ctx, container, client.ContainerStatPathOptions{Path: options.SourcePath}); err != nil {
+		return client.CopyFromContainerResult{}, fmt.Errorf("could not find the file %s in container %s", options.SourcePath, container)
 	}
-	return rc, containerType.PathStat{}, nil
+	return client.CopyFromContainerResult{}, nil
 }
 
-func (d *DryRunClient) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options containerType.CopyToContainerOptions) error {
-	return nil
+func (d *DryRunClient) CopyToContainer(ctx context.Context, container string, options client.CopyToContainerOptions) (client.CopyToContainerResult, error) {
+	return client.CopyToContainerResult{}, nil
 }
 
-func (d *DryRunClient) ImageBuild(ctx context.Context, reader io.Reader, options build.ImageBuildOptions) (build.ImageBuildResponse, error) {
-	rc := io.NopCloser(bytes.NewReader(nil))
-
-	return build.ImageBuildResponse{
-		Body: rc,
+func (d *DryRunClient) ImageBuild(ctx context.Context, reader io.Reader, options client.ImageBuildOptions) (client.ImageBuildResult, error) {
+	return client.ImageBuildResult{
+		Body: io.NopCloser(bytes.NewReader(nil)),
 	}, nil
 }
 
-func (d *DryRunClient) ImageInspect(ctx context.Context, imageName string, options ...client.ImageInspectOption) (image.InspectResponse, error) {
+func (d *DryRunClient) ImageInspect(ctx context.Context, imageName string, options ...client.ImageInspectOption) (client.ImageInspectResult, error) {
 	caller := getCallingFunction()
 	switch caller {
 	case "pullServiceImage", "buildContainerVolumes":
-		return image.InspectResponse{ID: "dryRunId"}, nil
+		return client.ImageInspectResult{
+			InspectResponse: image.InspectResponse{ID: "dryRunId"},
+		}, nil
 	default:
 		return d.apiClient.ImageInspect(ctx, imageName, options...)
 	}
 }
 
-// Deprecated: Use [DryRunClient.ImageInspect] instead; raw response can be obtained by [client.ImageInspectWithRawResponse] option.
-func (d *DryRunClient) ImageInspectWithRaw(ctx context.Context, imageName string) (image.InspectResponse, []byte, error) {
-	var buf bytes.Buffer
-	resp, err := d.ImageInspect(ctx, imageName, client.ImageInspectWithRawResponse(&buf))
-	if err != nil {
-		return image.InspectResponse{}, nil, err
-	}
-	return resp, buf.Bytes(), err
-}
-
-func (d *DryRunClient) ImagePull(ctx context.Context, ref string, options image.PullOptions) (io.ReadCloser, error) {
+func (d *DryRunClient) ImagePull(ctx context.Context, ref string, options client.ImagePullOptions) (client.ImagePullResponse, error) {
 	if _, _, err := d.resolver.Resolve(ctx, ref); err != nil {
 		return nil, err
 	}
-	rc := io.NopCloser(strings.NewReader(""))
-	return rc, nil
+	return fakeStreamResult{ReadCloser: http.NoBody}, nil
 }
 
-func (d *DryRunClient) ImagePush(ctx context.Context, ref string, options image.PushOptions) (io.ReadCloser, error) {
+func (d *DryRunClient) ImagePush(ctx context.Context, ref string, options client.ImagePushOptions) (client.ImagePushResponse, error) {
 	if _, _, err := d.resolver.Resolve(ctx, ref); err != nil {
 		return nil, err
 	}
-	jsonMessage, err := json.Marshal(&jsonmessage.JSONMessage{
+	jsonMessage, err := json.Marshal(&jsonstream.Message{
 		Status: "Pushed",
-		Progress: &jsonmessage.JSONProgress{
+		Progress: &jsonstream.Progress{
 			Current:    100,
 			Total:      100,
 			Start:      0,
@@ -251,48 +241,48 @@ func (d *DryRunClient) ImagePush(ctx context.Context, ref string, options image.
 	if err != nil {
 		return nil, err
 	}
-	rc := io.NopCloser(bytes.NewReader(jsonMessage))
-	return rc, nil
+	return fakeStreamResult{ReadCloser: io.NopCloser(bytes.NewReader(jsonMessage))}, nil
 }
 
-func (d *DryRunClient) ImageRemove(ctx context.Context, imageName string, options image.RemoveOptions) ([]image.DeleteResponse, error) {
-	return nil, nil
+func (d *DryRunClient) ImageRemove(ctx context.Context, imageName string, options client.ImageRemoveOptions) (client.ImageRemoveResult, error) {
+	return client.ImageRemoveResult{}, nil
 }
 
-func (d *DryRunClient) NetworkConnect(ctx context.Context, networkName, container string, config *network.EndpointSettings) error {
-	return nil
+func (d *DryRunClient) NetworkConnect(ctx context.Context, networkName string, options client.NetworkConnectOptions) (client.NetworkConnectResult, error) {
+	return client.NetworkConnectResult{}, nil
 }
 
-func (d *DryRunClient) NetworkCreate(ctx context.Context, name string, options network.CreateOptions) (network.CreateResponse, error) {
-	return network.CreateResponse{
-		ID:      name,
-		Warning: "",
+func (d *DryRunClient) NetworkCreate(ctx context.Context, name string, options client.NetworkCreateOptions) (client.NetworkCreateResult, error) {
+	return client.NetworkCreateResult{
+		ID: name,
 	}, nil
 }
 
-func (d *DryRunClient) NetworkDisconnect(ctx context.Context, networkName, container string, force bool) error {
-	return nil
+func (d *DryRunClient) NetworkDisconnect(ctx context.Context, networkName string, options client.NetworkDisconnectOptions) (client.NetworkDisconnectResult, error) {
+	return client.NetworkDisconnectResult{}, nil
 }
 
-func (d *DryRunClient) NetworkRemove(ctx context.Context, networkName string) error {
-	return nil
+func (d *DryRunClient) NetworkRemove(ctx context.Context, networkName string, options client.NetworkRemoveOptions) (client.NetworkRemoveResult, error) {
+	return client.NetworkRemoveResult{}, nil
 }
 
-func (d *DryRunClient) VolumeCreate(ctx context.Context, options volume.CreateOptions) (volume.Volume, error) {
-	return volume.Volume{
-		ClusterVolume: nil,
-		Driver:        options.Driver,
-		Labels:        options.Labels,
-		Name:          options.Name,
-		Options:       options.DriverOpts,
+func (d *DryRunClient) VolumeCreate(ctx context.Context, options client.VolumeCreateOptions) (client.VolumeCreateResult, error) {
+	return client.VolumeCreateResult{
+		Volume: volume.Volume{
+			ClusterVolume: nil,
+			Driver:        options.Driver,
+			Labels:        options.Labels,
+			Name:          options.Name,
+			Options:       options.DriverOpts,
+		},
 	}, nil
 }
 
-func (d *DryRunClient) VolumeRemove(ctx context.Context, volumeID string, force bool) error {
-	return nil
+func (d *DryRunClient) VolumeRemove(ctx context.Context, volumeID string, options client.VolumeRemoveOptions) (client.VolumeRemoveResult, error) {
+	return client.VolumeRemoveResult{}, nil
 }
 
-func (d *DryRunClient) ContainerExecCreate(ctx context.Context, container string, config containerType.ExecOptions) (containerType.ExecCreateResponse, error) {
+func (d *DryRunClient) ExecCreate(ctx context.Context, container string, config client.ExecCreateOptions) (client.ExecCreateResult, error) {
 	b := make([]byte, 32)
 	_, _ = rand.Read(b)
 	id := fmt.Sprintf("%x", b)
@@ -300,347 +290,327 @@ func (d *DryRunClient) ContainerExecCreate(ctx context.Context, container string
 		container: container,
 		command:   config.Cmd,
 	})
-	return containerType.ExecCreateResponse{
+	return client.ExecCreateResult{
 		ID: id,
 	}, nil
 }
 
-func (d *DryRunClient) ContainerExecStart(ctx context.Context, execID string, config containerType.ExecStartOptions) error {
+func (d *DryRunClient) ExecStart(ctx context.Context, execID string, config client.ExecStartOptions) (client.ExecStartResult, error) {
 	_, ok := d.execs.LoadAndDelete(execID)
 	if !ok {
-		return fmt.Errorf("invalid exec ID %q", execID)
+		return client.ExecStartResult{}, fmt.Errorf("invalid exec ID %q", execID)
 	}
-	return nil
+	return client.ExecStartResult{}, nil
 }
 
 // Functions delegated to original APIClient (not used by Compose or not modifying the Compose stack)
 
-func (d *DryRunClient) ConfigList(ctx context.Context, options swarm.ConfigListOptions) ([]swarm.Config, error) {
+func (d *DryRunClient) ConfigList(ctx context.Context, options client.ConfigListOptions) (client.ConfigListResult, error) {
 	return d.apiClient.ConfigList(ctx, options)
 }
 
-func (d *DryRunClient) ConfigCreate(ctx context.Context, config swarm.ConfigSpec) (swarm.ConfigCreateResponse, error) {
-	return d.apiClient.ConfigCreate(ctx, config)
+func (d *DryRunClient) ConfigInspect(ctx context.Context, name string, options client.ConfigInspectOptions) (client.ConfigInspectResult, error) {
+	return d.apiClient.ConfigInspect(ctx, name, options)
 }
 
-func (d *DryRunClient) ConfigRemove(ctx context.Context, id string) error {
-	return d.apiClient.ConfigRemove(ctx, id)
+func (d *DryRunClient) ConfigCreate(ctx context.Context, options client.ConfigCreateOptions) (client.ConfigCreateResult, error) {
+	return d.apiClient.ConfigCreate(ctx, options)
 }
 
-func (d *DryRunClient) ConfigInspectWithRaw(ctx context.Context, name string) (swarm.Config, []byte, error) {
-	return d.apiClient.ConfigInspectWithRaw(ctx, name)
+func (d *DryRunClient) ConfigRemove(ctx context.Context, id string, options client.ConfigRemoveOptions) (client.ConfigRemoveResult, error) {
+	return d.apiClient.ConfigRemove(ctx, id, options)
 }
 
-func (d *DryRunClient) ConfigUpdate(ctx context.Context, id string, version swarm.Version, config swarm.ConfigSpec) error {
-	return d.apiClient.ConfigUpdate(ctx, id, version, config)
+func (d *DryRunClient) ConfigUpdate(ctx context.Context, id string, options client.ConfigUpdateOptions) (client.ConfigUpdateResult, error) {
+	return d.apiClient.ConfigUpdate(ctx, id, options)
 }
 
-func (d *DryRunClient) ContainerCommit(ctx context.Context, container string, options containerType.CommitOptions) (containerType.CommitResponse, error) {
+func (d *DryRunClient) ContainerCommit(ctx context.Context, container string, options client.ContainerCommitOptions) (client.ContainerCommitResult, error) {
 	return d.apiClient.ContainerCommit(ctx, container, options)
 }
 
-func (d *DryRunClient) ContainerDiff(ctx context.Context, container string) ([]containerType.FilesystemChange, error) {
-	return d.apiClient.ContainerDiff(ctx, container)
-}
-
-func (d *DryRunClient) ContainerExecAttach(ctx context.Context, execID string, config containerType.ExecStartOptions) (moby.HijackedResponse, error) {
-	return moby.HijackedResponse{}, errors.New("interactive exec is not supported in dry-run mode")
+func (d *DryRunClient) ContainerDiff(ctx context.Context, container string, options client.ContainerDiffOptions) (client.ContainerDiffResult, error) {
+	return d.apiClient.ContainerDiff(ctx, container, options)
 }
 
-func (d *DryRunClient) ContainerExecInspect(ctx context.Context, execID string) (containerType.ExecInspect, error) {
-	return d.apiClient.ContainerExecInspect(ctx, execID)
+func (d *DryRunClient) ExecAttach(ctx context.Context, execID string, config client.ExecAttachOptions) (client.ExecAttachResult, error) {
+	return client.ExecAttachResult{}, errors.New("interactive exec is not supported in dry-run mode")
 }
 
-func (d *DryRunClient) ContainerExecResize(ctx context.Context, execID string, options containerType.ResizeOptions) error {
-	return d.apiClient.ContainerExecResize(ctx, execID, options)
+func (d *DryRunClient) ExecInspect(ctx context.Context, execID string, options client.ExecInspectOptions) (client.ExecInspectResult, error) {
+	return d.apiClient.ExecInspect(ctx, execID, options)
 }
 
-func (d *DryRunClient) ContainerExport(ctx context.Context, container string) (io.ReadCloser, error) {
-	return d.apiClient.ContainerExport(ctx, container)
+func (d *DryRunClient) ExecResize(ctx context.Context, execID string, options client.ExecResizeOptions) (client.ExecResizeResult, error) {
+	return d.apiClient.ExecResize(ctx, execID, options)
 }
 
-func (d *DryRunClient) ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (containerType.InspectResponse, []byte, error) {
-	return d.apiClient.ContainerInspectWithRaw(ctx, container, getSize)
+func (d *DryRunClient) ContainerExport(ctx context.Context, container string, options client.ContainerExportOptions) (client.ContainerExportResult, error) {
+	return d.apiClient.ContainerExport(ctx, container, options)
 }
 
-func (d *DryRunClient) ContainerLogs(ctx context.Context, container string, options containerType.LogsOptions) (io.ReadCloser, error) {
+func (d *DryRunClient) ContainerLogs(ctx context.Context, container string, options client.ContainerLogsOptions) (client.ContainerLogsResult, error) {
 	return d.apiClient.ContainerLogs(ctx, container, options)
 }
 
-func (d *DryRunClient) ContainerResize(ctx context.Context, container string, options containerType.ResizeOptions) error {
+func (d *DryRunClient) ContainerResize(ctx context.Context, container string, options client.ContainerResizeOptions) (client.ContainerResizeResult, error) {
 	return d.apiClient.ContainerResize(ctx, container, options)
 }
 
-func (d *DryRunClient) ContainerStatPath(ctx context.Context, container, path string) (containerType.PathStat, error) {
-	return d.apiClient.ContainerStatPath(ctx, container, path)
+func (d *DryRunClient) ContainerStatPath(ctx context.Context, container string, options client.ContainerStatPathOptions) (client.ContainerStatPathResult, error) {
+	return d.apiClient.ContainerStatPath(ctx, container, options)
 }
 
-func (d *DryRunClient) ContainerStats(ctx context.Context, container string, stream bool) (containerType.StatsResponseReader, error) {
-	return d.apiClient.ContainerStats(ctx, container, stream)
+func (d *DryRunClient) ContainerStats(ctx context.Context, container string, options client.ContainerStatsOptions) (client.ContainerStatsResult, error) {
+	return d.apiClient.ContainerStats(ctx, container, options)
 }
 
-func (d *DryRunClient) ContainerStatsOneShot(ctx context.Context, container string) (containerType.StatsResponseReader, error) {
-	return d.apiClient.ContainerStatsOneShot(ctx, container)
+func (d *DryRunClient) ContainerTop(ctx context.Context, container string, options client.ContainerTopOptions) (client.ContainerTopResult, error) {
+	return d.apiClient.ContainerTop(ctx, container, options)
 }
 
-func (d *DryRunClient) ContainerTop(ctx context.Context, container string, arguments []string) (containerType.TopResponse, error) {
-	return d.apiClient.ContainerTop(ctx, container, arguments)
+func (d *DryRunClient) ContainerUpdate(ctx context.Context, container string, options client.ContainerUpdateOptions) (client.ContainerUpdateResult, error) {
+	return d.apiClient.ContainerUpdate(ctx, container, options)
 }
 
-func (d *DryRunClient) ContainerUpdate(ctx context.Context, container string, updateConfig containerType.UpdateConfig) (containerType.UpdateResponse, error) {
-	return d.apiClient.ContainerUpdate(ctx, container, updateConfig)
+func (d *DryRunClient) ContainerWait(ctx context.Context, container string, options client.ContainerWaitOptions) client.ContainerWaitResult {
+	return d.apiClient.ContainerWait(ctx, container, options)
 }
 
-func (d *DryRunClient) ContainerWait(ctx context.Context, container string, condition containerType.WaitCondition) (<-chan containerType.WaitResponse, <-chan error) {
-	return d.apiClient.ContainerWait(ctx, container, condition)
+func (d *DryRunClient) ContainerPrune(ctx context.Context, options client.ContainerPruneOptions) (client.ContainerPruneResult, error) {
+	return d.apiClient.ContainerPrune(ctx, options)
 }
 
-func (d *DryRunClient) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (containerType.PruneReport, error) {
-	return d.apiClient.ContainersPrune(ctx, pruneFilters)
+func (d *DryRunClient) DistributionInspect(ctx context.Context, imageName string, options client.DistributionInspectOptions) (client.DistributionInspectResult, error) {
+	return d.apiClient.DistributionInspect(ctx, imageName, options)
 }
 
-func (d *DryRunClient) DistributionInspect(ctx context.Context, imageName, encodedRegistryAuth string) (registry.DistributionInspect, error) {
-	return d.apiClient.DistributionInspect(ctx, imageName, encodedRegistryAuth)
-}
-
-func (d *DryRunClient) BuildCachePrune(ctx context.Context, opts build.CachePruneOptions) (*build.CachePruneReport, error) {
+func (d *DryRunClient) BuildCachePrune(ctx context.Context, opts client.BuildCachePruneOptions) (client.BuildCachePruneResult, error) {
 	return d.apiClient.BuildCachePrune(ctx, opts)
 }
 
-func (d *DryRunClient) BuildCancel(ctx context.Context, id string) error {
-	return d.apiClient.BuildCancel(ctx, id)
-}
-
-func (d *DryRunClient) ImageCreate(ctx context.Context, parentReference string, options image.CreateOptions) (io.ReadCloser, error) {
-	return d.apiClient.ImageCreate(ctx, parentReference, options)
+func (d *DryRunClient) BuildCancel(ctx context.Context, id string, opts client.BuildCancelOptions) (client.BuildCancelResult, error) {
+	return d.apiClient.BuildCancel(ctx, id, opts)
 }
 
-func (d *DryRunClient) ImageHistory(ctx context.Context, imageName string, options ...client.ImageHistoryOption) ([]image.HistoryResponseItem, error) {
+func (d *DryRunClient) ImageHistory(ctx context.Context, imageName string, options ...client.ImageHistoryOption) (client.ImageHistoryResult, error) {
 	return d.apiClient.ImageHistory(ctx, imageName, options...)
 }
 
-func (d *DryRunClient) ImageImport(ctx context.Context, source image.ImportSource, ref string, options image.ImportOptions) (io.ReadCloser, error) {
+func (d *DryRunClient) ImageImport(ctx context.Context, source client.ImageImportSource, ref string, options client.ImageImportOptions) (client.ImageImportResult, error) {
 	return d.apiClient.ImageImport(ctx, source, ref, options)
 }
 
-func (d *DryRunClient) ImageList(ctx context.Context, options image.ListOptions) ([]image.Summary, error) {
+func (d *DryRunClient) ImageList(ctx context.Context, options client.ImageListOptions) (client.ImageListResult, error) {
 	return d.apiClient.ImageList(ctx, options)
 }
 
-func (d *DryRunClient) ImageLoad(ctx context.Context, input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error) {
+func (d *DryRunClient) ImageLoad(ctx context.Context, input io.Reader, options ...client.ImageLoadOption) (client.ImageLoadResult, error) {
 	return d.apiClient.ImageLoad(ctx, input, options...)
 }
 
-func (d *DryRunClient) ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error) {
+func (d *DryRunClient) ImageSearch(ctx context.Context, term string, options client.ImageSearchOptions) (client.ImageSearchResult, error) {
 	return d.apiClient.ImageSearch(ctx, term, options)
 }
 
-func (d *DryRunClient) ImageSave(ctx context.Context, images []string, options ...client.ImageSaveOption) (io.ReadCloser, error) {
+func (d *DryRunClient) ImageSave(ctx context.Context, images []string, options ...client.ImageSaveOption) (client.ImageSaveResult, error) {
 	return d.apiClient.ImageSave(ctx, images, options...)
 }
 
-func (d *DryRunClient) ImageTag(ctx context.Context, imageName, ref string) error {
-	return d.apiClient.ImageTag(ctx, imageName, ref)
+func (d *DryRunClient) ImageTag(ctx context.Context, options client.ImageTagOptions) (client.ImageTagResult, error) {
+	return d.apiClient.ImageTag(ctx, options)
 }
 
-func (d *DryRunClient) ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error) {
-	return d.apiClient.ImagesPrune(ctx, pruneFilter)
+func (d *DryRunClient) ImagePrune(ctx context.Context, options client.ImagePruneOptions) (client.ImagePruneResult, error) {
+	return d.apiClient.ImagePrune(ctx, options)
 }
 
-func (d *DryRunClient) NodeInspectWithRaw(ctx context.Context, nodeID string) (swarm.Node, []byte, error) {
-	return d.apiClient.NodeInspectWithRaw(ctx, nodeID)
+func (d *DryRunClient) NodeInspect(ctx context.Context, nodeID string, options client.NodeInspectOptions) (client.NodeInspectResult, error) {
+	return d.apiClient.NodeInspect(ctx, nodeID, options)
 }
 
-func (d *DryRunClient) NodeList(ctx context.Context, options swarm.NodeListOptions) ([]swarm.Node, error) {
+func (d *DryRunClient) NodeList(ctx context.Context, options client.NodeListOptions) (client.NodeListResult, error) {
 	return d.apiClient.NodeList(ctx, options)
 }
 
-func (d *DryRunClient) NodeRemove(ctx context.Context, nodeID string, options swarm.NodeRemoveOptions) error {
+func (d *DryRunClient) NodeRemove(ctx context.Context, nodeID string, options client.NodeRemoveOptions) (client.NodeRemoveResult, error) {
 	return d.apiClient.NodeRemove(ctx, nodeID, options)
 }
 
-func (d *DryRunClient) NodeUpdate(ctx context.Context, nodeID string, version swarm.Version, node swarm.NodeSpec) error {
-	return d.apiClient.NodeUpdate(ctx, nodeID, version, node)
+func (d *DryRunClient) NodeUpdate(ctx context.Context, nodeID string, options client.NodeUpdateOptions) (client.NodeUpdateResult, error) {
+	return d.apiClient.NodeUpdate(ctx, nodeID, options)
 }
 
-func (d *DryRunClient) NetworkInspect(ctx context.Context, networkName string, options network.InspectOptions) (network.Inspect, error) {
+func (d *DryRunClient) NetworkInspect(ctx context.Context, networkName string, options client.NetworkInspectOptions) (client.NetworkInspectResult, error) {
 	return d.apiClient.NetworkInspect(ctx, networkName, options)
 }
 
-func (d *DryRunClient) NetworkInspectWithRaw(ctx context.Context, networkName string, options network.InspectOptions) (network.Inspect, []byte, error) {
-	return d.apiClient.NetworkInspectWithRaw(ctx, networkName, options)
-}
-
-func (d *DryRunClient) NetworkList(ctx context.Context, options network.ListOptions) ([]network.Inspect, error) {
+func (d *DryRunClient) NetworkList(ctx context.Context, options client.NetworkListOptions) (client.NetworkListResult, error) {
 	return d.apiClient.NetworkList(ctx, options)
 }
 
-func (d *DryRunClient) NetworksPrune(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error) {
-	return d.apiClient.NetworksPrune(ctx, pruneFilter)
+func (d *DryRunClient) NetworkPrune(ctx context.Context, options client.NetworkPruneOptions) (client.NetworkPruneResult, error) {
+	return d.apiClient.NetworkPrune(ctx, options)
 }
 
-func (d *DryRunClient) PluginList(ctx context.Context, filter filters.Args) (moby.PluginsListResponse, error) {
-	return d.apiClient.PluginList(ctx, filter)
+func (d *DryRunClient) PluginList(ctx context.Context, options client.PluginListOptions) (client.PluginListResult, error) {
+	return d.apiClient.PluginList(ctx, options)
 }
 
-func (d *DryRunClient) PluginRemove(ctx context.Context, name string, options moby.PluginRemoveOptions) error {
+func (d *DryRunClient) PluginRemove(ctx context.Context, name string, options client.PluginRemoveOptions) (client.PluginRemoveResult, error) {
 	return d.apiClient.PluginRemove(ctx, name, options)
 }
 
-func (d *DryRunClient) PluginEnable(ctx context.Context, name string, options moby.PluginEnableOptions) error {
+func (d *DryRunClient) PluginEnable(ctx context.Context, name string, options client.PluginEnableOptions) (client.PluginEnableResult, error) {
 	return d.apiClient.PluginEnable(ctx, name, options)
 }
 
-func (d *DryRunClient) PluginDisable(ctx context.Context, name string, options moby.PluginDisableOptions) error {
+func (d *DryRunClient) PluginDisable(ctx context.Context, name string, options client.PluginDisableOptions) (client.PluginDisableResult, error) {
 	return d.apiClient.PluginDisable(ctx, name, options)
 }
 
-func (d *DryRunClient) PluginInstall(ctx context.Context, name string, options moby.PluginInstallOptions) (io.ReadCloser, error) {
+func (d *DryRunClient) PluginInstall(ctx context.Context, name string, options client.PluginInstallOptions) (client.PluginInstallResult, error) {
 	return d.apiClient.PluginInstall(ctx, name, options)
 }
 
-func (d *DryRunClient) PluginUpgrade(ctx context.Context, name string, options moby.PluginInstallOptions) (io.ReadCloser, error) {
+func (d *DryRunClient) PluginUpgrade(ctx context.Context, name string, options client.PluginUpgradeOptions) (client.PluginUpgradeResult, error) {
 	return d.apiClient.PluginUpgrade(ctx, name, options)
 }
 
-func (d *DryRunClient) PluginPush(ctx context.Context, name string, registryAuth string) (io.ReadCloser, error) {
-	return d.apiClient.PluginPush(ctx, name, registryAuth)
+func (d *DryRunClient) PluginPush(ctx context.Context, name string, options client.PluginPushOptions) (client.PluginPushResult, error) {
+	return d.apiClient.PluginPush(ctx, name, options)
 }
 
-func (d *DryRunClient) PluginSet(ctx context.Context, name string, args []string) error {
-	return d.apiClient.PluginSet(ctx, name, args)
+func (d *DryRunClient) PluginSet(ctx context.Context, name string, options client.PluginSetOptions) (client.PluginSetResult, error) {
+	return d.apiClient.PluginSet(ctx, name, options)
 }
 
-func (d *DryRunClient) PluginInspectWithRaw(ctx context.Context, name string) (*moby.Plugin, []byte, error) {
-	return d.apiClient.PluginInspectWithRaw(ctx, name)
+func (d *DryRunClient) PluginInspect(ctx context.Context, name string, options client.PluginInspectOptions) (client.PluginInspectResult, error) {
+	return d.apiClient.PluginInspect(ctx, name, options)
 }
 
-func (d *DryRunClient) PluginCreate(ctx context.Context, createContext io.Reader, options moby.PluginCreateOptions) error {
+func (d *DryRunClient) PluginCreate(ctx context.Context, createContext io.Reader, options client.PluginCreateOptions) (client.PluginCreateResult, error) {
 	return d.apiClient.PluginCreate(ctx, createContext, options)
 }
 
-func (d *DryRunClient) ServiceCreate(ctx context.Context, service swarm.ServiceSpec, options swarm.ServiceCreateOptions) (swarm.ServiceCreateResponse, error) {
-	return d.apiClient.ServiceCreate(ctx, service, options)
+func (d *DryRunClient) ServiceCreate(ctx context.Context, options client.ServiceCreateOptions) (client.ServiceCreateResult, error) {
+	return d.apiClient.ServiceCreate(ctx, options)
 }
 
-func (d *DryRunClient) ServiceInspectWithRaw(ctx context.Context, serviceID string, options swarm.ServiceInspectOptions) (swarm.Service, []byte, error) {
-	return d.apiClient.ServiceInspectWithRaw(ctx, serviceID, options)
+func (d *DryRunClient) ServiceInspect(ctx context.Context, serviceID string, options client.ServiceInspectOptions) (client.ServiceInspectResult, error) {
+	return d.apiClient.ServiceInspect(ctx, serviceID, options)
 }
 
-func (d *DryRunClient) ServiceList(ctx context.Context, options swarm.ServiceListOptions) ([]swarm.Service, error) {
+func (d *DryRunClient) ServiceList(ctx context.Context, options client.ServiceListOptions) (client.ServiceListResult, error) {
 	return d.apiClient.ServiceList(ctx, options)
 }
 
-func (d *DryRunClient) ServiceRemove(ctx context.Context, serviceID string) error {
-	return d.apiClient.ServiceRemove(ctx, serviceID)
+func (d *DryRunClient) ServiceRemove(ctx context.Context, serviceID string, options client.ServiceRemoveOptions) (client.ServiceRemoveResult, error) {
+	return d.apiClient.ServiceRemove(ctx, serviceID, options)
 }
 
-func (d *DryRunClient) ServiceUpdate(ctx context.Context, serviceID string, version swarm.Version, service swarm.ServiceSpec, options swarm.ServiceUpdateOptions) (swarm.ServiceUpdateResponse, error) {
-	return d.apiClient.ServiceUpdate(ctx, serviceID, version, service, options)
+func (d *DryRunClient) ServiceUpdate(ctx context.Context, serviceID string, options client.ServiceUpdateOptions) (client.ServiceUpdateResult, error) {
+	return d.apiClient.ServiceUpdate(ctx, serviceID, options)
 }
 
-func (d *DryRunClient) ServiceLogs(ctx context.Context, serviceID string, options containerType.LogsOptions) (io.ReadCloser, error) {
+func (d *DryRunClient) ServiceLogs(ctx context.Context, serviceID string, options client.ServiceLogsOptions) (client.ServiceLogsResult, error) {
 	return d.apiClient.ServiceLogs(ctx, serviceID, options)
 }
 
-func (d *DryRunClient) TaskLogs(ctx context.Context, taskID string, options containerType.LogsOptions) (io.ReadCloser, error) {
+func (d *DryRunClient) TaskLogs(ctx context.Context, taskID string, options client.TaskLogsOptions) (client.TaskLogsResult, error) {
 	return d.apiClient.TaskLogs(ctx, taskID, options)
 }
 
-func (d *DryRunClient) TaskInspectWithRaw(ctx context.Context, taskID string) (swarm.Task, []byte, error) {
-	return d.apiClient.TaskInspectWithRaw(ctx, taskID)
+func (d *DryRunClient) TaskInspect(ctx context.Context, taskID string, options client.TaskInspectOptions) (client.TaskInspectResult, error) {
+	return d.apiClient.TaskInspect(ctx, taskID, options)
 }
 
-func (d *DryRunClient) TaskList(ctx context.Context, options swarm.TaskListOptions) ([]swarm.Task, error) {
+func (d *DryRunClient) TaskList(ctx context.Context, options client.TaskListOptions) (client.TaskListResult, error) {
 	return d.apiClient.TaskList(ctx, options)
 }
 
-func (d *DryRunClient) SwarmInit(ctx context.Context, req swarm.InitRequest) (string, error) {
-	return d.apiClient.SwarmInit(ctx, req)
+func (d *DryRunClient) SwarmInit(ctx context.Context, options client.SwarmInitOptions) (client.SwarmInitResult, error) {
+	return d.apiClient.SwarmInit(ctx, options)
 }
 
-func (d *DryRunClient) SwarmJoin(ctx context.Context, req swarm.JoinRequest) error {
-	return d.apiClient.SwarmJoin(ctx, req)
+func (d *DryRunClient) SwarmJoin(ctx context.Context, options client.SwarmJoinOptions) (client.SwarmJoinResult, error) {
+	return d.apiClient.SwarmJoin(ctx, options)
 }
 
-func (d *DryRunClient) SwarmGetUnlockKey(ctx context.Context) (swarm.UnlockKeyResponse, error) {
+func (d *DryRunClient) SwarmGetUnlockKey(ctx context.Context) (client.SwarmGetUnlockKeyResult, error) {
 	return d.apiClient.SwarmGetUnlockKey(ctx)
 }
 
-func (d *DryRunClient) SwarmUnlock(ctx context.Context, req swarm.UnlockRequest) error {
-	return d.apiClient.SwarmUnlock(ctx, req)
+func (d *DryRunClient) SwarmUnlock(ctx context.Context, options client.SwarmUnlockOptions) (client.SwarmUnlockResult, error) {
+	return d.apiClient.SwarmUnlock(ctx, options)
 }
 
-func (d *DryRunClient) SwarmLeave(ctx context.Context, force bool) error {
-	return d.apiClient.SwarmLeave(ctx, force)
+func (d *DryRunClient) SwarmLeave(ctx context.Context, options client.SwarmLeaveOptions) (client.SwarmLeaveResult, error) {
+	return d.apiClient.SwarmLeave(ctx, options)
 }
 
-func (d *DryRunClient) SwarmInspect(ctx context.Context) (swarm.Swarm, error) {
-	return d.apiClient.SwarmInspect(ctx)
+func (d *DryRunClient) SwarmInspect(ctx context.Context, options client.SwarmInspectOptions) (client.SwarmInspectResult, error) {
+	return d.apiClient.SwarmInspect(ctx, options)
 }
 
-func (d *DryRunClient) SwarmUpdate(ctx context.Context, version swarm.Version, swarmSpec swarm.Spec, flags swarm.UpdateFlags) error {
-	return d.apiClient.SwarmUpdate(ctx, version, swarmSpec, flags)
+func (d *DryRunClient) SwarmUpdate(ctx context.Context, options client.SwarmUpdateOptions) (client.SwarmUpdateResult, error) {
+	return d.apiClient.SwarmUpdate(ctx, options)
 }
 
-func (d *DryRunClient) SecretList(ctx context.Context, options swarm.SecretListOptions) ([]swarm.Secret, error) {
+func (d *DryRunClient) SecretList(ctx context.Context, options client.SecretListOptions) (client.SecretListResult, error) {
 	return d.apiClient.SecretList(ctx, options)
 }
 
-func (d *DryRunClient) SecretCreate(ctx context.Context, secret swarm.SecretSpec) (swarm.SecretCreateResponse, error) {
-	return d.apiClient.SecretCreate(ctx, secret)
+func (d *DryRunClient) SecretCreate(ctx context.Context, options client.SecretCreateOptions) (client.SecretCreateResult, error) {
+	return d.apiClient.SecretCreate(ctx, options)
 }
 
-func (d *DryRunClient) SecretRemove(ctx context.Context, id string) error {
-	return d.apiClient.SecretRemove(ctx, id)
+func (d *DryRunClient) SecretRemove(ctx context.Context, id string, options client.SecretRemoveOptions) (client.SecretRemoveResult, error) {
+	return d.apiClient.SecretRemove(ctx, id, options)
 }
 
-func (d *DryRunClient) SecretInspectWithRaw(ctx context.Context, name string) (swarm.Secret, []byte, error) {
-	return d.apiClient.SecretInspectWithRaw(ctx, name)
+func (d *DryRunClient) SecretInspect(ctx context.Context, name string, options client.SecretInspectOptions) (client.SecretInspectResult, error) {
+	return d.apiClient.SecretInspect(ctx, name, options)
 }
 
-func (d *DryRunClient) SecretUpdate(ctx context.Context, id string, version swarm.Version, secret swarm.SecretSpec) error {
-	return d.apiClient.SecretUpdate(ctx, id, version, secret)
+func (d *DryRunClient) SecretUpdate(ctx context.Context, id string, options client.SecretUpdateOptions) (client.SecretUpdateResult, error) {
+	return d.apiClient.SecretUpdate(ctx, id, options)
 }
 
-func (d *DryRunClient) Events(ctx context.Context, options events.ListOptions) (<-chan events.Message, <-chan error) {
+func (d *DryRunClient) Events(ctx context.Context, options client.EventsListOptions) client.EventsResult {
 	return d.apiClient.Events(ctx, options)
 }
 
-func (d *DryRunClient) Info(ctx context.Context) (system.Info, error) {
-	return d.apiClient.Info(ctx)
+func (d *DryRunClient) Info(ctx context.Context, options client.InfoOptions) (client.SystemInfoResult, error) {
+	return d.apiClient.Info(ctx, options)
 }
 
-func (d *DryRunClient) RegistryLogin(ctx context.Context, auth registry.AuthConfig) (registry.AuthenticateOKBody, error) {
-	return d.apiClient.RegistryLogin(ctx, auth)
+func (d *DryRunClient) RegistryLogin(ctx context.Context, options client.RegistryLoginOptions) (client.RegistryLoginResult, error) {
+	return d.apiClient.RegistryLogin(ctx, options)
 }
 
-func (d *DryRunClient) DiskUsage(ctx context.Context, options moby.DiskUsageOptions) (moby.DiskUsage, error) {
+func (d *DryRunClient) DiskUsage(ctx context.Context, options client.DiskUsageOptions) (client.DiskUsageResult, error) {
 	return d.apiClient.DiskUsage(ctx, options)
 }
 
-func (d *DryRunClient) Ping(ctx context.Context) (moby.Ping, error) {
-	return d.apiClient.Ping(ctx)
-}
-
-func (d *DryRunClient) VolumeInspect(ctx context.Context, volumeID string) (volume.Volume, error) {
-	return d.apiClient.VolumeInspect(ctx, volumeID)
+func (d *DryRunClient) Ping(ctx context.Context, options client.PingOptions) (client.PingResult, error) {
+	return d.apiClient.Ping(ctx, options)
 }
 
-func (d *DryRunClient) VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error) {
-	return d.apiClient.VolumeInspectWithRaw(ctx, volumeID)
+func (d *DryRunClient) VolumeInspect(ctx context.Context, volumeID string, options client.VolumeInspectOptions) (client.VolumeInspectResult, error) {
+	return d.apiClient.VolumeInspect(ctx, volumeID, options)
 }
 
-func (d *DryRunClient) VolumeList(ctx context.Context, opts volume.ListOptions) (volume.ListResponse, error) {
+func (d *DryRunClient) VolumeList(ctx context.Context, opts client.VolumeListOptions) (client.VolumeListResult, error) {
 	return d.apiClient.VolumeList(ctx, opts)
 }
 
-func (d *DryRunClient) VolumesPrune(ctx context.Context, pruneFilter filters.Args) (volume.PruneReport, error) {
-	return d.apiClient.VolumesPrune(ctx, pruneFilter)
+func (d *DryRunClient) VolumePrune(ctx context.Context, options client.VolumePruneOptions) (client.VolumePruneResult, error) {
+	return d.apiClient.VolumePrune(ctx, options)
 }
 
-func (d *DryRunClient) VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error {
-	return d.apiClient.VolumeUpdate(ctx, volumeID, version, options)
+func (d *DryRunClient) VolumeUpdate(ctx context.Context, volumeID string, options client.VolumeUpdateOptions) (client.VolumeUpdateResult, error) {
+	return d.apiClient.VolumeUpdate(ctx, volumeID, options)
 }
 
 func (d *DryRunClient) ClientVersion() string {
@@ -651,20 +621,8 @@ func (d *DryRunClient) DaemonHost() string {
 	return d.apiClient.DaemonHost()
 }
 
-func (d *DryRunClient) HTTPClient() *http.Client {
-	return d.apiClient.HTTPClient()
-}
-
-func (d *DryRunClient) ServerVersion(ctx context.Context) (moby.Version, error) {
-	return d.apiClient.ServerVersion(ctx)
-}
-
-func (d *DryRunClient) NegotiateAPIVersion(ctx context.Context) {
-	d.apiClient.NegotiateAPIVersion(ctx)
-}
-
-func (d *DryRunClient) NegotiateAPIVersionPing(ping moby.Ping) {
-	d.apiClient.NegotiateAPIVersionPing(ping)
+func (d *DryRunClient) ServerVersion(ctx context.Context, options client.ServerVersionOptions) (client.ServerVersionResult, error) {
+	return d.apiClient.ServerVersion(ctx, options)
 }
 
 func (d *DryRunClient) DialHijack(ctx context.Context, url, proto string, meta map[string][]string) (net.Conn, error) {
@@ -679,14 +637,14 @@ func (d *DryRunClient) Close() error {
 	return d.apiClient.Close()
 }
 
-func (d *DryRunClient) CheckpointCreate(ctx context.Context, container string, options checkpoint.CreateOptions) error {
+func (d *DryRunClient) CheckpointCreate(ctx context.Context, container string, options client.CheckpointCreateOptions) (client.CheckpointCreateResult, error) {
 	return d.apiClient.CheckpointCreate(ctx, container, options)
 }
 
-func (d *DryRunClient) CheckpointDelete(ctx context.Context, container string, options checkpoint.DeleteOptions) error {
-	return d.apiClient.CheckpointDelete(ctx, container, options)
+func (d *DryRunClient) CheckpointRemove(ctx context.Context, container string, options client.CheckpointRemoveOptions) (client.CheckpointRemoveResult, error) {
+	return d.apiClient.CheckpointRemove(ctx, container, options)
 }
 
-func (d *DryRunClient) CheckpointList(ctx context.Context, container string, options checkpoint.ListOptions) ([]checkpoint.Summary, error) {
+func (d *DryRunClient) CheckpointList(ctx context.Context, container string, options client.CheckpointListOptions) (client.CheckpointListResult, error) {
 	return d.apiClient.CheckpointList(ctx, container, options)
 }

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 251 - 329
pkg/mocks/mock_docker_api.go


+ 1 - 19
pkg/mocks/mock_docker_cli.go

@@ -17,7 +17,7 @@ import (
 	docker "github.com/docker/cli/cli/context/docker"
 	store "github.com/docker/cli/cli/context/store"
 	streams "github.com/docker/cli/cli/streams"
-	client "github.com/docker/docker/client"
+	client "github.com/moby/moby/client"
 	metric "go.opentelemetry.io/otel/metric"
 	resource "go.opentelemetry.io/otel/sdk/resource"
 	trace "go.opentelemetry.io/otel/trace"
@@ -47,24 +47,6 @@ func (m *MockCli) EXPECT() *MockCliMockRecorder {
 	return m.recorder
 }
 
-// Apply mocks base method.
-func (m *MockCli) Apply(arg0 ...command.CLIOption) error {
-	m.ctrl.T.Helper()
-	varargs := []any{}
-	for _, a := range arg0 {
-		varargs = append(varargs, a)
-	}
-	ret := m.ctrl.Call(m, "Apply", varargs...)
-	ret0, _ := ret[0].(error)
-	return ret0
-}
-
-// Apply indicates an expected call of Apply.
-func (mr *MockCliMockRecorder) Apply(arg0 ...any) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Apply", reflect.TypeOf((*MockCli)(nil).Apply), arg0...)
-}
-
 // BuildKitEnabled mocks base method.
 func (m *MockCli) BuildKitEnabled() (bool, error) {
 	m.ctrl.T.Helper()

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio