Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions tests/integration/dry_run_test.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package integration_test

import (
"os"
"path/filepath"
"strings"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

var _ = Describe("dry-run", func() {
Expand Down Expand Up @@ -65,4 +68,69 @@ var _ = Describe("dry-run", func() {
expectNoRepositoriesInRegistry(*testRegistry)
})
})

Describe("mirrorToDisk dry-run with a manifest list image", func() {
iscManifestList := filepath.Join("dry_run", "isc-manifest-list.yaml")
topLevelSource := "docker://quay.io/openshifttest/hello-openshift@sha256:61b8f5e1a3b5dbd9e2c35fd448dc5106337d7a299873dd3a6f0cd8d4891ecc27"

// The digest above resolves to a manifest list (image index) with these two
// platform-specific sub-manifests, which never change since it's pinned by digest.
manifestListSubDigests := []string{
"sha256:685a0ca5f33d9f921966c9d9f5922e266affbf93dde0c156709ecdea362f88f4",
"sha256:a51d6da571b2e1f57249f4d966af65cbfb361dad66cde7121c1bb656ab196269",
}

It("should include manifest list sub-digests in mapping.txt (OCPBUGS-66263)", func() {
By("running mirrorToDisk with --dry-run-manifest-lists")
result, err := runner.MirrorToDisk(ctx, filepath.Join(iscDir, iscManifestList), workDir,
"--remove-signatures=true", "--dry-run-manifest-lists")
expectOcMirrorCommandSuccess(result, err)

By("verifying mapping.txt contains an entry for each manifest list sub-digest")
expectMappingContainsManifestListSubDigests(workDir, topLevelSource, manifestListSubDigests)
})
})
})

// expectMappingContainsManifestListSubDigests verifies that mapping.txt contains one extra
// line per manifest list sub-digest, each re-pinned to the top-level destination's repository.
// Guards against OCPBUGS-66263, where sub-manifest digests were dropped from the mapping file.
func expectMappingContainsManifestListSubDigests(workDir, topLevelSource string, subDigests []string) {
mappingPath := filepath.Join(workDir, dirWorkingDir, "dry-run", "mapping.txt")
data, err := os.ReadFile(mappingPath)
Expect(err).NotTo(HaveOccurred(), "mapping.txt not found at: %s", mappingPath)

mappings := make(map[string]string)
for _, line := range strings.Split(strings.TrimSpace(string(data)), "\n") {
parts := strings.SplitN(line, "=", 2)
Expect(parts).To(HaveLen(2), "mapping line does not follow source=destination format: %s", line)
mappings[parts[0]] = parts[1]
}

destination, found := mappings[topLevelSource]
Expect(found).To(BeTrue(), "mapping.txt does not contain top-level entry for %q", topLevelSource)

sourceBase, _, _ := strings.Cut(topLevelSource, "@")
destBase := stripTagOrDigest(destination)
for _, digest := range subDigests {
subSource := sourceBase + "@" + digest
subDest := destBase + "@" + digest
Expect(mappings).To(HaveKeyWithValue(subSource, subDest),
"mapping.txt is missing sub-digest entry %q -> %q", subSource, subDest)
}
}

// stripTagOrDigest removes a trailing ":tag" or "@digest" from an image reference. Tag
// separators are only looked for after the last "/", so a registry port (e.g. "localhost:55000")
// isn't mistaken for one.
func stripTagOrDigest(ref string) string {
if base, _, found := strings.Cut(ref, "@"); found {
return base
}
if slash := strings.LastIndex(ref, "/"); slash != -1 {
if colon := strings.Index(ref[slash:], ":"); colon != -1 {
return ref[:slash+colon]
}
}
return ref
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# ImageSetConfig to test dry-run mapping of a manifest list (multi-arch) additional image.
# quay.io/openshifttest/hello-openshift@sha256:61b8f5e1a3b5dbd9e2c35fd448dc5106337d7a299873dd3a6f0cd8d4891ecc27
# is a manifest list with two platform-specific sub-manifests (arm64, ppc64le), used to verify that
# dry-run mapping.txt includes an entry for each sub-digest (OCPBUGS-66263).
kind: ImageSetConfiguration
apiVersion: mirror.openshift.io/v2alpha1
mirror:
additionalImages:
- name: quay.io/openshifttest/hello-openshift@sha256:61b8f5e1a3b5dbd9e2c35fd448dc5106337d7a299873dd3a6f0cd8d4891ecc27