1
0
mirror of https://github.com/docker/compose.git synced 2025-04-08 17:05:13 +02:00

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 <nicolas.deloof@gmail.com>
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2025-02-12 09:34:07 +01:00 committed by Nicolas De loof
parent d0398a4681
commit cf2fc2005c
40 changed files with 417 additions and 382 deletions

@ -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),

6
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

12
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=

@ -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

@ -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{

@ -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 {

@ -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)

@ -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)

@ -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,

@ -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)

@ -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)
}

@ -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
}

@ -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{

@ -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 {

@ -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
})

@ -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,
})

@ -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)

@ -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)
}

@ -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)

@ -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
}

@ -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"

@ -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

@ -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,
}

@ -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()
}

@ -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,
}

@ -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,

@ -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,

@ -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)

@ -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)
}

@ -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

@ -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)
}

@ -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
}

@ -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
}

@ -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,
})

@ -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
}

@ -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,

@ -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)

@ -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
}

@ -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

@ -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.