mirror of https://github.com/docker/compose.git
				
				
				
			Merge pull request #10235 from glours/dry-run-cp-support
support dry-run for cp command
This commit is contained in:
		
						commit
						23585b9e6d
					
				|  | @ -18,9 +18,11 @@ package api | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 	"net" | 	"net" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	moby "github.com/docker/docker/api/types" | 	moby "github.com/docker/docker/api/types" | ||||||
| 	containerType "github.com/docker/docker/api/types/container" | 	containerType "github.com/docker/docker/api/types/container" | ||||||
|  | @ -35,6 +37,10 @@ import ( | ||||||
| 	specs "github.com/opencontainers/image-spec/specs-go/v1" | 	specs "github.com/opencontainers/image-spec/specs-go/v1" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | const ( | ||||||
|  | 	DRYRUN_PREFIX = " DRY-RUN MODE - " | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| var _ client.APIClient = &DryRunClient{} | var _ client.APIClient = &DryRunClient{} | ||||||
| 
 | 
 | ||||||
| type DryRunKey struct{} | type DryRunKey struct{} | ||||||
|  | @ -95,11 +101,18 @@ func (d *DryRunClient) ContainerUnpause(ctx context.Context, container string) e | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (d *DryRunClient) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, moby.ContainerPathStat, error) { | func (d *DryRunClient) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, moby.ContainerPathStat, error) { | ||||||
| 	return nil, moby.ContainerPathStat{}, ErrNotImplemented | 	rc := io.NopCloser(strings.NewReader("")) | ||||||
|  | 	if _, err := d.ContainerStatPath(ctx, container, srcPath); err != nil { | ||||||
|  | 		return rc, moby.ContainerPathStat{}, fmt.Errorf(" %s Could not find the file %s in container %s", DRYRUN_PREFIX, srcPath, container) | ||||||
|  | 	} | ||||||
|  | 	return rc, moby.ContainerPathStat{}, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (d *DryRunClient) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options moby.CopyToContainerOptions) error { | func (d *DryRunClient) CopyToContainer(ctx context.Context, container, path string, content io.Reader, options moby.CopyToContainerOptions) error { | ||||||
| 	return ErrNotImplemented | 	if _, err := d.ContainerStatPath(ctx, container, path); err != nil { | ||||||
|  | 		return fmt.Errorf(" %s Could not find the file %s in container %s", DRYRUN_PREFIX, path, container) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (d *DryRunClient) ImageBuild(ctx context.Context, reader io.Reader, options moby.ImageBuildOptions) (moby.ImageBuildResponse, error) { | func (d *DryRunClient) ImageBuild(ctx context.Context, reader io.Reader, options moby.ImageBuildOptions) (moby.ImageBuildResponse, error) { | ||||||
|  |  | ||||||
|  | @ -67,6 +67,7 @@ func (s *composeService) MaxConcurrency(i int) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (s *composeService) DryRunMode(ctx context.Context, dryRun bool) (context.Context, error) { | func (s *composeService) DryRunMode(ctx context.Context, dryRun bool) (context.Context, error) { | ||||||
|  | 	s.dryRun = dryRun | ||||||
| 	if dryRun { | 	if dryRun { | ||||||
| 		cli, err := command.NewDockerCli() | 		cli, err := command.NewDockerCli() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  |  | ||||||
|  | @ -79,10 +79,18 @@ func (s *composeService) Copy(ctx context.Context, projectName string, options a | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	g := errgroup.Group{} | 	g := errgroup.Group{} | ||||||
| 	for _, container := range containers { | 	for _, cont := range containers { | ||||||
| 		containerID := container.ID | 		container := cont | ||||||
| 		g.Go(func() error { | 		g.Go(func() error { | ||||||
| 			return copyFunc(ctx, containerID, srcPath, dstPath, options) | 			if err := copyFunc(ctx, container.ID, srcPath, dstPath, options); err != nil { | ||||||
|  | 				return err | ||||||
|  | 			} | ||||||
|  | 			fromOrInside := "inside" | ||||||
|  | 			if direction == fromService { | ||||||
|  | 				fromOrInside = "from" | ||||||
|  | 			} | ||||||
|  | 			fmt.Fprintf(s.stderr(), "Copy %s to path %s %s %s service container\n", srcPath, dstPath, fromOrInside, getCanonicalContainerName(container)) | ||||||
|  | 			return nil | ||||||
| 		}) | 		}) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -194,14 +202,17 @@ func (s *composeService) copyToContainer(ctx context.Context, containerID string | ||||||
| 		// extracted. This function also infers from the source and destination
 | 		// extracted. This function also infers from the source and destination
 | ||||||
| 		// info which directory to extract to, which may be the parent of the
 | 		// info which directory to extract to, which may be the parent of the
 | ||||||
| 		// destination that the user specified.
 | 		// destination that the user specified.
 | ||||||
| 		dstDir, preparedArchive, err := archive.PrepareArchiveCopy(srcArchive, srcInfo, dstInfo) | 		// Don't create the archive if running in Dry Run mode
 | ||||||
| 		if err != nil { | 		if !s.dryRun { | ||||||
| 			return err | 			dstDir, preparedArchive, err := archive.PrepareArchiveCopy(srcArchive, srcInfo, dstInfo) | ||||||
| 		} | 			if err != nil { | ||||||
| 		defer preparedArchive.Close() //nolint:errcheck
 | 				return err | ||||||
|  | 			} | ||||||
|  | 			defer preparedArchive.Close() //nolint:errcheck
 | ||||||
| 
 | 
 | ||||||
| 		resolvedDstPath = dstDir | 			resolvedDstPath = dstDir | ||||||
| 		content = preparedArchive | 			content = preparedArchive | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	options := moby.CopyToContainerOptions{ | 	options := moby.CopyToContainerOptions{ | ||||||
|  |  | ||||||
|  | @ -20,6 +20,8 @@ import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
|  | 
 | ||||||
|  | 	"github.com/docker/compose/v2/pkg/api" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type plainWriter struct { | type plainWriter struct { | ||||||
|  | @ -40,7 +42,7 @@ func (p *plainWriter) Start(ctx context.Context) error { | ||||||
| func (p *plainWriter) Event(e Event) { | func (p *plainWriter) Event(e Event) { | ||||||
| 	prefix := "" | 	prefix := "" | ||||||
| 	if p.dryRun { | 	if p.dryRun { | ||||||
| 		prefix = "DRY RUN MODE - " | 		prefix = api.DRYRUN_PREFIX | ||||||
| 	} | 	} | ||||||
| 	fmt.Fprintln(p.out, prefix, e.ID, e.Text, e.StatusText) | 	fmt.Fprintln(p.out, prefix, e.ID, e.Text, e.StatusText) | ||||||
| } | } | ||||||
|  | @ -54,7 +56,7 @@ func (p *plainWriter) Events(events []Event) { | ||||||
| func (p *plainWriter) TailMsgf(m string, args ...interface{}) { | func (p *plainWriter) TailMsgf(m string, args ...interface{}) { | ||||||
| 	prefix := "" | 	prefix := "" | ||||||
| 	if p.dryRun { | 	if p.dryRun { | ||||||
| 		prefix = DRYRUN_PREFIX | 		prefix = api.DRYRUN_PREFIX | ||||||
| 	} | 	} | ||||||
| 	fmt.Fprintln(p.out, append([]interface{}{prefix, m}, args...)...) | 	fmt.Fprintln(p.out, append([]interface{}{prefix, m}, args...)...) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -25,6 +25,7 @@ import ( | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/docker/compose/v2/pkg/api" | ||||||
| 	"github.com/docker/compose/v2/pkg/utils" | 	"github.com/docker/compose/v2/pkg/utils" | ||||||
| 
 | 
 | ||||||
| 	"github.com/buger/goterm" | 	"github.com/buger/goterm" | ||||||
|  | @ -110,7 +111,7 @@ func (w *ttyWriter) TailMsgf(msg string, args ...interface{}) { | ||||||
| 	defer w.mtx.Unlock() | 	defer w.mtx.Unlock() | ||||||
| 	msgWithPrefix := msg | 	msgWithPrefix := msg | ||||||
| 	if w.dryRun { | 	if w.dryRun { | ||||||
| 		msgWithPrefix = strings.TrimSpace(DRYRUN_PREFIX + msg) | 		msgWithPrefix = strings.TrimSpace(api.DRYRUN_PREFIX + msg) | ||||||
| 	} | 	} | ||||||
| 	w.tailEvents = append(w.tailEvents, fmt.Sprintf(msgWithPrefix, args...)) | 	w.tailEvents = append(w.tailEvents, fmt.Sprintf(msgWithPrefix, args...)) | ||||||
| } | } | ||||||
|  | @ -206,7 +207,7 @@ func lineText(event Event, pad string, terminalWidth, statusPadding int, color b | ||||||
| 	} | 	} | ||||||
| 	prefix := "" | 	prefix := "" | ||||||
| 	if dryRun { | 	if dryRun { | ||||||
| 		prefix = DRYRUN_PREFIX | 		prefix = api.DRYRUN_PREFIX | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	elapsed := endTime.Sub(event.startTime).Seconds() | 	elapsed := endTime.Sub(event.startTime).Seconds() | ||||||
|  |  | ||||||
|  | @ -28,10 +28,6 @@ import ( | ||||||
| 	"golang.org/x/sync/errgroup" | 	"golang.org/x/sync/errgroup" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( |  | ||||||
| 	DRYRUN_PREFIX = " DRY-RUN MODE - " |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Writer can write multiple progress events
 | // Writer can write multiple progress events
 | ||||||
| type Writer interface { | type Writer interface { | ||||||
| 	Start(context.Context) error | 	Start(context.Context) error | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue