From cf2fc2005c1e9c5e4c798cb69014c7b8e61d609c Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Wed, 12 Feb 2025 09:34:07 +0100 Subject: [PATCH] go.mod: docker/docker, docker/cli v28.0.0, buildx v0.21.1 full diff: - https://github.com/docker/docker/compare/v27.5.1...v28.0.0 - https://github.com/docker/cli/compare/v27.5.1...v28.0.0 - https://github.com/docker/buildx/compare/v0.20.1...v0.21.1 Co-authored-by: Nicolas De Loof Signed-off-by: Sebastiaan van Stijn --- cmd/formatter/container.go | 6 +-- go.mod | 6 +-- go.sum | 12 ++--- internal/sync/tar.go | 4 +- internal/tracing/attributes.go | 14 ++--- pkg/api/dryrunclient.go | 62 ++++++++++++---------- pkg/compose/attach.go | 7 ++- pkg/compose/build.go | 4 +- pkg/compose/commit.go | 8 +-- pkg/compose/compose.go | 20 +++---- pkg/compose/containers.go | 34 ++++++------ pkg/compose/convergence.go | 67 ++++++++++++------------ pkg/compose/convergence_test.go | 49 +++++++++--------- pkg/compose/create.go | 14 ++--- pkg/compose/create_test.go | 11 ++-- pkg/compose/down.go | 21 ++++---- pkg/compose/down_test.go | 61 +++++++++++----------- pkg/compose/exec.go | 4 +- pkg/compose/generate.go | 21 ++++---- pkg/compose/hook.go | 21 ++++---- pkg/compose/image_pruner.go | 2 +- pkg/compose/images.go | 17 +++--- pkg/compose/images_test.go | 28 +++++----- pkg/compose/kill.go | 27 +++++----- pkg/compose/kill_test.go | 19 ++++--- pkg/compose/logs.go | 15 +++--- pkg/compose/logs_test.go | 13 +++-- pkg/compose/ls.go | 17 +++--- pkg/compose/ls_test.go | 8 +-- pkg/compose/pause.go | 10 ++-- pkg/compose/port.go | 11 ++-- pkg/compose/ps_test.go | 19 ++++--- pkg/compose/pull.go | 2 +- pkg/compose/remove.go | 13 +++-- pkg/compose/restart.go | 6 +-- pkg/compose/start.go | 25 +++++---- pkg/compose/stop_test.go | 14 +++-- pkg/compose/watch.go | 5 +- pkg/compose/watch_test.go | 10 ++-- pkg/mocks/mock_docker_api.go | 92 +++++++++++++++++++++++---------- 40 files changed, 417 insertions(+), 382 deletions(-) diff --git a/cmd/formatter/container.go b/cmd/formatter/container.go index f1eb47caf..e8e331b80 100644 --- a/cmd/formatter/container.go +++ b/cmd/formatter/container.go @@ -24,7 +24,7 @@ import ( "github.com/docker/cli/cli/command/formatter" "github.com/docker/compose/v2/pkg/api" - "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/stringid" "github.com/docker/go-units" ) @@ -212,9 +212,9 @@ func (c *ContainerContext) Publishers() api.PortPublishers { } func (c *ContainerContext) Ports() string { - var ports []types.Port + var ports []container.Port for _, publisher := range c.c.Publishers { - ports = append(ports, types.Port{ + ports = append(ports, container.Port{ IP: publisher.URL, PrivatePort: uint16(publisher.TargetPort), PublicPort: uint16(publisher.PublishedPort), diff --git a/go.mod b/go.mod index 7b5e03b9e..92d954d26 100644 --- a/go.mod +++ b/go.mod @@ -12,10 +12,10 @@ require ( github.com/containerd/platforms v1.0.0-rc.1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/distribution/reference v0.6.0 - github.com/docker/buildx v0.20.1 - github.com/docker/cli v27.5.1+incompatible + github.com/docker/buildx v0.21.1 + github.com/docker/cli v28.0.0+incompatible github.com/docker/cli-docs-tool v0.9.0 - github.com/docker/docker v27.5.1+incompatible + github.com/docker/docker v28.0.0+incompatible github.com/docker/go-connections v0.5.0 github.com/docker/go-units v0.5.0 github.com/eiannone/keyboard v0.0.0-20220611211555-0d226195f203 diff --git a/go.sum b/go.sum index a731c354c..6fe7eb2be 100644 --- a/go.sum +++ b/go.sum @@ -127,17 +127,17 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8Yc github.com/denisenkom/go-mssqldb v0.0.0-20191128021309-1d7a30a10f73/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/buildx v0.20.1 h1:q88EfoYwrWEKVqNb9stOFq8fUlFp/OPlDcFE+QUYZBM= -github.com/docker/buildx v0.20.1/go.mod h1:VVi4Nvo4jd/IkRvwyExbIyW7u82fivK61MRx5I0oKic= -github.com/docker/cli v27.5.1+incompatible h1:JB9cieUT9YNiMITtIsguaN55PLOHhBSz3LKVc6cqWaY= -github.com/docker/cli v27.5.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/buildx v0.21.1 h1:YjV2k6CsSDbkDTOMsjARUIrj2xv+zZR+M2dtrRyzXhg= +github.com/docker/buildx v0.21.1/go.mod h1:8V4UMnlKsaGYwz83BygmIbJIFEAYGHT6KAv8akDZmqo= +github.com/docker/cli v28.0.0+incompatible h1:ido37VmLUqEp+5NFb9icd6BuBB+SNDgCn+5kPCr2buA= +github.com/docker/cli v28.0.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/cli-docs-tool v0.9.0 h1:CVwQbE+ZziwlPqrJ7LRyUF6GvCA+6gj7MTCsayaK9t0= github.com/docker/cli-docs-tool v0.9.0/go.mod h1:ClrwlNW+UioiRyH9GiAOe1o3J/TsY3Tr1ipoypjAUtc= 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 v27.5.1+incompatible h1:4PYU5dnBYqRQi0294d1FBECqT9ECWeQAIfE8q4YnPY8= -github.com/docker/docker v27.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v28.0.0+incompatible h1:Olh0KS820sJ7nPsBKChVhk5pzqcwDR15fumfAd/p9hM= +github.com/docker/docker v28.0.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= diff --git a/internal/sync/tar.go b/internal/sync/tar.go index d9abd2f88..740a693c2 100644 --- a/internal/sync/tar.go +++ b/internal/sync/tar.go @@ -32,7 +32,7 @@ import ( "github.com/hashicorp/go-multierror" - moby "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/archive" ) @@ -43,7 +43,7 @@ type archiveEntry struct { } type LowLevelClient interface { - ContainersForService(ctx context.Context, projectName string, serviceName string) ([]moby.Container, error) + ContainersForService(ctx context.Context, projectName string, serviceName string) ([]container.Summary, error) Exec(ctx context.Context, containerID string, cmd []string, in io.Reader) error Untar(ctx context.Context, id string, reader io.ReadCloser) error diff --git a/internal/tracing/attributes.go b/internal/tracing/attributes.go index 3d27c4796..3365616eb 100644 --- a/internal/tracing/attributes.go +++ b/internal/tracing/attributes.go @@ -25,7 +25,7 @@ import ( "time" "github.com/compose-spec/compose-go/v2/types" - moby "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" ) @@ -140,15 +140,15 @@ func ServiceOptions(service types.ServiceConfig) SpanOptions { // For convenience, it's returned as a SpanOptions object to allow it to be // passed directly to the wrapping helper methods in this package such as // SpanWrapFunc. -func ContainerOptions(container moby.Container) SpanOptions { +func ContainerOptions(ctr container.Summary) SpanOptions { attrs := []attribute.KeyValue{ - attribute.String("container.id", container.ID), - attribute.String("container.image", container.Image), - unixTimeAttr("container.created_at", container.Created), + attribute.String("container.id", ctr.ID), + attribute.String("container.image", ctr.Image), + unixTimeAttr("container.created_at", ctr.Created), } - if len(container.Names) != 0 { - attrs = append(attrs, attribute.String("container.name", strings.TrimPrefix(container.Names[0], "/"))) + if len(ctr.Names) != 0 { + attrs = append(attrs, attribute.String("container.name", strings.TrimPrefix(ctr.Names[0], "/"))) } return []trace.SpanStartEventOption{ diff --git a/pkg/api/dryrunclient.go b/pkg/api/dryrunclient.go index ef6269af5..00fbb7c83 100644 --- a/pkg/api/dryrunclient.go +++ b/pkg/api/dryrunclient.go @@ -60,7 +60,7 @@ type DryRunKey struct{} // DryRunClient implements APIClient by delegating to implementation functions. This allows lazy init and per-method overrides type DryRunClient struct { apiClient client.APIClient - containers []moby.Container + containers []containerType.Summary execs sync.Map resolver *imagetools.Resolver } @@ -82,7 +82,7 @@ func NewDryRunClient(apiClient client.APIClient, cli command.Cli) (*DryRunClient } return &DryRunClient{ apiClient: apiClient, - containers: []moby.Container{}, + containers: []containerType.Summary{}, execs: sync.Map{}, resolver: imagetools.New(configFile), }, nil @@ -103,7 +103,7 @@ func (d *DryRunClient) ContainerAttach(ctx context.Context, container string, op func (d *DryRunClient) ContainerCreate(ctx context.Context, config *containerType.Config, hostConfig *containerType.HostConfig, networkingConfig *network.NetworkingConfig, platform *specs.Platform, containerName string, ) (containerType.CreateResponse, error) { - d.containers = append(d.containers, moby.Container{ + d.containers = append(d.containers, containerType.Summary{ ID: containerName, Names: []string{containerName}, Labels: config.Labels, @@ -115,7 +115,7 @@ func (d *DryRunClient) ContainerCreate(ctx context.Context, config *containerTyp return containerType.CreateResponse{ID: containerName}, nil } -func (d *DryRunClient) ContainerInspect(ctx context.Context, container string) (moby.ContainerJSON, error) { +func (d *DryRunClient) ContainerInspect(ctx context.Context, container string) (containerType.InspectResponse, error) { containerJSON, err := d.apiClient.ContainerInspect(ctx, container) if err != nil { id := "dryRunId" @@ -124,20 +124,20 @@ func (d *DryRunClient) ContainerInspect(ctx context.Context, container string) ( id = container } } - return moby.ContainerJSON{ - ContainerJSONBase: &moby.ContainerJSONBase{ + return containerType.InspectResponse{ + ContainerJSONBase: &containerType.ContainerJSONBase{ ID: id, Name: container, - State: &moby.ContainerState{ + State: &containerType.State{ Status: "running", // needed for --wait option - Health: &moby.Health{ - Status: moby.Healthy, // needed for healthcheck control + Health: &containerType.Health{ + Status: containerType.Healthy, // needed for healthcheck control }, }, }, Mounts: nil, Config: &containerType.Config{}, - NetworkSettings: &moby.NetworkSettings{}, + NetworkSettings: &containerType.NetworkSettings{}, }, nil } return containerJSON, err @@ -147,7 +147,7 @@ func (d *DryRunClient) ContainerKill(ctx context.Context, container, signal stri return nil } -func (d *DryRunClient) ContainerList(ctx context.Context, options containerType.ListOptions) ([]moby.Container, error) { +func (d *DryRunClient) ContainerList(ctx context.Context, options containerType.ListOptions) ([]containerType.Summary, error) { caller := getCallingFunction() switch caller { case "start": @@ -222,16 +222,26 @@ func (d *DryRunClient) ImageBuild(ctx context.Context, reader io.Reader, options }, nil } -func (d *DryRunClient) ImageInspectWithRaw(ctx context.Context, imageName string) (moby.ImageInspect, []byte, error) { +func (d *DryRunClient) ImageInspect(ctx context.Context, imageName string, options ...client.ImageInspectOption) (image.InspectResponse, error) { caller := getCallingFunction() switch caller { case "pullServiceImage", "buildContainerVolumes": - return moby.ImageInspect{ID: "dryRunId"}, nil, nil + return image.InspectResponse{ID: "dryRunId"}, nil default: - return d.apiClient.ImageInspectWithRaw(ctx, imageName) + 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) { if _, _, err := d.resolver.Resolve(ctx, ref); err != nil { return nil, err @@ -299,7 +309,7 @@ func (d *DryRunClient) VolumeRemove(ctx context.Context, volumeID string, force return nil } -func (d *DryRunClient) ContainerExecCreate(ctx context.Context, container string, config containerType.ExecOptions) (moby.IDResponse, error) { +func (d *DryRunClient) ContainerExecCreate(ctx context.Context, container string, config containerType.ExecOptions) (containerType.ExecCreateResponse, error) { b := make([]byte, 32) _, _ = rand.Read(b) id := fmt.Sprintf("%x", b) @@ -307,7 +317,7 @@ func (d *DryRunClient) ContainerExecCreate(ctx context.Context, container string container: container, command: config.Cmd, }) - return moby.IDResponse{ + return containerType.ExecCreateResponse{ ID: id, }, nil } @@ -344,7 +354,7 @@ func (d *DryRunClient) ConfigUpdate(ctx context.Context, id string, version swar return d.apiClient.ConfigUpdate(ctx, id, version, config) } -func (d *DryRunClient) ContainerCommit(ctx context.Context, container string, options containerType.CommitOptions) (moby.IDResponse, error) { +func (d *DryRunClient) ContainerCommit(ctx context.Context, container string, options containerType.CommitOptions) (containerType.CommitResponse, error) { return d.apiClient.ContainerCommit(ctx, container, options) } @@ -368,7 +378,7 @@ func (d *DryRunClient) ContainerExport(ctx context.Context, container string) (i return d.apiClient.ContainerExport(ctx, container) } -func (d *DryRunClient) ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (moby.ContainerJSON, []byte, error) { +func (d *DryRunClient) ContainerInspectWithRaw(ctx context.Context, container string, getSize bool) (containerType.InspectResponse, []byte, error) { return d.apiClient.ContainerInspectWithRaw(ctx, container, getSize) } @@ -392,11 +402,11 @@ func (d *DryRunClient) ContainerStatsOneShot(ctx context.Context, container stri return d.apiClient.ContainerStatsOneShot(ctx, container) } -func (d *DryRunClient) ContainerTop(ctx context.Context, container string, arguments []string) (containerType.ContainerTopOKBody, error) { +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, updateConfig containerType.UpdateConfig) (containerType.ContainerUpdateOKBody, error) { +func (d *DryRunClient) ContainerUpdate(ctx context.Context, container string, updateConfig containerType.UpdateConfig) (containerType.UpdateResponse, error) { return d.apiClient.ContainerUpdate(ctx, container, updateConfig) } @@ -424,8 +434,8 @@ func (d *DryRunClient) ImageCreate(ctx context.Context, parentReference string, return d.apiClient.ImageCreate(ctx, parentReference, options) } -func (d *DryRunClient) ImageHistory(ctx context.Context, imageName string) ([]image.HistoryResponseItem, error) { - return d.apiClient.ImageHistory(ctx, imageName) +func (d *DryRunClient) ImageHistory(ctx context.Context, imageName string, options ...client.ImageHistoryOption) ([]image.HistoryResponseItem, 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) { @@ -436,16 +446,16 @@ func (d *DryRunClient) ImageList(ctx context.Context, options image.ListOptions) return d.apiClient.ImageList(ctx, options) } -func (d *DryRunClient) ImageLoad(ctx context.Context, input io.Reader, quiet bool) (image.LoadResponse, error) { - return d.apiClient.ImageLoad(ctx, input, quiet) +func (d *DryRunClient) ImageLoad(ctx context.Context, input io.Reader, options ...client.ImageLoadOption) (image.LoadResponse, error) { + return d.apiClient.ImageLoad(ctx, input, options...) } func (d *DryRunClient) ImageSearch(ctx context.Context, term string, options registry.SearchOptions) ([]registry.SearchResult, error) { return d.apiClient.ImageSearch(ctx, term, options) } -func (d *DryRunClient) ImageSave(ctx context.Context, images []string) (io.ReadCloser, error) { - return d.apiClient.ImageSave(ctx, images) +func (d *DryRunClient) ImageSave(ctx context.Context, images []string, options ...client.ImageSaveOption) (io.ReadCloser, error) { + return d.apiClient.ImageSave(ctx, images, options...) } func (d *DryRunClient) ImageTag(ctx context.Context, imageName, ref string) error { diff --git a/pkg/compose/attach.go b/pkg/compose/attach.go index dcae402a1..8c17e056a 100644 --- a/pkg/compose/attach.go +++ b/pkg/compose/attach.go @@ -25,7 +25,6 @@ import ( "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/streams" - moby "github.com/docker/docker/api/types" containerType "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/stdcopy" "github.com/moby/term" @@ -52,8 +51,8 @@ func (s *composeService) attach(ctx context.Context, project *types.Project, lis _, _ = fmt.Fprintf(s.stdout(), "Attaching to %s\n", strings.Join(names, ", ")) - for _, container := range containers { - err := s.attachContainer(ctx, container, listener) + for _, ctr := range containers { + err := s.attachContainer(ctx, ctr, listener) if err != nil { return nil, err } @@ -61,7 +60,7 @@ func (s *composeService) attach(ctx context.Context, project *types.Project, lis return containers, err } -func (s *composeService) attachContainer(ctx context.Context, container moby.Container, listener api.ContainerEventListener) error { +func (s *composeService) attachContainer(ctx context.Context, container containerType.Summary, listener api.ContainerEventListener) error { serviceName := container.Labels[api.ServiceLabel] containerName := getContainerNameWithoutProject(container) diff --git a/pkg/compose/build.go b/pkg/compose/build.go index 3d6c8fc02..ecbc0a839 100644 --- a/pkg/compose/build.go +++ b/pkg/compose/build.go @@ -340,7 +340,7 @@ func (s *composeService) getLocalImagesDigests(ctx context.Context, project *typ if err != nil { return nil, err } - inspect, _, err := s.apiClient().ImageInspectWithRaw(ctx, digest) + inspect, err := s.apiClient().ImageInspect(ctx, digest) if err != nil { return nil, err } @@ -436,7 +436,7 @@ func (s *composeService) toBuildOptions(project *types.Project, service types.Se return build.Options{}, err } if service.Build.Privileged { - allow = append(allow, entitlements.EntitlementSecurityInsecure) + allow = append(allow, entitlements.EntitlementSecurityInsecure.String()) } imageLabels := getImageBuildLabels(project, service) diff --git a/pkg/compose/commit.go b/pkg/compose/commit.go index 8ff4e5389..97644353e 100644 --- a/pkg/compose/commit.go +++ b/pkg/compose/commit.go @@ -23,7 +23,7 @@ import ( "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/progress" - containerType "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/container" ) func (s *composeService) Commit(ctx context.Context, projectName string, options api.CommitOptions) error { @@ -35,7 +35,7 @@ func (s *composeService) Commit(ctx context.Context, projectName string, options func (s *composeService) commit(ctx context.Context, projectName string, options api.CommitOptions) error { projectName = strings.ToLower(projectName) - container, err := s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, options.Service, options.Index) + ctr, err := s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, options.Service, options.Index) if err != nil { return err } @@ -44,7 +44,7 @@ func (s *composeService) commit(ctx context.Context, projectName string, options w := progress.ContextWriter(ctx) - name := getCanonicalContainerName(container) + name := getCanonicalContainerName(ctr) msg := fmt.Sprintf("Commit %s", name) w.Event(progress.Event{ @@ -65,7 +65,7 @@ func (s *composeService) commit(ctx context.Context, projectName string, options return nil } - response, err := clnt.ContainerCommit(ctx, container.ID, containerType.CommitOptions{ + response, err := clnt.ContainerCommit(ctx, ctr.ID, container.CommitOptions{ Reference: options.Reference, Comment: options.Comment, Author: options.Author, diff --git a/pkg/compose/compose.go b/pkg/compose/compose.go index 18769e645..10c322554 100644 --- a/pkg/compose/compose.go +++ b/pkg/compose/compose.go @@ -25,22 +25,22 @@ import ( "strings" "sync" - "github.com/docker/compose/v2/internal/desktop" - "github.com/docker/compose/v2/internal/experimental" - "github.com/docker/docker/api/types/network" - "github.com/docker/docker/api/types/volume" - "github.com/jonboulle/clockwork" - "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/command" "github.com/docker/cli/cli/config/configfile" "github.com/docker/cli/cli/flags" "github.com/docker/cli/cli/streams" - "github.com/docker/compose/v2/pkg/api" - 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/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/docker/compose/v2/internal/desktop" + "github.com/docker/compose/v2/internal/experimental" + "github.com/docker/compose/v2/pkg/api" ) var stdioToStdout bool @@ -139,7 +139,7 @@ func (s *composeService) stdinfo() *streams.Out { return s.dockerCli.Err() } -func getCanonicalContainerName(c moby.Container) string { +func getCanonicalContainerName(c container.Summary) string { if len(c.Names) == 0 { // corner case, sometime happens on removal. return short ID as a safeguard value return c.ID[:12] @@ -154,7 +154,7 @@ func getCanonicalContainerName(c moby.Container) string { return strings.TrimPrefix(c.Names[0], "/") } -func getContainerNameWithoutProject(c moby.Container) string { +func getContainerNameWithoutProject(c container.Summary) string { project := c.Labels[api.ProjectLabel] defaultName := getDefaultContainerName(project, c.Labels[api.ServiceLabel], c.Labels[api.ContainerNumberLabel]) name := getCanonicalContainerName(c) diff --git a/pkg/compose/containers.go b/pkg/compose/containers.go index 4828cb919..1bf078432 100644 --- a/pkg/compose/containers.go +++ b/pkg/compose/containers.go @@ -25,13 +25,12 @@ import ( "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/utils" - moby "github.com/docker/docker/api/types" - containerType "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" ) // Containers is a set of moby Container -type Containers []moby.Container +type Containers []container.Summary type oneOff int @@ -44,7 +43,7 @@ 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, containerType.ListOptions{ + containers, err := s.apiClient().ContainerList(ctx, container.ListOptions{ Filters: filters.NewArgs(f...), All: all, }) @@ -73,25 +72,25 @@ func getDefaultFilters(projectName string, oneOff oneOff, selectedServices ...st return f } -func (s *composeService) getSpecifiedContainer(ctx context.Context, projectName string, oneOff oneOff, all bool, serviceName string, containerIndex int) (moby.Container, error) { +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)) } - containers, err := s.apiClient().ContainerList(ctx, containerType.ListOptions{ + containers, err := s.apiClient().ContainerList(ctx, container.ListOptions{ Filters: filters.NewArgs( defaultFilters..., ), All: all, }) if err != nil { - return moby.Container{}, err + return container.Summary{}, err } if len(containers) < 1 { if containerIndex > 0 { - return moby.Container{}, fmt.Errorf("service %q is not running container #%d", serviceName, containerIndex) + return container.Summary{}, fmt.Errorf("service %q is not running container #%d", serviceName, containerIndex) } - return moby.Container{}, fmt.Errorf("service %q is not running", serviceName) + return container.Summary{}, fmt.Errorf("service %q is not running", serviceName) } // Sort by container number first, then put one-off containers at the end @@ -107,14 +106,13 @@ func (s *composeService) getSpecifiedContainer(ctx context.Context, projectName return numberLabelX < numberLabelY }) - container := containers[0] - return container, nil + return containers[0], nil } // containerPredicate define a predicate we want container to satisfy for filtering operations -type containerPredicate func(c moby.Container) bool +type containerPredicate func(c container.Summary) bool -func matches(c moby.Container, predicates ...containerPredicate) bool { +func matches(c container.Summary, predicates ...containerPredicate) bool { for _, predicate := range predicates { if !predicate(c) { return false @@ -124,14 +122,14 @@ func matches(c moby.Container, predicates ...containerPredicate) bool { } func isService(services ...string) containerPredicate { - return func(c moby.Container) bool { + return func(c container.Summary) bool { service := c.Labels[api.ServiceLabel] return utils.StringContains(services, service) } } func isRunning() containerPredicate { - return func(c moby.Container) bool { + return func(c container.Summary) bool { return c.State == "running" } } @@ -139,7 +137,7 @@ func isRunning() containerPredicate { // isOrphaned is a predicate to select containers without a matching service definition in compose project func isOrphaned(project *types.Project) containerPredicate { services := append(project.ServiceNames(), project.DisabledServiceNames()...) - return func(c moby.Container) bool { + return func(c container.Summary) bool { // One-off container v, ok := c.Labels[api.OneoffLabel] if ok && v == "True" { @@ -151,7 +149,7 @@ func isOrphaned(project *types.Project) containerPredicate { } } -func isNotOneOff(c moby.Container) bool { +func isNotOneOff(c container.Summary) bool { v, ok := c.Labels[api.OneoffLabel] return !ok || v == "False" } @@ -175,7 +173,7 @@ func (containers Containers) names() []string { return names } -func (containers Containers) forEach(fn func(moby.Container)) { +func (containers Containers) forEach(fn func(container.Summary)) { for _, c := range containers { fn(c) } diff --git a/pkg/compose/convergence.go b/pkg/compose/convergence.go index d0a94db3e..6d59576e8 100644 --- a/pkg/compose/convergence.go +++ b/pkg/compose/convergence.go @@ -29,7 +29,6 @@ import ( "github.com/compose-spec/compose-go/v2/types" "github.com/containerd/platforms" - moby "github.com/docker/docker/api/types" containerType "github.com/docker/docker/api/types/container" mmount "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/versions" @@ -324,7 +323,7 @@ func (c *convergence) resolveSharedNamespaces(service *types.ServiceConfig) erro return nil } -func (c *convergence) mustRecreate(expected types.ServiceConfig, actual moby.Container, policy string) (bool, error) { +func (c *convergence) mustRecreate(expected types.ServiceConfig, actual containerType.Summary, policy string) (bool, error) { if policy == api.RecreateNever { return false, nil } @@ -356,7 +355,7 @@ func (c *convergence) mustRecreate(expected types.ServiceConfig, actual moby.Con return false, nil } -func checkExpectedNetworks(expected types.ServiceConfig, actual moby.Container, networks map[string]string) bool { +func checkExpectedNetworks(expected types.ServiceConfig, actual containerType.Summary, networks map[string]string) bool { // check the networks container is connected to are the expected ones for net := range expected.Networks { id := networks[net] @@ -379,7 +378,7 @@ func checkExpectedNetworks(expected types.ServiceConfig, actual moby.Container, return false } -func checkExpectedVolumes(expected types.ServiceConfig, actual moby.Container, volumes map[string]string) bool { +func checkExpectedVolumes(expected types.ServiceConfig, actual containerType.Summary, volumes map[string]string) bool { // check container's volume mounts and search for the expected ones for _, vol := range expected.Volumes { if vol.Type != string(mmount.TypeVolume) { @@ -419,22 +418,22 @@ func getDefaultContainerName(projectName, serviceName, index string) string { return strings.Join([]string{projectName, serviceName, index}, api.Separator) } -func getContainerProgressName(container moby.Container) string { - return "Container " + getCanonicalContainerName(container) +func getContainerProgressName(ctr containerType.Summary) string { + return "Container " + getCanonicalContainerName(ctr) } func containerEvents(containers Containers, eventFunc func(string) progress.Event) []progress.Event { events := []progress.Event{} - for _, container := range containers { - events = append(events, eventFunc(getContainerProgressName(container))) + for _, ctr := range containers { + events = append(events, eventFunc(getContainerProgressName(ctr))) } return events } func containerReasonEvents(containers Containers, eventFunc func(string, string) progress.Event, reason string) []progress.Event { events := []progress.Event{} - for _, container := range containers { - events = append(events, eventFunc(getContainerProgressName(container), reason)) + for _, ctr := range containers { + events = append(events, eventFunc(getContainerProgressName(ctr), reason)) } return events } @@ -564,7 +563,7 @@ func shouldWaitForDependency(serviceName string, dependencyConfig types.ServiceD return true, nil } -func nextContainerNumber(containers []moby.Container) int { +func nextContainerNumber(containers []containerType.Summary) int { maxNumber := 0 for _, c := range containers { s, ok := c.Labels[api.ContainerNumberLabel] @@ -585,11 +584,11 @@ func nextContainerNumber(containers []moby.Container) int { func (s *composeService) createContainer(ctx context.Context, project *types.Project, service types.ServiceConfig, name string, number int, opts createOptions, -) (container moby.Container, err error) { +) (ctr containerType.Summary, err error) { w := progress.ContextWriter(ctx) eventName := "Container " + name w.Event(progress.CreatingEvent(eventName)) - container, err = s.createMobyContainer(ctx, project, service, name, number, nil, opts, w) + ctr, err = s.createMobyContainer(ctx, project, service, name, number, nil, opts, w) if err != nil { return } @@ -598,9 +597,9 @@ func (s *composeService) createContainer(ctx context.Context, project *types.Pro } func (s *composeService) recreateContainer(ctx context.Context, project *types.Project, service types.ServiceConfig, - replaced moby.Container, inherit bool, timeout *time.Duration, -) (moby.Container, error) { - var created moby.Container + replaced containerType.Summary, inherit bool, timeout *time.Duration, +) (containerType.Summary, error) { + var created containerType.Summary w := progress.ContextWriter(ctx) w.Event(progress.NewEvent(getContainerProgressName(replaced), progress.Working, "Recreate")) @@ -609,7 +608,7 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P return created, err } - var inherited *moby.Container + var inherited *containerType.Summary if inherit { inherited = &replaced } @@ -646,14 +645,14 @@ func (s *composeService) recreateContainer(ctx context.Context, project *types.P return created, err } -func (s *composeService) startContainer(ctx context.Context, container moby.Container) error { +func (s *composeService) startContainer(ctx context.Context, ctr containerType.Summary) error { w := progress.ContextWriter(ctx) - w.Event(progress.NewEvent(getContainerProgressName(container), progress.Working, "Restart")) - err := s.apiClient().ContainerStart(ctx, container.ID, containerType.StartOptions{}) + w.Event(progress.NewEvent(getContainerProgressName(ctr), progress.Working, "Restart")) + err := s.apiClient().ContainerStart(ctx, ctr.ID, containerType.StartOptions{}) if err != nil { return err } - w.Event(progress.NewEvent(getContainerProgressName(container), progress.Done, "Restarted")) + w.Event(progress.NewEvent(getContainerProgressName(ctr), progress.Done, "Restarted")) return nil } @@ -662,11 +661,11 @@ func (s *composeService) createMobyContainer(ctx context.Context, service types.ServiceConfig, name string, number int, - inherit *moby.Container, + inherit *containerType.Summary, opts createOptions, w progress.Writer, -) (moby.Container, error) { - var created moby.Container +) (containerType.Summary, error) { + var created containerType.Summary cfgs, err := s.getCreateConfigs(ctx, project, service, number, inherit, opts) if err != nil { return created, err @@ -700,11 +699,11 @@ func (s *composeService) createMobyContainer(ctx context.Context, if err != nil { return created, err } - created = moby.Container{ + created = containerType.Summary{ ID: inspectedContainer.ID, Labels: inspectedContainer.Config.Labels, Names: []string{inspectedContainer.Name}, - NetworkSettings: &moby.SummaryNetworkSettings{ + NetworkSettings: &containerType.NetworkSettingsSummary{ Networks: inspectedContainer.NetworkSettings.Networks, }, } @@ -821,11 +820,11 @@ func (s *composeService) isServiceHealthy(ctx context.Context, containers Contai return false, fmt.Errorf("container %s has no healthcheck configured", name) } switch container.State.Health.Status { - case moby.Healthy: + case containerType.Healthy: // Continue by checking the next container. - case moby.Unhealthy: + case containerType.Unhealthy: return false, fmt.Errorf("container %s is unhealthy", name) - case moby.Starting: + case containerType.Starting: return false, nil default: return false, fmt.Errorf("container %s had unexpected health status %q", name, container.State.Health.Status) @@ -869,19 +868,19 @@ func (s *composeService) startService(ctx context.Context, } w := progress.ContextWriter(ctx) - for _, container := range containers.filter(isService(service.Name)) { - if container.State == ContainerRunning { + for _, ctr := range containers.filter(isService(service.Name)) { + if ctr.State == ContainerRunning { continue } - eventName := getContainerProgressName(container) + eventName := getContainerProgressName(ctr) w.Event(progress.StartingEvent(eventName)) - err = s.apiClient().ContainerStart(ctx, container.ID, containerType.StartOptions{}) + err = s.apiClient().ContainerStart(ctx, ctr.ID, containerType.StartOptions{}) if err != nil { return err } for _, hook := range service.PostStart { - err = s.runHook(ctx, container, service, hook, listener) + err = s.runHook(ctx, ctr, service, hook, listener) if err != nil { return err } diff --git a/pkg/compose/convergence_test.go b/pkg/compose/convergence_test.go index 0f15afc57..319c811e7 100644 --- a/pkg/compose/convergence_test.go +++ b/pkg/compose/convergence_test.go @@ -25,8 +25,9 @@ import ( "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/config/configfile" moby "github.com/docker/docker/api/types" - containerType "github.com/docker/docker/api/types/container" + "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" "go.uber.org/mock/gomock" @@ -70,7 +71,7 @@ func TestServiceLinks(t *testing.T) { Scale: intPtr(1), } - containerListOptions := containerType.ListOptions{ + containerListOptions := container.ListOptions{ Filters: filters.NewArgs( projectFilter(testProject), serviceFilter("db"), @@ -94,7 +95,7 @@ func TestServiceLinks(t *testing.T) { s.Links = []string{"db"} c := testContainer("db", dbContainerName, false) - apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]moby.Container{c}, nil) + apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]container.Summary{c}, nil) links, err := tested.getLinks(context.Background(), testProject, s, 1) assert.NilError(t, err) @@ -119,7 +120,7 @@ func TestServiceLinks(t *testing.T) { c := testContainer("db", dbContainerName, false) - apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]moby.Container{c}, nil) + apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]container.Summary{c}, nil) links, err := tested.getLinks(context.Background(), testProject, s, 1) assert.NilError(t, err) @@ -142,7 +143,7 @@ func TestServiceLinks(t *testing.T) { s.Links = []string{"db:dbname"} c := testContainer("db", dbContainerName, false) - apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]moby.Container{c}, nil) + apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]container.Summary{c}, nil) links, err := tested.getLinks(context.Background(), testProject, s, 1) assert.NilError(t, err) @@ -167,7 +168,7 @@ func TestServiceLinks(t *testing.T) { s.ExternalLinks = []string{"db1:db2"} c := testContainer("db", dbContainerName, false) - apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]moby.Container{c}, nil) + apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptions).Return([]container.Summary{c}, nil) links, err := tested.getLinks(context.Background(), testProject, s, 1) assert.NilError(t, err) @@ -196,7 +197,7 @@ func TestServiceLinks(t *testing.T) { s.Labels = s.Labels.Add(api.OneoffLabel, "True") c := testContainer("web", webContainerName, true) - containerListOptionsOneOff := containerType.ListOptions{ + containerListOptionsOneOff := container.ListOptions{ Filters: filters.NewArgs( projectFilter(testProject), serviceFilter("web"), @@ -205,7 +206,7 @@ func TestServiceLinks(t *testing.T) { ), All: true, } - apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptionsOneOff).Return([]moby.Container{c}, nil) + apiClient.EXPECT().ContainerList(gomock.Any(), containerListOptionsOneOff).Return([]container.Summary{c}, nil) links, err := tested.getLinks(context.Background(), testProject, s, 1) assert.NilError(t, err) @@ -268,7 +269,7 @@ func TestCreateMobyContainer(t *testing.T) { cli.EXPECT().Client().Return(apiClient).AnyTimes() cli.EXPECT().ConfigFile().Return(&configfile.ConfigFile{}).AnyTimes() apiClient.EXPECT().DaemonHost().Return("").AnyTimes() - apiClient.EXPECT().ImageInspectWithRaw(gomock.Any(), gomock.Any()).Return(moby.ImageInspect{}, nil, nil).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{ @@ -303,11 +304,11 @@ func TestCreateMobyContainer(t *testing.T) { var falseBool bool apiClient.EXPECT().ContainerCreate(gomock.Any(), gomock.Any(), gomock.Eq( - &containerType.HostConfig{ + &container.HostConfig{ PortBindings: nat.PortMap{}, ExtraHosts: []string{}, Tmpfs: map[string]string{}, - Resources: containerType.Resources{ + Resources: container.Resources{ OomKillDisable: &falseBool, }, NetworkMode: "b-moby-name", @@ -320,18 +321,18 @@ func TestCreateMobyContainer(t *testing.T) { }, }, }), gomock.Any(), gomock.Any()).Times(1).Return( - containerType.CreateResponse{ + container.CreateResponse{ ID: "an-id", }, nil) apiClient.EXPECT().ContainerInspect(gomock.Any(), gomock.Eq("an-id")).Times(1).Return( - moby.ContainerJSON{ - ContainerJSONBase: &moby.ContainerJSONBase{ + container.InspectResponse{ + ContainerJSONBase: &container.ContainerJSONBase{ ID: "an-id", Name: "a-name", }, - Config: &containerType.Config{}, - NetworkSettings: &moby.NetworkSettings{}, + Config: &container.Config{}, + NetworkSettings: &container.NetworkSettings{}, }, nil) apiClient.EXPECT().NetworkConnect(gomock.Any(), "a-moby-name", "an-id", gomock.Eq( @@ -357,7 +358,7 @@ func TestCreateMobyContainer(t *testing.T) { cli.EXPECT().Client().Return(apiClient).AnyTimes() cli.EXPECT().ConfigFile().Return(&configfile.ConfigFile{}).AnyTimes() apiClient.EXPECT().DaemonHost().Return("").AnyTimes() - apiClient.EXPECT().ImageInspectWithRaw(gomock.Any(), gomock.Any()).Return(moby.ImageInspect{}, nil, nil).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{ @@ -392,11 +393,11 @@ func TestCreateMobyContainer(t *testing.T) { var falseBool bool apiClient.EXPECT().ContainerCreate(gomock.Any(), gomock.Any(), gomock.Eq( - &containerType.HostConfig{ + &container.HostConfig{ PortBindings: nat.PortMap{}, ExtraHosts: []string{}, Tmpfs: map[string]string{}, - Resources: containerType.Resources{ + Resources: container.Resources{ OomKillDisable: &falseBool, }, NetworkMode: "b-moby-name", @@ -413,18 +414,18 @@ func TestCreateMobyContainer(t *testing.T) { }, }, }), gomock.Any(), gomock.Any()).Times(1).Return( - containerType.CreateResponse{ + container.CreateResponse{ ID: "an-id", }, nil) apiClient.EXPECT().ContainerInspect(gomock.Any(), gomock.Eq("an-id")).Times(1).Return( - moby.ContainerJSON{ - ContainerJSONBase: &moby.ContainerJSONBase{ + container.InspectResponse{ + ContainerJSONBase: &container.ContainerJSONBase{ ID: "an-id", Name: "a-name", }, - Config: &containerType.Config{}, - NetworkSettings: &moby.NetworkSettings{}, + Config: &container.Config{}, + NetworkSettings: &container.NetworkSettings{}, }, nil) _, err := tested.createMobyContainer(context.Background(), &project, service, "test", 0, nil, createOptions{ diff --git a/pkg/compose/create.go b/pkg/compose/create.go index cce98010b..357791c3d 100644 --- a/pkg/compose/create.go +++ b/pkg/compose/create.go @@ -36,10 +36,10 @@ import ( "github.com/docker/compose/v2/pkg/progress" "github.com/docker/compose/v2/pkg/prompt" "github.com/docker/compose/v2/pkg/utils" - moby "github.com/docker/docker/api/types" "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/image" "github.com/docker/docker/api/types/mount" "github.com/docker/docker/api/types/network" "github.com/docker/docker/api/types/strslice" @@ -215,7 +215,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context, p *types.Project, service types.ServiceConfig, number int, - inherit *moby.Container, + inherit *container.Summary, opts createOptions, ) (createConfigs, error) { labels, err := s.prepareLabels(opts.Labels, service, number) @@ -274,7 +274,7 @@ func (s *composeService) getCreateConfigs(ctx context.Context, WorkingDir: service.WorkingDir, Entrypoint: entrypoint, NetworkDisabled: service.NetworkMode == "disabled", - MacAddress: macAddress, + 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), @@ -829,13 +829,13 @@ func (s *composeService) buildContainerVolumes( ctx context.Context, p types.Project, service types.ServiceConfig, - inherit *moby.Container, + inherit *container.Summary, ) ([]string, []mount.Mount, error) { var mounts []mount.Mount var binds []string - image := api.GetImageNameOrDefault(service, p.Name) - imgInspect, _, err := s.apiClient().ImageInspectWithRaw(ctx, image) + img := api.GetImageNameOrDefault(service, p.Name) + imgInspect, err := s.apiClient().ImageInspect(ctx, img) if err != nil { return nil, nil, err } @@ -890,7 +890,7 @@ func requireMountAPI(bind *types.ServiceVolumeBind) bool { } } -func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img moby.ImageInspect, inherit *moby.Container) ([]mount.Mount, error) { +func buildContainerMountOptions(p types.Project, s types.ServiceConfig, img image.InspectResponse, inherit *container.Summary) ([]mount.Mount, error) { mounts := map[string]mount.Mount{} if inherit != nil { for _, m := range inherit.Mounts { diff --git a/pkg/compose/create_test.go b/pkg/compose/create_test.go index eb44d0f93..ae7eb12d7 100644 --- a/pkg/compose/create_test.go +++ b/pkg/compose/create_test.go @@ -22,13 +22,14 @@ import ( "sort" "testing" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/image" "gotest.tools/v3/assert/cmp" "github.com/docker/compose/v2/pkg/api" "github.com/docker/docker/api/types/network" composetypes "github.com/compose-spec/compose-go/v2/types" - moby "github.com/docker/docker/api/types" mountTypes "github.com/docker/docker/api/types/mount" "gotest.tools/v3/assert" @@ -140,8 +141,8 @@ func TestBuildContainerMountOptions(t *testing.T) { }), } - inherit := &moby.Container{ - Mounts: []moby.MountPoint{ + inherit := &container.Summary{ + Mounts: []container.MountPoint{ { Type: composetypes.VolumeTypeVolume, Destination: "/var/myvolume1", @@ -153,7 +154,7 @@ func TestBuildContainerMountOptions(t *testing.T) { }, } - mounts, err := buildContainerMountOptions(project, project.Services["myService"], moby.ImageInspect{}, inherit) + mounts, err := buildContainerMountOptions(project, project.Services["myService"], image.InspectResponse{}, inherit) sort.Slice(mounts, func(i, j int) bool { return mounts[i].Target < mounts[j].Target }) @@ -165,7 +166,7 @@ func TestBuildContainerMountOptions(t *testing.T) { assert.Equal(t, mounts[2].VolumeOptions.Subpath, "etc") assert.Equal(t, mounts[3].Target, "\\\\.\\pipe\\docker_engine") - mounts, err = buildContainerMountOptions(project, project.Services["myService"], moby.ImageInspect{}, inherit) + mounts, err = buildContainerMountOptions(project, project.Services["myService"], image.InspectResponse{}, inherit) sort.Slice(mounts, func(i, j int) bool { return mounts[i].Target < mounts[j].Target }) diff --git a/pkg/compose/down.go b/pkg/compose/down.go index 23fe4641c..3a088251b 100644 --- a/pkg/compose/down.go +++ b/pkg/compose/down.go @@ -27,7 +27,6 @@ import ( "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/progress" "github.com/docker/compose/v2/pkg/utils" - moby "github.com/docker/docker/api/types" containerType "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" imageapi "github.com/docker/docker/api/types/image" @@ -297,13 +296,13 @@ func (s *composeService) removeVolume(ctx context.Context, id string, w progress return err } -func (s *composeService) stopContainer(ctx context.Context, w progress.Writer, service *types.ServiceConfig, container moby.Container, timeout *time.Duration) error { - eventName := getContainerProgressName(container) +func (s *composeService) stopContainer(ctx context.Context, w progress.Writer, service *types.ServiceConfig, ctr containerType.Summary, timeout *time.Duration) error { + eventName := getContainerProgressName(ctr) w.Event(progress.StoppingEvent(eventName)) if service != nil { for _, hook := range service.PreStop { - err := s.runHook(ctx, container, *service, hook, nil) + err := s.runHook(ctx, ctr, *service, hook, nil) if err != nil { return err } @@ -311,7 +310,7 @@ func (s *composeService) stopContainer(ctx context.Context, w progress.Writer, s } timeoutInSecond := utils.DurationSecondToInt(timeout) - err := s.apiClient().ContainerStop(ctx, container.ID, containerType.StopOptions{Timeout: timeoutInSecond}) + err := s.apiClient().ContainerStop(ctx, ctr.ID, containerType.StopOptions{Timeout: timeoutInSecond}) if err != nil { w.Event(progress.ErrorMessageEvent(eventName, "Error while Stopping")) return err @@ -320,7 +319,7 @@ func (s *composeService) stopContainer(ctx context.Context, w progress.Writer, s return nil } -func (s *composeService) stopContainers(ctx context.Context, w progress.Writer, serv *types.ServiceConfig, containers []moby.Container, timeout *time.Duration) error { +func (s *composeService) stopContainers(ctx context.Context, w progress.Writer, serv *types.ServiceConfig, containers []containerType.Summary, timeout *time.Duration) error { eg, ctx := errgroup.WithContext(ctx) for _, ctr := range containers { eg.Go(func() error { @@ -330,7 +329,7 @@ func (s *composeService) stopContainers(ctx context.Context, w progress.Writer, return eg.Wait() } -func (s *composeService) removeContainers(ctx context.Context, containers []moby.Container, service *types.ServiceConfig, timeout *time.Duration, volumes bool) error { +func (s *composeService) removeContainers(ctx context.Context, containers []containerType.Summary, service *types.ServiceConfig, timeout *time.Duration, volumes bool) error { eg, _ := errgroup.WithContext(ctx) for _, ctr := range containers { eg.Go(func() error { @@ -340,10 +339,10 @@ func (s *composeService) removeContainers(ctx context.Context, containers []moby return eg.Wait() } -func (s *composeService) stopAndRemoveContainer(ctx context.Context, container moby.Container, service *types.ServiceConfig, timeout *time.Duration, volumes bool) error { +func (s *composeService) stopAndRemoveContainer(ctx context.Context, ctr containerType.Summary, service *types.ServiceConfig, timeout *time.Duration, volumes bool) error { w := progress.ContextWriter(ctx) - eventName := getContainerProgressName(container) - err := s.stopContainer(ctx, w, service, container, timeout) + eventName := getContainerProgressName(ctr) + err := s.stopContainer(ctx, w, service, ctr, timeout) if errdefs.IsNotFound(err) { w.Event(progress.RemovedEvent(eventName)) return nil @@ -352,7 +351,7 @@ func (s *composeService) stopAndRemoveContainer(ctx context.Context, container m return err } w.Event(progress.RemovingEvent(eventName)) - err = s.apiClient().ContainerRemove(ctx, container.ID, containerType.RemoveOptions{ + err = s.apiClient().ContainerRemove(ctx, ctr.ID, containerType.RemoveOptions{ Force: true, RemoveVolumes: volumes, }) diff --git a/pkg/compose/down_test.go b/pkg/compose/down_test.go index 996e479a8..ac147d653 100644 --- a/pkg/compose/down_test.go +++ b/pkg/compose/down_test.go @@ -25,8 +25,7 @@ import ( "github.com/compose-spec/compose-go/v2/types" "github.com/docker/cli/cli/streams" - moby "github.com/docker/docker/api/types" - containerType "github.com/docker/docker/api/types/container" + "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" @@ -49,7 +48,7 @@ func TestDown(t *testing.T) { } api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return( - []moby.Container{ + []container.Summary{ testContainer("service1", "123", false), testContainer("service2", "456", false), testContainer("service2", "789", false), @@ -70,14 +69,14 @@ func TestDown(t *testing.T) { {ID: "def456", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}}, }, nil) - stopOptions := containerType.StopOptions{} + 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", containerType.RemoveOptions{Force: true}).Return(nil) - api.EXPECT().ContainerRemove(gomock.Any(), "456", containerType.RemoveOptions{Force: true}).Return(nil) - api.EXPECT().ContainerRemove(gomock.Any(), "789", containerType.RemoveOptions{Force: true}).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( @@ -106,7 +105,7 @@ func TestDownWithGivenServices(t *testing.T) { } api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return( - []moby.Container{ + []container.Summary{ testContainer("service1", "123", false), testContainer("service2", "456", false), testContainer("service2", "789", false), @@ -127,10 +126,10 @@ func TestDownWithGivenServices(t *testing.T) { {ID: "def456", Name: "myProject_default", Labels: map[string]string{compose.NetworkLabel: "default"}}, }, nil) - stopOptions := containerType.StopOptions{} + stopOptions := container.StopOptions{} api.EXPECT().ContainerStop(gomock.Any(), "123", stopOptions).Return(nil) - api.EXPECT().ContainerRemove(gomock.Any(), "123", containerType.RemoveOptions{Force: true}).Return(nil) + api.EXPECT().ContainerRemove(gomock.Any(), "123", container.RemoveOptions{Force: true}).Return(nil) api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{ Filters: filters.NewArgs( @@ -158,7 +157,7 @@ func TestDownWithSpecifiedServiceButTheServicesAreNotRunning(t *testing.T) { } api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return( - []moby.Container{ + []container.Summary{ testContainer("service1", "123", false), testContainer("service2", "456", false), testContainer("service2", "789", false), @@ -195,7 +194,7 @@ func TestDownRemoveOrphans(t *testing.T) { } api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(true)).Return( - []moby.Container{ + []container.Summary{ testContainer("service1", "123", false), testContainer("service2", "789", false), testContainer("service_orphan", "321", true), @@ -214,14 +213,14 @@ func TestDownRemoveOrphans(t *testing.T) { }, }, nil) - stopOptions := containerType.StopOptions{} + 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) - api.EXPECT().ContainerRemove(gomock.Any(), "123", containerType.RemoveOptions{Force: true}).Return(nil) - api.EXPECT().ContainerRemove(gomock.Any(), "789", containerType.RemoveOptions{Force: true}).Return(nil) - api.EXPECT().ContainerRemove(gomock.Any(), "321", containerType.RemoveOptions{Force: true}).Return(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().NetworkList(gomock.Any(), network.ListOptions{ Filters: filters.NewArgs( @@ -246,7 +245,7 @@ func TestDownRemoveVolumes(t *testing.T) { } api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return( - []moby.Container{testContainer("service1", "123", false)}, nil) + []container.Summary{testContainer("service1", "123", false)}, nil) api.EXPECT().VolumeList( gomock.Any(), volume.ListOptions{ @@ -258,8 +257,8 @@ func TestDownRemoveVolumes(t *testing.T) { api.EXPECT().NetworkList(gomock.Any(), network.ListOptions{Filters: filters.NewArgs(projectFilter(strings.ToLower(testProject)))}). Return(nil, nil) - api.EXPECT().ContainerStop(gomock.Any(), "123", containerType.StopOptions{}).Return(nil) - api.EXPECT().ContainerRemove(gomock.Any(), "123", containerType.RemoveOptions{Force: true, RemoveVolumes: true}).Return(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().VolumeRemove(gomock.Any(), "myProject_volume", true).Return(nil) @@ -291,7 +290,7 @@ func TestDownRemoveImages(t *testing.T) { } api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)). - Return([]moby.Container{ + Return([]container.Summary{ testContainer("service1", "123", false), }, nil). AnyTimes() @@ -320,7 +319,7 @@ func TestDownRemoveImages(t *testing.T) { "missing-named-image": false, } for img, exists := range imagesToBeInspected { - var resp moby.ImageInspect + var resp image.InspectResponse var err error if exists { resp.RepoTags = []string{img} @@ -328,13 +327,13 @@ func TestDownRemoveImages(t *testing.T) { err = errdefs.NotFound(fmt.Errorf("test specified that image %q should not exist", img)) } - api.EXPECT().ImageInspectWithRaw(gomock.Any(), img). - Return(resp, nil, err). + api.EXPECT().ImageInspect(gomock.Any(), img). + Return(resp, err). AnyTimes() } - api.EXPECT().ImageInspectWithRaw(gomock.Any(), "registry.example.com/remote-image-tagged:v1.0"). - Return(moby.ImageInspect{RepoTags: []string{"registry.example.com/remote-image-tagged:v1.0"}}, nil, nil). + 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). AnyTimes() localImagesToBeRemoved := []string{ @@ -379,10 +378,10 @@ func TestDownRemoveImages_NoLabel(t *testing.T) { dockerCli: cli, } - container := testContainer("service1", "123", false) + ctr := testContainer("service1", "123", false) api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return( - []moby.Container{container}, nil) + []container.Summary{ctr}, nil) api.EXPECT().VolumeList( gomock.Any(), @@ -404,11 +403,11 @@ func TestDownRemoveImages_NoLabel(t *testing.T) { ), }).Return(nil, nil) - api.EXPECT().ImageInspectWithRaw(gomock.Any(), "testproject-service1"). - Return(moby.ImageInspect{}, nil, nil) + api.EXPECT().ImageInspect(gomock.Any(), "testproject-service1"). + Return(image.InspectResponse{}, nil) - api.EXPECT().ContainerStop(gomock.Any(), "123", containerType.StopOptions{}).Return(nil) - api.EXPECT().ContainerRemove(gomock.Any(), "123", containerType.RemoveOptions{Force: true}).Return(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().ImageRemove(gomock.Any(), "testproject-service1:latest", image.RemoveOptions{}).Return(nil, nil) diff --git a/pkg/compose/exec.go b/pkg/compose/exec.go index cade07514..bc4599705 100644 --- a/pkg/compose/exec.go +++ b/pkg/compose/exec.go @@ -24,7 +24,7 @@ import ( "github.com/docker/cli/cli" "github.com/docker/cli/cli/command/container" "github.com/docker/compose/v2/pkg/api" - moby "github.com/docker/docker/api/types" + containerType "github.com/docker/docker/api/types/container" ) func (s *composeService) Exec(ctx context.Context, projectName string, options api.RunOptions) (int, error) { @@ -57,6 +57,6 @@ func (s *composeService) Exec(ctx context.Context, projectName string, options a return 0, err } -func (s *composeService) getExecTarget(ctx context.Context, projectName string, opts api.RunOptions) (moby.Container, error) { +func (s *composeService) getExecTarget(ctx context.Context, projectName string, opts api.RunOptions) (containerType.Summary, error) { return s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, opts.Service, opts.Index) } diff --git a/pkg/compose/generate.go b/pkg/compose/generate.go index ec72f03e0..157c1384e 100644 --- a/pkg/compose/generate.go +++ b/pkg/compose/generate.go @@ -24,8 +24,7 @@ import ( "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/utils" - moby "github.com/docker/docker/api/types" - containerType "github.com/docker/docker/api/types/container" + "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" @@ -40,7 +39,7 @@ func (s *composeService) Generate(ctx context.Context, options api.GenerateOptio filtersListNames.Add("name", containerName) filtersListIDs.Add("id", containerName) } - containers, err := s.apiClient().ContainerList(ctx, containerType.ListOptions{ + containers, err := s.apiClient().ContainerList(ctx, container.ListOptions{ Filters: filtersListNames, All: true, }) @@ -48,16 +47,16 @@ func (s *composeService) Generate(ctx context.Context, options api.GenerateOptio return nil, err } - containersByIds, err := s.apiClient().ContainerList(ctx, containerType.ListOptions{ + containersByIds, err := s.apiClient().ContainerList(ctx, container.ListOptions{ Filters: filtersListIDs, All: true, }) if err != nil { return nil, err } - for _, container := range containersByIds { - if !utils.Contains(containers, container) { - containers = append(containers, container) + for _, ctr := range containersByIds { + if !utils.Contains(containers, ctr) { + containers = append(containers, ctr) } } @@ -68,7 +67,7 @@ func (s *composeService) Generate(ctx context.Context, options api.GenerateOptio return s.createProjectFromContainers(containers, options.ProjectName) } -func (s *composeService) createProjectFromContainers(containers []moby.Container, projectName string) (*types.Project, error) { +func (s *composeService) createProjectFromContainers(containers []container.Summary, projectName string) (*types.Project, error) { project := &types.Project{} services := types.Services{} networks := types.Networks{} @@ -112,7 +111,7 @@ func (s *composeService) createProjectFromContainers(containers []moby.Container return project, nil } -func (s *composeService) extractComposeConfiguration(service *types.ServiceConfig, inspect moby.ContainerJSON, volumes types.Volumes, secrets types.Secrets, networks types.Networks) { +func (s *composeService) extractComposeConfiguration(service *types.ServiceConfig, inspect container.InspectResponse, volumes types.Volumes, secrets types.Secrets, networks types.Networks) { service.Environment = types.NewMappingWithEquals(inspect.Config.Env) if inspect.Config.Healthcheck != nil { healthConfig := inspect.Config.Healthcheck @@ -144,7 +143,7 @@ func (s *composeService) extractComposeConfiguration(service *types.ServiceConfi } } -func (s *composeService) toComposeHealthCheck(healthConfig *containerType.HealthConfig) *types.HealthCheckConfig { +func (s *composeService) toComposeHealthCheck(healthConfig *container.HealthConfig) *types.HealthCheckConfig { var healthCheck types.HealthCheckConfig healthCheck.Test = healthConfig.Test if healthConfig.Timeout != 0 { @@ -170,7 +169,7 @@ func (s *composeService) toComposeHealthCheck(healthConfig *containerType.Health return &healthCheck } -func (s *composeService) toComposeVolumes(volumes []moby.MountPoint) (map[string]types.VolumeConfig, +func (s *composeService) toComposeVolumes(volumes []container.MountPoint) (map[string]types.VolumeConfig, []types.ServiceVolumeConfig, map[string]types.SecretConfig, []types.ServiceSecretConfig, ) { volumeConfigs := make(map[string]types.VolumeConfig) diff --git a/pkg/compose/hook.go b/pkg/compose/hook.go index 8a7bb39a4..79831d5b0 100644 --- a/pkg/compose/hook.go +++ b/pkg/compose/hook.go @@ -25,17 +25,16 @@ import ( "github.com/compose-spec/compose-go/v2/types" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/utils" - moby "github.com/docker/docker/api/types" - containerType "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/pkg/stdcopy" ) -func (s composeService) runHook(ctx context.Context, container moby.Container, service types.ServiceConfig, hook types.ServiceHook, listener api.ContainerEventListener) error { +func (s composeService) runHook(ctx context.Context, ctr container.Summary, service types.ServiceConfig, hook types.ServiceHook, listener api.ContainerEventListener) error { wOut := utils.GetWriter(func(line string) { listener(api.ContainerEvent{ Type: api.HookEventLog, - Container: getContainerNameWithoutProject(container) + " ->", - ID: container.ID, + Container: getContainerNameWithoutProject(ctr) + " ->", + ID: ctr.ID, Service: service.Name, Line: line, }) @@ -43,7 +42,7 @@ func (s composeService) runHook(ctx context.Context, container moby.Container, s defer wOut.Close() //nolint:errcheck detached := listener == nil - exec, err := s.apiClient().ContainerExecCreate(ctx, container.ID, containerType.ExecOptions{ + exec, err := s.apiClient().ContainerExecCreate(ctx, ctr.ID, container.ExecOptions{ User: hook.User, Privileged: hook.Privileged, Env: ToMobyEnv(hook.Environment), @@ -58,12 +57,12 @@ func (s composeService) runHook(ctx context.Context, container moby.Container, s } if detached { - return s.runWaitExec(ctx, exec, service, listener) + return s.runWaitExec(ctx, exec.ID, service, listener) } height, width := s.stdout().GetTtySize() consoleSize := &[2]uint{height, width} - attach, err := s.apiClient().ContainerExecAttach(ctx, exec.ID, containerType.ExecAttachOptions{ + attach, err := s.apiClient().ContainerExecAttach(ctx, exec.ID, container.ExecAttachOptions{ Tty: service.Tty, ConsoleSize: consoleSize, }) @@ -91,8 +90,8 @@ func (s composeService) runHook(ctx context.Context, container moby.Container, s return nil } -func (s composeService) runWaitExec(ctx context.Context, exec moby.IDResponse, service types.ServiceConfig, listener api.ContainerEventListener) error { - err := s.apiClient().ContainerExecStart(ctx, exec.ID, containerType.ExecStartOptions{ +func (s composeService) runWaitExec(ctx context.Context, execID string, service types.ServiceConfig, listener api.ContainerEventListener) error { + err := s.apiClient().ContainerExecStart(ctx, execID, container.ExecStartOptions{ Detach: listener == nil, Tty: service.Tty, }) @@ -107,7 +106,7 @@ func (s composeService) runWaitExec(ctx context.Context, exec moby.IDResponse, s case <-ctx.Done(): return nil case <-tick.C: - inspect, err := s.apiClient().ContainerExecInspect(ctx, exec.ID) + inspect, err := s.apiClient().ContainerExecInspect(ctx, execID) if err != nil { return nil } diff --git a/pkg/compose/image_pruner.go b/pkg/compose/image_pruner.go index 2cb34930c..25306849b 100644 --- a/pkg/compose/image_pruner.go +++ b/pkg/compose/image_pruner.go @@ -203,7 +203,7 @@ func (p *ImagePruner) filterImagesByExistence(ctx context.Context, imageNames [] eg, ctx := errgroup.WithContext(ctx) for _, img := range imageNames { eg.Go(func() error { - _, _, err := p.client.ImageInspectWithRaw(ctx, img) + _, err := p.client.ImageInspect(ctx, img) if errdefs.IsNotFound(err) { // err on the side of caution: only skip if we successfully // queried the API and got back a definitive "not exists" diff --git a/pkg/compose/images.go b/pkg/compose/images.go index c307c4f63..e344666a8 100644 --- a/pkg/compose/images.go +++ b/pkg/compose/images.go @@ -23,8 +23,7 @@ import ( "sync" "github.com/distribution/reference" - moby "github.com/docker/docker/api/types" - containerType "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/errdefs" "golang.org/x/sync/errgroup" @@ -35,14 +34,14 @@ import ( func (s *composeService) Images(ctx context.Context, projectName string, options api.ImagesOptions) ([]api.ImageSummary, error) { projectName = strings.ToLower(projectName) - allContainers, err := s.apiClient().ContainerList(ctx, containerType.ListOptions{ + allContainers, err := s.apiClient().ContainerList(ctx, container.ListOptions{ All: true, Filters: filters.NewArgs(projectFilter(projectName)), }) if err != nil { return nil, err } - containers := []moby.Container{} + var containers []container.Summary if len(options.Services) > 0 { // filter service containers for _, c := range allContainers { @@ -65,14 +64,14 @@ func (s *composeService) Images(ctx context.Context, projectName string, options return nil, err } summary := make([]api.ImageSummary, len(containers)) - for i, container := range containers { - img, ok := imageSummaries[container.Image] + for i, c := range containers { + img, ok := imageSummaries[c.Image] if !ok { - return nil, fmt.Errorf("failed to retrieve image for container %s", getCanonicalContainerName(container)) + return nil, fmt.Errorf("failed to retrieve image for container %s", getCanonicalContainerName(c)) } summary[i] = img - summary[i].ContainerName = getCanonicalContainerName(container) + summary[i].ContainerName = getCanonicalContainerName(c) } return summary, nil } @@ -83,7 +82,7 @@ func (s *composeService) getImageSummaries(ctx context.Context, repoTags []strin eg, ctx := errgroup.WithContext(ctx) for _, repoTag := range repoTags { eg.Go(func() error { - inspect, _, err := s.apiClient().ImageInspectWithRaw(ctx, repoTag) + inspect, err := s.apiClient().ImageInspect(ctx, repoTag) if err != nil { if errdefs.IsNotFound(err) { return nil diff --git a/pkg/compose/images_test.go b/pkg/compose/images_test.go index 9da4c6815..62fbd1dc5 100644 --- a/pkg/compose/images_test.go +++ b/pkg/compose/images_test.go @@ -21,13 +21,13 @@ import ( "strings" "testing" - containerType "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/image" "go.uber.org/mock/gomock" "gotest.tools/v3/assert" compose "github.com/docker/compose/v2/pkg/api" - moby "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/filters" ) func TestImages(t *testing.T) { @@ -41,16 +41,16 @@ func TestImages(t *testing.T) { ctx := context.Background() args := filters.NewArgs(projectFilter(strings.ToLower(testProject))) - listOpts := containerType.ListOptions{All: true, Filters: args} + listOpts := container.ListOptions{All: true, Filters: args} image1 := imageInspect("image1", "foo:1", 12345) image2 := imageInspect("image2", "bar:2", 67890) - api.EXPECT().ImageInspectWithRaw(anyCancellableContext(), "foo:1").Return(image1, nil, nil) - api.EXPECT().ImageInspectWithRaw(anyCancellableContext(), "bar:2").Return(image2, nil, nil) + api.EXPECT().ImageInspect(anyCancellableContext(), "foo:1").Return(image1, nil) + 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 = []moby.Port{{PublicPort: 80, PrivatePort: 90, IP: "localhost"}} + c2.Ports = []container.Port{{PublicPort: 80, PrivatePort: 90, IP: "localhost"}} c3 := containerDetail("service2", "789", "exited", "foo:1") - api.EXPECT().ContainerList(ctx, listOpts).Return([]moby.Container{c1, c2, c3}, nil) + api.EXPECT().ContainerList(ctx, listOpts).Return([]container.Summary{c1, c2, c3}, nil) images, err := tested.Images(ctx, strings.ToLower(testProject), compose.ImagesOptions{}) @@ -81,22 +81,22 @@ func TestImages(t *testing.T) { assert.DeepEqual(t, images, expected) } -func imageInspect(id string, image string, size int64) moby.ImageInspect { - return moby.ImageInspect{ +func imageInspect(id string, imageReference string, size int64) image.InspectResponse { + return image.InspectResponse{ ID: id, RepoTags: []string{ "someRepo:someTag", - image, + imageReference, }, Size: size, } } -func containerDetail(service string, id string, status string, image string) moby.Container { - return moby.Container{ +func containerDetail(service string, id string, status string, imageName string) container.Summary { + return container.Summary{ ID: id, Names: []string{"/" + id}, - Image: image, + Image: imageName, Labels: containerLabels(service, false), State: status, } diff --git a/pkg/compose/kill.go b/pkg/compose/kill.go index 5dfa811f0..badf90e03 100644 --- a/pkg/compose/kill.go +++ b/pkg/compose/kill.go @@ -21,7 +21,7 @@ import ( "fmt" "strings" - moby "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "golang.org/x/sync/errgroup" "github.com/docker/compose/v2/pkg/api" @@ -62,19 +62,18 @@ func (s *composeService) kill(ctx context.Context, projectName string, options a } eg, ctx := errgroup.WithContext(ctx) - containers. - forEach(func(container moby.Container) { - eg.Go(func() error { - eventName := getContainerProgressName(container) - w.Event(progress.KillingEvent(eventName)) - err := s.apiClient().ContainerKill(ctx, container.ID, options.Signal) - if err != nil { - w.Event(progress.ErrorMessageEvent(eventName, "Error while Killing")) - return err - } - w.Event(progress.KilledEvent(eventName)) - return nil - }) + containers.forEach(func(ctr container.Summary) { + eg.Go(func() error { + eventName := getContainerProgressName(ctr) + w.Event(progress.KillingEvent(eventName)) + err := s.apiClient().ContainerKill(ctx, ctr.ID, options.Signal) + if err != nil { + w.Event(progress.ErrorMessageEvent(eventName, "Error while Killing")) + return err + } + w.Event(progress.KilledEvent(eventName)) + return nil }) + }) return eg.Wait() } diff --git a/pkg/compose/kill_test.go b/pkg/compose/kill_test.go index 69a4c480d..32a8f7730 100644 --- a/pkg/compose/kill_test.go +++ b/pkg/compose/kill_test.go @@ -23,8 +23,7 @@ import ( "strings" "testing" - moby "github.com/docker/docker/api/types" - containerType "github.com/docker/docker/api/types/container" + "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" @@ -48,10 +47,10 @@ func TestKillAll(t *testing.T) { name := strings.ToLower(testProject) ctx := context.Background() - api.EXPECT().ContainerList(ctx, containerType.ListOptions{ + api.EXPECT().ContainerList(ctx, container.ListOptions{ Filters: filters.NewArgs(projectFilter(name), hasConfigHashLabel()), }).Return( - []moby.Container{testContainer("service1", "123", false), testContainer("service1", "456", false), testContainer("service2", "789", false)}, nil) + []container.Summary{testContainer("service1", "123", false), testContainer("service1", "456", false), testContainer("service2", "789", false)}, nil) api.EXPECT().VolumeList( gomock.Any(), volume.ListOptions{ @@ -81,12 +80,12 @@ func TestKillSignal(t *testing.T) { } name := strings.ToLower(testProject) - listOptions := containerType.ListOptions{ + listOptions := container.ListOptions{ Filters: filters.NewArgs(projectFilter(name), serviceFilter(serviceName), hasConfigHashLabel()), } ctx := context.Background() - api.EXPECT().ContainerList(ctx, listOptions).Return([]moby.Container{testContainer(serviceName, "123", false)}, nil) + api.EXPECT().ContainerList(ctx, listOptions).Return([]container.Summary{testContainer(serviceName, "123", false)}, nil) api.EXPECT().VolumeList( gomock.Any(), volume.ListOptions{ @@ -103,12 +102,12 @@ func TestKillSignal(t *testing.T) { assert.NilError(t, err) } -func testContainer(service string, id string, oneOff bool) moby.Container { +func testContainer(service string, id string, oneOff bool) container.Summary { // canonical docker names in the API start with a leading slash, some // parts of Compose code will attempt to strip this off, so make sure // it's consistently present name := "/" + strings.TrimPrefix(id, "/") - return moby.Container{ + return container.Summary{ ID: id, Names: []string{name}, Labels: containerLabels(service, oneOff), @@ -137,7 +136,7 @@ func anyCancellableContext() gomock.Matcher { return gomock.AssignableToTypeOf(ctxWithCancel) } -func projectFilterListOpt(withOneOff bool) containerType.ListOptions { +func projectFilterListOpt(withOneOff bool) container.ListOptions { filter := filters.NewArgs( projectFilter(strings.ToLower(testProject)), hasConfigHashLabel(), @@ -145,7 +144,7 @@ func projectFilterListOpt(withOneOff bool) containerType.ListOptions { if !withOneOff { filter.Add("label", fmt.Sprintf("%s=False", compose.OneoffLabel)) } - return containerType.ListOptions{ + return container.ListOptions{ Filters: filter, All: true, } diff --git a/pkg/compose/logs.go b/pkg/compose/logs.go index 4efb0cfb3..284068e4c 100644 --- a/pkg/compose/logs.go +++ b/pkg/compose/logs.go @@ -22,8 +22,7 @@ import ( "io" "time" - "github.com/docker/docker/api/types" - containerType "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/errdefs" "github.com/docker/docker/pkg/stdcopy" "github.com/sirupsen/logrus" @@ -43,11 +42,11 @@ func (s *composeService) Logs( var err error if options.Index > 0 { - container, err := s.getSpecifiedContainer(ctx, projectName, oneOffExclude, true, options.Services[0], options.Index) + ctr, err := s.getSpecifiedContainer(ctx, projectName, oneOffExclude, true, options.Services[0], options.Index) if err != nil { return err } - containers = append(containers, container) + containers = append(containers, ctr) } else { containers, err = s.getContainers(ctx, projectName, oneOffExclude, true, options.Services...) if err != nil { @@ -92,7 +91,7 @@ func (s *composeService) Logs( } eg.Go(func() error { - err := s.watchContainers(ctx, projectName, options.Services, nil, printer.HandleEvent, containers, func(c types.Container, t time.Time) error { + err := s.watchContainers(ctx, projectName, options.Services, nil, printer.HandleEvent, containers, func(c container.Summary, t time.Time) error { printer.HandleEvent(api.ContainerEvent{ Type: api.ContainerEventAttach, Container: getContainerNameWithoutProject(c), @@ -115,7 +114,7 @@ func (s *composeService) Logs( return err }) return nil - }, func(c types.Container, t time.Time) error { + }, func(c container.Summary, t time.Time) error { printer.HandleEvent(api.ContainerEvent{ Type: api.ContainerEventAttach, Container: "", // actual name will be set by start event @@ -132,13 +131,13 @@ func (s *composeService) Logs( return eg.Wait() } -func (s *composeService) logContainers(ctx context.Context, consumer api.LogConsumer, c types.Container, options api.LogOptions) error { +func (s *composeService) logContainers(ctx context.Context, consumer api.LogConsumer, c container.Summary, options api.LogOptions) error { cnt, err := s.apiClient().ContainerInspect(ctx, c.ID) if err != nil { return err } - r, err := s.apiClient().ContainerLogs(ctx, cnt.ID, containerType.LogsOptions{ + r, err := s.apiClient().ContainerLogs(ctx, cnt.ID, container.LogsOptions{ ShowStdout: true, ShowStderr: true, Follow: options.Follow, diff --git a/pkg/compose/logs_test.go b/pkg/compose/logs_test.go index 5792e235a..46893e636 100644 --- a/pkg/compose/logs_test.go +++ b/pkg/compose/logs_test.go @@ -24,7 +24,6 @@ import ( "testing" "github.com/compose-spec/compose-go/v2/types" - moby "github.com/docker/docker/api/types" containerType "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/pkg/stdcopy" @@ -51,7 +50,7 @@ func TestComposeService_Logs_Demux(t *testing.T) { All: true, Filters: filters.NewArgs(oneOffFilter(false), projectFilter(name), hasConfigHashLabel()), }).Return( - []moby.Container{ + []containerType.Summary{ testContainer("service", "c", false), }, nil, @@ -59,8 +58,8 @@ func TestComposeService_Logs_Demux(t *testing.T) { api.EXPECT(). ContainerInspect(anyCancellableContext(), "c"). - Return(moby.ContainerJSON{ - ContainerJSONBase: &moby.ContainerJSONBase{ID: "c"}, + Return(containerType.InspectResponse{ + ContainerJSONBase: &containerType.ContainerJSONBase{ID: "c"}, Config: &containerType.Config{Tty: false}, }, nil) c1Reader, c1Writer := io.Pipe() @@ -122,7 +121,7 @@ func TestComposeService_Logs_ServiceFiltering(t *testing.T) { All: true, Filters: filters.NewArgs(oneOffFilter(false), projectFilter(name), hasConfigHashLabel()), }).Return( - []moby.Container{ + []containerType.Summary{ testContainer("serviceA", "c1", false), testContainer("serviceA", "c2", false), // serviceB will be filtered out by the project definition to @@ -137,8 +136,8 @@ func TestComposeService_Logs_ServiceFiltering(t *testing.T) { api.EXPECT(). ContainerInspect(anyCancellableContext(), id). Return( - moby.ContainerJSON{ - ContainerJSONBase: &moby.ContainerJSONBase{ID: id}, + containerType.InspectResponse{ + ContainerJSONBase: &containerType.ContainerJSONBase{ID: id}, Config: &containerType.Config{Tty: true}, }, nil, diff --git a/pkg/compose/ls.go b/pkg/compose/ls.go index 359cc6c2f..706bcf0d5 100644 --- a/pkg/compose/ls.go +++ b/pkg/compose/ls.go @@ -24,14 +24,13 @@ import ( "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/utils" - moby "github.com/docker/docker/api/types" - containerType "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/sirupsen/logrus" ) func (s *composeService) List(ctx context.Context, opts api.ListOptions) ([]api.Stack, error) { - list, err := s.apiClient().ContainerList(ctx, containerType.ListOptions{ + list, err := s.apiClient().ContainerList(ctx, container.ListOptions{ Filters: filters.NewArgs(hasProjectLabelFilter(), hasConfigHashLabel()), All: opts.All, }) @@ -42,7 +41,7 @@ func (s *composeService) List(ctx context.Context, opts api.ListOptions) ([]api. return containersToStacks(list) } -func containersToStacks(containers []moby.Container) ([]api.Stack, error) { +func containersToStacks(containers []container.Summary) ([]api.Stack, error) { containersByLabel, keys, err := groupContainerByLabel(containers, api.ProjectLabel) if err != nil { return nil, err @@ -65,7 +64,7 @@ func containersToStacks(containers []moby.Container) ([]api.Stack, error) { return projects, nil } -func combinedConfigFiles(containers []moby.Container) (string, error) { +func combinedConfigFiles(containers []container.Summary) (string, error) { configFiles := []string{} for _, c := range containers { @@ -84,7 +83,7 @@ func combinedConfigFiles(containers []moby.Container) (string, error) { return strings.Join(configFiles, ","), nil } -func containerToState(containers []moby.Container) []string { +func containerToState(containers []container.Summary) []string { statuses := []string{} for _, c := range containers { statuses = append(statuses, c.State) @@ -115,8 +114,8 @@ func combinedStatus(statuses []string) string { return result } -func groupContainerByLabel(containers []moby.Container, labelName string) (map[string][]moby.Container, []string, error) { - containersByLabel := map[string][]moby.Container{} +func groupContainerByLabel(containers []container.Summary, labelName string) (map[string][]container.Summary, []string, error) { + containersByLabel := map[string][]container.Summary{} keys := []string{} for _, c := range containers { label, ok := c.Labels[labelName] @@ -125,7 +124,7 @@ func groupContainerByLabel(containers []moby.Container, labelName string) (map[s } labelContainers, ok := containersByLabel[label] if !ok { - labelContainers = []moby.Container{} + labelContainers = []container.Summary{} keys = append(keys, label) } labelContainers = append(labelContainers, c) diff --git a/pkg/compose/ls_test.go b/pkg/compose/ls_test.go index 0d3b9dd5b..214f8c40f 100644 --- a/pkg/compose/ls_test.go +++ b/pkg/compose/ls_test.go @@ -21,13 +21,13 @@ import ( "testing" "github.com/docker/compose/v2/pkg/api" + "github.com/docker/docker/api/types/container" - moby "github.com/docker/docker/api/types" "gotest.tools/v3/assert" ) func TestContainersToStacks(t *testing.T) { - containers := []moby.Container{ + containers := []container.Summary{ { ID: "service1", State: "running", @@ -69,7 +69,7 @@ func TestStacksMixedStatus(t *testing.T) { } func TestCombinedConfigFiles(t *testing.T) { - containersByLabel := map[string][]moby.Container{ + containersByLabel := map[string][]container.Summary{ "project1": { { ID: "service1", @@ -113,7 +113,7 @@ func TestCombinedConfigFiles(t *testing.T) { expected := testData[project] if expected.Error != nil { - assert.Equal(t, err.Error(), expected.Error.Error()) + assert.Error(t, err, expected.Error.Error()) } else { assert.Equal(t, err, expected.Error) } diff --git a/pkg/compose/pause.go b/pkg/compose/pause.go index 1032539f8..4f86d0e09 100644 --- a/pkg/compose/pause.go +++ b/pkg/compose/pause.go @@ -20,7 +20,7 @@ import ( "context" "strings" - moby "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" "golang.org/x/sync/errgroup" "github.com/docker/compose/v2/pkg/api" @@ -45,7 +45,7 @@ func (s *composeService) pause(ctx context.Context, projectName string, options w := progress.ContextWriter(ctx) eg, ctx := errgroup.WithContext(ctx) - containers.forEach(func(container moby.Container) { + containers.forEach(func(container container.Summary) { eg.Go(func() error { err := s.apiClient().ContainerPause(ctx, container.ID) if err == nil { @@ -76,11 +76,11 @@ func (s *composeService) unPause(ctx context.Context, projectName string, option w := progress.ContextWriter(ctx) eg, ctx := errgroup.WithContext(ctx) - containers.forEach(func(container moby.Container) { + containers.forEach(func(ctr container.Summary) { eg.Go(func() error { - err = s.apiClient().ContainerUnpause(ctx, container.ID) + err = s.apiClient().ContainerUnpause(ctx, ctr.ID) if err == nil { - eventName := getContainerProgressName(container) + eventName := getContainerProgressName(ctr) w.Event(progress.NewEvent(eventName, progress.Done, "Unpaused")) } return err diff --git a/pkg/compose/port.go b/pkg/compose/port.go index 570c6202f..35c2832ac 100644 --- a/pkg/compose/port.go +++ b/pkg/compose/port.go @@ -22,25 +22,24 @@ import ( "strings" "github.com/docker/compose/v2/pkg/api" - - moby "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/container" ) func (s *composeService) Port(ctx context.Context, projectName string, service string, port uint16, options api.PortOptions) (string, int, error) { projectName = strings.ToLower(projectName) - container, err := s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, service, options.Index) + ctr, err := s.getSpecifiedContainer(ctx, projectName, oneOffInclude, false, service, options.Index) if err != nil { return "", 0, err } - for _, p := range container.Ports { + for _, p := range ctr.Ports { if p.PrivatePort == port && p.Type == options.Protocol { return p.IP, int(p.PublicPort), nil } } - return "", 0, portNotFoundError(options.Protocol, port, container) + return "", 0, portNotFoundError(options.Protocol, port, ctr) } -func portNotFoundError(protocol string, port uint16, ctr moby.Container) error { +func portNotFoundError(protocol string, port uint16, ctr container.Summary) error { formatPort := func(protocol string, port uint16) string { return fmt.Sprintf("%d/%s", port, protocol) } diff --git a/pkg/compose/ps_test.go b/pkg/compose/ps_test.go index c4b5ffe63..41cd807e3 100644 --- a/pkg/compose/ps_test.go +++ b/pkg/compose/ps_test.go @@ -26,7 +26,6 @@ import ( "gotest.tools/v3/assert" compose "github.com/docker/compose/v2/pkg/api" - moby "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" ) @@ -45,9 +44,9 @@ func TestPs(t *testing.T) { listOpts := containerType.ListOptions{Filters: args, All: false} c1, inspect1 := containerDetails("service1", "123", "running", "healthy", 0) c2, inspect2 := containerDetails("service1", "456", "running", "", 0) - c2.Ports = []moby.Port{{PublicPort: 80, PrivatePort: 90, IP: "localhost"}} + c2.Ports = []containerType.Port{{PublicPort: 80, PrivatePort: 90, IP: "localhost"}} c3, inspect3 := containerDetails("service2", "789", "exited", "", 130) - api.EXPECT().ContainerList(ctx, listOpts).Return([]moby.Container{c1, c2, c3}, nil) + api.EXPECT().ContainerList(ctx, 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) @@ -91,14 +90,22 @@ func TestPs(t *testing.T) { assert.DeepEqual(t, containers, expected) } -func containerDetails(service string, id string, status string, health string, exitCode int) (moby.Container, moby.ContainerJSON) { - container := moby.Container{ +func containerDetails(service string, id string, status string, health string, exitCode int) (containerType.Summary, containerType.InspectResponse) { + container := containerType.Summary{ ID: id, Names: []string{"/" + id}, Image: "foo", Labels: containerLabels(service, false), State: status, } - inspect := moby.ContainerJSON{ContainerJSONBase: &moby.ContainerJSONBase{State: &moby.ContainerState{Status: status, Health: &moby.Health{Status: health}, ExitCode: exitCode}}} + inspect := containerType.InspectResponse{ + ContainerJSONBase: &containerType.ContainerJSONBase{ + State: &containerType.State{ + Status: status, + Health: &containerType.Health{Status: health}, + ExitCode: exitCode, + }, + }, + } return container, inspect } diff --git a/pkg/compose/pull.go b/pkg/compose/pull.go index 4707e7c60..992fa1bfe 100644 --- a/pkg/compose/pull.go +++ b/pkg/compose/pull.go @@ -246,7 +246,7 @@ func (s *composeService) pullServiceImage(ctx context.Context, service types.Ser Text: "Pulled", }) - inspected, _, err := s.apiClient().ImageInspectWithRaw(ctx, service.Image) + inspected, err := s.apiClient().ImageInspect(ctx, service.Image) if err != nil { return "", err } diff --git a/pkg/compose/remove.go b/pkg/compose/remove.go index 1d13790aa..e8515a79a 100644 --- a/pkg/compose/remove.go +++ b/pkg/compose/remove.go @@ -22,8 +22,7 @@ import ( "strings" "github.com/docker/compose/v2/pkg/api" - moby "github.com/docker/docker/api/types" - containerType "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/container" "golang.org/x/sync/errgroup" "github.com/docker/compose/v2/pkg/progress" @@ -57,9 +56,9 @@ func (s *composeService) Remove(ctx context.Context, projectName string, options } var stoppedContainers Containers - for _, container := range 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, container.ID) + inspected, err := s.apiClient().ContainerInspect(ctx, ctr.ID) if api.IsNotFoundError(err) { // Already removed. Maybe configured with auto-remove continue @@ -68,12 +67,12 @@ func (s *composeService) Remove(ctx context.Context, projectName string, options return err } if !inspected.State.Running || (options.Stop && s.dryRun) { - stoppedContainers = append(stoppedContainers, container) + stoppedContainers = append(stoppedContainers, ctr) } } var names []string - stoppedContainers.forEach(func(c moby.Container) { + stoppedContainers.forEach(func(c container.Summary) { names = append(names, getCanonicalContainerName(c)) }) @@ -106,7 +105,7 @@ func (s *composeService) remove(ctx context.Context, containers Containers, opti eg.Go(func() error { eventName := getContainerProgressName(ctr) w.Event(progress.RemovingEvent(eventName)) - err := s.apiClient().ContainerRemove(ctx, ctr.ID, containerType.RemoveOptions{ + err := s.apiClient().ContainerRemove(ctx, ctr.ID, container.RemoveOptions{ RemoveVolumes: options.Volumes, Force: options.Force, }) diff --git a/pkg/compose/restart.go b/pkg/compose/restart.go index 2f987aeff..e18570afc 100644 --- a/pkg/compose/restart.go +++ b/pkg/compose/restart.go @@ -24,7 +24,7 @@ import ( "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/progress" "github.com/docker/compose/v2/pkg/utils" - containerType "github.com/docker/docker/api/types/container" + "github.com/docker/docker/api/types/container" "golang.org/x/sync/errgroup" ) @@ -56,7 +56,7 @@ func (s *composeService) restart(ctx context.Context, projectName string, option } // ignore depends_on relations which are not impacted by restarting service or not required - project, err = project.WithServicesTransform(func(name string, s types.ServiceConfig) (types.ServiceConfig, error) { + project, err = project.WithServicesTransform(func(_ string, s types.ServiceConfig) (types.ServiceConfig, error) { for name, r := range s.DependsOn { if !r.Restart { delete(s.DependsOn, name) @@ -83,7 +83,7 @@ func (s *composeService) restart(ctx context.Context, projectName string, option eventName := getContainerProgressName(ctr) w.Event(progress.RestartingEvent(eventName)) timeout := utils.DurationSecondToInt(options.Timeout) - err := s.apiClient().ContainerRestart(ctx, ctr.ID, containerType.StopOptions{Timeout: timeout}) + err := s.apiClient().ContainerRestart(ctx, ctr.ID, container.StopOptions{Timeout: timeout}) if err != nil { return err } diff --git a/pkg/compose/start.go b/pkg/compose/start.go index c45de4aed..06d73d9cc 100644 --- a/pkg/compose/start.go +++ b/pkg/compose/start.go @@ -31,7 +31,6 @@ import ( "github.com/docker/compose/v2/pkg/utils" "github.com/compose-spec/compose-go/v2/types" - moby "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "golang.org/x/sync/errgroup" ) @@ -85,26 +84,26 @@ func (s *composeService) start(ctx context.Context, projectName string, options // N.B. this uses the parent context (instead of attachCtx) so that the watch itself can // continue even if one of the log streams fails return s.watchContainers(ctx, project.Name, toWatch, required.Elements(), listener, containers, - func(container moby.Container, _ time.Time) error { - svc := container.Labels[api.ServiceLabel] + func(ctr containerType.Summary, _ time.Time) error { + svc := ctr.Labels[api.ServiceLabel] if attachTo.Has(svc) { - return s.attachContainer(attachCtx, container, listener) + return s.attachContainer(attachCtx, ctr, listener) } // HACK: simulate an "attach" event listener(api.ContainerEvent{ Type: api.ContainerEventAttach, - Container: getContainerNameWithoutProject(container), - ID: container.ID, + Container: getContainerNameWithoutProject(ctr), + ID: ctr.ID, Service: svc, }) return nil - }, func(container moby.Container, _ time.Time) error { + }, func(ctr containerType.Summary, _ time.Time) error { listener(api.ContainerEvent{ Type: api.ContainerEventAttach, Container: "", // actual name will be set by start event - ID: container.ID, - Service: container.Labels[api.ServiceLabel], + ID: ctr.ID, + Service: ctr.Labels[api.ServiceLabel], }) return nil }) @@ -175,7 +174,7 @@ func getDependencyCondition(service types.ServiceConfig, project *types.Project) return ServiceConditionRunningOrHealthy } -type containerWatchFn func(container moby.Container, t time.Time) error +type containerWatchFn func(ctr containerType.Summary, t time.Time) error // watchContainers uses engine events to capture container start/die and notify ContainerEventListener func (s *composeService) watchContainers(ctx context.Context, //nolint:gocyclo @@ -197,7 +196,7 @@ func (s *composeService) watchContainers(ctx context.Context, //nolint:gocyclo } // predicate to tell if a container we receive event for should be considered or ignored - ofInterest := func(c moby.Container) bool { + ofInterest := func(c containerType.Summary) bool { if len(services) > 0 { // we only watch some services return utils.Contains(services, c.Labels[api.ServiceLabel]) @@ -206,7 +205,7 @@ func (s *composeService) watchContainers(ctx context.Context, //nolint:gocyclo } // predicate to tell if a container we receive event for should be watched until termination - isRequired := func(c moby.Container) bool { + isRequired := func(c containerType.Summary) bool { if len(services) > 0 && len(required) > 0 { // we only watch some services return utils.Contains(required, c.Labels[api.ServiceLabel]) @@ -248,7 +247,7 @@ func (s *composeService) watchContainers(ctx context.Context, //nolint:gocyclo } return err } - container := moby.Container{ + container := containerType.Summary{ ID: inspected.ID, Names: []string{inspected.Name}, Labels: inspected.Config.Labels, diff --git a/pkg/compose/stop_test.go b/pkg/compose/stop_test.go index 8294b4deb..9c5d79ef7 100644 --- a/pkg/compose/stop_test.go +++ b/pkg/compose/stop_test.go @@ -22,17 +22,15 @@ import ( "testing" "time" - "github.com/docker/compose/v2/pkg/utils" - - compose "github.com/docker/compose/v2/pkg/api" - containerType "github.com/docker/docker/api/types/container" - - 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/network" "github.com/docker/docker/api/types/volume" "go.uber.org/mock/gomock" "gotest.tools/v3/assert" + + compose "github.com/docker/compose/v2/pkg/api" + "github.com/docker/compose/v2/pkg/utils" ) func TestStopTimeout(t *testing.T) { @@ -46,7 +44,7 @@ func TestStopTimeout(t *testing.T) { ctx := context.Background() api.EXPECT().ContainerList(gomock.Any(), projectFilterListOpt(false)).Return( - []moby.Container{ + []container.Summary{ testContainer("service1", "123", false), testContainer("service1", "456", false), testContainer("service2", "789", false), @@ -61,7 +59,7 @@ func TestStopTimeout(t *testing.T) { Return([]network.Summary{}, nil) timeout := 2 * time.Second - stopConfig := containerType.StopOptions{Timeout: utils.DurationSecondToInt(&timeout)} + 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) diff --git a/pkg/compose/watch.go b/pkg/compose/watch.go index b4edff9f4..31c811e77 100644 --- a/pkg/compose/watch.go +++ b/pkg/compose/watch.go @@ -35,7 +35,6 @@ import ( "github.com/docker/compose/v2/internal/sync" "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/watch" - 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" @@ -343,7 +342,7 @@ type tarDockerClient struct { s *composeService } -func (t tarDockerClient) ContainersForService(ctx context.Context, projectName string, serviceName string) ([]moby.Container, error) { +func (t tarDockerClient) ContainersForService(ctx context.Context, projectName string, serviceName string) ([]container.Summary, error) { containers, err := t.s.getContainers(ctx, projectName, oneOffExclude, true, serviceName) if err != nil { return nil, err @@ -724,7 +723,7 @@ func (s *composeService) imageCreatedTime(ctx context.Context, project *types.Pr return time.Now(), fmt.Errorf("Could not get created time for service's image") } - img, _, err := s.apiClient().ImageInspectWithRaw(ctx, containers[0].ImageID) + img, err := s.apiClient().ImageInspect(ctx, containers[0].ImageID) if err != nil { return time.Now(), err } diff --git a/pkg/compose/watch_test.go b/pkg/compose/watch_test.go index e123ecd21..e7492f2bc 100644 --- a/pkg/compose/watch_test.go +++ b/pkg/compose/watch_test.go @@ -27,7 +27,7 @@ import ( "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/mocks" "github.com/docker/compose/v2/pkg/watch" - 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/jonboulle/clockwork" @@ -67,11 +67,11 @@ func (s stdLogger) Err(containerName, message string) { fmt.Fprintf(os.Stderr, "%s: %s\n", containerName, message) } -func (s stdLogger) Status(container, msg string) { - fmt.Printf("%s: %s\n", container, msg) +func (s stdLogger) Status(containerName, msg string) { + fmt.Printf("%s: %s\n", containerName, msg) } -func (s stdLogger) Register(container string) { +func (s stdLogger) Register(containerName string) { } func TestWatch_Sync(t *testing.T) { @@ -79,7 +79,7 @@ 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([]moby.Container{ + apiClient.EXPECT().ContainerList(gomock.Any(), gomock.Any()).Return([]container.Summary{ testContainer("test", "123", false), }, nil).AnyTimes() // we expect the image to be pruned diff --git a/pkg/mocks/mock_docker_api.go b/pkg/mocks/mock_docker_api.go index 7365d6513..fe6caf01b 100644 --- a/pkg/mocks/mock_docker_api.go +++ b/pkg/mocks/mock_docker_api.go @@ -27,6 +27,7 @@ import ( swarm "github.com/docker/docker/api/types/swarm" system "github.com/docker/docker/api/types/system" volume "github.com/docker/docker/api/types/volume" + client "github.com/docker/docker/client" v1 "github.com/opencontainers/image-spec/specs-go/v1" gomock "go.uber.org/mock/gomock" ) @@ -244,10 +245,10 @@ func (mr *MockAPIClientMockRecorder) ContainerAttach(arg0, arg1, arg2 any) *gomo } // ContainerCommit mocks base method. -func (m *MockAPIClient) ContainerCommit(arg0 context.Context, arg1 string, arg2 container.CommitOptions) (types.IDResponse, error) { +func (m *MockAPIClient) ContainerCommit(arg0 context.Context, arg1 string, arg2 container.CommitOptions) (container.CommitResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ContainerCommit", arg0, arg1, arg2) - ret0, _ := ret[0].(types.IDResponse) + ret0, _ := ret[0].(container.CommitResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -304,10 +305,10 @@ func (mr *MockAPIClientMockRecorder) ContainerExecAttach(arg0, arg1, arg2 any) * } // ContainerExecCreate mocks base method. -func (m *MockAPIClient) ContainerExecCreate(arg0 context.Context, arg1 string, arg2 container.ExecOptions) (types.IDResponse, error) { +func (m *MockAPIClient) ContainerExecCreate(arg0 context.Context, arg1 string, arg2 container.ExecOptions) (container.ExecCreateResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ContainerExecCreate", arg0, arg1, arg2) - ret0, _ := ret[0].(types.IDResponse) + ret0, _ := ret[0].(container.ExecCreateResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -377,10 +378,10 @@ func (mr *MockAPIClientMockRecorder) ContainerExport(arg0, arg1 any) *gomock.Cal } // ContainerInspect mocks base method. -func (m *MockAPIClient) ContainerInspect(arg0 context.Context, arg1 string) (types.ContainerJSON, error) { +func (m *MockAPIClient) ContainerInspect(arg0 context.Context, arg1 string) (container.InspectResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ContainerInspect", arg0, arg1) - ret0, _ := ret[0].(types.ContainerJSON) + ret0, _ := ret[0].(container.InspectResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -392,10 +393,10 @@ func (mr *MockAPIClientMockRecorder) ContainerInspect(arg0, arg1 any) *gomock.Ca } // ContainerInspectWithRaw mocks base method. -func (m *MockAPIClient) ContainerInspectWithRaw(arg0 context.Context, arg1 string, arg2 bool) (types.ContainerJSON, []byte, error) { +func (m *MockAPIClient) ContainerInspectWithRaw(arg0 context.Context, arg1 string, arg2 bool) (container.InspectResponse, []byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ContainerInspectWithRaw", arg0, arg1, arg2) - ret0, _ := ret[0].(types.ContainerJSON) + ret0, _ := ret[0].(container.InspectResponse) ret1, _ := ret[1].([]byte) ret2, _ := ret[2].(error) return ret0, ret1, ret2 @@ -422,10 +423,10 @@ func (mr *MockAPIClientMockRecorder) ContainerKill(arg0, arg1, arg2 any) *gomock } // ContainerList mocks base method. -func (m *MockAPIClient) ContainerList(arg0 context.Context, arg1 container.ListOptions) ([]types.Container, error) { +func (m *MockAPIClient) ContainerList(arg0 context.Context, arg1 container.ListOptions) ([]container.Summary, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ContainerList", arg0, arg1) - ret0, _ := ret[0].([]types.Container) + ret0, _ := ret[0].([]container.Summary) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -595,10 +596,10 @@ func (mr *MockAPIClientMockRecorder) ContainerStop(arg0, arg1, arg2 any) *gomock } // ContainerTop mocks base method. -func (m *MockAPIClient) ContainerTop(arg0 context.Context, arg1 string, arg2 []string) (container.ContainerTopOKBody, error) { +func (m *MockAPIClient) ContainerTop(arg0 context.Context, arg1 string, arg2 []string) (container.TopResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ContainerTop", arg0, arg1, arg2) - ret0, _ := ret[0].(container.ContainerTopOKBody) + ret0, _ := ret[0].(container.TopResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -624,10 +625,10 @@ func (mr *MockAPIClientMockRecorder) ContainerUnpause(arg0, arg1 any) *gomock.Ca } // ContainerUpdate mocks base method. -func (m *MockAPIClient) ContainerUpdate(arg0 context.Context, arg1 string, arg2 container.UpdateConfig) (container.ContainerUpdateOKBody, error) { +func (m *MockAPIClient) ContainerUpdate(arg0 context.Context, arg1 string, arg2 container.UpdateConfig) (container.UpdateResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ContainerUpdate", arg0, arg1, arg2) - ret0, _ := ret[0].(container.ContainerUpdateOKBody) + ret0, _ := ret[0].(container.UpdateResponse) ret1, _ := ret[1].(error) return ret0, ret1 } @@ -831,18 +832,23 @@ func (mr *MockAPIClientMockRecorder) ImageCreate(arg0, arg1, arg2 any) *gomock.C } // ImageHistory mocks base method. -func (m *MockAPIClient) ImageHistory(arg0 context.Context, arg1 string) ([]image.HistoryResponseItem, error) { +func (m *MockAPIClient) ImageHistory(arg0 context.Context, arg1 string, arg2 ...client.ImageHistoryOption) ([]image.HistoryResponseItem, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ImageHistory", arg0, arg1) + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ImageHistory", varargs...) ret0, _ := ret[0].([]image.HistoryResponseItem) ret1, _ := ret[1].(error) return ret0, ret1 } // ImageHistory indicates an expected call of ImageHistory. -func (mr *MockAPIClientMockRecorder) ImageHistory(arg0, arg1 any) *gomock.Call { +func (mr *MockAPIClientMockRecorder) ImageHistory(arg0, arg1 any, arg2 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageHistory", reflect.TypeOf((*MockAPIClient)(nil).ImageHistory), arg0, arg1) + varargs := append([]any{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageHistory", reflect.TypeOf((*MockAPIClient)(nil).ImageHistory), varargs...) } // ImageImport mocks base method. @@ -860,11 +866,31 @@ func (mr *MockAPIClientMockRecorder) ImageImport(arg0, arg1, arg2, arg3 any) *go return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageImport", reflect.TypeOf((*MockAPIClient)(nil).ImageImport), arg0, arg1, arg2, arg3) } +// ImageInspect mocks base method. +func (m *MockAPIClient) ImageInspect(arg0 context.Context, arg1 string, arg2 ...client.ImageInspectOption) (image.InspectResponse, error) { + m.ctrl.T.Helper() + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ImageInspect", varargs...) + ret0, _ := ret[0].(image.InspectResponse) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ImageInspect indicates an expected call of ImageInspect. +func (mr *MockAPIClientMockRecorder) ImageInspect(arg0, arg1 any, arg2 ...any) *gomock.Call { + mr.mock.ctrl.T.Helper() + varargs := append([]any{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageInspect", reflect.TypeOf((*MockAPIClient)(nil).ImageInspect), varargs...) +} + // ImageInspectWithRaw mocks base method. -func (m *MockAPIClient) ImageInspectWithRaw(arg0 context.Context, arg1 string) (types.ImageInspect, []byte, error) { +func (m *MockAPIClient) ImageInspectWithRaw(arg0 context.Context, arg1 string) (image.InspectResponse, []byte, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "ImageInspectWithRaw", arg0, arg1) - ret0, _ := ret[0].(types.ImageInspect) + ret0, _ := ret[0].(image.InspectResponse) ret1, _ := ret[1].([]byte) ret2, _ := ret[2].(error) return ret0, ret1, ret2 @@ -892,18 +918,23 @@ func (mr *MockAPIClientMockRecorder) ImageList(arg0, arg1 any) *gomock.Call { } // ImageLoad mocks base method. -func (m *MockAPIClient) ImageLoad(arg0 context.Context, arg1 io.Reader, arg2 bool) (image.LoadResponse, error) { +func (m *MockAPIClient) ImageLoad(arg0 context.Context, arg1 io.Reader, arg2 ...client.ImageLoadOption) (image.LoadResponse, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ImageLoad", arg0, arg1, arg2) + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ImageLoad", varargs...) ret0, _ := ret[0].(image.LoadResponse) ret1, _ := ret[1].(error) return ret0, ret1 } // ImageLoad indicates an expected call of ImageLoad. -func (mr *MockAPIClientMockRecorder) ImageLoad(arg0, arg1, arg2 any) *gomock.Call { +func (mr *MockAPIClientMockRecorder) ImageLoad(arg0, arg1 any, arg2 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageLoad", reflect.TypeOf((*MockAPIClient)(nil).ImageLoad), arg0, arg1, arg2) + varargs := append([]any{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageLoad", reflect.TypeOf((*MockAPIClient)(nil).ImageLoad), varargs...) } // ImagePull mocks base method. @@ -952,18 +983,23 @@ func (mr *MockAPIClientMockRecorder) ImageRemove(arg0, arg1, arg2 any) *gomock.C } // ImageSave mocks base method. -func (m *MockAPIClient) ImageSave(arg0 context.Context, arg1 []string) (io.ReadCloser, error) { +func (m *MockAPIClient) ImageSave(arg0 context.Context, arg1 []string, arg2 ...client.ImageSaveOption) (io.ReadCloser, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ImageSave", arg0, arg1) + varargs := []any{arg0, arg1} + for _, a := range arg2 { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ImageSave", varargs...) ret0, _ := ret[0].(io.ReadCloser) ret1, _ := ret[1].(error) return ret0, ret1 } // ImageSave indicates an expected call of ImageSave. -func (mr *MockAPIClientMockRecorder) ImageSave(arg0, arg1 any) *gomock.Call { +func (mr *MockAPIClientMockRecorder) ImageSave(arg0, arg1 any, arg2 ...any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageSave", reflect.TypeOf((*MockAPIClient)(nil).ImageSave), arg0, arg1) + varargs := append([]any{arg0, arg1}, arg2...) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ImageSave", reflect.TypeOf((*MockAPIClient)(nil).ImageSave), varargs...) } // ImageSearch mocks base method.