From 7ae2f28e1d7d55b46d3826caa8a7ad123576373e Mon Sep 17 00:00:00 2001 From: Joao Pereira Date: Fri, 24 May 2024 10:41:27 -0500 Subject: [PATCH 1/2] Introduction of the copy API Signed-off-by: Joao Pereira --- pkg/imgpkg/cmd/copy.go | 54 ++- pkg/imgpkg/imageset/unprocessed_image_refs.go | 6 + .../{cmd/copy_repo_src.go => v1/copy.go} | 152 +++---- .../copy_repo_src_test.go => v1/copy_test.go} | 393 +++++++----------- pkg/imgpkg/v1/describe.go | 2 + .../test_assets/bundle}/.imgpkg/bundle.yml | 2 +- .../bundle/.imgpkg/images.yml.template | 6 + .../test_assets/bundle}/config.yml | 0 .../.imgpkg/bundle.yml | 2 +- .../.imgpkg/images.yml.template | 0 .../bundle_with_dockerhub_images}/config.yml | 0 .../.imgpkg/bundle.yml | 9 + .../.imgpkg/images.yml.template | 0 .../bundle_with_mult_images/config.yml | 33 ++ .../test_assets/image_with_config/config.yml | 33 ++ test/e2e/copy_from_image_test.go | 61 ++- test/helpers/fake_registry.go | 4 + 17 files changed, 409 insertions(+), 348 deletions(-) rename pkg/imgpkg/{cmd/copy_repo_src.go => v1/copy.go} (54%) rename pkg/imgpkg/{cmd/copy_repo_src_test.go => v1/copy_test.go} (80%) rename pkg/imgpkg/{cmd/test_assets/bundle_with_mult_images => v1/test_assets/bundle}/.imgpkg/bundle.yml (83%) create mode 100644 pkg/imgpkg/v1/test_assets/bundle/.imgpkg/images.yml.template rename pkg/imgpkg/{cmd/test_assets/bundle_with_dockerhub_images => v1/test_assets/bundle}/config.yml (100%) rename pkg/imgpkg/{cmd => v1}/test_assets/bundle_with_dockerhub_images/.imgpkg/bundle.yml (85%) rename pkg/imgpkg/{cmd => v1}/test_assets/bundle_with_dockerhub_images/.imgpkg/images.yml.template (100%) rename pkg/imgpkg/{cmd/test_assets/bundle_with_mult_images => v1/test_assets/bundle_with_dockerhub_images}/config.yml (100%) create mode 100644 pkg/imgpkg/v1/test_assets/bundle_with_mult_images/.imgpkg/bundle.yml rename pkg/imgpkg/{cmd => v1}/test_assets/bundle_with_mult_images/.imgpkg/images.yml.template (100%) create mode 100644 pkg/imgpkg/v1/test_assets/bundle_with_mult_images/config.yml create mode 100644 pkg/imgpkg/v1/test_assets/image_with_config/config.yml diff --git a/pkg/imgpkg/cmd/copy.go b/pkg/imgpkg/cmd/copy.go index ae3db0d2c..3e98bdb8c 100644 --- a/pkg/imgpkg/cmd/copy.go +++ b/pkg/imgpkg/cmd/copy.go @@ -13,12 +13,11 @@ import ( "carvel.dev/imgpkg/pkg/imgpkg/plainimage" "carvel.dev/imgpkg/pkg/imgpkg/registry" "carvel.dev/imgpkg/pkg/imgpkg/signature" + v1 "carvel.dev/imgpkg/pkg/imgpkg/v1" "github.com/cppforlife/go-cli-ui/ui" "github.com/spf13/cobra" ) -const rootBundleLabelKey string = "dev.carvel.imgpkg.copy.root-bundle" - type CopyOptions struct { ui ui.UI @@ -116,26 +115,21 @@ func (c *CopyOptions) Run() error { imageSet := ctlimgset.NewImageSet(c.Concurrency, prefixedLogger, tagGen) tarImageSet := ctlimgset.NewTarImageSet(imageSet, c.Concurrency, prefixedLogger) - var signatureRetriever SignatureRetriever + var signatureRetriever v1.SignatureFetcher if c.SignatureFlags.CopyCosignSignatures { signatureRetriever = signature.NewSignatures(signature.NewCosign(reg), c.Concurrency) } else { signatureRetriever = signature.NewNoop() } - repoSrc := CopyRepoSrc{ - ImageFlags: c.ImageFlags, - BundleFlags: c.BundleFlags, - LockInputFlags: c.LockInputFlags, - TarFlags: c.TarFlags, - IncludeNonDistributable: c.IncludeNonDistributable, + opts := v1.CopyOpts{ + Logger: levelLogger, + ImageSet: imageSet, + TarImageSet: tarImageSet, Concurrency: c.Concurrency, - - logger: levelLogger, - registry: registry.NewRegistryWithProgress(reg, imagesUploaderLogger), - imageSet: imageSet, - tarImageSet: tarImageSet, - signatureRetriever: signatureRetriever, + SignatureRetriever: signatureRetriever, + IncludeNonDistributable: c.IncludeNonDistributable, + Resume: c.TarFlags.Resume, } switch { @@ -146,17 +140,41 @@ func (c *CopyOptions) Run() error { if c.LockOutputFlags.LockFilePath != "" { return fmt.Errorf("Cannot output lock file with tar destination") } - return repoSrc.CopyToTar(c.TarFlags.TarDst, c.TarFlags.Resume) + + origin := v1.CopyOrigin{ + ImageRef: c.ImageFlags.Image, + BundleRef: c.BundleFlags.Bundle, + LockfilePath: c.LockInputFlags.LockFilePath, + } + ids, err := v1.CopyToTar(origin, c.TarFlags.TarDst, opts, registry.NewRegistryWithProgress(reg, imagesUploaderLogger)) + if err != nil { + return err + } + informUserToUseTheNonDistributableFlagWithDescriptors( + levelLogger, c.IncludeNonDistributable, getNonDistributableLayersFromImageDescriptors(ids)) + + return nil case c.isRepoDst(): if c.TarFlags.Resume { return fmt.Errorf("Flag --resume can only be used when copying to tar") } - processedImages, err := repoSrc.CopyToRepo(c.RepoDst) + origin := v1.CopyOrigin{ + ImageRef: c.ImageFlags.Image, + BundleRef: c.BundleFlags.Bundle, + TarPath: c.TarFlags.TarSrc, + LockfilePath: c.LockInputFlags.LockFilePath, + } + + processedImages, err := v1.CopyToRepository(origin, c.RepoDst, opts, reg) if err != nil { return err } + + informUserToUseTheNonDistributableFlagWithDescriptors( + levelLogger, c.IncludeNonDistributable, processedImagesNonDistLayer(processedImages)) + return c.writeLockOutput(processedImages, reg) default: @@ -205,7 +223,7 @@ func (c *CopyOptions) findProcessedImageRootBundle(processedImages *ctlimgset.Pr var bundleProcessedImage *ctlimgset.ProcessedImage for _, processedImage := range processedImages.All() { - if _, ok := processedImage.Labels[rootBundleLabelKey]; ok { + if v1.IsRootBundle(processedImage) { if bundleProcessedImage != nil { panic("Internal inconsistency: expected only 1 root bundle") } diff --git a/pkg/imgpkg/imageset/unprocessed_image_refs.go b/pkg/imgpkg/imageset/unprocessed_image_refs.go index 56beb7445..3e9c0cc52 100644 --- a/pkg/imgpkg/imageset/unprocessed_image_refs.go +++ b/pkg/imgpkg/imageset/unprocessed_image_refs.go @@ -18,6 +18,12 @@ type UnprocessedImageRef struct { OrigRef string } +// LabelValue returns the value of the provided label and a bool to identify if the label was present or not +func (u UnprocessedImageRef) LabelValue(label string) (string, bool) { + value, ok := u.Labels[label] + return value, ok +} + // Key that uniquely identify a ImageRef func (u UnprocessedImageRef) Key() string { // With this definition of key if one image is shared by 2 bundles diff --git a/pkg/imgpkg/cmd/copy_repo_src.go b/pkg/imgpkg/v1/copy.go similarity index 54% rename from pkg/imgpkg/cmd/copy_repo_src.go rename to pkg/imgpkg/v1/copy.go index 00a2b0a7f..98e415d24 100644 --- a/pkg/imgpkg/cmd/copy_repo_src.go +++ b/pkg/imgpkg/v1/copy.go @@ -1,13 +1,13 @@ // Copyright 2024 The Carvel Authors. // SPDX-License-Identifier: Apache-2.0 -package cmd +package v1 import ( "fmt" ctlbundle "carvel.dev/imgpkg/pkg/imgpkg/bundle" - "carvel.dev/imgpkg/pkg/imgpkg/imageset" + "carvel.dev/imgpkg/pkg/imgpkg/imagedesc" ctlimgset "carvel.dev/imgpkg/pkg/imgpkg/imageset" "carvel.dev/imgpkg/pkg/imgpkg/imagetar" "carvel.dev/imgpkg/pkg/imgpkg/internal/util" @@ -17,61 +17,57 @@ import ( regname "github.com/google/go-containerregistry/pkg/name" ) -type SignatureRetriever interface { - Fetch(images *imageset.UnprocessedImageRefs) (*imageset.UnprocessedImageRefs, error) -} +const rootBundleLabelKey string = "dev.carvel.imgpkg.copy.root-bundle" -type CopyRepoSrc struct { - ImageFlags ImageFlags - BundleFlags BundleFlags - LockInputFlags LockInputFlags - TarFlags TarFlags - IncludeNonDistributable bool +// CopyOpts Option that can be provided to the copy request +type CopyOpts struct { + Logger Logger + ImageSet ctlimgset.ImageSet + TarImageSet ctlimgset.TarImageSet Concurrency int + SignatureRetriever SignatureFetcher + IncludeNonDistributable bool + Resume bool +} - logger util.LoggerWithLevels - imageSet ctlimgset.ImageSet - tarImageSet ctlimgset.TarImageSet - registry registry.ImagesReaderWriter - signatureRetriever SignatureRetriever +// CopyOrigin abstracts the original location to copy from +type CopyOrigin struct { + ImageRef string + BundleRef string + TarPath string + LockfilePath string } -// CopyToTar copies image or bundle into the provided path -func (c CopyRepoSrc) CopyToTar(dstPath string, resume bool) error { - c.logger.Tracef("CopyToTar\n") +// CopyToTar copy origin image/s to a tar file in disc +func CopyToTar(origin CopyOrigin, outputTarPath string, opts CopyOpts, reg registry.Registry) (*imagedesc.ImageRefDescriptors, error) { + opts.Logger.Tracef("CopyToTar\n") - unprocessedImageRefs, _, err := c.getAllSourceImages() + unprocessedImageRefs, _, err := getAllSourceImages(origin, reg, opts) if err != nil { - return err + return nil, err } - c.logger.Tracef("Exporting images to tar\n") - ids, err := c.tarImageSet.Export(unprocessedImageRefs, dstPath, c.registry, imagetar.NewImageLayerWriterCheck(c.IncludeNonDistributable), resume) + opts.Logger.Tracef("Exporting images to tar\n") + ids, err := opts.TarImageSet.Export(unprocessedImageRefs, outputTarPath, reg, imagetar.NewImageLayerWriterCheck(opts.IncludeNonDistributable), opts.Resume) if err != nil { - return err + return nil, err } - informUserToUseTheNonDistributableFlagWithDescriptors( - c.logger, c.IncludeNonDistributable, getNonDistributableLayersFromImageDescriptors(ids)) - - return nil + return ids, nil } -func (c CopyRepoSrc) CopyToRepo(repo string) (*ctlimgset.ProcessedImages, error) { - c.logger.Tracef("CopyToRepo(%s)\n", repo) +// CopyToRepository copy origin image/s to a repository in a remote registry +func CopyToRepository(origin CopyOrigin, repository string, opts CopyOpts, reg registry.Registry) (*ctlimgset.ProcessedImages, error) { + opts.Logger.Tracef("CopyToRepository(%s)\n", repository) var processedImages *ctlimgset.ProcessedImages - importRepo, err := regname.NewRepository(repo) + importRepo, err := regname.NewRepository(repository) if err != nil { return nil, fmt.Errorf("Building import repository ref: %s", err) } - if c.TarFlags.IsSrc() { - if c.TarFlags.IsDst() { - return nil, fmt.Errorf("Cannot use tar source (--tar) with tar destination (--to-tar)") - } - - processedImages, err = c.tarImageSet.Import(c.TarFlags.TarSrc, importRepo, c.registry) + if origin.TarPath != "" { + processedImages, err = opts.TarImageSet.Import(origin.TarPath, importRepo, reg) if err != nil { return nil, err } @@ -83,52 +79,49 @@ func (c CopyRepoSrc) CopyToRepo(repo string) (*ctlimgset.ProcessedImages, error) continue } - if _, ok := processedImage.Labels[rootBundleLabelKey]; ok { + if IsRootBundle(processedImage) { if foundRootBundle { panic("Internal inconsistency: expected only 1 root bundle") } foundRootBundle = true pImage := plainimage.NewFetchedPlainImageWithTag(processedImage.DigestRef, processedImage.Tag, processedImage.Image) lockReader := ctlbundle.NewImagesLockReader() - parentBundle = ctlbundle.NewBundle(pImage, c.registry, lockReader, ctlbundle.NewFetcherFromProcessedImages(processedImages.All(), c.registry, lockReader)) + parentBundle = ctlbundle.NewBundle(pImage, reg, lockReader, ctlbundle.NewFetcherFromProcessedImages(processedImages.All(), reg, lockReader)) } } if foundRootBundle { - bundles, _, err := parentBundle.AllImagesLockRefs(c.Concurrency, c.logger) + bundles, _, err := parentBundle.AllImagesLockRefs(opts.Concurrency, opts.Logger) if err != nil { return nil, err } for _, bundle := range bundles { - if err := bundle.NoteCopy(processedImages, c.registry, c.logger); err != nil { + if err := bundle.NoteCopy(processedImages, reg, opts.Logger); err != nil { return nil, fmt.Errorf("Creating copy information for bundle %s: %s", bundle.DigestRef(), err) } } } } else { - unprocessedImageRefs, bundles, err := c.getAllSourceImages() + unprocessedImageRefs, bundles, err := getAllSourceImages(origin, reg, opts) if err != nil { return nil, err } - processedImages, err = c.imageSet.Relocate(unprocessedImageRefs, importRepo, c.registry) + processedImages, err = opts.ImageSet.Relocate(unprocessedImageRefs, importRepo, reg) if err != nil { return nil, err } for _, bundle := range bundles { - if err := bundle.NoteCopy(processedImages, c.registry, c.logger); err != nil { + if err := bundle.NoteCopy(processedImages, reg, opts.Logger); err != nil { return nil, fmt.Errorf("Creating copy information for bundle %s: %s", bundle.DigestRef(), err) } } } - informUserToUseTheNonDistributableFlagWithDescriptors( - c.logger, c.IncludeNonDistributable, processedImagesNonDistLayer(processedImages)) - - c.logger.Logf("Tagging images\n") - err = c.tagAllImages(processedImages) + opts.Logger.Logf("Tagging images\n") + err = tagAllImages(reg, opts, processedImages) if err != nil { return nil, fmt.Errorf("Tagging images: %s", err) } @@ -136,15 +129,26 @@ func (c CopyRepoSrc) CopyToRepo(repo string) (*ctlimgset.ProcessedImages, error) return processedImages, nil } -func (c CopyRepoSrc) getAllSourceImages() (*ctlimgset.UnprocessedImageRefs, []*ctlbundle.Bundle, error) { - unprocessedImageRefs, bundles, err := c.getProvidedSourceImages() +// ImageLabels used to retrieve the value of a label from an image +type ImageLabels interface { + LabelValue(string) (string, bool) +} + +// IsRootBundle check if a particular bundle is a root bundle or a inner bundle +func IsRootBundle(img ImageLabels) bool { + _, ok := img.LabelValue(rootBundleLabelKey) + return ok +} + +func getAllSourceImages(origin CopyOrigin, reg registry.Registry, opts CopyOpts) (*ctlimgset.UnprocessedImageRefs, []*ctlbundle.Bundle, error) { + unprocessedImageRefs, bundles, err := getProvidedSourceImages(origin, reg, opts) if err != nil { return nil, nil, err } - c.logger.Debugf("Fetching signatures\n") + opts.Logger.Debugf("Fetching signatures\n") - signatures, err := c.signatureRetriever.Fetch(unprocessedImageRefs) + signatures, err := opts.SignatureRetriever.Fetch(unprocessedImageRefs) if err != nil { return nil, nil, err } @@ -156,19 +160,19 @@ func (c CopyRepoSrc) getAllSourceImages() (*ctlimgset.UnprocessedImageRefs, []*c return unprocessedImageRefs, bundles, nil } -func (c CopyRepoSrc) getProvidedSourceImages() (*ctlimgset.UnprocessedImageRefs, []*ctlbundle.Bundle, error) { +func getProvidedSourceImages(origin CopyOrigin, reg registry.Registry, opts CopyOpts) (*ctlimgset.UnprocessedImageRefs, []*ctlbundle.Bundle, error) { unprocessedImageRefs := ctlimgset.NewUnprocessedImageRefs() switch { - case c.LockInputFlags.LockFilePath != "": - bundleLock, imagesLock, err := lockconfig.NewLockFromPath(c.LockInputFlags.LockFilePath) + case origin.LockfilePath != "": + bundleLock, imagesLock, err := lockconfig.NewLockFromPath(origin.LockfilePath) if err != nil { return nil, nil, err } switch { case bundleLock != nil: - c.logger.Tracef("get images from BundleLock file\n") - _, bundles, imagesRef, err := c.getBundleImageRefs(bundleLock.Bundle.Image) + opts.Logger.Tracef("get images from BundleLock file\n") + _, bundles, imagesRef, err := getBundleImageRefs(bundleLock.Bundle.Image, reg, opts) if err != nil { return nil, nil, err } @@ -188,11 +192,11 @@ func (c CopyRepoSrc) getProvidedSourceImages() (*ctlimgset.UnprocessedImageRefs, return unprocessedImageRefs, bundles, nil case imagesLock != nil: - c.logger.Tracef("get images from ImagesLock file\n") + opts.Logger.Tracef("get images from ImagesLock file\n") for _, img := range imagesLock.Images { - plainImg := plainimage.NewPlainImage(img.Image, c.registry) + plainImg := plainimage.NewPlainImage(img.Image, reg) - ok, err := ctlbundle.NewBundleFromPlainImage(plainImg, c.registry).IsBundle() + ok, err := ctlbundle.NewBundleFromPlainImage(plainImg, reg).IsBundle() if err != nil { return nil, nil, err } @@ -208,11 +212,11 @@ func (c CopyRepoSrc) getProvidedSourceImages() (*ctlimgset.UnprocessedImageRefs, panic("Unreachable") } - case c.ImageFlags.Image != "": - c.logger.Tracef("copy single image\n") - plainImg := plainimage.NewPlainImage(c.ImageFlags.Image, c.registry) + case origin.ImageRef != "": + opts.Logger.Tracef("copy single image\n") + plainImg := plainimage.NewPlainImage(origin.ImageRef, reg) - ok, err := ctlbundle.NewBundleFromPlainImage(plainImg, c.registry).IsBundle() + ok, err := ctlbundle.NewBundleFromPlainImage(plainImg, reg).IsBundle() if err != nil { return nil, nil, err } @@ -224,8 +228,8 @@ func (c CopyRepoSrc) getProvidedSourceImages() (*ctlimgset.UnprocessedImageRefs, return unprocessedImageRefs, nil, nil default: - c.logger.Tracef("copy bundle\n") - bundle, allBundles, imagesRef, err := c.getBundleImageRefs(c.BundleFlags.Bundle) + opts.Logger.Tracef("copy bundle\n") + bundle, allBundles, imagesRef, err := getBundleImageRefs(origin.BundleRef, reg, opts) if err != nil { return nil, nil, err } @@ -246,9 +250,9 @@ func (c CopyRepoSrc) getProvidedSourceImages() (*ctlimgset.UnprocessedImageRefs, } } -func (c CopyRepoSrc) getBundleImageRefs(bundleRef string) (*ctlbundle.Bundle, []*ctlbundle.Bundle, ctlbundle.ImageRefs, error) { +func getBundleImageRefs(bundleRef string, reg registry.Registry, copyOpts CopyOpts) (*ctlbundle.Bundle, []*ctlbundle.Bundle, ctlbundle.ImageRefs, error) { lockReader := ctlbundle.NewImagesLockReader() - bundle := ctlbundle.NewBundleFromRef(bundleRef, c.registry, lockReader, ctlbundle.NewRegistryFetcher(c.registry, lockReader)) + bundle := ctlbundle.NewBundleFromRef(bundleRef, reg, lockReader, ctlbundle.NewRegistryFetcher(reg, lockReader)) isBundle, err := bundle.IsBundle() if err != nil { return nil, nil, ctlbundle.ImageRefs{}, err @@ -257,15 +261,15 @@ func (c CopyRepoSrc) getBundleImageRefs(bundleRef string) (*ctlbundle.Bundle, [] return nil, nil, ctlbundle.ImageRefs{}, fmt.Errorf("Expected bundle image but found plain image (hint: Did you use -i instead of -b?)") } - nestedBundles, imageRefs, err := bundle.AllImagesLockRefs(c.Concurrency, c.logger) + nestedBundles, imageRefs, err := bundle.AllImagesLockRefs(copyOpts.Concurrency, copyOpts.Logger) if err != nil { return nil, nil, ctlbundle.ImageRefs{}, fmt.Errorf("Reading Images from Bundle: %s", err) } return bundle, nestedBundles, imageRefs, nil } -func (c CopyRepoSrc) tagAllImages(processedImages *ctlimgset.ProcessedImages) error { - throttle := util.NewThrottle(c.Concurrency) +func tagAllImages(reg registry.Registry, copyOpts CopyOpts, processedImages *ctlimgset.ProcessedImages) error { + throttle := util.NewThrottle(copyOpts.Concurrency) totalThreads := 0 errCh := make(chan error, processedImages.Len()) @@ -290,14 +294,14 @@ func (c CopyRepoSrc) tagAllImages(processedImages *ctlimgset.ProcessedImages) er switch { case item.Image != nil: - err = c.registry.WriteTag(customTagRef, item.Image) + err = reg.WriteTag(customTagRef, item.Image) if err != nil { errCh <- fmt.Errorf("Tagging image %s: %s", digest.Name(), err) return } case item.ImageIndex != nil: - err = c.registry.WriteTag(customTagRef, item.ImageIndex) + err = reg.WriteTag(customTagRef, item.ImageIndex) if err != nil { errCh <- fmt.Errorf("Tagging image index %s: %s", digest.Name(), err) return diff --git a/pkg/imgpkg/cmd/copy_repo_src_test.go b/pkg/imgpkg/v1/copy_test.go similarity index 80% rename from pkg/imgpkg/cmd/copy_repo_src_test.go rename to pkg/imgpkg/v1/copy_test.go index 02bfc7045..e3979b073 100644 --- a/pkg/imgpkg/cmd/copy_repo_src_test.go +++ b/pkg/imgpkg/v1/copy_test.go @@ -1,7 +1,7 @@ // Copyright 2024 The Carvel Authors. // SPDX-License-Identifier: Apache-2.0 -package cmd +package v1_test import ( "archive/tar" @@ -23,6 +23,7 @@ import ( "carvel.dev/imgpkg/pkg/imgpkg/internal/util" "carvel.dev/imgpkg/pkg/imgpkg/lockconfig" "carvel.dev/imgpkg/pkg/imgpkg/registry" + v1 "carvel.dev/imgpkg/pkg/imgpkg/v1" "carvel.dev/imgpkg/test/helpers" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" @@ -32,28 +33,42 @@ import ( "github.com/stretchr/testify/require" ) -var subject CopyRepoSrc var stdOut *bytes.Buffer -func TestMain(m *testing.M) { +func testSetup(registryBuild *helpers.FakeTestRegistryBuilder, imageName string, bundleName string, tarPath string, lockfilePath string) (v1.CopyOrigin, v1.CopyOpts, registry.Registry) { stdOut = bytes.NewBufferString("") - uiLogger := util.NewUILevelLogger(util.LogWarn, util.NewBufferLogger(stdOut)) - tagGen := util.DefaultTagGenerator{} imageSet := imageset.NewImageSet(1, uiLogger, tagGen) - subject = CopyRepoSrc{ - logger: uiLogger, - imageSet: imageSet, - tarImageSet: imageset.NewTarImageSet(imageSet, 1, uiLogger), + opts := v1.CopyOpts{ + Logger: uiLogger, + ImageSet: imageSet, + TarImageSet: imageset.NewTarImageSet(imageSet, 1, uiLogger), Concurrency: 1, - signatureRetriever: &fakeSignatureRetriever{}, + SignatureRetriever: &fakeSignatureRetriever{}, + Resume: false, + } + if registryBuild == nil { + origin := v1.CopyOrigin{ + ImageRef: imageName, + BundleRef: bundleName, + TarPath: tarPath, + LockfilePath: lockfilePath, + } + return origin, opts, nil } - os.Exit(m.Run()) -} + reg := registryBuild.Build() + origin := v1.CopyOrigin{ + ImageRef: registryBuild.ReferenceOnTestServer(imageName), + BundleRef: registryBuild.ReferenceOnTestServer(bundleName), + TarPath: tarPath, + LockfilePath: lockfilePath, + } + return origin, opts, reg +} func TestToTarBundle(t *testing.T) { bundleName := "library/bundle" fakeRegistry := helpers.NewFakeRegistry(t, &helpers.Logger{LogLevel: helpers.LogDebug}) @@ -62,15 +77,13 @@ func TestToTarBundle(t *testing.T) { defer fakeRegistry.CleanUp() - subject := subject - subject.BundleFlags = BundleFlags{fakeRegistry.ReferenceOnTestServer(bundleName)} - subject.registry = fakeRegistry.Build() + origin, opts, reg := testSetup(fakeRegistry, "", bundleName, "", "") t.Run("Tar should contain every layer", func(t *testing.T) { bundleTarPath := filepath.Join(os.TempDir(), "bundle.tar") defer os.Remove(bundleTarPath) - err := subject.CopyToTar(bundleTarPath, false) + _, err := v1.CopyToTar(origin, bundleTarPath, opts, reg) require.NoError(t, err) assertTarballContainsEveryLayer(t, bundleTarPath) @@ -97,23 +110,21 @@ bundle: bundleLockTempDir := filepath.Join(assets.CreateTempFolder("bundle-lock"), "lock.yml") assert.NoError(t, bundleLock.WriteToPath(bundleLockTempDir)) - subject := subject - subject.BundleFlags.Bundle = "" - subject.LockInputFlags.LockFilePath = bundleLockTempDir - subject.registry = fakeRegistry.Build() - - subject.BundleFlags.Bundle = fakeRegistry.ReferenceOnTestServer( + reg = fakeRegistry.Build() + origin := origin + origin.BundleRef = fakeRegistry.ReferenceOnTestServer( bundleWithNested.BundleName + "@" + bundleWithNested.Digest) + origin.LockfilePath = bundleLockTempDir bundleTarPath := filepath.Join(os.TempDir(), "bundle.tar") defer os.Remove(bundleTarPath) - err = subject.CopyToTar(bundleTarPath, false) + _, err = v1.CopyToTar(origin, bundleTarPath, opts, reg) require.NoError(t, err) assertTarballContainsOnlyDistributableLayers(bundleTarPath, t) - assertTarballLabelsOuterBundle(bundleTarPath, subject.BundleFlags.Bundle, t) + assertTarballLabelsOuterBundle(bundleTarPath, origin.BundleRef, t) }) } @@ -122,7 +133,7 @@ func TestToTarBundleContainingNonDistributableLayers(t *testing.T) { fakeRegistry := helpers.NewFakeRegistry(t, &helpers.Logger{LogLevel: helpers.LogDebug}) defer fakeRegistry.CleanUp() randomImage := fakeRegistry.WithRandomImage("library/image_with_config") - randomImageWithNonDistributableLayer, nonDistributableLayer := fakeRegistry. + randomImageWithNonDistributableLayer, _ := fakeRegistry. WithRandomImage("library/image_with_non_dist_layer").WithNonDistributableLayer() fakeRegistry.WithBundleFromPath(bundleName, "test_assets/bundle_with_mult_images"). @@ -131,64 +142,29 @@ func TestToTarBundleContainingNonDistributableLayers(t *testing.T) { {Image: randomImageWithNonDistributableLayer.RefDigest}, }) - subject := subject - subject.BundleFlags = BundleFlags{fakeRegistry.ReferenceOnTestServer(bundleName)} - subject.registry = fakeRegistry.Build() + origin, opts, reg := testSetup(fakeRegistry, "", bundleName, "", "") t.Run("Tar should contain every distributable layer only", func(t *testing.T) { imageTarPath := filepath.Join(os.TempDir(), "bundle.tar") defer os.Remove(imageTarPath) - err := subject.CopyToTar(imageTarPath, false) + _, err := v1.CopyToTar(origin, imageTarPath, opts, reg) require.NoError(t, err) assertTarballContainsOnlyDistributableLayers(imageTarPath, t) }) - t.Run("Warning message should be printed indicating layers have been skipped", func(t *testing.T) { - stdOut.Reset() - - imageTarPath := filepath.Join(os.TempDir(), "bundle.tar") - defer os.Remove(imageTarPath) - - err := subject.CopyToTar(imageTarPath, false) - require.NoError(t, err) - - digest, err := nonDistributableLayer.Digest() - require.NoError(t, err) - expectedOutput := fmt.Sprintf(`Skipped the followings layer(s) due to it being non-distributable. If you would like to include non-distributable layers, use the --include-non-distributable-layers flag - - Image: %s - Layers: - - %s`, randomImageWithNonDistributableLayer.RefDigest, digest.String()) - require.Contains(t, stdOut.String(), expectedOutput) - }) - t.Run("When Include-non-distributable-layers flag is provided the tarball should contain every layer", func(t *testing.T) { - subject := subject - subject.IncludeNonDistributable = true - imageTarPath := filepath.Join(os.TempDir(), "bundle.tar") defer os.Remove(imageTarPath) - err := subject.CopyToTar(imageTarPath, false) - require.NoError(t, err) - - assertTarballContainsEveryLayer(t, imageTarPath) - }) - - t.Run("When Include-non-distributable-layers flag is provided a warning message should not be printed", func(t *testing.T) { - stdOut.Reset() - subject := subject - subject.IncludeNonDistributable = true - - imageTarPath := filepath.Join(os.TempDir(), "bundle.tar") - defer os.Remove(imageTarPath) + opts := opts + opts.IncludeNonDistributable = true - err := subject.CopyToTar(imageTarPath, false) + _, err := v1.CopyToTar(origin, imageTarPath, opts, reg) require.NoError(t, err) - assert.NotContains(t, stdOut.String(), "Warning: '--include-non-distributable-layers' flag provided, but no images contained a non-distributable layer.") - assert.NotContains(t, stdOut.String(), "Skipped the followings layer(s) due") + assertTarballContainsEveryLayer(t, imageTarPath) }) t.Run("When a bundle contains a bundle with non distributable layer, it copies all layers to tar", func(t *testing.T) { @@ -207,16 +183,15 @@ images: bundleDir := bundleBuilder.CreateBundleDir(helpers.BundleYAML, imageLockYAML) bundleWithNested := fakeRegistry.WithBundleFromPath("library/with-nested-bundle", bundleDir) - subject := subject - subject.registry = fakeRegistry.Build() - - subject.BundleFlags.Bundle = fakeRegistry.ReferenceOnTestServer(bundleWithNested.BundleName + "@" + + reg := fakeRegistry.Build() + origin := origin + origin.BundleRef = fakeRegistry.ReferenceOnTestServer(bundleWithNested.BundleName + "@" + bundleWithNested.Digest) imageTarPath := filepath.Join(os.TempDir(), "bundle.tar") defer os.Remove(imageTarPath) - err := subject.CopyToTar(imageTarPath, false) + _, err := v1.CopyToTar(origin, imageTarPath, opts, reg) require.NoError(t, err) assertTarballContainsOnlyDistributableLayers(imageTarPath, t) @@ -231,49 +206,31 @@ func TestToTarImage(t *testing.T) { fakeRegistry.WithRandomImageWithLayers(randomImageName, 20) defer fakeRegistry.CleanUp() - subject := subject - subject.ImageFlags = ImageFlags{ - fakeRegistry.ReferenceOnTestServer(imageName), - } - subject.registry = fakeRegistry.Build() + origin, opts, reg := testSetup(fakeRegistry, imageName, "", "", "") t.Run("Tar should contain every layer", func(t *testing.T) { imageTarPath := filepath.Join(os.TempDir(), "bundle.tar") defer os.Remove(imageTarPath) - err := subject.CopyToTar(imageTarPath, false) + _, err := v1.CopyToTar(origin, imageTarPath, opts, reg) require.NoError(t, err) assertTarballContainsEveryLayer(t, imageTarPath) }) t.Run("When Include-non-distributable flag is provided the tarball should contain every layer", func(t *testing.T) { - subject := subject - subject.IncludeNonDistributable = true + opts := opts + opts.IncludeNonDistributable = true imageTarPath := filepath.Join(os.TempDir(), "bundle.tar") defer os.Remove(imageTarPath) - err := subject.CopyToTar(imageTarPath, false) + _, err := v1.CopyToTar(origin, imageTarPath, opts, reg) require.NoError(t, err) assertTarballContainsEveryLayer(t, imageTarPath) }) - t.Run("When Include-non-distributable flag is provided a warning message should be printed", func(t *testing.T) { - stdOut.Reset() - subject := subject - subject.IncludeNonDistributable = true - - imageTarPath := filepath.Join(os.TempDir(), "bundle.tar") - defer os.Remove(imageTarPath) - - err := subject.CopyToTar(imageTarPath, false) - require.NoError(t, err) - - require.Contains(t, stdOut.String(), "Warning: '--include-non-distributable-layers' flag provided, but no images contained a non-distributable layer.\n") - }) - t.Run("When copy to tar fails the first time but second call with resume completes successfully", func(t *testing.T) { numberOfRequests := 0 var failedDigest regv1.Hash @@ -331,18 +288,19 @@ func TestToTarImage(t *testing.T) { } defer os.Remove(imageTarPath) - subject := subject - subject.ImageFlags = ImageFlags{ - fakeRegistry.ReferenceOnTestServer(randomImageName), - } - err := subject.CopyToTar(imageTarPath, false) + origin := origin + origin.ImageRef = fakeRegistry.ReferenceOnTestServer(randomImageName) + + _, err := v1.CopyToTar(origin, imageTarPath, opts, reg) require.ErrorContains(t, err, "error verifying sha256 checksum") layersInTar, err = imagetar.NewTarReader(imageTarPath).PresentLayers() require.NoError(t, err) require.Greater(t, len(layersInTar), 1) require.NotContains(t, layersInTar, failedDigest, "tar should not contain the layer that fails to download") - err = subject.CopyToTar(imageTarPath, true) + opts := opts + opts.Resume = true + _, err = v1.CopyToTar(origin, imageTarPath, opts, reg) require.NoError(t, err) assertTarballContainsEveryLayer(t, imageTarPath) @@ -355,34 +313,27 @@ func TestToTarImageContainingNonDistributableLayers(t *testing.T) { fakeRegistry.WithImageFromPath(imageName, "test_assets/image_with_config", map[string]string{}). WithNonDistributableLayer() defer fakeRegistry.CleanUp() - subject := subject - subject.ImageFlags = ImageFlags{ - fakeRegistry.ReferenceOnTestServer(imageName), - } - subject.registry = fakeRegistry.Build() + + origin, opts, reg := testSetup(fakeRegistry, imageName, "", "", "") t.Run("Tar should contain every distributable layer only", func(t *testing.T) { imageTarPath := filepath.Join(os.TempDir(), "bundle.tar") defer os.Remove(imageTarPath) - err := subject.CopyToTar(imageTarPath, false) - if err != nil { - t.Fatalf("Expected CopyToTar() to succeed but got: %s", err) - } + _, err := v1.CopyToTar(origin, imageTarPath, opts, reg) + require.NoError(t, err) assertTarballContainsOnlyDistributableLayers(imageTarPath, t) }) t.Run("When Include-non-distributable-layers flag is provided the tarball should contain every layer", func(t *testing.T) { - subject := subject - subject.IncludeNonDistributable = true + opts := opts + opts.IncludeNonDistributable = true imageTarPath := filepath.Join(os.TempDir(), "bundle.tar") defer os.Remove(imageTarPath) - err := subject.CopyToTar(imageTarPath, false) - if err != nil { - t.Fatalf("Expected CopyToTar() to succeed but got: %s", err) - } + _, err := v1.CopyToTar(origin, imageTarPath, opts, reg) + require.NoError(t, err) assertTarballContainsEveryLayer(t, imageTarPath) }) @@ -394,17 +345,14 @@ func TestToTarImageIndex(t *testing.T) { imageIndex := fakeRegistry.WithARandomImageIndex("library/imageindex", numOfImagesForImageIndex) defer fakeRegistry.CleanUp() - subject := subject - subject.ImageFlags = ImageFlags{ - imageIndex.RefDigest, - } - subject.registry = fakeRegistry.Build() + origin, opts, reg := testSetup(fakeRegistry, "", "", "", "") + origin.ImageRef = imageIndex.RefDigest t.Run("Tar should contain every layer", func(t *testing.T) { imageTarPath := filepath.Join(os.TempDir(), "bundle.tar") defer os.Remove(imageTarPath) - err := subject.CopyToTar(imageTarPath, false) + _, err := v1.CopyToTar(origin, imageTarPath, opts, reg) assert.NoError(t, err) assertTarballContainsEveryImageInImageIndex(t, imageTarPath, int(numOfImagesForImageIndex)) @@ -416,17 +364,14 @@ func TestToRepoImageIndex(t *testing.T) { expectedNumOfImagesForImgIndex := int64(3) randomImageIndex := fakeRegistry.WithARandomImageIndex("library/imageindex", expectedNumOfImagesForImgIndex) defer fakeRegistry.CleanUp() - subject := subject - subject.ImageFlags = ImageFlags{ - randomImageIndex.RefDigest, - } + + origin, opts, reg := testSetup(nil, "", "", "", "") + origin.ImageRef = randomImageIndex.RefDigest destinationImageName := "library/copied-img" t.Run("should copy every image to repo", func(t *testing.T) { - subject := subject - subject.registry = fakeRegistry.Build() - - processedImages, err := subject.CopyToRepo(fakeRegistry.ReferenceOnTestServer(destinationImageName)) + reg = fakeRegistry.Build() + processedImages, err := v1.CopyToRepository(origin, fakeRegistry.ReferenceOnTestServer(destinationImageName), opts, reg) require.NoError(t, err) require.Len(t, processedImages.All(), 1) @@ -453,12 +398,12 @@ images: err = os.WriteFile(lockFile.Name(), []byte(imageLockYAML), 0600) require.NoError(t, err) - subject := subject - subject.LockInputFlags.LockFilePath = lockFile.Name() - subject.registry = fakeRegistry.Build() + origin := origin + origin.LockfilePath = lockFile.Name() + reg := fakeRegistry.Build() - processedImages, err := subject.CopyToRepo(fakeRegistry.ReferenceOnTestServer(destinationImageName)) - assert.NoError(t, err) + processedImages, err := v1.CopyToRepository(origin, fakeRegistry.ReferenceOnTestServer(destinationImageName), opts, reg) + require.NoError(t, err) require.Len(t, processedImages.All(), 1) manifest, err := processedImages.All()[0].ImageIndex.IndexManifest() @@ -485,16 +430,13 @@ func TestToRepoBundleContainingANestedBundle(t *testing.T) { {Image: bundleWithTwoImages.RefDigest}, }) - subject := subject - subject.BundleFlags.Bundle = bundleWithNestedBundle.RefDigest - subject.registry = fakeRegistry.Build() + origin, opts, reg := testSetup(nil, "", bundleWithNestedBundle.RefDigest, "", "") t.Run("When recursive bundle is enabled, it copies every image to repo", func(t *testing.T) { - subject := subject - subject.registry = fakeRegistry.Build() - + reg = fakeRegistry.Build() destRepo := fakeRegistry.ReferenceOnTestServer("library/bundle-copy") - processedImages, err := subject.CopyToRepo(destRepo) + + processedImages, err := v1.CopyToRepository(origin, destRepo, opts, reg) require.NoError(t, err) require.Len(t, processedImages.All(), 4) @@ -503,7 +445,7 @@ func TestToRepoBundleContainingANestedBundle(t *testing.T) { processedImageDigest := []string{} for _, processedImage := range processedImages.All() { processedImageDigest = append(processedImageDigest, processedImage.DigestRef) - if _, ok := processedImage.Labels[rootBundleLabelKey]; ok { + if _, ok := processedImage.Labels["dev.carvel.imgpkg.copy.root-bundle"]; ok { processedBundle = processedImage } } @@ -518,9 +460,9 @@ func TestToRepoBundleContainingANestedBundle(t *testing.T) { }) t.Run("When user defined tag is provided, it applies it after the upload of the blobs finishes", func(t *testing.T) { - subject := subject - subject.registry = fakeRegistry.Build() - subject.BundleFlags.Bundle = fakeRegistry.ReferenceOnTestServer(bundleWithNestedBundle.BundleName) + origin := origin + origin.BundleRef = fakeRegistry.ReferenceOnTestServer(bundleWithNestedBundle.BundleName) + reg = fakeRegistry.Build() fakeDestRegistry := helpers.NewFakeRegistry(t, &helpers.Logger{LogLevel: helpers.LogTrace}) defer fakeDestRegistry.CleanUp() @@ -529,7 +471,7 @@ func TestToRepoBundleContainingANestedBundle(t *testing.T) { fakeDestRegistry.Build() destRepo := fakeDestRegistry.ReferenceOnTestServer("library/bundle-copy") - _, err := subject.CopyToRepo(destRepo) + _, err := v1.CopyToRepository(origin, destRepo, opts, reg) require.NoError(t, err) // Ensure that the last operation done against the registry is the creation of the tag @@ -545,20 +487,20 @@ func TestToRepoBundleContainingANestedBundle(t *testing.T) { apiVersion: imgpkg.carvel.dev/v1alpha1 kind: BundleLock bundle: - image: %s + image: %s `, bundleWithNestedBundle.RefDigest))) assert.NoError(t, err) bundleLockTempDir := filepath.Join(assets.CreateTempFolder("bundle-lock"), "lock.yml") assert.NoError(t, bundleLock.WriteToPath(bundleLockTempDir)) - subject := subject - subject.BundleFlags.Bundle = "" - subject.LockInputFlags.LockFilePath = bundleLockTempDir - subject.registry = fakeRegistry.Build() + origin := origin + origin.BundleRef = "" + origin.LockfilePath = bundleLockTempDir + reg = fakeRegistry.Build() destRepo := fakeRegistry.ReferenceOnTestServer("library/bundle-copy") - processedImages, err := subject.CopyToRepo(destRepo) + processedImages, err := v1.CopyToRepository(origin, destRepo, opts, reg) require.NoError(t, err) require.Len(t, processedImages.All(), 4) @@ -567,7 +509,7 @@ bundle: processedImageDigest := []string{} for _, processedImage := range processedImages.All() { processedImageDigest = append(processedImageDigest, processedImage.DigestRef) - if _, ok := processedImage.Labels[rootBundleLabelKey]; ok { + if _, ok := processedImage.Labels["dev.carvel.imgpkg.copy.root-bundle"]; ok { processedBundle = processedImage } } @@ -593,13 +535,13 @@ images: imagesLockTempDir := filepath.Join(assets.CreateTempFolder("images-lock"), "images-lock.yml") assert.NoError(t, imagesLock.WriteToPath(imagesLockTempDir)) - subject := subject - subject.BundleFlags.Bundle = "" - subject.LockInputFlags.LockFilePath = imagesLockTempDir - subject.registry = fakeRegistry.Build() + origin := origin + origin.BundleRef = "" + origin.LockfilePath = imagesLockTempDir + reg = fakeRegistry.Build() destRepo := fakeRegistry.ReferenceOnTestServer("library/bundle-copy") - _, err = subject.CopyToRepo(destRepo) + _, err = v1.CopyToRepository(origin, destRepo, opts, reg) require.Error(t, err) assert.EqualError(t, err, "Unable to copy bundles using an Images Lock file (hint: Create a bundle with these images)") }) @@ -622,19 +564,16 @@ func TestToRepoBundleCreatesValidLocationOCI(t *testing.T) { {Image: bundleWithOneImages.RefDigest}, }) - subject := subject - subject.BundleFlags.Bundle = bundleWithNestedBundle.RefDigest - subject.registry = fakeRegistry.Build() + origin, opts, reg := testSetup(nil, "", bundleWithNestedBundle.RefDigest, "", "") t.Run("A bundle with an image without a qualified image name", func(t *testing.T) { assets := &helpers.Assets{T: t} defer assets.CleanCreatedFolders() - subject := subject - subject.registry = fakeRegistry.Build() + reg = fakeRegistry.Build() destRepo := fakeRegistry.ReferenceOnTestServer("library/bundle-copy") - processedImages, err := subject.CopyToRepo(destRepo) + processedImages, err := v1.CopyToRepository(origin, destRepo, opts, reg) require.NoError(t, err) require.Len(t, processedImages.All(), 3) @@ -642,7 +581,7 @@ func TestToRepoBundleCreatesValidLocationOCI(t *testing.T) { processedImageDigest := []string{} for _, processedImage := range processedImages.All() { processedImageDigest = append(processedImageDigest, processedImage.DigestRef) - if _, ok := processedImage.Labels[rootBundleLabelKey]; ok { + if _, ok := processedImage.Labels["dev.carvel.imgpkg.copy.root-bundle"]; ok { processedBundle = processedImage } } @@ -706,19 +645,19 @@ func TestToRepoBundleCreatesValidLocationOCI(t *testing.T) { tmpFolder := assets.CreateTempFolder("tar-valid-oci-image") tarFile := filepath.Join(tmpFolder, "bundle.tar") - subject := subject - subject.registry = fakeRegistry.Build() + reg = fakeRegistry.Build() + origin := origin destRepo := fakeRegistry.ReferenceOnTestServer("library/bundle-copy") logger.Section("create Tar file with bundle", func() { - err := subject.CopyToTar(tarFile, false) + _, err := v1.CopyToTar(origin, tarFile, opts, reg) require.NoError(t, err) }) logger.Section("copy bundle from Tar file to Repository", func() { - subject.BundleFlags.Bundle = "" - subject.TarFlags.TarSrc = tarFile - _, err := subject.CopyToRepo(destRepo) + origin.BundleRef = "" + origin.TarPath = tarFile + _, err := v1.CopyToRepository(origin, destRepo, opts, reg) require.NoError(t, err) }) @@ -782,9 +721,7 @@ func TestToRepoBundleCreatesValidLocationOCI(t *testing.T) { assets := &helpers.Assets{T: t} defer assets.CleanCreatedFolders() - subject := subject - subject.registry = fakeRegistry.Build() - + reg = fakeRegistry.Build() destRepo := fakeRegistry.ReferenceOnTestServer("library/bundle-copy") locationImg := fmt.Sprintf("%s:%s.image-locations.imgpkg", destRepo, strings.ReplaceAll(bundleWithNestedBundle.Digest, ":", "-")) @@ -793,7 +730,7 @@ func TestToRepoBundleCreatesValidLocationOCI(t *testing.T) { fakeRegistry.WithImageStatusCodeRemap(fmt.Sprintf("%s.image-locations.imgpkg", strings.ReplaceAll(bundleWithNestedBundle.Digest, ":", "-")), 404, remappedStatusCode) defer fakeRegistry.ResetHandler() - processedImages, err := subject.CopyToRepo(destRepo) + processedImages, err := v1.CopyToRepository(origin, destRepo, opts, reg) require.NoError(t, err) require.Len(t, processedImages.All(), 3) @@ -803,7 +740,7 @@ func TestToRepoBundleCreatesValidLocationOCI(t *testing.T) { for _, processedImage := range processedImages.All() { processedImageDigest = append(processedImageDigest, processedImage.DigestRef) - if _, ok := processedImage.Labels[rootBundleLabelKey]; ok { + if _, ok := processedImage.Labels["dev.carvel.imgpkg.copy.root-bundle"]; ok { processedBundle = processedImage } } @@ -835,9 +772,7 @@ func TestToRepoFromTar(t *testing.T) { {Image: bundleWithOneImages.RefDigest}, }) - subject := subject - subject.BundleFlags.Bundle = bundleWithNestedBundle.RefDigest - subject.registry = fakeRegistry.Build() + origin, opts, reg := testSetup(nil, "", bundleWithNestedBundle.RefDigest, "", "") t.Run("When copying from tar do not try to reach to the original registry", func(t *testing.T) { assets := &helpers.Assets{T: t} @@ -846,24 +781,23 @@ func TestToRepoFromTar(t *testing.T) { tmpFolder := assets.CreateTempFolder("tar-valid-oci-image") tarFile := filepath.Join(tmpFolder, "bundle.tar") - subject := subject - subject.registry = fakeRegistry.Build() + reg = fakeRegistry.Build() + origin := origin logger.Section("create Tar file with bundle", func() { - err := subject.CopyToTar(tarFile, false) + _, err := v1.CopyToTar(origin, tarFile, opts, reg) require.NoError(t, err) }) fakeRegistry.CleanUp() destFakeRegistry := helpers.NewFakeRegistry(t, logger) defer destFakeRegistry.CleanUp() - subject.registry = destFakeRegistry.Build() + reg = destFakeRegistry.Build() destRepo := destFakeRegistry.ReferenceOnTestServer("library/bundle-copy") logger.Section("copy bundle from Tar file to Repository", func() { - subject.BundleFlags.Bundle = "" - subject.TarFlags.TarSrc = tarFile - _, err := subject.CopyToRepo(destRepo) + tarOrigin := v1.CopyOrigin{TarPath: tarFile} + _, err := v1.CopyToRepository(tarOrigin, destRepo, opts, reg) require.NoError(t, err) }) }) @@ -893,19 +827,15 @@ func TestToRepoBundleRunTwiceCreatesValidLocationOCI(t *testing.T) { {Image: bundleWithOneImages.RefDigest}, }) - subject := subject - subject.BundleFlags.Bundle = bundleWithNestedBundle.RefDigest - subject.registry = fakeRegistry.Build() + origin, opts, reg := testSetup(fakeRegistry, "", "", "", "") + origin.BundleRef = bundleWithNestedBundle.RefDigest t.Run("A bundle with an image without a qualified image name", func(t *testing.T) { assets := &helpers.Assets{T: t} defer assets.CleanCreatedFolders() - subject := subject - subject.registry = fakeRegistry.Build() - destRepo := fakeRegistry.ReferenceOnTestServer("library/bundle-copy") - processedImages, err := subject.CopyToRepo(destRepo) + processedImages, err := v1.CopyToRepository(origin, destRepo, opts, reg) require.NoError(t, err) require.Len(t, processedImages.All(), 3) @@ -914,7 +844,7 @@ func TestToRepoBundleRunTwiceCreatesValidLocationOCI(t *testing.T) { processedImageDigest := []string{} for _, processedImage := range processedImages.All() { processedImageDigest = append(processedImageDigest, processedImage.DigestRef) - if _, ok := processedImage.Labels[rootBundleLabelKey]; ok { + if _, ok := processedImage.Labels["dev.carvel.imgpkg.copy.root-bundle"]; ok { processedBundle = processedImage } } @@ -990,13 +920,12 @@ func TestToRepoBundleWithMultipleRegistries(t *testing.T) { {Image: randomImage1FromDockerhub.RefDigest}, }) - subject := subject - subject.BundleFlags = BundleFlags{bundleWithImageRefsToDockerhub.RefDigest} - subject.registry = fakePrivateRegistry.Build() + origin, opts, reg := testSetup(fakePrivateRegistry, "", "", "", "") + origin.BundleRef = bundleWithImageRefsToDockerhub.RefDigest fakeDockerhubRegistry.Build() t.Run("Images are copied from fake-registry and not from the bundle's ImagesLockFile registry (index.docker.io)", func(t *testing.T) { - processedImages, err := subject.CopyToRepo(fakePrivateRegistry.ReferenceOnTestServer(destinationBundleName)) + processedImages, err := v1.CopyToRepository(origin, fakePrivateRegistry.ReferenceOnTestServer(destinationBundleName), opts, reg) require.NoError(t, err, "expected copy command to succeed") require.Len(t, processedImages.All(), 2) @@ -1014,18 +943,16 @@ func TestToRepoBundleWithMultipleRegistries(t *testing.T) { apiVersion: imgpkg.carvel.dev/v1alpha1 kind: BundleLock bundle: - image: %s + image: %s `, bundleWithImageRefsToDockerhub.RefDigest))) assert.NoError(t, err) bundleLockTempDir := filepath.Join(assets.CreateTempFolder("bundle-lock"), "lock.yml") assert.NoError(t, bundleLock.WriteToPath(bundleLockTempDir)) - subject := subject - subject.BundleFlags.Bundle = "" - subject.LockInputFlags.LockFilePath = bundleLockTempDir + origin := v1.CopyOrigin{LockfilePath: bundleLockTempDir} - processedImages, err := subject.CopyToRepo(fakePrivateRegistry.ReferenceOnTestServer(destinationBundleName)) + processedImages, err := v1.CopyToRepository(origin, fakePrivateRegistry.ReferenceOnTestServer(destinationBundleName), opts, reg) require.NoError(t, err, "expected copy command to succeed") require.Len(t, processedImages.All(), 2) @@ -1041,22 +968,7 @@ func TestToRepoImage(t *testing.T) { fakeRegistry := helpers.NewFakeRegistry(t, &helpers.Logger{LogLevel: helpers.LogDebug}) defer fakeRegistry.CleanUp() image1 := fakeRegistry.WithImageFromPath(imageName, "test_assets/image_with_config", map[string]string{}) - subject := subject - subject.ImageFlags = ImageFlags{ - fakeRegistry.ReferenceOnTestServer(imageName), - } - - t.Run("When Include-non-distributable-layers flag is provided a warning message should be printed", func(t *testing.T) { - stdOut.Reset() - subject := subject - subject.registry = fakeRegistry.Build() - subject.IncludeNonDistributable = true - - _, err := subject.CopyToRepo(fakeRegistry.ReferenceOnTestServer("fakeregistry/some-repo")) - require.NoError(t, err) - - require.Contains(t, stdOut.String(), "Warning: '--include-non-distributable-layers' flag provided, but no images contained a non-distributable layer.") - }) + _, opts, _ := testSetup(nil, "", "", "", "") t.Run("When an ImageLock file is provided it should copy every image from the file", func(t *testing.T) { assets := &helpers.Assets{T: t} @@ -1081,11 +993,10 @@ images: err = os.WriteFile(lockFile.Name(), []byte(imageLockYAML), 0600) require.NoError(t, err) - subject := subject - subject.LockInputFlags.LockFilePath = lockFile.Name() - subject.registry = fakeRegistry.Build() + origin := v1.CopyOrigin{LockfilePath: lockFile.Name()} + reg := fakeRegistry.Build() - processedImages, err := subject.CopyToRepo(fakeRegistry.ReferenceOnTestServer(destinationImageName)) + processedImages, err := v1.CopyToRepository(origin, fakeRegistry.ReferenceOnTestServer(destinationImageName), opts, reg) require.NoError(t, err) require.Len(t, processedImages.All(), 2) @@ -1109,11 +1020,10 @@ images: imgToCopy := "library/image-to-copy:some-tag" fakeRegistry.WithRandomImage(imgToCopy) - subject := subject - subject.ImageFlags.Image = fakeRegistry.ReferenceOnTestServer(imgToCopy) - subject.registry = fakeRegistry.Build() + origin := v1.CopyOrigin{ImageRef: fakeRegistry.ReferenceOnTestServer(imgToCopy)} + reg := fakeRegistry.Build() - _, err := subject.CopyToRepo(fakeDestRegistry.ReferenceOnTestServer(destinationImageName)) + _, err := v1.CopyToRepository(origin, fakeDestRegistry.ReferenceOnTestServer(destinationImageName), opts, reg) require.NoError(t, err) // Ensure that the last operation done against the registry is the creation of the tag @@ -1134,9 +1044,8 @@ images: image2RefDigest := fakeRegistry.WithRandomImage(originImageName).RefDigest - subject := subject - subject.ImageFlags.Image = image2RefDigest - subject.registry = fakeRegistry.BuildWithRegistryOpts(registry.Opts{ + origin := v1.CopyOrigin{ImageRef: image2RefDigest} + reg := fakeRegistry.BuildWithRegistryOpts(registry.Opts{ EnvironFunc: func() []string { return []string{ "IMGPKG_REGISTRY_HOSTNAME_0=" + fakeRegistry.ReferenceOnTestServer("repo"), @@ -1154,7 +1063,7 @@ images: fakeRegistry.WithBasicAuthPerRepository("repo", "some-user", "some-password") fakeRegistry.WithBasicAuthPerRepository("some/other", "some-other-user", "some-other-password") - processedImages, err := subject.CopyToRepo(destinationImageName) + processedImages, err := v1.CopyToRepository(origin, destinationImageName, opts, reg) require.NoError(t, err) require.Len(t, processedImages.All(), 1) assert.Equal(t, image2RefDigest, processedImages.All()[0].UnprocessedImageRef.DigestRef) @@ -1172,9 +1081,8 @@ images: image2RefDigest := fakeRegistry.WithRandomImage(originImageName).RefDigest - subject := subject - subject.ImageFlags.Image = image2RefDigest - subject.registry = fakeRegistry.BuildWithRegistryOpts(registry.Opts{ + origin := v1.CopyOrigin{ImageRef: image2RefDigest} + reg := fakeRegistry.BuildWithRegistryOpts(registry.Opts{ EnvironFunc: func() []string { return []string{ "IMGPKG_REGISTRY_HOSTNAME_0=" + fakeRegistry.ReferenceOnTestServer("repo"), @@ -1192,7 +1100,7 @@ images: fakeRegistry.WithBasicAuthPerRepository("repo", "some-user", "some-password") fakeRegistry.WithBasicAuthPerRepository("some/other", "some-user", "some-password") - processedImages, err := subject.CopyToRepo(destinationImageName) + processedImages, err := v1.CopyToRepository(origin, destinationImageName, opts, reg) require.NoError(t, err) require.Len(t, processedImages.All(), 1) assert.Equal(t, image2RefDigest, processedImages.All()[0].UnprocessedImageRef.DigestRef) @@ -1210,9 +1118,8 @@ images: image2RefDigest := fakeRegistry.WithRandomImage(originImageName).RefDigest - subject := subject - subject.ImageFlags.Image = image2RefDigest - subject.registry = fakeRegistry.BuildWithRegistryOpts(registry.Opts{ + origin := v1.CopyOrigin{ImageRef: image2RefDigest} + reg := fakeRegistry.BuildWithRegistryOpts(registry.Opts{ RetryCount: 2, }) numberOfTries := 0 @@ -1228,7 +1135,7 @@ images: return true }) - _, err := subject.CopyToRepo(destinationImageName) + _, err := v1.CopyToRepository(origin, destinationImageName, opts, reg) assert.Equal(t, 2, numberOfTries) require.Error(t, err) }) @@ -1237,11 +1144,15 @@ images: type fakeSignatureRetriever struct { } -func (f fakeSignatureRetriever) Fetch(images *imageset.UnprocessedImageRefs) (*imageset.UnprocessedImageRefs, error) { +func (f fakeSignatureRetriever) FetchForImageRefs(_ []lockconfig.ImageRef) ([]lockconfig.ImageRef, error) { + return nil, nil +} + +func (f fakeSignatureRetriever) Fetch(_ *imageset.UnprocessedImageRefs) (*imageset.UnprocessedImageRefs, error) { return imageset.NewUnprocessedImageRefs(), nil } -var _ SignatureRetriever = new(fakeSignatureRetriever) +var _ v1.SignatureFetcher = new(fakeSignatureRetriever) func assertTarballContainsEveryLayer(t *testing.T, imageTarPath string) { path := imagetar.NewTarReader(imageTarPath) diff --git a/pkg/imgpkg/v1/describe.go b/pkg/imgpkg/v1/describe.go index 742501538..5a0556ab7 100644 --- a/pkg/imgpkg/v1/describe.go +++ b/pkg/imgpkg/v1/describe.go @@ -9,6 +9,7 @@ import ( "sort" "carvel.dev/imgpkg/pkg/imgpkg/bundle" + "carvel.dev/imgpkg/pkg/imgpkg/imageset" "carvel.dev/imgpkg/pkg/imgpkg/lockconfig" "carvel.dev/imgpkg/pkg/imgpkg/registry" "carvel.dev/imgpkg/pkg/imgpkg/signature" @@ -78,6 +79,7 @@ type DescribeOpts struct { // SignatureFetcher Interface to retrieve signatures associated with Images type SignatureFetcher interface { FetchForImageRefs(images []lockconfig.ImageRef) ([]lockconfig.ImageRef, error) + Fetch(images *imageset.UnprocessedImageRefs) (*imageset.UnprocessedImageRefs, error) } // Describe Given a Bundle URL fetch the information about the contents of the Bundle and Nested Bundles diff --git a/pkg/imgpkg/cmd/test_assets/bundle_with_mult_images/.imgpkg/bundle.yml b/pkg/imgpkg/v1/test_assets/bundle/.imgpkg/bundle.yml similarity index 83% rename from pkg/imgpkg/cmd/test_assets/bundle_with_mult_images/.imgpkg/bundle.yml rename to pkg/imgpkg/v1/test_assets/bundle/.imgpkg/bundle.yml index dd110b24a..21d9583ae 100644 --- a/pkg/imgpkg/cmd/test_assets/bundle_with_mult_images/.imgpkg/bundle.yml +++ b/pkg/imgpkg/v1/test_assets/bundle/.imgpkg/bundle.yml @@ -4,6 +4,6 @@ metadata: name: basic authors: - name: Carvel Team - email: carvel@vmware.com + email: carvel@carvel.dev websites: - url: carvel.dev/imgpkg diff --git a/pkg/imgpkg/v1/test_assets/bundle/.imgpkg/images.yml.template b/pkg/imgpkg/v1/test_assets/bundle/.imgpkg/images.yml.template new file mode 100644 index 000000000..45bc68b0b --- /dev/null +++ b/pkg/imgpkg/v1/test_assets/bundle/.imgpkg/images.yml.template @@ -0,0 +1,6 @@ +apiVersion: imgpkg.carvel.dev/v1alpha1 +kind: ImagesLock +images: +- image: library/image_with_config@sha256:4c8b96d4fffdfae29258d94a22ae4ad1fe36139d47288b8960d9958d1e63a9d0 + annotations: + kbld.carvel.dev/id: docker.io/library/image_with_config diff --git a/pkg/imgpkg/cmd/test_assets/bundle_with_dockerhub_images/config.yml b/pkg/imgpkg/v1/test_assets/bundle/config.yml similarity index 100% rename from pkg/imgpkg/cmd/test_assets/bundle_with_dockerhub_images/config.yml rename to pkg/imgpkg/v1/test_assets/bundle/config.yml diff --git a/pkg/imgpkg/cmd/test_assets/bundle_with_dockerhub_images/.imgpkg/bundle.yml b/pkg/imgpkg/v1/test_assets/bundle_with_dockerhub_images/.imgpkg/bundle.yml similarity index 85% rename from pkg/imgpkg/cmd/test_assets/bundle_with_dockerhub_images/.imgpkg/bundle.yml rename to pkg/imgpkg/v1/test_assets/bundle_with_dockerhub_images/.imgpkg/bundle.yml index 06d4b2899..0bc70f378 100644 --- a/pkg/imgpkg/cmd/test_assets/bundle_with_dockerhub_images/.imgpkg/bundle.yml +++ b/pkg/imgpkg/v1/test_assets/bundle_with_dockerhub_images/.imgpkg/bundle.yml @@ -4,6 +4,6 @@ metadata: name: basic with dockerhub images authors: - name: Carvel Team - email: carvel@vmware.com + email: carvel@carvel.dev websites: - url: carvel.dev/imgpkg diff --git a/pkg/imgpkg/cmd/test_assets/bundle_with_dockerhub_images/.imgpkg/images.yml.template b/pkg/imgpkg/v1/test_assets/bundle_with_dockerhub_images/.imgpkg/images.yml.template similarity index 100% rename from pkg/imgpkg/cmd/test_assets/bundle_with_dockerhub_images/.imgpkg/images.yml.template rename to pkg/imgpkg/v1/test_assets/bundle_with_dockerhub_images/.imgpkg/images.yml.template diff --git a/pkg/imgpkg/cmd/test_assets/bundle_with_mult_images/config.yml b/pkg/imgpkg/v1/test_assets/bundle_with_dockerhub_images/config.yml similarity index 100% rename from pkg/imgpkg/cmd/test_assets/bundle_with_mult_images/config.yml rename to pkg/imgpkg/v1/test_assets/bundle_with_dockerhub_images/config.yml diff --git a/pkg/imgpkg/v1/test_assets/bundle_with_mult_images/.imgpkg/bundle.yml b/pkg/imgpkg/v1/test_assets/bundle_with_mult_images/.imgpkg/bundle.yml new file mode 100644 index 000000000..21d9583ae --- /dev/null +++ b/pkg/imgpkg/v1/test_assets/bundle_with_mult_images/.imgpkg/bundle.yml @@ -0,0 +1,9 @@ +apiVersion: imgpkg.carvel.dev/v1alpha1 +kind: Bundle +metadata: + name: basic +authors: +- name: Carvel Team + email: carvel@carvel.dev +websites: +- url: carvel.dev/imgpkg diff --git a/pkg/imgpkg/cmd/test_assets/bundle_with_mult_images/.imgpkg/images.yml.template b/pkg/imgpkg/v1/test_assets/bundle_with_mult_images/.imgpkg/images.yml.template similarity index 100% rename from pkg/imgpkg/cmd/test_assets/bundle_with_mult_images/.imgpkg/images.yml.template rename to pkg/imgpkg/v1/test_assets/bundle_with_mult_images/.imgpkg/images.yml.template diff --git a/pkg/imgpkg/v1/test_assets/bundle_with_mult_images/config.yml b/pkg/imgpkg/v1/test_assets/bundle_with_mult_images/config.yml new file mode 100644 index 000000000..cca6283ea --- /dev/null +++ b/pkg/imgpkg/v1/test_assets/bundle_with_mult_images/config.yml @@ -0,0 +1,33 @@ +--- +apiVersion: v1 +kind: Service +metadata: + namespace: default + name: simple-app +spec: + ports: + - port: 80 + targetPort: 80 + selector: + simple-app: "" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: default + name: simple-app +spec: + selector: + matchLabels: + simple-app: "" + template: + metadata: + labels: + simple-app: "" + spec: + containers: + - name: simple-app + image: docker.io/dkalinin/k8s-simple-app + env: + - name: HELLO_MSG + value: stranger diff --git a/pkg/imgpkg/v1/test_assets/image_with_config/config.yml b/pkg/imgpkg/v1/test_assets/image_with_config/config.yml new file mode 100644 index 000000000..cca6283ea --- /dev/null +++ b/pkg/imgpkg/v1/test_assets/image_with_config/config.yml @@ -0,0 +1,33 @@ +--- +apiVersion: v1 +kind: Service +metadata: + namespace: default + name: simple-app +spec: + ports: + - port: 80 + targetPort: 80 + selector: + simple-app: "" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: default + name: simple-app +spec: + selector: + matchLabels: + simple-app: "" + template: + metadata: + labels: + simple-app: "" + spec: + containers: + - name: simple-app + image: docker.io/dkalinin/k8s-simple-app + env: + - name: HELLO_MSG + value: stranger diff --git a/test/e2e/copy_from_image_test.go b/test/e2e/copy_from_image_test.go index 5c2bf0603..dd1ad9934 100644 --- a/test/e2e/copy_from_image_test.go +++ b/test/e2e/copy_from_image_test.go @@ -60,7 +60,7 @@ func TestCopyImageToRepoDestinationAndOutputImageLockFileAndPreserveImageTag(t * }) } -func TestCopyAnImageFromATarToARepoThatDoesNotContainNonDistributableLayersButTheFlagWasIncluded(t *testing.T) { +func TestCopyAnImageFromATarToARepoThatDoesContainNonDistributableLayersButTheFlagWasIncluded(t *testing.T) { t.Run("environment with internet", func(t *testing.T) { env := helpers.BuildEnv(t) @@ -74,15 +74,12 @@ func TestCopyAnImageFromATarToARepoThatDoesNotContainNonDistributableLayersButTh nonDistributableLayerDigest := env.ImageFactory.PushImageWithANonDistributableLayer(env.RelocationRepo, types.OCIUncompressedRestrictedLayer) repoToCopyName := env.RelocationRepo + "include-non-distributable-layers" - var stdOutWriter bytes.Buffer // copy to tar skipping NDL - imgpkg.Run([]string{"copy", "-i", env.RelocationRepo, "--to-tar", tarFilePath}) + stdout, _ := imgpkg.RunWithOpts([]string{"copy", "--tty", "-i", env.RelocationRepo, "--to-tar", tarFilePath}, helpers.RunOpts{}) + require.Contains(t, stdout, "Skipped the followings layer(s) due to it being non-distributable") - imgpkg.RunWithOpts([]string{"copy", "--tar", tarFilePath, "--to-repo", repoToCopyName, "--include-non-distributable-layers"}, helpers.RunOpts{ - StderrWriter: &stdOutWriter, - StdoutWriter: &stdOutWriter, - }) + imgpkg.Run([]string{"copy", "--tar", tarFilePath, "--to-repo", repoToCopyName, "--include-non-distributable-layers"}) digestOfNonDistributableLayer, err := name.NewDigest(repoToCopyName + "@" + nonDistributableLayerDigest) require.NoError(t, err) @@ -126,7 +123,7 @@ func TestCopyAnImageFromATarToARepoThatDoesNotContainNonDistributableLayersButTh }) } -func TestCopyAnImageFromARepoToATarThatDoesNotContainNonDistributableLayersButTheFlagWasIncluded(t *testing.T) { +func TestCopyAnImageFromARepoToATarThatDoesContainNonDistributableLayersButTheFlagWasIncluded(t *testing.T) { env := helpers.BuildEnv(t) imgpkg := helpers.Imgpkg{T: t, L: helpers.Logger{}, ImgpkgPath: env.ImgpkgPath} defer env.Cleanup() @@ -141,10 +138,9 @@ func TestCopyAnImageFromARepoToATarThatDoesNotContainNonDistributableLayersButTh }) repoToCopyName := env.RelocationRepo + "-include-non-distributable-layers-1" - var stdOutWriter bytes.Buffer logger.Section("copying an image that contains a NDL to a tarball (the tarball includes the NDL)", func() { - imgpkg.Run([]string{"copy", "-i", env.RelocationRepo, "--to-tar", tarFilePath, "--include-non-distributable-layers"}) + imgpkg.Run([]string{"copy", "--tty", "-i", env.RelocationRepo, "--to-tar", tarFilePath, "--include-non-distributable-layers"}) }) var imageDigest string @@ -157,8 +153,47 @@ func TestCopyAnImageFromARepoToATarThatDoesNotContainNonDistributableLayersButTh }) logger.Section("copying from a repo (the image in the repo does *not* include the NDL) to a tarball. We expect NDL to be copied into the tarball", func() { - imgpkg.Run([]string{"copy", "-i", repoToCopyName + imageDigest, "--to-tar", tarFilePath + "2", "--include-non-distributable-layers"}) - require.NotContains(t, stdOutWriter.String(), "--include-non-distributable-layers") + stdout := imgpkg.Run([]string{"copy", "--tty", "-i", repoToCopyName + imageDigest, "--to-tar", tarFilePath + "2", "--include-non-distributable-layers"}) + require.NotContains(t, stdout, "--include-non-distributable-layers") + }) +} + +func TestCopyAnImageFromARepoToATarThatDoesNOTContainNonDistributableLayersAndTheFlagWasIncluded(t *testing.T) { + env := helpers.BuildEnv(t) + imgpkg := helpers.Imgpkg{T: t, L: helpers.Logger{}, ImgpkgPath: env.ImgpkgPath} + defer env.Cleanup() + logger := helpers.Logger{} + + var tarFilePath, imgRef string + logger.Section("Create Image without Non Distributable Layer", func() { + testDir := env.Assets.CreateTempFolder("image-to-tar") + tarFilePath = filepath.Join(testDir, "image.tar") + imgName := env.Image + "-no-distributable-layers" + imgRef = imgName + env.ImageFactory.PushSimpleAppImageWithRandomFile(imgpkg, imgName) + }) + + logger.Section("copying an image to tar providing the flag --include-non-distributable-layers provides warning", func() { + stdout := imgpkg.Run([]string{"copy", "--tty", "-i", imgRef, "--to-tar", tarFilePath, "--include-non-distributable-layers"}) + require.Contains(t, stdout, "flag provided, but no images contained a non-distributable layer") + }) +} + +func TestCopyAnImageFromARepoToATarThatDoesContainNonDistributableLayersAndTheFlagWasNOTIncluded(t *testing.T) { + env := helpers.BuildEnv(t) + imgpkg := helpers.Imgpkg{T: t, L: helpers.Logger{}, ImgpkgPath: env.ImgpkgPath} + defer env.Cleanup() + logger := helpers.Logger{} + + var tarFilePath string + logger.Section("Create Image with Non Distributable Layer", func() { + testDir := env.Assets.CreateTempFolder("image-to-tar") + tarFilePath = filepath.Join(testDir, "image.tar") + env.ImageFactory.PushImageWithANonDistributableLayer(env.RelocationRepo, types.OCIUncompressedRestrictedLayer) + }) + + logger.Section("copying an image to tar providing the flag --include-non-distributable-layers provides warning", func() { + stdout := imgpkg.Run([]string{"copy", "--tty", "-i", env.RelocationRepo, "--to-tar", tarFilePath}) + require.Contains(t, stdout, "Skipped the followings layer(s) due to it being non-distributable") }) } @@ -246,7 +281,7 @@ func TestCopyRepoToTarAndThenCopyFromTarToRepo(t *testing.T) { }) logger.Section("Check that non distributable layer was not copied", func() { - require.Contains(t, stdOutWriter.String(), "Skipped the followings layer(s) due") + require.Contains(t, stdOutWriter.String(), "Skipped the followings layer(s) due to it being non-distributable") digestOfNonDistributableLayer, err := name.NewDigest(repoToCopyName + "@" + nonDistributableLayerDigest) require.NoError(t, err) diff --git a/test/helpers/fake_registry.go b/test/helpers/fake_registry.go index dcbab0ef4..f65cef949 100644 --- a/test/helpers/fake_registry.go +++ b/test/helpers/fake_registry.go @@ -655,7 +655,11 @@ func (r *FakeTestRegistryBuilder) CleanUp() { } } +// ReferenceOnTestServer adds the registry location to the repository name provided if is not "" func (r *FakeTestRegistryBuilder) ReferenceOnTestServer(repo string) string { + if repo == "" { + return "" + } u, err := url.Parse(r.server.URL) assert.NoError(r.t, err) return fmt.Sprintf("%s/%s", u.Host, repo) From 038dd374e313575ee57411de0d65b79f32ca14f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pereira?= Date: Thu, 30 May 2024 15:06:15 -0500 Subject: [PATCH 2/2] Allow parameters to be passed to all tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: João Pereira --- hack/test-all-local-registry.sh | 2 +- hack/test-all.sh | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hack/test-all-local-registry.sh b/hack/test-all-local-registry.sh index 3b9d12bbd..2ba0984dc 100755 --- a/hack/test-all-local-registry.sh +++ b/hack/test-all-local-registry.sh @@ -13,4 +13,4 @@ trap cleanup EXIT docker run -d -p "$PORT":5000 -e REGISTRY_VALIDATION_MANIFESTS_URLS_ALLOW='- ^https?://' --restart always --name registry-"$PORT" registry:2 export IMGPKG_E2E_IMAGE="localhost:$PORT/local-tests/test-repo" export IMGPKG_E2E_RELOCATION_REPO="localhost:$PORT/local-tests/test-relocation-repo" -./hack/test-all.sh $@ +./hack/test-all.sh ${@:2} diff --git a/hack/test-all.sh b/hack/test-all.sh index 54b710a2b..462f7aa40 100755 --- a/hack/test-all.sh +++ b/hack/test-all.sh @@ -10,9 +10,9 @@ fi export IMGPKG_BINARY="$PWD/imgpkg${IMGPKG_BINARY_EXT-}" -./hack/test.sh -./hack/test-e2e.sh -./hack/test-perf.sh -./hack/test-helpers.sh +./hack/test.sh $@ +./hack/test-e2e.sh $@ +./hack/test-perf.sh $@ +./hack/test-helpers.sh $@ echo ALL SUCCESS