Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd-push-container-manifest: change image key schema #3129

Merged
merged 4 commits into from
Oct 21, 2022
Merged
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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 4 additions & 12 deletions pkg/builds/cosa_v1.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package builds

// generated by 'make schema'
// source hash: 3508b2f150e72b8e24151d870789809cf4070cec6b4716966a4e8bc585e0c5f1
// source hash: 1e32ab25dfdd0724f8e8246008b9d91b88a40e9ea834cf779ab0da818bf1cf25

type AdvisoryDiff []AdvisoryDiffItems

Expand All @@ -27,18 +27,14 @@ type Artifact struct {
UncompressedSize int `json:"uncompressed-size,omitempty"`
}

type BaseOsContainer struct {
Image string `json:"image"`
}

type Build struct {
AdvisoryDiffAgainstParent AdvisoryDiff `json:"parent-advisories-diff,omitempty"`
AdvisoryDiffBetweenBuilds AdvisoryDiff `json:"advisories-diff,omitempty"`
AlibabaAliyunUploads []AliyunImage `json:"aliyun,omitempty"`
Amis []Amis `json:"amis,omitempty"`
Architecture string `json:"coreos-assembler.basearch,omitempty"`
Azure *Cloudartifact `json:"azure,omitempty"`
BaseOsContainer *BaseOsContainer `json:"base-oscontainer,omitempty"`
BaseOsContainer *Image `json:"base-oscontainer,omitempty"`
BuildArtifacts *BuildArtifacts `json:"images,omitempty"`
BuildID string `json:"buildid"`
BuildRef string `json:"ref,omitempty"`
Expand All @@ -54,7 +50,7 @@ type Build struct {
CosaImageChecksum string `json:"coreos-assembler.image-config-checksum,omitempty"`
CosaImageVersion int `json:"coreos-assembler.image-genver,omitempty"`
Extensions *Extensions `json:"extensions,omitempty"`
ExtensionsContainer *ExtensionsContainer `json:"extensions-container,omitempty"`
ExtensionsContainer *Image `json:"extensions-container,omitempty"`
FedoraCoreOsParentCommit string `json:"fedora-coreos.parent-commit,omitempty"`
FedoraCoreOsParentVersion string `json:"fedora-coreos.parent-version,omitempty"`
Gcp *Gcp `json:"gcp,omitempty"`
Expand Down Expand Up @@ -134,10 +130,6 @@ type Extensions struct {
Sha256 string `json:"sha256"`
}

type ExtensionsContainer struct {
Image string `json:"image"`
}

type Gcp struct {
ImageFamily string `json:"family,omitempty"`
ImageName string `json:"image"`
Expand All @@ -154,7 +146,7 @@ type Git struct {

type Image struct {
Comment string `json:"comment,omitempty"`
Digest string `json:"digest"`
Digest string `json:"digest,omitempty"`
Image string `json:"image"`
}

Expand Down
26 changes: 4 additions & 22 deletions pkg/builds/schema_doc.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// Generated by ./generate-schema.sh
// Source hash: 3508b2f150e72b8e24151d870789809cf4070cec6b4716966a4e8bc585e0c5f1
// Source hash: 1e32ab25dfdd0724f8e8246008b9d91b88a40e9ea834cf779ab0da818bf1cf25
// DO NOT EDIT

package builds
Expand Down Expand Up @@ -56,10 +56,10 @@ var generatedSchemaJSON = `{
"image": {
"type": "object",
"required": [
"digest",
"image"
],
"optional": [
"digest",
"comment"
],
"properties": {
Expand Down Expand Up @@ -882,31 +882,13 @@ var generatedSchemaJSON = `{
"$id": "#/properties/base-oscontainer",
"type": "object",
"title": "Base OS container",
"required": [
"image"
],
"properties": {
"image": {
"$id": "#/properties/base-oscontainer/image",
"type": "string",
"title": "Image"
}
}
"$ref": "#/definitions/image"
},
"extensions-container": {
"$id": "#/properties/extensions-container",
"type": "object",
"title": "Extensions container",
"required": [
"image"
],
"properties": {
"image": {
"$id": "#/properties/extensions-container/image",
"type": "string",
"title": "Image"
}
}
"$ref": "#/definitions/image"
},
"gcp": {
"$id": "#/properties/gcp",
Expand Down
5 changes: 4 additions & 1 deletion src/cmd-push-container
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ with tempfile.NamedTemporaryFile(dir='tmp', prefix='push-container-digestfile')
container = 'base-oscontainer'
if args.image != 'ostree':
container = args.image
meta[container] = {'image': f"{container_name}@{digest}"}
meta[container] = {
'image': container_name,
'digest': digest
}
metapath_new = f"{metapath}.new"
with open(metapath_new, 'w') as f:
json.dump(meta, f, sort_keys=True)
Expand Down
36 changes: 22 additions & 14 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.tag, 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,16 +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.tag, 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] = {'image': f"{args.repo}@{digest}"}
buildmeta.write(artifact_name=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': manifest['digest']
}
buildmetas[arch].write(artifact_name=args.metajsonname)


def parse_args():
Expand All @@ -95,10 +102,11 @@ Examples:
--repo quay.io/dustymabe/fedora-coreos --tag stable --artifact=ostree \\
--metajsonname=base-oscontainer --build=latest --arch=x86_64 --arch=aarch64""")
parser.add_argument("--repo", required=True, help="The registry repo to target for the manifest")
parser.add_argument("--tag", required=True, help="The tag of the manifest to use")
parser.add_argument("--tag", required=True, dest='tags', action='append',
help="The tag of the manifest to use")
parser.add_argument("--authfile", help="A file to use for registry auth")
parser.add_argument('--v2s2', action='store_true',
help='Use old image manifest version2 schema 2 format')
help='Use old image manifest version 2 schema 2 format')

group = parser.add_mutually_exclusive_group(required=True)
group.add_argument("--image", dest='images', action='append', default=[],
Expand All @@ -112,7 +120,7 @@ Examples:
parser.add_argument("--arch", dest='arches', action='append', default=[],
help="""Limit the architectures to upload to the specificed set
(otherwise it defaults to all available for that build). Can be
specificed multiple times like: --arch x86_64 --arch aarch64""")
specified multiple times like: --arch x86_64 --arch aarch64""")
parser.add_argument("--metajsonname",
help="The name under which to store the container information in meta.json")
return parser.parse_args()
Expand Down
39 changes: 21 additions & 18 deletions src/cosalib/container_manifest.py
Original file line number Diff line number Diff line change
@@ -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
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,35 +30,33 @@ def delete_local_container_manifest(repo, tag):
runcmd(cmd)


def push_container_manifest(repo, tag, digestfile, v2s2=False):
def push_container_manifest(repo, tags, v2s2=False):
'''
Push manifest to registry
@param repo str registry repository
@param tag str manifest tag
@param digestfile str write container digest to file
@param tags list of tags to push
@param v2s2 boolean use to force v2s2 format
'''
cmd = ["podman", "manifest", "push",
"--all", f"{repo}:{tag}", f"{repo}:{tag}"]
base_cmd = ["podman", "manifest", "push", "--all", f"{repo}:{tags[0]}"]
if v2s2:
# `--remove-signatures -f v2s2` is a workaround for when you try
# to create a manifest with 2 different mediaType. It seems to be
# a Quay issue.
cmd.extend(["--remove-signatures", "-f", "v2s2"])
if digestfile:
cmd.extend([f"--digestfile={digestfile}"])
runcmd(cmd)
base_cmd.extend(["--remove-signatures", "-f", "v2s2"])
runcmd(base_cmd + [f"{repo}:{tags[0]}"])
for tag in tags[1:]:
runcmd(base_cmd + [f"{repo}:{tag}"])
jlebon marked this conversation as resolved.
Show resolved Hide resolved


def create_and_push_container_manifest(repo, tag, 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 tag str manifest tag
@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, tag, images)
push_container_manifest(repo, tag, digestfile, v2s2)
delete_local_container_manifest(repo, tag)
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
Loading