From 2336d9fe35714f6d5f73e9e9762cd4ff3475b18e Mon Sep 17 00:00:00 2001 From: Guillaume Lours <705411+glours@users.noreply.github.com> Date: Fri, 3 Feb 2023 12:51:52 +0100 Subject: [PATCH 1/2] support dry-run for cp command Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com> --- pkg/api/dryrunclient.go | 17 +++++++++++++++-- pkg/compose/compose.go | 1 + pkg/compose/cp.go | 31 +++++++++++++++++++++---------- pkg/progress/plain.go | 6 ++++-- pkg/progress/tty.go | 5 +++-- pkg/progress/writer.go | 4 ---- 6 files changed, 44 insertions(+), 20 deletions(-) diff --git a/pkg/api/dryrunclient.go b/pkg/api/dryrunclient.go index a5ff50999..18a0f49ca 100644 --- a/pkg/api/dryrunclient.go +++ b/pkg/api/dryrunclient.go @@ -18,9 +18,11 @@ package api import ( "context" + "fmt" "io" "net" "net/http" + "strings" moby "github.com/docker/docker/api/types" containerType "github.com/docker/docker/api/types/container" @@ -35,6 +37,10 @@ import ( specs "github.com/opencontainers/image-spec/specs-go/v1" ) +const ( + DRYRUN_PREFIX = " DRY-RUN MODE - " +) + var _ client.APIClient = &DryRunClient{} 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) { - 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 { - 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) { diff --git a/pkg/compose/compose.go b/pkg/compose/compose.go index 3bb40c8f1..d54f48636 100644 --- a/pkg/compose/compose.go +++ b/pkg/compose/compose.go @@ -67,6 +67,7 @@ func (s *composeService) MaxConcurrency(i int) { } func (s *composeService) DryRunMode(ctx context.Context, dryRun bool) (context.Context, error) { + s.dryRun = dryRun if dryRun { cli, err := command.NewDockerCli() if err != nil { diff --git a/pkg/compose/cp.go b/pkg/compose/cp.go index d7fcd89e5..8cdfce4c4 100644 --- a/pkg/compose/cp.go +++ b/pkg/compose/cp.go @@ -79,10 +79,18 @@ func (s *composeService) Copy(ctx context.Context, projectName string, options a } g := errgroup.Group{} - for _, container := range containers { - containerID := container.ID + for _, cont := range containers { + container := cont g.Go(func() error { - return copyFunc(ctx, containerID, srcPath, dstPath, options) + err := copyFunc(ctx, container.ID, srcPath, dstPath, options) + if s.dryRun && err == nil { + fromOrInside := "inside" + if direction == fromService { + fromOrInside = "from" + } + fmt.Printf("Copy %s to path %s %s %s service container\n", srcPath, dstPath, fromOrInside, getCanonicalContainerName(container)) + } + return err }) } @@ -194,14 +202,17 @@ func (s *composeService) copyToContainer(ctx context.Context, containerID string // extracted. This function also infers from the source and destination // info which directory to extract to, which may be the parent of the // destination that the user specified. - dstDir, preparedArchive, err := archive.PrepareArchiveCopy(srcArchive, srcInfo, dstInfo) - if err != nil { - return err - } - defer preparedArchive.Close() //nolint:errcheck + // Don't create the archive if running in Dry Run mode + if !s.dryRun { + dstDir, preparedArchive, err := archive.PrepareArchiveCopy(srcArchive, srcInfo, dstInfo) + if err != nil { + return err + } + defer preparedArchive.Close() //nolint:errcheck - resolvedDstPath = dstDir - content = preparedArchive + resolvedDstPath = dstDir + content = preparedArchive + } } options := moby.CopyToContainerOptions{ diff --git a/pkg/progress/plain.go b/pkg/progress/plain.go index ce20a01f9..48483ee0c 100644 --- a/pkg/progress/plain.go +++ b/pkg/progress/plain.go @@ -20,6 +20,8 @@ import ( "context" "fmt" "io" + + "github.com/docker/compose/v2/pkg/api" ) type plainWriter struct { @@ -40,7 +42,7 @@ func (p *plainWriter) Start(ctx context.Context) error { func (p *plainWriter) Event(e Event) { prefix := "" if p.dryRun { - prefix = "DRY RUN MODE - " + prefix = api.DRYRUN_PREFIX } 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{}) { prefix := "" if p.dryRun { - prefix = DRYRUN_PREFIX + prefix = api.DRYRUN_PREFIX } fmt.Fprintln(p.out, append([]interface{}{prefix, m}, args...)...) } diff --git a/pkg/progress/tty.go b/pkg/progress/tty.go index 9352ac0a7..f9b6ee50e 100644 --- a/pkg/progress/tty.go +++ b/pkg/progress/tty.go @@ -25,6 +25,7 @@ import ( "sync" "time" + "github.com/docker/compose/v2/pkg/api" "github.com/docker/compose/v2/pkg/utils" "github.com/buger/goterm" @@ -110,7 +111,7 @@ func (w *ttyWriter) TailMsgf(msg string, args ...interface{}) { defer w.mtx.Unlock() msgWithPrefix := msg 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...)) } @@ -206,7 +207,7 @@ func lineText(event Event, pad string, terminalWidth, statusPadding int, color b } prefix := "" if dryRun { - prefix = DRYRUN_PREFIX + prefix = api.DRYRUN_PREFIX } elapsed := endTime.Sub(event.startTime).Seconds() diff --git a/pkg/progress/writer.go b/pkg/progress/writer.go index 8858c0734..62c4bd200 100644 --- a/pkg/progress/writer.go +++ b/pkg/progress/writer.go @@ -28,10 +28,6 @@ import ( "golang.org/x/sync/errgroup" ) -const ( - DRYRUN_PREFIX = " DRY-RUN MODE - " -) - // Writer can write multiple progress events type Writer interface { Start(context.Context) error From fdc1738143b0b110a8883c13b3c1abfce1d1795f Mon Sep 17 00:00:00 2001 From: Guillaume Lours <705411+glours@users.noreply.github.com> Date: Fri, 3 Feb 2023 16:20:35 +0100 Subject: [PATCH 2/2] add log when copying files/directories between host and containers (both way) Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com> --- pkg/compose/cp.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pkg/compose/cp.go b/pkg/compose/cp.go index 8cdfce4c4..95c09b6c0 100644 --- a/pkg/compose/cp.go +++ b/pkg/compose/cp.go @@ -82,15 +82,15 @@ func (s *composeService) Copy(ctx context.Context, projectName string, options a for _, cont := range containers { container := cont g.Go(func() error { - err := copyFunc(ctx, container.ID, srcPath, dstPath, options) - if s.dryRun && err == nil { - fromOrInside := "inside" - if direction == fromService { - fromOrInside = "from" - } - fmt.Printf("Copy %s to path %s %s %s service container\n", srcPath, dstPath, fromOrInside, getCanonicalContainerName(container)) + if err := copyFunc(ctx, container.ID, srcPath, dstPath, options); err != nil { + return err } - 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 }) }