Skip to content

Commit

Permalink
cmd-push-container-manifest: store arch-specific digest in meta.json
Browse files Browse the repository at this point in the history
As discussed in coreos#3122,
ART needs the arch-specific digest in the `meta.json` rather than the
manifest list digest. FCOS isn't planning to use the digest so doesn't
care about which one gets chosen.

Update `cosa push-container-manifest` to use the arch-specific digest.

(cherry picked from commit c7b5757)
(cherry picked from commit 2efa549)
(cherry picked from commit 3685382)
  • Loading branch information
jlebon authored and dustymabe committed Nov 15, 2022
1 parent 33edce9 commit a2c9361
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 23 deletions.
28 changes: 16 additions & 12 deletions src/cmd-push-container-manifest
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()
Expand Down Expand Up @@ -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_info = 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_info['manifests']) == len(buildmetas)
for manifest in manifest_info['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():
Expand Down
24 changes: 13 additions & 11 deletions src/cosalib/container_manifest.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import json

from cosalib.utils 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
Expand All @@ -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):
Expand All @@ -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]}"]
Expand All @@ -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 manifest 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

0 comments on commit a2c9361

Please sign in to comment.