diff --git a/pkg/imgpkg/cmd/describe.go b/pkg/imgpkg/cmd/describe.go index 8616ea0d0..a7298e7e6 100644 --- a/pkg/imgpkg/cmd/describe.go +++ b/pkg/imgpkg/cmd/describe.go @@ -140,7 +140,7 @@ func (p bundleTextPrinter) printerRec(description v1.Description, originalLogger indentLogger.Logf(" Origin: %s\n", b.Origin) indentLogger.Logf(" Layers:\n") for _, d := range b.Layers { - indentLogger.Logf(" - Digest: %s\n", d) + indentLogger.Logf(" - Digest: %s\n", d.Digest) } annotations := b.Annotations @@ -166,7 +166,7 @@ func (p bundleTextPrinter) printerRec(description v1.Description, originalLogger } indentLogger.Logf(" Layers:\n") for _, d := range image.Layers { - indentLogger.Logf(" - Digest: %s\n", d) + indentLogger.Logf(" - Digest: %s\n", d.Digest) } annotations := image.Annotations p.printAnnotations(annotations, util.NewIndentedLogger(indentLogger)) diff --git a/pkg/imgpkg/v1/describe.go b/pkg/imgpkg/v1/describe.go index 2a2d7a084..a1cc67454 100644 --- a/pkg/imgpkg/v1/describe.go +++ b/pkg/imgpkg/v1/describe.go @@ -36,6 +36,11 @@ type Metadata struct { Websites []Website `json:"websites,omitempty"` } +// Layers image layers info +type Layers struct { + Digest string `json:"digest,omitempty"` +} + // ImageInfo URLs where the image can be found as well as annotations provided in the Images Lock type ImageInfo struct { Image string `json:"image,omitempty"` @@ -43,7 +48,7 @@ type ImageInfo struct { Annotations map[string]string `json:"annotations,omitempty"` ImageType bundle.ImageType `json:"imageType"` Error string `json:"error,omitempty"` - Layers []string `json:"layers,omitempty"` + Layers []Layers `json:"layers,omitempty"` } // Content Contents present in a Bundle @@ -59,7 +64,7 @@ type Description struct { Annotations map[string]string `json:"annotations,omitempty"` Metadata Metadata `json:"metadata,omitempty"` Content Content `json:"content"` - Layers []string `json:"layers,omitempty"` + Layers []Layers `json:"layers,omitempty"` } // DescribeOpts Options used when calling the Describe function @@ -111,7 +116,7 @@ func DescribeWithRegistryAndSignatureFetcher(bundleImage string, opts DescribeOp topBundle := refWithDescription{ imgRef: bundle.NewBundleImageRef(lockconfig.ImageRef{Image: newBundle.DigestRef()}), } - return topBundle.DescribeBundle(allBundles), nil + return topBundle.DescribeBundle(allBundles) } type refWithDescription struct { @@ -119,40 +124,22 @@ type refWithDescription struct { bundle Description } -func (r *refWithDescription) DescribeBundle(bundles []*bundle.Bundle) Description { +func (r *refWithDescription) DescribeBundle(bundles []*bundle.Bundle) (Description, error) { var visitedImgs map[string]refWithDescription return r.describeBundleRec(visitedImgs, r.imgRef, bundles) } -func (r *refWithDescription) describeBundleRec(visitedImgs map[string]refWithDescription, currentBundle bundle.ImageRef, bundles []*bundle.Bundle) Description { +func (r *refWithDescription) describeBundleRec(visitedImgs map[string]refWithDescription, currentBundle bundle.ImageRef, bundles []*bundle.Bundle) (Description, error) { desc, wasVisited := visitedImgs[currentBundle.Image] if wasVisited { - return desc.bundle - } - - layers := []string{} - parsedImgRef, err := regname.ParseReference(currentBundle.Image, regname.WeakValidation) - if err != nil { - panic(fmt.Sprintf("Internal inconsistency: image %s should be fully resolved, error: %s", currentBundle.Image, err.Error())) - } - - v1Img, err := remote.Image(parsedImgRef, remote.WithAuthFromKeychain(authn.DefaultKeychain)) - if err != nil { - panic(fmt.Sprintf("Internal inconsistency: image %s should be fully resolved, error: %s", currentBundle.Image, err.Error())) + return desc.bundle, nil } - imgLayers, err := v1Img.Layers() + layers, err := getImageLayersInfo(currentBundle.Image) if err != nil { - panic(fmt.Sprintf("Internal inconsistency: image %s should be fully resolved, error: %s", currentBundle.Image, err.Error())) + return desc.bundle, err } - for _, imgLayer := range imgLayers { - digHash, err := imgLayer.Digest() - if err != nil { - panic(fmt.Sprintf("Internal inconsistency: image %s should be fully resolved, error: %s", currentBundle.Image, err.Error())) - } - layers = append(layers, digHash.String()) - } desc = refWithDescription{ imgRef: currentBundle, bundle: Description{ @@ -175,57 +162,40 @@ func (r *refWithDescription) describeBundleRec(visitedImgs map[string]refWithDes } } if newBundle == nil { - panic(fmt.Sprintf("Internal consistency: bundle with ref '%s' could not be found in list of bundles", currentBundle.PrimaryLocation())) + return desc.bundle, fmt.Errorf("Internal consistency: bundle with ref '%s' could not be found in list of bundles", currentBundle.PrimaryLocation()) } imagesRefs := newBundle.ImagesRefsWithErrors() - sort.Slice(imagesRefs, func(i, j int) bool { return imagesRefs[i].Image < imagesRefs[j].Image }) for _, ref := range imagesRefs { if ref.IsBundle == nil { - panic("Internal consistency: IsBundle after processing must always have a value") + return desc.bundle, fmt.Errorf("Internal consistency: IsBundle after processing must always have a value") } if *ref.IsBundle { - bundleDesc := r.describeBundleRec(visitedImgs, ref, bundles) + bundleDesc, err := r.describeBundleRec(visitedImgs, ref, bundles) + if err != nil { + return desc.bundle, err + } + digest, err := name.NewDigest(bundleDesc.Image) if err != nil { - panic(fmt.Sprintf("Internal inconsistency: image %s should be fully resolved", bundleDesc.Image)) + return desc.bundle, fmt.Errorf("Internal inconsistency: image %s should be fully resolved", bundleDesc.Image) } desc.bundle.Content.Bundles[digest.DigestStr()] = bundleDesc } else { if ref.Error == "" { digest, err := name.NewDigest(ref.Image) if err != nil { - panic(fmt.Sprintf("Internal inconsistency: image %s should be fully resolved", ref.Image)) - } - layers = []string{} - parsedImgRef, err = regname.ParseReference(ref.Image, regname.WeakValidation) - if err != nil { - panic(fmt.Sprintf("Internal inconsistency: image %s should be fully resolved, error: %s", ref.Image, err.Error())) - } - - v1Img, err = remote.Image(parsedImgRef, remote.WithAuthFromKeychain(authn.DefaultKeychain)) - if err != nil { - panic(fmt.Sprintf("Internal inconsistency: image %s should be fully resolved, error: %s", ref.Image, err.Error())) + return desc.bundle, fmt.Errorf("Internal inconsistency: image %s should be fully resolved", ref.Image) } - - imgLayers, err = v1Img.Layers() + layers, err = getImageLayersInfo(ref.Image) if err != nil { - panic(fmt.Sprintf("Internal inconsistency: image %s should be fully resolved, error: %s", ref.Image, err.Error())) - } - - for _, imgLayer := range imgLayers { - digHash, err := imgLayer.Digest() - if err != nil { - panic(fmt.Sprintf("Internal inconsistency: image %s should be fully resolved, error: %s", ref.Image, err.Error())) - } - layers = append(layers, digHash.String()) + return desc.bundle, err } - desc.bundle.Content.Images[digest.DigestStr()] = ImageInfo{ Image: ref.PrimaryLocation(), Origin: ref.Image, @@ -242,5 +212,32 @@ func (r *refWithDescription) describeBundleRec(visitedImgs map[string]refWithDes } } - return desc.bundle + return desc.bundle, nil +} + +func getImageLayersInfo(image string) ([]Layers, error) { + layers := []Layers{} + parsedImgRef, err := regname.ParseReference(image, regname.WeakValidation) + if err != nil { + return nil, fmt.Errorf("Error: %s in parsing image %s", err.Error(), image) + } + + v1Img, err := remote.Image(parsedImgRef, remote.WithAuthFromKeychain(authn.DefaultKeychain)) + if err != nil { + return nil, fmt.Errorf("Error: %s in getting remote access of image %s", err.Error(), image) + } + + imgLayers, err := v1Img.Layers() + if err != nil { + return nil, fmt.Errorf("Error: %s in getting layers of image %s", err.Error(), image) + } + + for _, imgLayer := range imgLayers { + digHash, err := imgLayer.Digest() + if err != nil { + return nil, fmt.Errorf("Error: %s in getting digest of layer's of image %s", err.Error(), image) + } + layers = append(layers, Layers{Digest: digHash.String()}) + } + return layers, nil } diff --git a/test/e2e/describe_test.go b/test/e2e/describe_test.go index 4e0ca5b9a..194bc8716 100644 --- a/test/e2e/describe_test.go +++ b/test/e2e/describe_test.go @@ -67,42 +67,46 @@ images: "--bundle", fmt.Sprintf("%s%s", env.RelocationRepo, bundleDigest), }, ) - fmt.Printf("\n\nOutput: %s\n\n", stdout) + + digestSha := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + imageDigest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s%s Type: Image Origin: %s%s - Layers: - - Digest: "sha256:a37f35f3e418ea6c1b339df0fc89c8d3155d937740445906ba71466996fac625" + Layers: + - Digest: %s Annotations: some.annotation: some value some.other.annotation: some other value -`, env.RelocationRepo, imageDigest, env.Image, imageDigest)) +`, env.RelocationRepo, imageDigest, env.Image, imageDigest, digestSha)) + digestSha = env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + imgSigDigest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s@%s Type: Signature - Layers: - - Digest: "sha256:4197c5ac7fb0ba1e597a2377a1b58332d10f6de53dce9c89fd96a3f37034f88b" + Layers: + - Digest: %s Annotations: tag: %s -`, env.RelocationRepo, imgSigDigest, imgSigTag)) +`, env.RelocationRepo, imgSigDigest, digestSha, imgSigTag)) + + digestSha = env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + bundleSigDigest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s@%s Type: Signature - Layers: - - Digest: "sha256:28014a7e4bef0b7c3f1da47d095f8bb131f474bd5fc96caa4d6125818220b00e" + Layers: + - Digest: %s Annotations: tag: %s -`, env.RelocationRepo, bundleSigDigest, bundleSigTag)) +`, env.RelocationRepo, bundleSigDigest, digestSha, bundleSigTag)) + digestSha = env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + locationsImgDigest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s@%s Type: Internal - Layers: - - - Digest: "sha256:5d43e9fc8f1ad1b339b5f37bb050b150640ad2c1594345178f1fb38656583a94" -`, env.RelocationRepo, locationsImgDigest)) + Layers: + - Digest: %s +`, env.RelocationRepo, locationsImgDigest, digestSha)) }) }) @@ -175,39 +179,61 @@ images: locationsNestedBundleImgDigest := env.ImageFactory.ImageDigest(fmt.Sprintf("%s:%s.image-locations.imgpkg", env.RelocationRepo, strings.ReplaceAll(nestedBundleDigest[1:], ":", "-"))) locationsOuterBundleImgDigest := env.ImageFactory.ImageDigest(fmt.Sprintf("%s:%s.image-locations.imgpkg", env.RelocationRepo, strings.ReplaceAll(outerBundleDigest[1:], ":", "-"))) + digestSha := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + nestedBundleDigest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s%s Type: Bundle Origin: %s%s + Layers: + - Digest: %s Annotations: what is this: this is the nested bundle -`, env.RelocationRepo, nestedBundleDigest, nestedBundle, nestedBundleDigest)) +`, env.RelocationRepo, nestedBundleDigest, nestedBundle, nestedBundleDigest, digestSha)) + digestSha = env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + img1Digest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s%s Type: Image Origin: %s -`, env.RelocationRepo, img1Digest, img1DigestRef)) + Layers: + - Digest: %s +`, env.RelocationRepo, img1Digest, img1DigestRef, digestSha)) + + digestSha = env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + img2Digest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s%s Type: Image Origin: %s -`, env.RelocationRepo, img2Digest, img2DigestRef)) + Layers: + - Digest: %s +`, env.RelocationRepo, img2Digest, img2DigestRef, digestSha)) + + digestSha = env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + locationsNestedBundleImgDigest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s@%s Type: Internal -`, env.RelocationRepo, locationsNestedBundleImgDigest)) + Layers: + - Digest: %s +`, env.RelocationRepo, locationsNestedBundleImgDigest, digestSha)) + + digestSha = env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + img1Digest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s%s Type: Image Origin: %s + Layers: + - Digest: %s Annotations: what is this: this is just an image -`, env.RelocationRepo, img1Digest, img1DigestRef)) +`, env.RelocationRepo, img1Digest, img1DigestRef, digestSha)) + + digestSha = env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + locationsOuterBundleImgDigest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s@%s Type: Internal -`, env.RelocationRepo, locationsOuterBundleImgDigest)) + Layers: + - Digest: %s +`, env.RelocationRepo, locationsOuterBundleImgDigest, digestSha)) }) }) @@ -273,33 +299,51 @@ images: }, ) + digestSha := env.ImageFactory.GetImageLayerDigest(nestedBundle + nestedBundleDigest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s%s Type: Bundle Origin: %s%s -`, nestedBundle, nestedBundleDigest, nestedBundle, nestedBundleDigest)) + Layers: + - Digest: %s +`, nestedBundle, nestedBundleDigest, nestedBundle, nestedBundleDigest, digestSha)) + + digestSha = env.ImageFactory.GetImageLayerDigest(img1DigestRef) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s Type: Image Origin: %s -`, img1DigestRef, img1DigestRef)) + Layers: + - Digest: %s +`, img1DigestRef, img1DigestRef, digestSha)) + + digestSha = env.ImageFactory.GetImageLayerDigest(img2DigestRef) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s Type: Image Origin: %s -`, img2DigestRef, img2DigestRef)) + Layers: + - Digest: %s +`, img2DigestRef, img2DigestRef, digestSha)) + + digestSha = env.ImageFactory.GetImageLayerDigest(imgRef.Context().Name() + "-img2" + "@" + img2SigDigest) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s@%s Type: Signature + Layers: + - Digest: %s Annotations: tag: %s -`, imgRef.Context().Name()+"-img2", img2SigDigest, img2SigTag)) +`, imgRef.Context().Name()+"-img2", img2SigDigest, digestSha, img2SigTag)) + digestSha = env.ImageFactory.GetImageLayerDigest(img1DigestRef) assert.Contains(t, stdout, fmt.Sprintf( ` - Image: %s Type: Image Origin: %s -`, img1DigestRef, img1DigestRef)) + Layers: + - Digest: %s +`, img1DigestRef, img1DigestRef, digestSha)) }) }) } @@ -359,6 +403,11 @@ images: stdoutLines := strings.Split(stdout, "\n") stdout = strings.Join(stdoutLines[:len(stdoutLines)-1], "\n") + digestSha1 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + imageDigest) + digestSha2 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + bundleSigDigest) + digestSha3 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + imgSigDigest) + digestSha4 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + locationsImgDigest) + digestSha5 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + bundleDigest) require.YAMLEq(t, fmt.Sprintf(`sha: %s content: images: @@ -368,42 +417,56 @@ content: some.other.annotation: some other value image: %s%s imageType: Image + layers: + - digest: %s origin: %s%s "%s": annotations: tag: %s image: %s@%s imageType: Signature + layers: + - digest: %s origin: %s@%s "%s": annotations: tag: %s image: %s@%s imageType: Signature + layers: + - digest: %s origin: %s@%s "%s": image: %s@%s imageType: Internal + layers: + - digest: %s origin: %s@%s image: %s%s +layers: +- digest: %s metadata: {} origin: %s%s `, bundleDigest[1:], imageDigest[1:], env.RelocationRepo, imageDigest, + digestSha1, env.Image, imageDigest, bundleSigDigest, bundleSigTag, env.RelocationRepo, bundleSigDigest, + digestSha2, env.RelocationRepo, bundleSigDigest, imgSigDigest, imgSigTag, env.RelocationRepo, imgSigDigest, + digestSha3, env.RelocationRepo, imgSigDigest, locationsImgDigest, env.RelocationRepo, locationsImgDigest, + digestSha4, env.RelocationRepo, locationsImgDigest, - env.RelocationRepo, bundleDigest, env.RelocationRepo, bundleDigest), stdout) + env.RelocationRepo, bundleDigest, digestSha5, env.RelocationRepo, bundleDigest), stdout) }) }) @@ -456,7 +519,11 @@ images: }, ) locationsImgDigest := env.ImageFactory.ImageDigest(fmt.Sprintf("%s:%s.image-locations.imgpkg", env.RelocationRepo, strings.ReplaceAll(bundleDigest[1:], ":", "-"))) - + digestSha1 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + imageDigest) + digestSha2 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + bundleSigDigest) + digestSha3 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + imgSigDigest) + digestSha4 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + locationsImgDigest) + digestSha5 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + bundleDigest) require.YAMLEq(t, fmt.Sprintf(`content: images: "%s": @@ -465,43 +532,53 @@ images: some.other.annotation: some other value image: %s%s imageType: Image + layers: + - digest: %s origin: %s%s "%s": annotations: tag: %s image: %s@%s imageType: Signature + layers: + - digest: %s origin: %s@%s "%s": annotations: tag: %s image: %s@%s imageType: Signature + layers: + - digest: %s origin: %s@%s "%s": image: %s@%s imageType: Internal + layers: + - digest: %s origin: %s@%s metadata: {} image: %s%s +layers: +- digest: %s origin: %s%s sha: %s `, imageDigest[1:], - env.RelocationRepo, imageDigest, + env.RelocationRepo, imageDigest, digestSha1, env.Image, imageDigest, bundleSigDigest, bundleSigTag, - env.RelocationRepo, bundleSigDigest, + env.RelocationRepo, bundleSigDigest, digestSha2, env.RelocationRepo, bundleSigDigest, imgSigDigest, imgSigTag, - env.RelocationRepo, imgSigDigest, + env.RelocationRepo, imgSigDigest, digestSha3, env.RelocationRepo, imgSigDigest, locationsImgDigest, + env.RelocationRepo, locationsImgDigest, digestSha4, env.RelocationRepo, locationsImgDigest, - env.RelocationRepo, locationsImgDigest, - env.RelocationRepo, bundleDigest, env.RelocationRepo, bundleDigest, bundleDigest[1:]), stdout) + env.RelocationRepo, bundleDigest, digestSha5, env.RelocationRepo, bundleDigest, bundleDigest[1:]), stdout) }) }) @@ -576,6 +653,13 @@ images: locationsOuterBundleImgDigest := env.ImageFactory.ImageDigest(fmt.Sprintf("%s:%s.image-locations.imgpkg", env.RelocationRepo, strings.ReplaceAll(outerBundleDigest[1:], ":", "-"))) stdoutLines := strings.Split(stdout, "\n") stdout = strings.Join(stdoutLines[:len(stdoutLines)-1], "\n") + digestSha1 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + img1Digest) + digestSha2 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + img2Digest) + digestSha3 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + locationsNestedBundleImgDigest) + digestSha4 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + nestedBundleDigest) + digestSha5 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + img1Digest) + digestSha6 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + "@" + locationsOuterBundleImgDigest) + digestSha7 := env.ImageFactory.GetImageLayerDigest(env.RelocationRepo + outerBundleDigest) require.YAMLEq(t, fmt.Sprintf(`sha: %s content: bundles: @@ -587,16 +671,24 @@ content: "%s": image: %s%s imageType: Image + layers: + - digest: %s origin: %s "%s": image: %s%s imageType: Image + layers: + - digest: %s origin: %s "%s": image: %s@%s imageType: Internal + layers: + - digest: %s origin: %s@%s image: %s%s + layers: + - digest: %s metadata: {} origin: %s%s images: @@ -605,29 +697,35 @@ content: what is this: this is just an image image: %s%s imageType: Image + layers: + - digest: %s origin: %s "%s": image: %s@%s imageType: Internal + layers: + - digest: %s origin: %s@%s image: %s%s +layers: +- digest: %s metadata: {} origin: %s%s `, outerBundleDigest[1:], nestedBundleDigest[1:], img1Digest[1:], - env.RelocationRepo, img1Digest, img1DigestRef, + env.RelocationRepo, img1Digest, digestSha1, img1DigestRef, img2Digest[1:], - env.RelocationRepo, img2Digest, img2DigestRef, + env.RelocationRepo, img2Digest, digestSha2, img2DigestRef, locationsNestedBundleImgDigest, - env.RelocationRepo, locationsNestedBundleImgDigest, env.RelocationRepo, locationsNestedBundleImgDigest, - env.RelocationRepo, nestedBundleDigest, nestedBundle, nestedBundleDigest, + env.RelocationRepo, locationsNestedBundleImgDigest, digestSha3, env.RelocationRepo, locationsNestedBundleImgDigest, + env.RelocationRepo, nestedBundleDigest, digestSha4, nestedBundle, nestedBundleDigest, img1Digest[1:], - env.RelocationRepo, img1Digest, img1DigestRef, + env.RelocationRepo, img1Digest, digestSha5, img1DigestRef, locationsOuterBundleImgDigest, - env.RelocationRepo, locationsOuterBundleImgDigest, env.RelocationRepo, locationsOuterBundleImgDigest, - env.RelocationRepo, outerBundleDigest, env.RelocationRepo, outerBundleDigest, + env.RelocationRepo, locationsOuterBundleImgDigest, digestSha6, env.RelocationRepo, locationsOuterBundleImgDigest, + env.RelocationRepo, outerBundleDigest, digestSha7, env.RelocationRepo, outerBundleDigest, ), stdout) }) }) @@ -696,6 +794,12 @@ images: stdoutLines := strings.Split(stdout, "\n") stdout = strings.Join(stdoutLines[:len(stdoutLines)-1], "\n") + digestSha1 := env.ImageFactory.GetImageLayerDigest(img1DigestRef) + digestSha2 := env.ImageFactory.GetImageLayerDigest(img2DigestRef) + digestSha3 := env.ImageFactory.GetImageLayerDigest(imgRef.Context().Name() + "-img2" + "@" + img2SigDigest) + digestSha4 := env.ImageFactory.GetImageLayerDigest(nestedBundle + nestedBundleDigest) + digestSha5 := env.ImageFactory.GetImageLayerDigest(img1DigestRef) + digestSha6 := env.ImageFactory.GetImageLayerDigest(outerBundle + outerBundleDigest) require.YAMLEq(t, fmt.Sprintf(`sha: %s content: bundles: @@ -705,43 +809,55 @@ content: "%s": image: %s imageType: Image + layers: + - digest: %s origin: %s "%s": image: %s imageType: Image + layers: + - digest: %s origin: %s "%s": annotations: tag: %s image: %s@%s imageType: Signature + layers: + - digest: %s origin: %s@%s image: %s%s + layers: + - digest: %s metadata: {} origin: %s%s images: "%s": image: %s imageType: Image + layers: + - digest: %s origin: %s image: %s%s +layers: +- digest: %s metadata: {} origin: %s%s `, outerBundleDigest[1:], nestedBundleDigest[1:], img1Digest[1:], - img1DigestRef, img1DigestRef, + img1DigestRef, digestSha1, img1DigestRef, img2Digest[1:], - img2DigestRef, img2DigestRef, + img2DigestRef, digestSha2, img2DigestRef, img2SigDigest, img2SigTag, + imgRef.Context().Name()+"-img2", img2SigDigest, digestSha3, imgRef.Context().Name()+"-img2", img2SigDigest, - imgRef.Context().Name()+"-img2", img2SigDigest, - nestedBundle, nestedBundleDigest, nestedBundle, nestedBundleDigest, + nestedBundle, nestedBundleDigest, digestSha4, nestedBundle, nestedBundleDigest, img1Digest[1:], - img1DigestRef, img1DigestRef, - outerBundle, outerBundleDigest, outerBundle, outerBundleDigest, + img1DigestRef, digestSha5, img1DigestRef, + outerBundle, outerBundleDigest, digestSha6, outerBundle, outerBundleDigest, ), stdout) }) }) diff --git a/test/helpers/image_factory.go b/test/helpers/image_factory.go index e3e1a9998..5bc6c7b0b 100644 --- a/test/helpers/image_factory.go +++ b/test/helpers/image_factory.go @@ -42,6 +42,25 @@ func (i *ImageFactory) ImageDigest(imgRef string) string { return digest.String() } +// GetImageLayerDigest will return image's layer digest +func (i *ImageFactory) GetImageLayerDigest(image string) string { + parsedImgRef, err := name.ParseReference(image, name.WeakValidation) + require.NoError(i.T, err) + + v1Img, err := remote.Image(parsedImgRef, remote.WithAuthFromKeychain(authn.DefaultKeychain)) + require.NoError(i.T, err) + + imgLayers, err := v1Img.Layers() + require.NoError(i.T, err) + digestSha := "" + for _, imgLayer := range imgLayers { + digHash, err := imgLayer.Digest() + require.NoError(i.T, err) + digestSha = digHash.String() + } + return digestSha +} + func (i *ImageFactory) PushImageWithANonDistributableLayer(imgRef string, mediaType types.MediaType) string { imageRef, err := name.ParseReference(imgRef, name.WeakValidation) require.NoError(i.T, err)