stages/coreos.live-artifacts: rework volume ID handling

In https://github.com/osbuild/osbuild/pull/2148, we changed the logic to
generate the volume ID from the data in `/usr/lib/os-release` to sever
the reliance on metadata in the embedded treefile that will no longer
exist.

This had no effect in FCOS, but had an effect in RHCOS, which
went from a volume ID of `rhcos-...` to `rhel-coreos-...`.
This was considered harmless at the time, but in fact ended
up affecting the OpenShift Assisted Image Service. See e.g.
https://github.com/openshift/assisted-image-service/pull/477 which
attempted to adapt that code. But in the end, it felt safer and less
work to just revert back to the previous volume ID. So here we are.

But we still don't want to go back to using the embedded treefile.
Instead, we now have access to the OS name to use as a label on the
container image. This label gets serialized into the aleph during the
creation of the metal image (via the `org.osbuild.ostree.aleph` stage)
which we have access here when mounting the metal image via loopback.

So pick it up from there and use that. But in case it's missing,
fallback to the previous logic rather than hard fail to make this easier
to ratchet in.
This commit is contained in:
Jonathan Lebon 2025-08-20 12:14:44 -04:00 committed by Simon de Vlieger
parent 9e85ec6f85
commit b63306616a

View file

@ -130,11 +130,6 @@ def make_stream_hash(src, dest):
outf.write(hashlib.sha256(buf).hexdigest() + '\n')
def get_os_name(tree):
os_release = osrelease.parse_files(os.path.join(tree, 'usr', 'lib', 'os-release'))
return f"{os_release['ID']}-{os_release['VARIANT_ID']}"
def ensure_glob(pathname, n="", **kwargs):
"""
Call glob.glob() and fail if there are no results or
@ -300,7 +295,7 @@ def genisoargs_s390x(paths, test_fixture, volid, name_version):
os.path.join(os.path.relpath(paths["iso/images"], paths["iso"]), 'cdboot.img')]
def gen_live_artifacts(paths, tree, filenames, deployed_tree, loop_client, version, blsentry_kargs):
def gen_live_artifacts(paths, tree, filenames, deployed_tree, loop_client, version, blsentry_kargs, osname):
"""
Generate the ISO image.
Based on the Lorax templates [1].
@ -310,7 +305,7 @@ def gen_live_artifacts(paths, tree, filenames, deployed_tree, loop_client, versi
[2] https://fedoraproject.org/wiki/User:Pjones/BootableCDsForBIOSAndUEFI
"""
base_name = get_os_name(tree=deployed_tree)
base_name = osname
name_version = f'{base_name}-{version}'
# The short volume ID can only be 32 characters (bytes probably). We may in
# the future want to shorten this more intelligently, otherwise we truncate the
@ -555,7 +550,7 @@ def mkrootfs_metal(paths, workdir, img_metal, fstype, fsoptions, loop_client):
Mounts a copy of the metal image and modifies it accordingly to create a (fstype) rootfs from its contents for the
live ISO. fstype must be squashfs or erofs.
Returns the bls entry kernel arguments for the ISO bootloader.
Returns the bls entry kernel arguments for the ISO bootloader and the OS name extracted from the aleph.
"""
basearch = os.uname().machine
tmp_rootfs_dir = os.path.join(workdir, 'tmp-rootfs-dir')
@ -637,7 +632,15 @@ def mkrootfs_metal(paths, workdir, img_metal, fstype, fsoptions, loop_client):
if len(blsentry_kargs) == 0:
raise ValueError("found no kargs in metal image")
return blsentry_kargs
# while we're here, also get the OS name from the aleph since we'll
# need that for the volume ID
ALEPH_FILENAME = ".aleph-version.json"
with open(os.path.join(tmp_rootfs_dir, ALEPH_FILENAME), encoding='utf8') as f:
aleph = json.load(f)
osname = aleph.get('container-image', {}).get('image-labels', {}).get('com.coreos.osname')
return (blsentry_kargs, osname)
# pylint: disable=too-many-branches
@ -923,7 +926,11 @@ def main(workdir, tree, inputs, options, loop_client):
mk_osmet_files(deployed_tree, img_metal, img_metal4k, loop_client, paths, os_release)
blsentry_kargs = mkrootfs_metal(paths, workdir, img_metal, fstype, fsoptions, loop_client)
blsentry_kargs, osname = mkrootfs_metal(paths, workdir, img_metal, fstype, fsoptions, loop_client)
if not osname:
osname = os_release['ID']
if 'VARIANT_ID' in os_release:
osname += f"-{os_release['VARIANT_ID']}"
# Generate rootfs image
# The rootfs must be uncompressed because the ISO mounts root.squashfs
@ -951,7 +958,7 @@ def main(workdir, tree, inputs, options, loop_client):
extend_initramfs(initramfs=paths["iso/images/pxeboot/initrd.img"], tree=paths["initrd"])
filenames = options['filenames']
gen_live_artifacts(paths, tree, filenames, deployed_tree, loop_client, version, blsentry_kargs)
gen_live_artifacts(paths, tree, filenames, deployed_tree, loop_client, version, blsentry_kargs, osname)
if __name__ == "__main__":