From b63306616ad56f786bc9957e1edd6dd866695b2e Mon Sep 17 00:00:00 2001 From: Jonathan Lebon Date: Wed, 20 Aug 2025 12:14:44 -0400 Subject: [PATCH] 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. --- stages/org.osbuild.coreos.live-artifacts.mono | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/stages/org.osbuild.coreos.live-artifacts.mono b/stages/org.osbuild.coreos.live-artifacts.mono index 4a95b607..35ecac4e 100755 --- a/stages/org.osbuild.coreos.live-artifacts.mono +++ b/stages/org.osbuild.coreos.live-artifacts.mono @@ -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__":