Sfoglia il codice sorgente

Merge pull request #9004 from ndeloof/cp_stopped

compose cp doesn't need a full project and can copy from stopped containers
Ulysses Souza 3 anni fa
parent
commit
9e52e9fbe3
5 ha cambiato i file con 21 aggiunte e 20 eliminazioni
  1. 2 2
      cmd/compose/cp.go
  2. 1 1
      pkg/api/api.go
  3. 2 5
      pkg/api/proxy.go
  4. 9 0
      pkg/compose/containers.go
  5. 7 12
      pkg/compose/cp.go

+ 2 - 2
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,

+ 1 - 1
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`

+ 2 - 5
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)
 }
 

+ 9 - 0
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

+ 7 - 12
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{}