diff --git a/cmd/buildah/manifest.go b/cmd/buildah/manifest.go index ae49b801b9c..08fd63693e5 100644 --- a/cmd/buildah/manifest.go +++ b/cmd/buildah/manifest.go @@ -227,6 +227,7 @@ func init() { flags.StringVar(&manifestPushOpts.creds, "creds", "", "use `[username[:password]]` for accessing the registry") flags.StringVar(&manifestPushOpts.digestfile, "digestfile", "", "after copying the image, write the digest of the resulting digest to the file") flags.StringVarP(&manifestPushOpts.format, "format", "f", "", "manifest type (oci or v2s2) to attempt to use when pushing the manifest list (default is manifest type of source)") + flags.StringSliceVar(&manifestPushOpts.addCompression, "add-compression", nil, "add instances with selected compression while pushing") flags.BoolVarP(&manifestPushOpts.removeSignatures, "remove-signatures", "", false, "don't copy signatures when pushing images") flags.StringVar(&manifestPushOpts.signBy, "sign-by", "", "sign the image using a GPG key with the specified `FINGERPRINT`") flags.StringVar(&manifestPushOpts.signaturePolicy, "signature-policy", "", "`pathname` of signature policy file (not usually used)") @@ -906,6 +907,7 @@ func manifestPush(systemContext *types.SystemContext, store storage.Store, listI RemoveSignatures: opts.removeSignatures, SignBy: opts.signBy, ManifestType: manifestType, + AddCompression: opts.addCompression, } if opts.all { options.ImageListSelection = cp.CopyAllImages diff --git a/cmd/buildah/push.go b/cmd/buildah/push.go index cc59c7976ca..4fc815576bb 100644 --- a/cmd/buildah/push.go +++ b/cmd/buildah/push.go @@ -46,6 +46,7 @@ type pushOptions struct { encryptionKeys []string encryptLayers []int insecure bool + addCompression []string } func init() { diff --git a/docs/buildah-manifest-push.1.md b/docs/buildah-manifest-push.1.md index 4b55cac1245..66f67217e99 100644 --- a/docs/buildah-manifest-push.1.md +++ b/docs/buildah-manifest-push.1.md @@ -18,6 +18,15 @@ The list image's ID and the digest of the image's manifest. ## OPTIONS +**--add-compression** *compression* + +Makes sure that requested compression variant for each platform is added to the manifest list keeping original instance +intact in the same manifest list. Supported values are (`gzip`, `zstd` and `zstd:chunked`) + +Note: This is different than `--compression` which replaces the instance with requested with specified compression +while `--add-compression` makes sure than each instance has it variant added to manifest list without modifying the +original instance. + **--all** Push the images mentioned in the manifest list or image index, in addition to diff --git a/tests/bud.bats b/tests/bud.bats index 0fa5db3216a..f42bf5e7251 100644 --- a/tests/bud.bats +++ b/tests/bud.bats @@ -11,6 +11,55 @@ load helpers run_buildah build $BUDFILES/stdio } +@test "bud: build manifest list and --add-compression zstd" { + local contextdir=${TEST_SCRATCH_DIR}/bud/platform + mkdir -p $contextdir + + cat > $contextdir/Dockerfile1 << _EOF +FROM alpine +_EOF + + start_registry + run_buildah login --tls-verify=false --authfile ${TEST_SCRATCH_DIR}/test.auth --username testuser --password testpassword localhost:${REGISTRY_PORT} + run_buildah build $WITH_POLICY_JSON -t image1 --platform linux/amd64 -f $contextdir/Dockerfile1 + run_buildah build $WITH_POLICY_JSON -t image2 --platform linux/arm64 -f $contextdir/Dockerfile1 + + run_buildah manifest create foo + run_buildah manifest add foo image1 + run_buildah manifest add foo image2 + + run_buildah manifest push $WITH_POLICY_JSON --authfile ${TEST_SCRATCH_DIR}/test.auth --all --add-compression zstd --tls-verify=false foo docker://localhost:${REGISTRY_PORT}/list + + run_buildah manifest inspect --authfile ${TEST_SCRATCH_DIR}/test.auth --tls-verify=false localhost:${REGISTRY_PORT}/list + list="$output" + + # verify original `gzip` and its `zstd` variant on `amd64` + # first instance must be `gzip` for `amd64` + run jq -r '.manifests[0].annotations' <<< "$list" + expect_output --substring 'null' + run jq -r '.manifests[0].platform.architecture' <<< "$list" + expect_output --substring "amd64" + + # third instance must be `zstd` for `amd64` + run jq -r '.manifests[2].annotations' <<< "$list" + expect_output --substring '"io.github.containers.compression.zstd": "true"' + run jq -r '.manifests[2].platform.architecture' <<< "$list" + expect_output --substring "amd64" + + # verify original `gzip` and its `zstd`variant on `arm64` + # first instance must be `gzip` for `arm64` + run jq -r '.manifests[1].annotations' <<< "$list" + expect_output --substring 'null' + run jq -r '.manifests[1].platform.architecture' <<< "$list" + expect_output --substring "arm64" + + # third instance must be `zstd` for `arm64` + run jq -r '.manifests[3].annotations' <<< "$list" + expect_output --substring '"io.github.containers.compression.zstd": "true"' + run jq -r '.manifests[3].platform.architecture' <<< "$list" + expect_output --substring "arm64" +} + @test "bud with --dns* flags" { _prefetch alpine