diff --git a/pkg/imgpkg/bundle/bundlefakes/fake_images_metadata_writer.go b/pkg/imgpkg/bundle/bundlefakes/fake_images_metadata_writer.go index 492430c17..ba081c253 100644 --- a/pkg/imgpkg/bundle/bundlefakes/fake_images_metadata_writer.go +++ b/pkg/imgpkg/bundle/bundlefakes/fake_images_metadata_writer.go @@ -8,9 +8,22 @@ import ( v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/bundle" + "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/internal/util" + "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/registry" ) type FakeImagesMetadataWriter struct { + CloneWithLoggerStub func(util.ProgressLogger) registry.Registry + cloneWithLoggerMutex sync.RWMutex + cloneWithLoggerArgsForCall []struct { + arg1 util.ProgressLogger + } + cloneWithLoggerReturns struct { + result1 registry.Registry + } + cloneWithLoggerReturnsOnCall map[int]struct { + result1 registry.Registry + } DigestStub func(name.Reference) (v1.Hash, error) digestMutex sync.RWMutex digestArgsForCall []struct { @@ -63,11 +76,12 @@ type FakeImagesMetadataWriter struct { result1 v1.Image result2 error } - WriteImageStub func(name.Reference, v1.Image) error + WriteImageStub func(name.Reference, v1.Image, chan v1.Update) error writeImageMutex sync.RWMutex writeImageArgsForCall []struct { arg1 name.Reference arg2 v1.Image + arg3 chan v1.Update } writeImageReturns struct { result1 error @@ -91,6 +105,67 @@ type FakeImagesMetadataWriter struct { invocationsMutex sync.RWMutex } +func (fake *FakeImagesMetadataWriter) CloneWithLogger(arg1 util.ProgressLogger) registry.Registry { + fake.cloneWithLoggerMutex.Lock() + ret, specificReturn := fake.cloneWithLoggerReturnsOnCall[len(fake.cloneWithLoggerArgsForCall)] + fake.cloneWithLoggerArgsForCall = append(fake.cloneWithLoggerArgsForCall, struct { + arg1 util.ProgressLogger + }{arg1}) + stub := fake.CloneWithLoggerStub + fakeReturns := fake.cloneWithLoggerReturns + fake.recordInvocation("CloneWithLogger", []interface{}{arg1}) + fake.cloneWithLoggerMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeImagesMetadataWriter) CloneWithLoggerCallCount() int { + fake.cloneWithLoggerMutex.RLock() + defer fake.cloneWithLoggerMutex.RUnlock() + return len(fake.cloneWithLoggerArgsForCall) +} + +func (fake *FakeImagesMetadataWriter) CloneWithLoggerCalls(stub func(util.ProgressLogger) registry.Registry) { + fake.cloneWithLoggerMutex.Lock() + defer fake.cloneWithLoggerMutex.Unlock() + fake.CloneWithLoggerStub = stub +} + +func (fake *FakeImagesMetadataWriter) CloneWithLoggerArgsForCall(i int) util.ProgressLogger { + fake.cloneWithLoggerMutex.RLock() + defer fake.cloneWithLoggerMutex.RUnlock() + argsForCall := fake.cloneWithLoggerArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeImagesMetadataWriter) CloneWithLoggerReturns(result1 registry.Registry) { + fake.cloneWithLoggerMutex.Lock() + defer fake.cloneWithLoggerMutex.Unlock() + fake.CloneWithLoggerStub = nil + fake.cloneWithLoggerReturns = struct { + result1 registry.Registry + }{result1} +} + +func (fake *FakeImagesMetadataWriter) CloneWithLoggerReturnsOnCall(i int, result1 registry.Registry) { + fake.cloneWithLoggerMutex.Lock() + defer fake.cloneWithLoggerMutex.Unlock() + fake.CloneWithLoggerStub = nil + if fake.cloneWithLoggerReturnsOnCall == nil { + fake.cloneWithLoggerReturnsOnCall = make(map[int]struct { + result1 registry.Registry + }) + } + fake.cloneWithLoggerReturnsOnCall[i] = struct { + result1 registry.Registry + }{result1} +} + func (fake *FakeImagesMetadataWriter) Digest(arg1 name.Reference) (v1.Hash, error) { fake.digestMutex.Lock() ret, specificReturn := fake.digestReturnsOnCall[len(fake.digestArgsForCall)] @@ -352,19 +427,20 @@ func (fake *FakeImagesMetadataWriter) ImageReturnsOnCall(i int, result1 v1.Image }{result1, result2} } -func (fake *FakeImagesMetadataWriter) WriteImage(arg1 name.Reference, arg2 v1.Image) error { +func (fake *FakeImagesMetadataWriter) WriteImage(arg1 name.Reference, arg2 v1.Image, arg3 chan v1.Update) error { fake.writeImageMutex.Lock() ret, specificReturn := fake.writeImageReturnsOnCall[len(fake.writeImageArgsForCall)] fake.writeImageArgsForCall = append(fake.writeImageArgsForCall, struct { arg1 name.Reference arg2 v1.Image - }{arg1, arg2}) + arg3 chan v1.Update + }{arg1, arg2, arg3}) stub := fake.WriteImageStub fakeReturns := fake.writeImageReturns - fake.recordInvocation("WriteImage", []interface{}{arg1, arg2}) + fake.recordInvocation("WriteImage", []interface{}{arg1, arg2, arg3}) fake.writeImageMutex.Unlock() if stub != nil { - return stub(arg1, arg2) + return stub(arg1, arg2, arg3) } if specificReturn { return ret.result1 @@ -378,17 +454,17 @@ func (fake *FakeImagesMetadataWriter) WriteImageCallCount() int { return len(fake.writeImageArgsForCall) } -func (fake *FakeImagesMetadataWriter) WriteImageCalls(stub func(name.Reference, v1.Image) error) { +func (fake *FakeImagesMetadataWriter) WriteImageCalls(stub func(name.Reference, v1.Image, chan v1.Update) error) { fake.writeImageMutex.Lock() defer fake.writeImageMutex.Unlock() fake.WriteImageStub = stub } -func (fake *FakeImagesMetadataWriter) WriteImageArgsForCall(i int) (name.Reference, v1.Image) { +func (fake *FakeImagesMetadataWriter) WriteImageArgsForCall(i int) (name.Reference, v1.Image, chan v1.Update) { fake.writeImageMutex.RLock() defer fake.writeImageMutex.RUnlock() argsForCall := fake.writeImageArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 } func (fake *FakeImagesMetadataWriter) WriteImageReturns(result1 error) { @@ -479,6 +555,8 @@ func (fake *FakeImagesMetadataWriter) WriteTagReturnsOnCall(i int, result1 error func (fake *FakeImagesMetadataWriter) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() + fake.cloneWithLoggerMutex.RLock() + defer fake.cloneWithLoggerMutex.RUnlock() fake.digestMutex.RLock() defer fake.digestMutex.RUnlock() fake.firstImageExistsMutex.RLock() diff --git a/pkg/imgpkg/bundle/contents.go b/pkg/imgpkg/bundle/contents.go index 48b9208c2..1f64b616c 100644 --- a/pkg/imgpkg/bundle/contents.go +++ b/pkg/imgpkg/bundle/contents.go @@ -13,7 +13,9 @@ import ( regname "github.com/google/go-containerregistry/pkg/name" regv1 "github.com/google/go-containerregistry/pkg/v1" regremote "github.com/google/go-containerregistry/pkg/v1/remote" + "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/internal/util" "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/plainimage" + "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/registry" ) const ( @@ -30,8 +32,9 @@ type Contents struct { //go:generate go run github.com/maxbrunsfeld/counterfeiter/v6 . ImagesMetadataWriter type ImagesMetadataWriter interface { ImagesMetadata - WriteImage(regname.Reference, regv1.Image) error + WriteImage(regname.Reference, regv1.Image, chan regv1.Update) error WriteTag(ref regname.Tag, taggagle regremote.Taggable) error + CloneWithLogger(logger util.ProgressLogger) registry.Registry } func NewContents(paths []string, excludedPaths []string) Contents { diff --git a/pkg/imgpkg/bundle/locations_configs.go b/pkg/imgpkg/bundle/locations_configs.go index ad75d392d..b00d0052d 100644 --- a/pkg/imgpkg/bundle/locations_configs.go +++ b/pkg/imgpkg/bundle/locations_configs.go @@ -132,7 +132,7 @@ func (r LocationsConfigs) Save(reg ImagesMetadataWriter, bundleRef name.Digest, r.ui.Tracef("Pushing image\n") - _, err = plainimage.NewContents([]string{tmpDir}, nil).Push(locRef, nil, reg, ui) + _, err = plainimage.NewContents([]string{tmpDir}, nil).Push(locRef, nil, reg.CloneWithLogger(util.NewNoopProgressBar()), ui) if err != nil { // Immutable tag errors within registries are not standardized. // Assume word "immutable" would be present in most cases. diff --git a/pkg/imgpkg/internal/util/progress_logger.go b/pkg/imgpkg/internal/util/progress_logger.go index 5aa71dfc5..e8cd2fcc6 100644 --- a/pkg/imgpkg/internal/util/progress_logger.go +++ b/pkg/imgpkg/internal/util/progress_logger.go @@ -14,24 +14,29 @@ import ( "github.com/mattn/go-isatty" ) +// ProgressLogger Progress bar type ProgressLogger interface { - Start(progress <-chan regv1.Update) + Start(ctx context.Context, progress <-chan regv1.Update) End() } // NewProgressBar constructor to build a ProgressLogger responsible for printing out a progress bar using updates when // writing to a registry via ggcr func NewProgressBar(ui goui.UI, finalMessage, errorMessagePrefix string) ProgressLogger { - ctx, cancel := context.WithCancel(context.Background()) if isatty.IsTerminal(os.Stdout.Fd()) { - return &ProgressBarLogger{ctx: ctx, cancelFunc: cancel, ui: ui, finalMessage: finalMessage, errorMessagePrefix: errorMessagePrefix} + return &ProgressBarLogger{ui: ui, finalMessage: finalMessage, errorMessagePrefix: errorMessagePrefix} } - return &ProgressBarNoTTYLogger{ui: ui, ctx: ctx, cancelFunc: cancel, finalMessage: finalMessage} + return &ProgressBarNoTTYLogger{ui: ui, finalMessage: finalMessage} } +// NewNoopProgressBar constructs a Noop Progress bar that will not display anything +func NewNoopProgressBar() ProgressLogger { + return &ProgressBarNoTTYLogger{} +} + +// ProgressBarLogger display progress bar on output type ProgressBarLogger struct { - ctx context.Context cancelFunc context.CancelFunc bar *pb.ProgressBar ui goui.UI @@ -39,7 +44,10 @@ type ProgressBarLogger struct { errorMessagePrefix string } -func (l *ProgressBarLogger) Start(progressChan <-chan regv1.Update) { +// Start the display of the Progress Bar +func (l *ProgressBarLogger) Start(ctx context.Context, progressChan <-chan regv1.Update) { + ctx, cancelFunc := context.WithCancel(ctx) + l.cancelFunc = cancelFunc // Add a new empty line to separate the progress bar from prior output fmt.Println() l.bar = pb.New64(0) @@ -48,7 +56,7 @@ func (l *ProgressBarLogger) Start(progressChan <-chan regv1.Update) { go func() { for { select { - case <-l.ctx.Done(): + case <-ctx.Done(): return case update := <-progressChan: if update.Error != nil { @@ -70,24 +78,30 @@ func (l *ProgressBarLogger) Start(progressChan <-chan regv1.Update) { }() } +// End stops the progress bar and writes the final message func (l *ProgressBarLogger) End() { - l.cancelFunc() + if l.cancelFunc != nil { + l.cancelFunc() + } l.bar.Finish() l.ui.BeginLinef("\n%s", l.finalMessage) } +// ProgressBarNoTTYLogger does not display the progress bar type ProgressBarNoTTYLogger struct { - ctx context.Context cancelFunc context.CancelFunc ui goui.UI finalMessage string } -func (l *ProgressBarNoTTYLogger) Start(progressChan <-chan regv1.Update) { +// Start consuming the progress channel but does not display anything +func (l *ProgressBarNoTTYLogger) Start(ctx context.Context, progressChan <-chan regv1.Update) { + ctx, cancelFunc := context.WithCancel(ctx) + l.cancelFunc = cancelFunc go func() { for { select { - case <-l.ctx.Done(): + case <-ctx.Done(): return case <-progressChan: } @@ -95,7 +109,12 @@ func (l *ProgressBarNoTTYLogger) Start(progressChan <-chan regv1.Update) { }() } +// End Write the final message func (l *ProgressBarNoTTYLogger) End() { - l.cancelFunc() - l.ui.BeginLinef(l.finalMessage) + if l.cancelFunc != nil { + l.cancelFunc() + } + if l.ui != nil && l.finalMessage != "" { + l.ui.BeginLinef(l.finalMessage) + } } diff --git a/pkg/imgpkg/plainimage/contents.go b/pkg/imgpkg/plainimage/contents.go index 8185bf53c..28315dbb0 100644 --- a/pkg/imgpkg/plainimage/contents.go +++ b/pkg/imgpkg/plainimage/contents.go @@ -23,7 +23,7 @@ type Contents struct { } type ImagesWriter interface { - WriteImage(regname.Reference, regv1.Image) error + WriteImage(regname.Reference, regv1.Image, chan regv1.Update) error WriteTag(ref regname.Tag, taggagle regremote.Taggable) error } @@ -46,7 +46,8 @@ func (i Contents) Push(uploadRef regname.Tag, labels map[string]string, writer I defer img.Remove() - err = writer.WriteImage(uploadRef, img) + err = writer.WriteImage(uploadRef, img, nil) + if err != nil { return "", fmt.Errorf("Writing '%s': %s", uploadRef.Name(), err) } diff --git a/pkg/imgpkg/registry/registry.go b/pkg/imgpkg/registry/registry.go index d96970b39..0c975cee3 100644 --- a/pkg/imgpkg/registry/registry.go +++ b/pkg/imgpkg/registry/registry.go @@ -20,6 +20,7 @@ import ( regv1 "github.com/google/go-containerregistry/pkg/v1" regremote "github.com/google/go-containerregistry/pkg/v1/remote" "github.com/google/go-containerregistry/pkg/v1/remote/transport" + "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/internal/util" "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/registry/auth" ) @@ -50,13 +51,14 @@ type Registry interface { FirstImageExists(digests []string) (string, error) MultiWrite(imageOrIndexesToUpload map[regname.Reference]regremote.Taggable, concurrency int, updatesCh chan regv1.Update) error - WriteImage(reference regname.Reference, image regv1.Image) error + WriteImage(regname.Reference, regv1.Image, chan regv1.Update) error WriteIndex(reference regname.Reference, index regv1.ImageIndex) error WriteTag(tag regname.Tag, taggable regremote.Taggable) error ListTags(repo regname.Repository) ([]string, error) CloneWithSingleAuth(imageRef regname.Tag) (Registry, error) + CloneWithLogger(logger util.ProgressLogger) Registry } // ImagesReader Interface for Reading Images @@ -74,11 +76,12 @@ type ImagesReader interface { type ImagesReaderWriter interface { ImagesReader MultiWrite(imageOrIndexesToUpload map[regname.Reference]regremote.Taggable, concurrency int, updatesCh chan regv1.Update) error - WriteImage(regname.Reference, regv1.Image) error + WriteImage(regname.Reference, regv1.Image, chan regv1.Update) error WriteIndex(regname.Reference, regv1.ImageIndex) error WriteTag(regname.Tag, regremote.Taggable) error CloneWithSingleAuth(imageRef regname.Tag) (Registry, error) + CloneWithLogger(logger util.ProgressLogger) Registry } var _ Registry = &SimpleRegistry{} @@ -190,6 +193,18 @@ func (r SimpleRegistry) CloneWithSingleAuth(imageRef regname.Tag) (Registry, err }, nil } +// CloneWithLogger Clones the provided registry updating the progress logger to NoTTYLogger +// that does not display the progress bar +func (r SimpleRegistry) CloneWithLogger(_ util.ProgressLogger) Registry { + return &SimpleRegistry{ + remoteOpts: r.remoteOpts, + refOpts: r.refOpts, + keychain: r.keychain, + roundTrippers: r.roundTrippers, + transportAccess: &sync.Mutex{}, + } +} + // readOpts Returns the readOpts + the keychain func (r *SimpleRegistry) readOpts(ref regname.Reference) ([]regremote.Option, error) { rt, err := r.transport(ref, ref.Scope(transport.PullScope)) @@ -319,7 +334,7 @@ func (r *SimpleRegistry) MultiWrite(imageOrIndexesToUpload map[regname.Reference } // WriteImage Upload Image to registry -func (r *SimpleRegistry) WriteImage(ref regname.Reference, img regv1.Image) error { +func (r *SimpleRegistry) WriteImage(ref regname.Reference, img regv1.Image, updatesCh chan regv1.Update) error { if err := r.validateRef(ref); err != nil { return err } @@ -332,7 +347,9 @@ func (r *SimpleRegistry) WriteImage(ref regname.Reference, img regv1.Image) erro if err != nil { return err } - + if updatesCh != nil { + opts = append(opts, regremote.WithProgress(updatesCh)) + } err = regremote.Write(overriddenRef, img, opts...) if err != nil { return fmt.Errorf("Writing image: %s", err) diff --git a/pkg/imgpkg/registry/registry_test.go b/pkg/imgpkg/registry/registry_test.go index a220b85b9..997b68ca0 100644 --- a/pkg/imgpkg/registry/registry_test.go +++ b/pkg/imgpkg/registry/registry_test.go @@ -166,7 +166,7 @@ func TestInsecureRegistryFlag(t *testing.T) { exec: func(t *testing.T, r registry.Registry) error { img, err := name.ParseReference("my.registry.io/some/image") require.NoError(t, err) - return r.WriteImage(img, nil) + return r.WriteImage(img, nil, nil) }, }, { diff --git a/pkg/imgpkg/registry/registryfakes/fake_images_reader_writer.go b/pkg/imgpkg/registry/registryfakes/fake_images_reader_writer.go index e341c699e..9dab948f9 100644 --- a/pkg/imgpkg/registry/registryfakes/fake_images_reader_writer.go +++ b/pkg/imgpkg/registry/registryfakes/fake_images_reader_writer.go @@ -7,10 +7,22 @@ import ( "github.com/google/go-containerregistry/pkg/name" v1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/remote" + "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/internal/util" "github.com/vmware-tanzu/carvel-imgpkg/pkg/imgpkg/registry" ) type FakeImagesReaderWriter struct { + CloneWithLoggerStub func(util.ProgressLogger) registry.Registry + cloneWithLoggerMutex sync.RWMutex + cloneWithLoggerArgsForCall []struct { + arg1 util.ProgressLogger + } + cloneWithLoggerReturns struct { + result1 registry.Registry + } + cloneWithLoggerReturnsOnCall map[int]struct { + result1 registry.Registry + } CloneWithSingleAuthStub func(name.Tag) (registry.Registry, error) cloneWithSingleAuthMutex sync.RWMutex cloneWithSingleAuthArgsForCall []struct { @@ -102,11 +114,12 @@ type FakeImagesReaderWriter struct { multiWriteReturnsOnCall map[int]struct { result1 error } - WriteImageStub func(name.Reference, v1.Image) error + WriteImageStub func(name.Reference, v1.Image, chan v1.Update) error writeImageMutex sync.RWMutex writeImageArgsForCall []struct { arg1 name.Reference arg2 v1.Image + arg3 chan v1.Update } writeImageReturns struct { result1 error @@ -142,6 +155,67 @@ type FakeImagesReaderWriter struct { invocationsMutex sync.RWMutex } +func (fake *FakeImagesReaderWriter) CloneWithLogger(arg1 util.ProgressLogger) registry.Registry { + fake.cloneWithLoggerMutex.Lock() + ret, specificReturn := fake.cloneWithLoggerReturnsOnCall[len(fake.cloneWithLoggerArgsForCall)] + fake.cloneWithLoggerArgsForCall = append(fake.cloneWithLoggerArgsForCall, struct { + arg1 util.ProgressLogger + }{arg1}) + stub := fake.CloneWithLoggerStub + fakeReturns := fake.cloneWithLoggerReturns + fake.recordInvocation("CloneWithLogger", []interface{}{arg1}) + fake.cloneWithLoggerMutex.Unlock() + if stub != nil { + return stub(arg1) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeImagesReaderWriter) CloneWithLoggerCallCount() int { + fake.cloneWithLoggerMutex.RLock() + defer fake.cloneWithLoggerMutex.RUnlock() + return len(fake.cloneWithLoggerArgsForCall) +} + +func (fake *FakeImagesReaderWriter) CloneWithLoggerCalls(stub func(util.ProgressLogger) registry.Registry) { + fake.cloneWithLoggerMutex.Lock() + defer fake.cloneWithLoggerMutex.Unlock() + fake.CloneWithLoggerStub = stub +} + +func (fake *FakeImagesReaderWriter) CloneWithLoggerArgsForCall(i int) util.ProgressLogger { + fake.cloneWithLoggerMutex.RLock() + defer fake.cloneWithLoggerMutex.RUnlock() + argsForCall := fake.cloneWithLoggerArgsForCall[i] + return argsForCall.arg1 +} + +func (fake *FakeImagesReaderWriter) CloneWithLoggerReturns(result1 registry.Registry) { + fake.cloneWithLoggerMutex.Lock() + defer fake.cloneWithLoggerMutex.Unlock() + fake.CloneWithLoggerStub = nil + fake.cloneWithLoggerReturns = struct { + result1 registry.Registry + }{result1} +} + +func (fake *FakeImagesReaderWriter) CloneWithLoggerReturnsOnCall(i int, result1 registry.Registry) { + fake.cloneWithLoggerMutex.Lock() + defer fake.cloneWithLoggerMutex.Unlock() + fake.CloneWithLoggerStub = nil + if fake.cloneWithLoggerReturnsOnCall == nil { + fake.cloneWithLoggerReturnsOnCall = make(map[int]struct { + result1 registry.Registry + }) + } + fake.cloneWithLoggerReturnsOnCall[i] = struct { + result1 registry.Registry + }{result1} +} + func (fake *FakeImagesReaderWriter) CloneWithSingleAuth(arg1 name.Tag) (registry.Registry, error) { fake.cloneWithSingleAuthMutex.Lock() ret, specificReturn := fake.cloneWithSingleAuthReturnsOnCall[len(fake.cloneWithSingleAuthArgsForCall)] @@ -594,19 +668,20 @@ func (fake *FakeImagesReaderWriter) MultiWriteReturnsOnCall(i int, result1 error }{result1} } -func (fake *FakeImagesReaderWriter) WriteImage(arg1 name.Reference, arg2 v1.Image) error { +func (fake *FakeImagesReaderWriter) WriteImage(arg1 name.Reference, arg2 v1.Image, arg3 chan v1.Update) error { fake.writeImageMutex.Lock() ret, specificReturn := fake.writeImageReturnsOnCall[len(fake.writeImageArgsForCall)] fake.writeImageArgsForCall = append(fake.writeImageArgsForCall, struct { arg1 name.Reference arg2 v1.Image - }{arg1, arg2}) + arg3 chan v1.Update + }{arg1, arg2, arg3}) stub := fake.WriteImageStub fakeReturns := fake.writeImageReturns - fake.recordInvocation("WriteImage", []interface{}{arg1, arg2}) + fake.recordInvocation("WriteImage", []interface{}{arg1, arg2, arg3}) fake.writeImageMutex.Unlock() if stub != nil { - return stub(arg1, arg2) + return stub(arg1, arg2, arg3) } if specificReturn { return ret.result1 @@ -620,17 +695,17 @@ func (fake *FakeImagesReaderWriter) WriteImageCallCount() int { return len(fake.writeImageArgsForCall) } -func (fake *FakeImagesReaderWriter) WriteImageCalls(stub func(name.Reference, v1.Image) error) { +func (fake *FakeImagesReaderWriter) WriteImageCalls(stub func(name.Reference, v1.Image, chan v1.Update) error) { fake.writeImageMutex.Lock() defer fake.writeImageMutex.Unlock() fake.WriteImageStub = stub } -func (fake *FakeImagesReaderWriter) WriteImageArgsForCall(i int) (name.Reference, v1.Image) { +func (fake *FakeImagesReaderWriter) WriteImageArgsForCall(i int) (name.Reference, v1.Image, chan v1.Update) { fake.writeImageMutex.RLock() defer fake.writeImageMutex.RUnlock() argsForCall := fake.writeImageArgsForCall[i] - return argsForCall.arg1, argsForCall.arg2 + return argsForCall.arg1, argsForCall.arg2, argsForCall.arg3 } func (fake *FakeImagesReaderWriter) WriteImageReturns(result1 error) { @@ -783,6 +858,8 @@ func (fake *FakeImagesReaderWriter) WriteTagReturnsOnCall(i int, result1 error) func (fake *FakeImagesReaderWriter) Invocations() map[string][][]interface{} { fake.invocationsMutex.RLock() defer fake.invocationsMutex.RUnlock() + fake.cloneWithLoggerMutex.RLock() + defer fake.cloneWithLoggerMutex.RUnlock() fake.cloneWithSingleAuthMutex.RLock() defer fake.cloneWithSingleAuthMutex.RUnlock() fake.digestMutex.RLock() diff --git a/pkg/imgpkg/registry/with_progress.go b/pkg/imgpkg/registry/with_progress.go index ae45b9ba1..fa464be9f 100644 --- a/pkg/imgpkg/registry/with_progress.go +++ b/pkg/imgpkg/registry/with_progress.go @@ -4,6 +4,8 @@ package registry import ( + "context" + regname "github.com/google/go-containerregistry/pkg/name" regv1 "github.com/google/go-containerregistry/pkg/v1" "github.com/google/go-containerregistry/pkg/v1/remote" @@ -50,15 +52,19 @@ func (w *WithProgress) FirstImageExists(digests []string) (string, error) { // MultiWrite Upload multiple Images in Parallel to the Registry func (w *WithProgress) MultiWrite(imageOrIndexesToUpload map[regname.Reference]remote.Taggable, concurrency int, _ chan regv1.Update) error { uploadProgress := make(chan regv1.Update) - w.logger.Start(uploadProgress) + w.logger.Start(context.Background(), uploadProgress) defer w.logger.End() return w.delegate.MultiWrite(imageOrIndexesToUpload, concurrency, uploadProgress) } // WriteImage Upload Image to registry -func (w *WithProgress) WriteImage(reference regname.Reference, image regv1.Image) error { - return w.delegate.WriteImage(reference, image) +func (w *WithProgress) WriteImage(reference regname.Reference, image regv1.Image, _ chan regv1.Update) error { + uploadProgress := make(chan regv1.Update) + w.logger.Start(context.Background(), uploadProgress) + defer w.logger.End() + + return w.delegate.WriteImage(reference, image, uploadProgress) } // WriteIndex Uploads the Index manifest to the registry @@ -87,3 +93,8 @@ func (w WithProgress) CloneWithSingleAuth(imageRef regname.Tag) (Registry, error return &WithProgress{delegate: delegate}, nil } + +// CloneWithLogger Clones the provided registry updating the progress +func (w WithProgress) CloneWithLogger(logger util.ProgressLogger) Registry { + return &WithProgress{delegate: w.delegate, logger: logger} +}