diff --git a/cmd/compose/cp.go b/cmd/compose/cp.go index f028a790b..e38b9de42 100644 --- a/cmd/compose/cp.go +++ b/cmd/compose/cp.go @@ -73,12 +73,12 @@ func copyCommand(p *projectOptions, backend api.Service) *cobra.Command { } func runCopy(ctx context.Context, backend api.Service, opts copyOptions) error { - projects, err := opts.toProject(nil) + name, err := opts.toProjectName() if err != nil { return err } - return backend.Copy(ctx, projects, api.CopyOptions{ + return backend.Copy(ctx, name, api.CopyOptions{ Source: opts.source, Destination: opts.destination, All: opts.all, diff --git a/pkg/api/api.go b/pkg/api/api.go index 78b30202a..5d963569c 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -63,7 +63,7 @@ type Service interface { // Exec executes a command in a running service container Exec(ctx context.Context, project string, opts RunOptions) (int, error) // Copy copies a file/folder between a service container and the local filesystem - Copy(ctx context.Context, project *types.Project, opts CopyOptions) error + Copy(ctx context.Context, project string, options CopyOptions) error // Pause executes the equivalent to a `compose pause` Pause(ctx context.Context, project string, options PauseOptions) error // UnPause executes the equivalent to a `compose unpause` diff --git a/pkg/api/proxy.go b/pkg/api/proxy.go index aff81e1f4..6c3fe22f3 100644 --- a/pkg/api/proxy.go +++ b/pkg/api/proxy.go @@ -41,7 +41,7 @@ type ServiceProxy struct { RunOneOffContainerFn func(ctx context.Context, project *types.Project, opts RunOptions) (int, error) RemoveFn func(ctx context.Context, project *types.Project, options RemoveOptions) error ExecFn func(ctx context.Context, project string, opts RunOptions) (int, error) - CopyFn func(ctx context.Context, project *types.Project, opts CopyOptions) error + CopyFn func(ctx context.Context, project string, options CopyOptions) error PauseFn func(ctx context.Context, project string, options PauseOptions) error UnPauseFn func(ctx context.Context, project string, options PauseOptions) error TopFn func(ctx context.Context, projectName string, services []string) ([]ContainerProcSummary, error) @@ -269,13 +269,10 @@ func (s *ServiceProxy) Exec(ctx context.Context, project string, options RunOpti } // Copy implements Service interface -func (s *ServiceProxy) Copy(ctx context.Context, project *types.Project, options CopyOptions) error { +func (s *ServiceProxy) Copy(ctx context.Context, project string, options CopyOptions) error { if s.CopyFn == nil { return ErrNotImplemented } - for _, i := range s.interceptors { - i(ctx, project) - } return s.CopyFn(ctx, project, options) } diff --git a/pkg/compose/containers.go b/pkg/compose/containers.go index 5037a0116..25e1fabbc 100644 --- a/pkg/compose/containers.go +++ b/pkg/compose/containers.go @@ -19,6 +19,7 @@ package compose import ( "context" "sort" + "strconv" moby "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" @@ -86,6 +87,14 @@ func isNotOneOff(c moby.Container) bool { return !ok || v == "False" } +func indexed(index int) containerPredicate { + return func(c moby.Container) bool { + number := c.Labels[api.ContainerNumberLabel] + idx, err := strconv.Atoi(number) + return err == nil && index == idx + } +} + // filter return Containers with elements to match predicate func (containers Containers) filter(predicate containerPredicate) Containers { var filtered Containers diff --git a/pkg/compose/cp.go b/pkg/compose/cp.go index 28d923a91..435c96014 100644 --- a/pkg/compose/cp.go +++ b/pkg/compose/cp.go @@ -26,11 +26,9 @@ import ( "golang.org/x/sync/errgroup" - "github.com/compose-spec/compose-go/types" "github.com/docker/cli/cli/command" "github.com/docker/compose/v2/pkg/api" moby "github.com/docker/docker/api/types" - "github.com/docker/docker/api/types/filters" "github.com/docker/docker/pkg/archive" "github.com/docker/docker/pkg/system" "github.com/pkg/errors" @@ -44,7 +42,7 @@ const ( acrossServices = fromService | toService ) -func (s *composeService) Copy(ctx context.Context, project *types.Project, opts api.CopyOptions) error { +func (s *composeService) Copy(ctx context.Context, project string, opts api.CopyOptions) error { srcService, srcPath := splitCpArg(opts.Source) destService, dstPath := splitCpArg(opts.Destination) @@ -64,20 +62,17 @@ func (s *composeService) Copy(ctx context.Context, project *types.Project, opts serviceName = destService } - f := filters.NewArgs( - projectFilter(project.Name), - serviceFilter(serviceName), - ) - if !opts.All { - f.Add("label", fmt.Sprintf("%s=%d", api.ContainerNumberLabel, opts.Index)) - } - containers, err := s.apiClient.ContainerList(ctx, moby.ContainerListOptions{Filters: f}) + containers, err := s.getContainers(ctx, project, oneOffExclude, true, serviceName) if err != nil { return err } if len(containers) < 1 { - return fmt.Errorf("service %s not running", serviceName) + return fmt.Errorf("no container found for service %q", serviceName) + } + + if !opts.All { + containers = containers.filter(indexed(opts.Index)) } g := errgroup.Group{}