Skip to content

Commit 6738cd7

Browse files
PeaceRebeljlebon
andcommitted
Add cosa import
This command takes as argument a `containers-transport(5)`-style pullspec and creates a new cosa build dir from it. It essentially bridges the gap between coreos/fedora-coreos-config#3348 and the rest of the cosa pipeline. Co-authored-by: Jonathan Lebon <[email protected]>
1 parent b4275ff commit 6738cd7

File tree

8 files changed

+274
-54
lines changed

8 files changed

+274
-54
lines changed

cmd/coreos-assembler.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import (
1313

1414
// commands we'd expect to use in the local dev path
1515
var buildCommands = []string{"init", "fetch", "build", "osbuild", "run", "prune", "clean", "list"}
16-
var advancedBuildCommands = []string{"buildfetch", "buildupload", "oc-adm-release", "push-container"}
16+
var advancedBuildCommands = []string{"import", "buildfetch", "buildupload", "oc-adm-release", "push-container"}
1717
var buildextendCommands = []string{"aliyun", "applehv", "aws", "azure", "digitalocean", "exoscale", "extensions-container", "gcp", "hyperv", "ibmcloud", "kubevirt", "live", "metal", "metal4k", "nutanix", "openstack", "oraclecloud", "qemu", "secex", "virtualbox", "vmware", "vultr"}
1818

1919
var utilityCommands = []string{"aws-replicate", "coreos-prune", "compress", "copy-container", "diff", "koji-upload", "kola", "push-container-manifest", "remote-build-container", "remote-session", "sign", "tag", "update-variant"}

pkg/builds/cosa_v1.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package builds
22

33
// generated by 'make schema'
4-
// source hash: 4bb5641ee8c32b122c412cbaefe3d068685ea6cbffcf3162e600a01268c92146
4+
// source hash: 40070aa13f4501cb0c6025e1a19e638e823fd9daef234406344482da5bdf5bb5
55

66
type AdvisoryDiff []AdvisoryDiffItems
77

@@ -56,6 +56,7 @@ type Build struct {
5656
CosaDelayedMetaMerge bool `json:"coreos-assembler.delayed-meta-merge,omitempty"`
5757
CosaImageChecksum string `json:"coreos-assembler.image-config-checksum,omitempty"`
5858
CosaImageVersion int `json:"coreos-assembler.image-genver,omitempty"`
59+
CosaImportedOciImage bool `json:"coreos-assembler.oci-imported,omitempty"`
5960
Extensions *Extensions `json:"extensions,omitempty"`
6061
ExtensionsContainer *PrimaryImage `json:"extensions-container,omitempty"`
6162
FedoraCoreOsParentCommit string `json:"fedora-coreos.parent-commit,omitempty"`
@@ -64,15 +65,15 @@ type Build struct {
6465
GitDirty string `json:"coreos-assembler.config-dirty,omitempty"`
6566
IbmCloud []Cloudartifact `json:"ibmcloud,omitempty"`
6667
ImageInputChecksum string `json:"coreos-assembler.image-input-checksum,omitempty"`
67-
InputHashOfTheRpmOstree string `json:"rpm-ostree-inputhash"`
68+
InputHashOfTheRpmOstree string `json:"rpm-ostree-inputhash,omitempty"`
6869
Koji *Koji `json:"koji,omitempty"`
6970
KubevirtContainer *PrimaryImage `json:"kubevirt,omitempty"`
7071
MetaStamp float64 `json:"coreos-assembler.meta-stamp,omitempty"`
7172
Name string `json:"name"`
7273
Oscontainer *PrimaryImage `json:"oscontainer,omitempty"`
73-
OstreeCommit string `json:"ostree-commit"`
74+
OstreeCommit string `json:"ostree-commit,omitempty"`
7475
OstreeContentBytesWritten int `json:"ostree-content-bytes-written,omitempty"`
75-
OstreeContentChecksum string `json:"ostree-content-checksum"`
76+
OstreeContentChecksum string `json:"ostree-content-checksum,omitempty"`
7677
OstreeNCacheHits int `json:"ostree-n-cache-hits,omitempty"`
7778
OstreeNContentTotal int `json:"ostree-n-content-total,omitempty"`
7879
OstreeNContentWritten int `json:"ostree-n-content-written,omitempty"`

pkg/builds/schema_doc.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Generated by ./generate-schema.sh
2-
// Source hash: 4bb5641ee8c32b122c412cbaefe3d068685ea6cbffcf3162e600a01268c92146
2+
// Source hash: 40070aa13f4501cb0c6025e1a19e638e823fd9daef234406344482da5bdf5bb5
33
// DO NOT EDIT
44

55
package builds
@@ -254,11 +254,8 @@ var generatedSchemaJSON = `{
254254
"required": [
255255
"buildid",
256256
"name",
257-
"ostree-commit",
258-
"ostree-content-checksum",
259257
"ostree-timestamp",
260-
"ostree-version",
261-
"rpm-ostree-inputhash"
258+
"ostree-version"
262259
],
263260
"optional": [
264261
"aliyun",
@@ -273,13 +270,16 @@ var generatedSchemaJSON = `{
273270
"images",
274271
"koji",
275272
"oscontainer",
273+
"ostree-commit",
274+
"ostree-content-checksum",
276275
"extensions",
277276
"extensions-container",
278277
"parent-pkgdiff",
279278
"pkgdiff",
280279
"parent-advisories-diff",
281280
"advisories-diff",
282281
"release-payload",
282+
"rpm-ostree-inputhash",
283283
"summary",
284284
"s3",
285285
"coreos-assembler.basearch",
@@ -297,6 +297,7 @@ var generatedSchemaJSON = `{
297297
"coreos-assembler.meta-stamp",
298298
"coreos-assembler.overrides-active",
299299
"coreos-assembler.yumrepos-git",
300+
"coreos-assembeler.oci-imported",
300301
"fedora-coreos.parent-commit",
301302
"fedora-coreos.parent-version",
302303
"ref"
@@ -378,6 +379,12 @@ var generatedSchemaJSON = `{
378379
"default": "",
379380
"minLength": 1
380381
},
382+
"coreos-assembler.oci-imported": {
383+
"$id": "#/properties/coreos-assembler.oci-imported",
384+
"type": "boolean",
385+
"title": "COSA imported OCI image",
386+
"default": "False"
387+
},
381388
"coreos-assembler.code-source": {
382389
"$id": "#/properties/coreos-assembler.code-source",
383390
"type": "string",

src/cmd-coreos-prune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ Build = collections.namedtuple("Build", ["id", "images", "arch", "meta_json"])
5555
# set metadata caching to 5m
5656
CACHE_MAX_AGE_METADATA = 60 * 5
5757
# These lists are up to date as of schema hash
58-
# 4bb5641ee8c32b122c412cbaefe3d068685ea6cbffcf3162e600a01268c92146. If changing
58+
# 40070aa13f4501cb0c6025e1a19e638e823fd9daef234406344482da5bdf5bb5. If changing
5959
# this hash, ensure that the list of SUPPORTED and UNSUPPORTED artifacts below
6060
# is up to date.
6161
SUPPORTED = ["amis", "aws-winli", "gcp"]

src/cmd-import

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#!/usr/bin/python3
2+
3+
import argparse
4+
import datetime
5+
import json
6+
import os
7+
import subprocess
8+
import tempfile
9+
import shutil
10+
from stat import (
11+
S_IREAD,
12+
S_IRGRP,
13+
S_IROTH)
14+
from cosalib.builds import Builds
15+
from cosalib.cmdlib import (
16+
rfc3339_time,
17+
get_basearch,
18+
sha256sum_file)
19+
20+
VALID_NAMES = ["fedora-coreos", "rhcos", "scos"]
21+
22+
23+
def main():
24+
args = parse_args()
25+
with tempfile.TemporaryDirectory(prefix='cosa-import-', dir='tmp') as tmpd:
26+
tmp_ociarchive = os.path.join(tmpd, "out.ociarchive")
27+
28+
metadata = prepare_build(args, tmp_ociarchive)
29+
30+
name = metadata['Labels']['com.coreos.osname']
31+
buildid = metadata['Labels']['org.opencontainers.image.version']
32+
arch = get_basearch()
33+
34+
manifest = generate_manifest_json(tmpd, tmp_ociarchive, name, buildid, arch)
35+
meta_json = generate_meta_json(tmp_ociarchive, metadata, manifest['metadata'], name)
36+
37+
finalize_build(tmp_ociarchive, meta_json, manifest, buildid, arch)
38+
39+
40+
def parse_args():
41+
parser = argparse.ArgumentParser(prog='cosa import')
42+
parser.add_argument("srcimg", metavar='IMAGE',
43+
help="image to import (containers-transports(5) format)")
44+
return parser.parse_args()
45+
46+
47+
def prepare_build(args, target_ociarchive):
48+
import_oci_archive(args, target_ociarchive)
49+
return inspect_oci_archive(target_ociarchive)
50+
51+
52+
def finalize_build(source_ociarchive, meta_json, manifest, buildid, arch):
53+
os.makedirs(f'builds/{buildid}/{arch}/', exist_ok=True)
54+
55+
archive_name = meta_json['images']['ostree']['path']
56+
archive_path = f'builds/{buildid}/{arch}/{archive_name}'
57+
# Move ociarchive to build dir
58+
shutil.move(source_ociarchive, archive_path)
59+
60+
# move manifest file
61+
manifest_fname = manifest['metadata']['path']
62+
shutil.move(manifest['src_path'], f'builds/{buildid}/{arch}/{manifest_fname}')
63+
64+
with open(f'builds/{buildid}/{arch}/meta.json', 'w') as meta_file:
65+
json.dump(meta_json, meta_file, indent=4)
66+
67+
# Symlink build to latest
68+
if os.path.exists('builds/latest'):
69+
os.remove('builds/latest')
70+
os.symlink(f'{buildid}', 'builds/latest', target_is_directory=True)
71+
72+
builds = Builds()
73+
update_builds_json(builds, buildid, arch)
74+
75+
print(f'Successfully import oci image to {archive_path}')
76+
77+
78+
def update_builds_json(builds, buildid, arch):
79+
builds.insert_build(buildid, arch)
80+
builds.bump_timestamp()
81+
builds.flush()
82+
83+
84+
def import_oci_archive(args, target):
85+
subprocess.check_call(['skopeo', 'copy', args.srcimg,
86+
f"oci-archive:{target}"])
87+
88+
89+
def inspect_oci_archive(image):
90+
out = subprocess.check_output(['skopeo', 'inspect',
91+
f'oci-archive:{image}'])
92+
return json.loads(out)
93+
94+
95+
def generate_manifest_json(tmpd, ociarchive, name, buildid, arch):
96+
manifest = subprocess.check_output(["skopeo", "inspect", "--raw", f"oci-archive:{ociarchive}"])
97+
98+
ostree_oci_manifest_path = f"{name}-{buildid}-ostree.{arch}-manifest.json"
99+
manifest_json_dest = f'{tmpd}/manifest.json'
100+
101+
manifest_json_sha256 = None
102+
manifest_json_size = None
103+
with open(manifest_json_dest, 'wb') as manifest_json:
104+
manifest_json.write(manifest)
105+
os.fchmod(manifest_json.fileno(), S_IREAD | S_IRGRP | S_IROTH)
106+
107+
manifest_json_sha256 = sha256sum_file(manifest_json_dest)
108+
manifest_json_size = os.path.getsize(manifest_json_dest)
109+
110+
manifest_metadata = {
111+
'path': ostree_oci_manifest_path,
112+
'sha256': manifest_json_sha256,
113+
'size': manifest_json_size,
114+
"skip-compression": True,
115+
}
116+
117+
return {
118+
'metadata': manifest_metadata,
119+
'src_path': manifest_json_dest
120+
}
121+
122+
123+
def parse_timestamp(timestamp):
124+
# datetime's doesn't support nanoseconds.
125+
# So trim it.
126+
if len(timestamp) > 26 and timestamp[19] == '.':
127+
timestamp = timestamp[:26] + "Z"
128+
129+
timestamp = datetime.datetime.strptime(timestamp, '%Y-%m-%dT%H:%M:%S.%fZ')
130+
return rfc3339_time(timestamp.replace(tzinfo=datetime.timezone.utc))
131+
132+
133+
def generate_meta_json(ociarchive, metadata, oci_manifest, name):
134+
archive_sha256sum = sha256sum_file(ociarchive)
135+
136+
# let raise if missing
137+
assert metadata['Labels']['containers.bootc'] == '1'
138+
139+
buildid = metadata['Labels']['org.opencontainers.image.version']
140+
arch = get_basearch()
141+
created_timestamp = parse_timestamp(metadata['Created'])
142+
143+
meta_json = {
144+
'ostree-version': buildid, # proxy version label
145+
'buildid': buildid, # also version label
146+
'coreos-assembler.build-timestamp': created_timestamp, # proxy OCI build timestamp
147+
'coreos-assembler.oci-imported': True,
148+
'name': name,
149+
'ostree-timestamp': created_timestamp,
150+
'images': {
151+
'ostree': {
152+
"path": f"{name}-{buildid}-ostree.{arch}.ociarchive",
153+
"sha256": archive_sha256sum,
154+
"skip-compression": True
155+
},
156+
'oci-manifest': oci_manifest,
157+
},
158+
'coreos-assembler.basearch': arch,
159+
}
160+
161+
return meta_json
162+
163+
164+
if __name__ == '__main__':
165+
main()

src/cmd-osbuild

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,17 +170,19 @@ generate_runvm_osbuild_config() {
170170
fi
171171
rm -f "${workdir}"/tmp/runvm-osbuild-config-*.json # clean up any previous configs
172172

173-
# reread these values from the build itself rather than rely on the ones loaded
173+
# Ensure that we have the cached unpacked commit
174+
import_ostree_commit_for_build "${build}"
175+
176+
# reread these values from the repo itself rather than rely on the ones loaded
174177
# by prepare_build since the config might've changed since then
175-
ostree_commit=$(meta_key ostree-commit)
178+
ostree_commit=$(ostree rev-parse --repo "${tmprepo}" "${build}")
179+
176180
ostree_ref=$(meta_key ref)
177181
if [ "${ostree_ref}" = "None" ]; then
178182
ostree_ref=""
179183
fi
180184

181185
ostree_repo=${tmprepo}
182-
# Ensure that we have the cached unpacked commit
183-
import_ostree_commit_for_build "${build}"
184186
# Note this overwrote the bits generated in prepare_build
185187
# for image_json. In the future we expect to split prepare_build
186188
# into prepare_ostree_build and prepare_diskimage_build; the

0 commit comments

Comments
 (0)