|
@@ -49,60 +49,71 @@ func (s *composeService) Copy(ctx context.Context, projectName string, options a
|
|
|
|
|
|
var direction copyDirection
|
|
|
var serviceName string
|
|
|
+ var copyFunc func(ctx context.Context, containerID string, srcPath string, dstPath string, opts api.CopyOptions) error
|
|
|
if srcService != "" {
|
|
|
direction |= fromService
|
|
|
serviceName = srcService
|
|
|
+ copyFunc = s.copyFromContainer
|
|
|
|
|
|
// copying from multiple containers of a services doesn't make sense.
|
|
|
if options.All {
|
|
|
return errors.New("cannot use the --all flag when copying from a service")
|
|
|
}
|
|
|
- // due to remove of the --all flag, restore the default value to 1 when copying from a service container to the host.
|
|
|
- if options.Index == 0 {
|
|
|
- options.Index = 1
|
|
|
- }
|
|
|
}
|
|
|
if destService != "" {
|
|
|
direction |= toService
|
|
|
serviceName = destService
|
|
|
+ copyFunc = s.copyToContainer
|
|
|
+ }
|
|
|
+ if direction == acrossServices {
|
|
|
+ return errors.New("copying between services is not supported")
|
|
|
+ }
|
|
|
+
|
|
|
+ if direction == 0 {
|
|
|
+ return errors.New("unknown copy direction")
|
|
|
+ }
|
|
|
+
|
|
|
+ containers, err := s.listContainersTargetedForCopy(ctx, projectName, options.Index, direction, serviceName)
|
|
|
+ if err != nil {
|
|
|
+ return err
|
|
|
}
|
|
|
+
|
|
|
+ g := errgroup.Group{}
|
|
|
+ for _, container := range containers {
|
|
|
+ containerID := container.ID
|
|
|
+ g.Go(func() error {
|
|
|
+ return copyFunc(ctx, containerID, srcPath, dstPath, options)
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ return g.Wait()
|
|
|
+}
|
|
|
+
|
|
|
+func (s *composeService) listContainersTargetedForCopy(ctx context.Context, projectName string, index int, direction copyDirection, serviceName string) (Containers, error) {
|
|
|
var containers Containers
|
|
|
var err error
|
|
|
- if direction == fromService || (direction == toService && options.Index > 0) {
|
|
|
- container, err := s.getSpecifiedContainer(ctx, projectName, oneOffExclude, true, serviceName, options.Index)
|
|
|
+ switch {
|
|
|
+ case index > 0:
|
|
|
+ container, err := s.getSpecifiedContainer(ctx, projectName, oneOffExclude, true, serviceName, index)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return nil, err
|
|
|
}
|
|
|
- containers = append(containers, container)
|
|
|
- } else {
|
|
|
+ return append(containers, container), nil
|
|
|
+ default:
|
|
|
containers, err = s.getContainers(ctx, projectName, oneOffExclude, true, serviceName)
|
|
|
if err != nil {
|
|
|
- return err
|
|
|
+ return nil, err
|
|
|
}
|
|
|
|
|
|
if len(containers) < 1 {
|
|
|
- return fmt.Errorf("no container found for service %q", serviceName)
|
|
|
+ return nil, fmt.Errorf("no container found for service %q", serviceName)
|
|
|
}
|
|
|
- }
|
|
|
+ if direction == fromService {
|
|
|
+ return containers[:1], err
|
|
|
|
|
|
- g := errgroup.Group{}
|
|
|
- for _, container := range containers {
|
|
|
- containerID := container.ID
|
|
|
- g.Go(func() error {
|
|
|
- switch direction {
|
|
|
- case fromService:
|
|
|
- return s.copyFromContainer(ctx, containerID, srcPath, dstPath, options)
|
|
|
- case toService:
|
|
|
- return s.copyToContainer(ctx, containerID, srcPath, dstPath, options)
|
|
|
- case acrossServices:
|
|
|
- return errors.New("copying between services is not supported")
|
|
|
- default:
|
|
|
- return errors.New("unknown copy direction")
|
|
|
- }
|
|
|
- })
|
|
|
+ }
|
|
|
+ return containers, err
|
|
|
}
|
|
|
-
|
|
|
- return g.Wait()
|
|
|
}
|
|
|
|
|
|
func (s *composeService) copyToContainer(ctx context.Context, containerID string, srcPath string, dstPath string, opts api.CopyOptions) error {
|