mirror of
https://github.com/coreos/fedora-coreos-config.git
synced 2026-02-05 09:45:30 +01:00
build-rootfs: add overrides/rpm API
Allow a yum repo at `overrides/rpm` to exist in the context dir, in which case we automatically create a lockfile and repo file that we inject out of that. This matches the `overrides/rpm` functionality in cosa, but the API lives here. cosa can then just use that API to retain its `overrides/rpm` behaviour. A lot of the code is lifted from cosa's `cmdlib.sh`, which conveniently had it in Python already among its many liberal uses of inline Python scripts.
This commit is contained in:
@@ -5,6 +5,11 @@
|
||||
#
|
||||
# Note: we should be able to drop the `-v $PWD:/run/src` once
|
||||
# https://github.com/containers/buildah/issues/5952 is fixed.
|
||||
#
|
||||
# For development convenience, an `overrides/` directory in the context dir, or
|
||||
# mounted at `/run/src/overrides` is supported:
|
||||
# - The `overrides/rpm` directory can be a yum repo. Its packages take
|
||||
# precedence over those from remote repos.
|
||||
|
||||
# Overridden by build-args.conf. The value here is invalid on purpose.
|
||||
ARG BUILDER_IMG=overridden
|
||||
|
||||
49
build-rootfs
49
build-rootfs
@@ -35,7 +35,11 @@ def main():
|
||||
if repos:
|
||||
inject_yumrepos()
|
||||
|
||||
locked_nevras = get_locked_nevras()
|
||||
local_overrides = prepare_local_rpm_overrides(target_rootfs)
|
||||
if local_overrides:
|
||||
repos += ['overrides']
|
||||
|
||||
locked_nevras = get_locked_nevras(local_overrides)
|
||||
if locked_nevras:
|
||||
modify_pool_repo(locked_nevras)
|
||||
|
||||
@@ -179,6 +183,38 @@ def run_postprocess_scripts(rootfs, manifest):
|
||||
os.unlink(os.path.join(rootfs, name))
|
||||
|
||||
|
||||
def prepare_local_rpm_overrides(rootfs):
|
||||
overrides_repo = os.path.join(CONTEXTDIR, 'overrides/rpm')
|
||||
if not os.path.isdir(f'{overrides_repo}/repodata'):
|
||||
return None
|
||||
|
||||
pkglist = subprocess.check_output(['dnf', 'repoquery', f'--repofrompath=overrides,file://{overrides_repo}',
|
||||
'--repo=overrides', '--latest-limit=1', f'--arch={ARCH},noarch',
|
||||
'--qf', 'pkg: %{name} %{evr} %{arch}\n'], encoding='utf-8')
|
||||
lockfile = {"packages": {}}
|
||||
for line in pkglist.splitlines():
|
||||
if not line.startswith("pkg: "):
|
||||
continue
|
||||
_, name, evr, arch = line.strip().split()
|
||||
lockfile["packages"][name] = {"evra": f"{evr}.{arch}"}
|
||||
|
||||
if len(lockfile['packages']) == 0:
|
||||
return None
|
||||
|
||||
with open('/etc/yum.repos.d/overrides.repo', 'w') as f:
|
||||
f.write(f'''
|
||||
[overrides]
|
||||
name=overrides
|
||||
baseurl=file://{overrides_repo}
|
||||
gpgcheck=0
|
||||
cost=500
|
||||
priority=1
|
||||
''')
|
||||
|
||||
print("Injected", len(lockfile['packages']), 'package overrides')
|
||||
return lockfile
|
||||
|
||||
|
||||
# Could upstream this as e.g. `bootc-base-imagectl runroot /rootfs <cmd>` maybe?
|
||||
# But we'd need to carry it anyway at least for RHCOS 9.6.
|
||||
def bwrap(rootfs, args):
|
||||
@@ -189,7 +225,7 @@ def bwrap(rootfs, args):
|
||||
'--'] + args)
|
||||
|
||||
|
||||
def get_locked_nevras():
|
||||
def get_locked_nevras(local_overrides):
|
||||
lockfile_path = os.path.join(CONTEXTDIR, f"manifest-lock.{ARCH}.json")
|
||||
overrides_path = os.path.join(CONTEXTDIR, "manifest-lock.overrides.yaml")
|
||||
overrides_arch_path = os.path.join(CONTEXTDIR, f"manifest-lock.overrides.{ARCH}.yaml")
|
||||
@@ -205,6 +241,15 @@ def get_locked_nevras():
|
||||
# this essentially re-implements the merge semantics of rpm-ostree
|
||||
locks.update({pkgname: v['evra'] if 'evra' in v else v['evr']
|
||||
for (pkgname, v) in data['packages'].items()})
|
||||
if local_overrides:
|
||||
# Note here we only add the minimal number of overrides needed to
|
||||
# nullify the base locks rather than take all of them wholesale. We
|
||||
# don't want to force-install everything in `overrides/rpm` -- e.g. we
|
||||
# want to support dumb `koji download-build` flows. For everything else
|
||||
# that's unlocked, we rely on the overrides repo having priority=1.
|
||||
locks.update({pkgname: v['evra'] if 'evra' in v else v['evr']
|
||||
for (pkgname, v) in local_overrides['packages'].items()
|
||||
if pkgname in locks})
|
||||
return [f'{k}-{v}' for (k, v) in locks.items()]
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user