diff --git a/src/cmd-push-container-manifest b/src/cmd-push-container-manifest index e0f61b666f..a11712ae8b 100755 --- a/src/cmd-push-container-manifest +++ b/src/cmd-push-container-manifest @@ -6,7 +6,6 @@ import argparse import os import sys -import tempfile from cosalib.container_manifest import create_and_push_container_manifest from cosalib.builds import Builds from cosalib.meta import GenericBuildMeta @@ -22,7 +21,7 @@ def main(): if args.images: # User provided images directly create_and_push_container_manifest( - args.repo, args.tags, args.images, args.v2s2, None) + args.repo, args.tags, args.images, args.v2s2) else: # Picking up images from artifacts in meta.json builds = Builds() @@ -60,19 +59,24 @@ def main(): images.append(f"oci-archive:{ociarchive}") # Create/Upload the manifest list to the container registry - with tempfile.NamedTemporaryFile() as digestfile: - create_and_push_container_manifest( - args.repo, args.tags, images, args.v2s2, digestfile.name) - digestfile.seek(0) - digest = digestfile.read().decode('utf-8').strip() + manifest = create_and_push_container_manifest( + args.repo, args.tags, images, args.v2s2) - # Update the meta.json in each build/arch metadata - for _, buildmeta in buildmetas.items(): - buildmeta[args.metajsonname] = { + # Update the `meta.json` files. Note the digest included is the + # arch-specific one for each individual arch, and not the manifest list + # digest. See: https://github.com/coreos/coreos-assembler/issues/3122. + assert len(manifest['manifests']) == len(buildmetas) + for manifest in manifest['manifests']: + arch = manifest['platform']['architecture'] + if arch == 'arm64': + arch = 'aarch64' + elif arch == 'amd64': + arch = 'x86_64' + buildmetas[arch][args.metajsonname] = { 'image': args.repo, - 'digest': digest + 'digest': manifest['digest'] } - buildmeta.write(artifact_name=args.metajsonname) + buildmetas[arch].write(artifact_name=args.metajsonname) def parse_args(): diff --git a/src/cosalib/container_manifest.py b/src/cosalib/container_manifest.py index 6349f809ad..fa2ea942ee 100644 --- a/src/cosalib/container_manifest.py +++ b/src/cosalib/container_manifest.py @@ -1,9 +1,11 @@ +import json + from cosalib.cmdlib import runcmd -def create_local_container_manifest(repo, tag, images): +def create_local_container_manifest(repo, tag, images) -> dict: ''' - Create local manifest list + Create local manifest list and return the final manifest JSON @param images list of image specifications (including transport) @param repo str registry repository @param tag str manifest tag @@ -13,6 +15,9 @@ def create_local_container_manifest(repo, tag, images): for image in images: cmd = ["podman", "manifest", "add", f"{repo}:{tag}", image] runcmd(cmd) + manifest_info = runcmd(["podman", "manifest", "inspect", f"{repo}:{tag}"], + capture_output=True).stdout + return json.loads(manifest_info) def delete_local_container_manifest(repo, tag): @@ -25,12 +30,11 @@ def delete_local_container_manifest(repo, tag): runcmd(cmd) -def push_container_manifest(repo, tags, digestfile, v2s2=False): +def push_container_manifest(repo, tags, v2s2=False): ''' Push manifest to registry @param repo str registry repository @param tags list of tags to push - @param digestfile str write container digest to file @param v2s2 boolean use to force v2s2 format ''' base_cmd = ["podman", "manifest", "push", "--all", f"{repo}:{tags[0]}"] @@ -39,22 +43,20 @@ def push_container_manifest(repo, tags, digestfile, v2s2=False): # to create a manifest with 2 different mediaType. It seems to be # a Quay issue. base_cmd.extend(["--remove-signatures", "-f", "v2s2"]) - if digestfile: - base_cmd.extend([f"--digestfile={digestfile}"]) runcmd(base_cmd + [f"{repo}:{tags[0]}"]) for tag in tags[1:]: runcmd(base_cmd + [f"{repo}:{tag}"]) -def create_and_push_container_manifest(repo, tags, images, v2s2, digestfile): +def create_and_push_container_manifest(repo, tags, images, v2s2) -> dict: ''' - Do it all! Create, Push, Cleanup + Do it all! Create, push, cleanup, and return the final manifset JSON. @param repo str registry repository @param tags list of tags @param images list of image specifications (including transport) @param v2s2 boolean use to force v2s2 format - @param digestfile str write container digest to file ''' - create_local_container_manifest(repo, tags[0], images) - push_container_manifest(repo, tags, digestfile, v2s2) + manifest_info = create_local_container_manifest(repo, tags[0], images) + push_container_manifest(repo, tags, v2s2) delete_local_container_manifest(repo, tags[0]) + return manifest_info