Skip to content

Commit 84d2f6a

Browse files
cgwaltersopenshift-merge-robot
authored andcommitted
upload-oscontainer: Support oscontainer.yaml and extensions.yaml
Pairs with openshift/os#455 Add an `oscontainer.yaml` which allows configuring (currently) just the `FROM` line equivalent. This helps keep things declarative in the config instead of part of the pipeline. And since extensions are now a core part of OpenShift 4 (particularly RT kernel) which also uses the oscontainer, let's lift the logic to generate those bits of the oscontainer into this repo and out of the config git. Both of these are part of the general philosophy we've had that: - config git is declarative config - coreos-assembler is the mechanism - a pipeline just scripts coreos-assembler in a way that's easy to reproduce with plain podman too
1 parent 7bf455a commit 84d2f6a

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

src/cmd-upload-oscontainer

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import argparse
99
import json
10+
import yaml
1011
import os
1112
import shutil
1213
import subprocess
@@ -39,6 +40,24 @@ metapath = f"{latest_build_path}/meta.json"
3940
with open(metapath) as f:
4041
meta = json.load(f)
4142

43+
configdir = os.path.abspath('src/config')
44+
oscconfigpath = f'{configdir}/oscontainer.yaml'
45+
if os.path.exists(oscconfigpath):
46+
with open(oscconfigpath) as f:
47+
c = yaml.safe_load(f)
48+
base = c.get('base')
49+
if base is not None:
50+
args.from_image = base
51+
52+
extensions_src = 'src/config/extensions.yaml'
53+
extensions_destdir = None
54+
if os.path.exists(extensions_src):
55+
extensions_destdir = 'tmp/extensions'
56+
if os.path.exists(extensions_destdir):
57+
shutil.rmtree(extensions_destdir)
58+
os.mkdir(extensions_destdir)
59+
cmdlib.run_verbose(['/usr/lib/coreos-assembler/download-extensions', extensions_destdir])
60+
4261
print("Preparing to upload oscontainer for build: {}".format(latest_build))
4362
ostree_commit = meta['ostree-commit']
4463

@@ -87,6 +106,8 @@ os.environ['REGISTRY_AUTH_FILE'] = authfile
87106
cosa_argv.extend(['/usr/lib/coreos-assembler/oscontainer.py', '--workdir=./tmp', 'build', f"--from={args.from_image}"])
88107
for d in args.add_directory:
89108
cosa_argv.append(f"--add-directory={d}")
109+
if extensions_destdir is not None:
110+
cosa_argv.append(f"--add-directory={extensions_destdir}")
90111
cosa_argv.append(f"--display-name={display_name}")
91112
subprocess.check_call(cosa_argv +
92113
[f'--digestfile={digestfile}',

src/download-extensions

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python3
2+
# RPMs as operating system extensions, distinct from the base ostree commit/image
3+
# https://github.com/openshift/enhancements/blob/master/enhancements/rhcos/extensions.md
4+
5+
import os
6+
import sys
7+
import yaml
8+
from cosalib import cmdlib
9+
10+
destdir = sys.argv[1]
11+
tmpdir = 'tmp'
12+
# yum wants this to be absolute
13+
configdir = os.path.abspath('src/config')
14+
extsrcpath = f'{configdir}/extensions.yaml'
15+
extjson = f'{tmpdir}/extensions.json'
16+
basearch = cmdlib.get_basearch()
17+
18+
with open(extsrcpath) as f:
19+
extensions = yaml.safe_load(f)
20+
21+
# The "v2" format here is that there's an extensions/ directory, with subdirectories
22+
# for each extension - except you should ignore "repodata/".
23+
edestdir = f'{destdir}/extensions'
24+
os.mkdir(edestdir)
25+
26+
# Stuff that's not part of the extension
27+
dependenciesdir = f'{edestdir}/dependencies'
28+
os.mkdir(dependenciesdir)
29+
30+
31+
# Downloads packages from specified repos
32+
def yumdownload(destdir, pkgs):
33+
# FIXME eventually use rpm-ostree for this
34+
# shellcheck disable=SC2068
35+
args = ['yum', f'--setopt=reposdir={configdir}', f'--arch={basearch}', 'download']
36+
args.extend(pkgs)
37+
cmdlib.run_verbose(args, cwd=destdir)
38+
39+
40+
# Reuseable function for setting up an extension
41+
# Assumes it is running in "${destdir}/extensions"
42+
# 1 = extension name
43+
# 2 = package string/glob
44+
# 3 = OPTIONAL: dependencies string/glob
45+
def createext(extname, pkgs):
46+
print(f"Creating extension {extname}")
47+
extdir = f"{edestdir}/{extname}"
48+
os.mkdir(extdir)
49+
primary = pkgs[0]
50+
yumdownload(extdir, [primary])
51+
52+
deps = pkgs[1:]
53+
if len(deps) > 0:
54+
print(f"Downloading dependencies for {extname}")
55+
yumdownload(dependenciesdir, deps)
56+
57+
58+
for (name, ext) in extensions['extensions'].items():
59+
pkgs = ext['packages']
60+
extarches = ext.get('architectures')
61+
if extarches is not None and basearch not in extarches:
62+
print(f"Skipping extension {name} for this architecture")
63+
continue
64+
createext(name, pkgs)
65+
66+
# Create the yum/dnf repo
67+
cmdlib.run_verbose(['createrepo_c', '--no-database', '.'], cwd=destdir)

0 commit comments

Comments
 (0)