From ba12dc1c46ff95e3e672a5a298d56bfb34ea0d1f Mon Sep 17 00:00:00 2001 From: Renata Ravanelli Date: Tue, 1 Oct 2024 11:01:50 -0300 Subject: [PATCH] buildextend-live: Add OSBUILD support - Add support for OSBUILD via COSA_OSBUILD_LIVEISO env var for now. Once we finish the OSBUILD integration we can disable it via var. Signed-off-by: Renata Ravanelli --- src/cmd-buildextend-live | 145 ++++++++++++++++++++++++++------------- 1 file changed, 99 insertions(+), 46 deletions(-) diff --git a/src/cmd-buildextend-live b/src/cmd-buildextend-live index 24dac4a9b4..d4a4484987 100755 --- a/src/cmd-buildextend-live +++ b/src/cmd-buildextend-live @@ -29,6 +29,8 @@ IGNITION_IMG_SIZE = 256 * 1024 # Size of the file used to embed miniso data. MINISO_DATA_FILE_SIZE = 16 * 1024 +COSA_OSBUILD_LIVEISO = os.getenv("COSA_OSBUILD_LIVEISO", "") + live_exclude_kargs = set([ '$ignition_firstboot', # unsubstituted variable in grub config 'console', # no serial console by default on ISO @@ -97,12 +99,14 @@ name_version = f'{base_name}-{args.build}' # to shorten this more intelligently, otherwise we truncate the # version which may impede uniqueness. volid = name_version[0:32] -kernel_name = f'{base_name}-{args.build}-live-kernel-{basearch}' -initramfs_name = f'{base_name}-{args.build}-live-initramfs.{basearch}.img' -rootfs_name = f'{base_name}-{args.build}-live-rootfs.{basearch}.img' -kernel_file = os.path.join(builddir, kernel_name) -initramfs_file = os.path.join(builddir, initramfs_name) -rootfs_file = os.path.join(builddir, rootfs_name) +build_path = os.path.abspath(f"{builddir}/{base_name}-{args.build}") +tmpdir = os.environ.get("FORCE_TMPDIR", f"{workdir}/tmp/buildpost-live") +if os.path.isdir(tmpdir): + shutil.rmtree(tmpdir) +os.mkdir(tmpdir) +tmpisofile = os.path.join(tmpdir, iso_name) + + # The kernel requires that uncompressed cpio archives appended to an initrd # start on a 4-byte boundary. If there's misalignment, it stops unpacking # and says: @@ -119,6 +123,50 @@ def align_initrd_for_uncompressed_append(destf): destf.write(b'\0' * (4 - offset % 4)) +def update_buildmeta(initramfs_path, rootfs_path, kernel_path): + + kernel_name = f'{base_name}-{args.build}-live-kernel-{basearch}' + initramfs_name = f'{base_name}-{args.build}-live-initramfs.{basearch}.img' + rootfs_name = f'{base_name}-{args.build}-live-rootfs.{basearch}.img' + kernel_file = os.path.join(builddir, kernel_name) + initramfs_file = os.path.join(builddir, initramfs_name) + rootfs_file = os.path.join(builddir, rootfs_name) + + buildmeta['images'].update({ + 'live-iso': { + 'path': iso_name, + 'sha256': sha256sum_file(tmpisofile), + 'skip-compression': True, + } + }) + + shutil.move(tmpisofile, f"{builddir}/{iso_name}") + shutil.move(kernel_path, kernel_file) + shutil.move(initramfs_path, initramfs_file) + shutil.move(rootfs_path, rootfs_file) + + buildmeta['images'].update({ + 'live-kernel': { + 'path': kernel_name, + 'sha256': sha256sum_file(kernel_file), + 'skip-compression': True, + }, + 'live-initramfs': { + 'path': initramfs_name, + 'sha256': sha256sum_file(initramfs_file), + 'skip-compression': True, + }, + 'live-rootfs': { + 'path': rootfs_name, + 'sha256': sha256sum_file(rootfs_file), + 'skip-compression': True, + } + }) + + buildmeta.write(artifact_name='live') + print(f"Updated: {buildmeta_path}") + + # Return OS features table for features.json, which is read by # coreos-installer {iso|pxe} customize def get_os_features(): @@ -208,10 +256,6 @@ def generate_iso(): kargs_file = 'kargs.json' igninfo_file = 'igninfo.json' - tmpdir = os.environ.get("FORCE_TMPDIR", f"{workdir}/tmp/buildpost-live") - if os.path.isdir(tmpdir): - shutil.rmtree(tmpdir) - tmpisoroot = os.path.join(tmpdir, 'live') tmpisocoreos = os.path.join(tmpisoroot, 'coreos') tmpisoimages = os.path.join(tmpisoroot, 'images') @@ -222,12 +266,9 @@ def generate_iso(): # contents of rootfs image tmpinitrd_rootfs = os.path.join(tmpdir, 'initrd-rootfs') - for d in (tmpdir, tmpisoroot, tmpisocoreos, tmpisoimages, tmpisoimagespxe, + for d in (tmpisoroot, tmpisocoreos, tmpisoimages, tmpisoimagespxe, tmpisoisolinux, tmpinitrd_base, tmpinitrd_rootfs): os.mkdir(d) - - tmpisofile = os.path.join(tmpdir, iso_name) - img_metal_obj = buildmeta.get_artifact_meta("metal", unmerged=True)["images"].get("metal") if not img_metal_obj: raise Exception("Live image generation requires `metal` image") @@ -760,37 +801,7 @@ boot 'pack', 'minimal-iso', tmpisofile, f'{tmpisofile}.minimal', '--consume']) - buildmeta['images'].update({ - 'live-iso': { - 'path': iso_name, - 'sha256': sha256sum_file(tmpisofile), - 'skip-compression': True, - } - }) - shutil.move(tmpisofile, f"{builddir}/{iso_name}") - shutil.copyfile(os.path.join(tmpisoimagespxe, kernel_img), kernel_file) - shutil.move(pxe_initramfs, initramfs_file) - shutil.move(pxe_rootfs, rootfs_file) - buildmeta['images'].update({ - 'live-kernel': { - 'path': kernel_name, - 'sha256': sha256sum_file(kernel_file), - 'skip-compression': True, - }, - 'live-initramfs': { - 'path': initramfs_name, - 'sha256': sha256sum_file(initramfs_file), - 'skip-compression': True, - }, - 'live-rootfs': { - 'path': rootfs_name, - 'sha256': sha256sum_file(rootfs_file), - 'skip-compression': True, - } - }) - - buildmeta.write(artifact_name='live') - print(f"Updated: {buildmeta_path}") + update_buildmeta(pxe_initramfs, pxe_rootfs, os.path.join(tmpisoimagespxe, kernel_img)) # lock and build @@ -798,7 +809,49 @@ with open(build_semaphore, 'w') as f: f.write(f"{time.time_ns()}") try: - generate_iso() + if COSA_OSBUILD_LIVEISO == "": + generate_iso() + else: + data = { + "buildid": args.build, + "imgid": iso_name, + "ostree-commit": buildmeta_commit, + "container-imgref": "", + "deploy-via-container": "", + "osname": base_name, + "ostree-ref": args.build, + "ostree-container": f"{build_path}-ostree.{basearch}.ociarchive", + "metal-filename": f"{build_path}-metal.{basearch}.raw", + "metal4k-filename": f"{build_path}-metal4k.{basearch}.raw", + "ostree-repo": repo, + "extra-kargs-string": "mitigations=auto,nosmt", + "image-type": "live-iso", + "cloud-image-size": "10240", + "metal-image-size": "2405", + "squashfs-compression": squashfs_compression, + "rootfs-size": 0, + "live-efiboot-img-size": 16 + } + + image_for_disk_json = "runvm.json" + with open(image_for_disk_json, 'w') as file: + json.dump(data, file, indent=4) + + runcmd([ + "/usr/bin/cosa", "supermin-run", + "--cache", "/usr/lib/coreos-assembler/runvm-osbuild", + "--config", + image_for_disk_json, + "--mpp", + f"/usr/lib/coreos-assembler/osbuild-manifests/coreos.osbuild.{basearch}.mpp.yaml", + "--filepath", + tmpisofile + ]) + + # Extract live artifacts from ISO until we rework runvm-osbuild to support outputting multiple files + files_output = runcmd(["coreos-installer", "iso", "extract", "pxe", tmpisofile], capture_output=True) + initramfs_name, rootfs_name, kernel_name = files_output.stdout.decode().split() + update_buildmeta(initramfs_name, rootfs_name, kernel_name) finally: if os.path.exists(build_semaphore): os.unlink(build_semaphore)