From 38108fa2ec00805772c8e49b173aab44a7d35b50 Mon Sep 17 00:00:00 2001 From: jbtrystram Date: Thu, 17 Jul 2025 17:19:08 +0200 Subject: [PATCH 1/7] osbuild: make disk usage log conditional and add tips The log disk usage message comming every 10 seconds is quite noisy, hide it when we are in a shell in osbuild. I aslo added a couple of helpful tips in comments given by @dustymabe to work with osbuild. --- src/cmd-osbuild | 7 ++++++- src/cmdlib.sh | 2 +- src/runvm-osbuild | 9 ++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/cmd-osbuild b/src/cmd-osbuild index 0f263bede4..4aff613fb0 100755 --- a/src/cmd-osbuild +++ b/src/cmd-osbuild @@ -408,7 +408,12 @@ main() { else cmd="runvm_with_cache" fi - $cmd -- /usr/lib/coreos-assembler/runvm-osbuild \ + + # To get a shell in the osbuild supermin VM uncomment this. + # osbuild can then be started with `bash tmp/build./cmd.sh` + # See comment about checkpoints in runvm-osbuild + # RUNVM_SHELL=1 \ + $cmd -- /usr/lib/coreos-assembler/runvm-osbuild \ --config "${runvm_osbuild_config_json}" \ --mpp "/usr/lib/coreos-assembler/osbuild-manifests/coreos.osbuild.${basearch}.mpp.yaml" \ --outdir "${outdir}" \ diff --git a/src/cmdlib.sh b/src/cmdlib.sh index 979e00f5c5..7b796d16b8 100755 --- a/src/cmdlib.sh +++ b/src/cmdlib.sh @@ -787,7 +787,7 @@ rc=0 if [ -z "${RUNVM_SHELL:-}" ]; then (cd ${workdir}; bash ${tmp_builddir}/cmd.sh |& tee /dev/virtio-ports/cosa-cmdout) || rc=\$? else - (cd ${workdir}; bash) + (cd ${workdir}; RUNVM_SHELL=${RUNVM_SHELL:-} bash) fi echo \$rc > ${rc_file} if [ -n "\${cachedev}" ]; then diff --git a/src/runvm-osbuild b/src/runvm-osbuild index 2688248d8e..bc324d1468 100755 --- a/src/runvm-osbuild +++ b/src/runvm-osbuild @@ -122,11 +122,18 @@ set -x; osbuild-mpp \ "${mppyaml}" "${processed_json}" set +x -log_disk_usage +if [[ -z "${RUNVM_SHELL:-}" ]]; then + log_disk_usage +fi # Build the image set -x # shellcheck disable=SC2068 +# To stop osbuild at a given stage to inspect the state of +# things you can add `--break stage_id` to the following. +# eg : `--break org.osbuild.bootc.install-to-filesystem` +# The osbuild environnement is set up under `/run/osbuild` +# Use it in conjuction with `RUNVM_SHELL=1 in `cmd-osbuild` osbuild \ --out "$outdir" \ --store "$storedir" \ From 239478df8795418778d85ebc1476634ea2130071 Mon Sep 17 00:00:00 2001 From: jbtrystram Date: Tue, 29 Jul 2025 11:38:17 +0200 Subject: [PATCH 2/7] supermin: add ostree prepare-root config file Bootc is looking for the prepare-root config file in the buildroot environnement because the main assumption is that it's run from the target container. However, in osbuild, it's run from te buildroot, because podman inside bwrap (inside supermin in our case) causes issues. It's fine for RHCOS and SCOS where we use the target container as the buildroot but we cannot do that for FCOS because we require python in the buildroot. For now, insert a prepare-root file in the supermin VM (use as the buildroot for osbuild) until either : - bootc learn to look into the container for it [1] - we ship python in our images and can use them as buildroot. Another approach would be to layer python and the osbuild dependencies on top of our image and use that as the buildroot, but that would create room for packages drift (what was in the repos at build time?). At least using COSA it's easier to keep track of versions. [1] https://github.com/bootc-dev/bootc/issues/1410 --- src/supermin-init-prelude.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/supermin-init-prelude.sh b/src/supermin-init-prelude.sh index e17f7ff542..d5c506c63a 100644 --- a/src/supermin-init-prelude.sh +++ b/src/supermin-init-prelude.sh @@ -87,3 +87,13 @@ touch /etc/cosa-supermin # the missing link. Hehe. update-alternatives --install /etc/alternatives/iptables iptables /usr/sbin/iptables-legacy 1 update-alternatives --install /etc/alternatives/ip6tables ip6tables /usr/sbin/ip6tables-legacy 1 + +# To build the disk image using osbuild and bootc install to-filesystem we need to +# have a prepare-root config in the build environnement for bootc to read. +# This workaround can be removed when https://github.com/bootc-dev/bootc/issues/1410 +# is fixed or we have python in all streams which allows us to use the OCI image as the buildroot. +# Note that RHCOS and SCOS use the OCI as buildroot so they should not be affected by this. +cat > /usr/lib/ostree/prepare-root.conf < Date: Tue, 28 Oct 2025 16:18:35 +0100 Subject: [PATCH 3/7] cmdlib: make a helper for `manifest.metadata` knobs Prep work to add a knob for using bootc install in osbuild. Refactor the override logic in a helper function so we can easily add those knobs down the line. --- src/cmdlib.sh | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/src/cmdlib.sh b/src/cmdlib.sh index 7b796d16b8..6a4e8f442d 100755 --- a/src/cmdlib.sh +++ b/src/cmdlib.sh @@ -148,28 +148,49 @@ yaml2json() { python3 -c 'import sys, json, yaml; json.dump(yaml.safe_load(sys.stdin), sys.stdout, sort_keys=True)' < "$1" > "$2" } -should_build_with_buildah() { - local variant manifest - if [ -n "${COSA_BUILD_WITH_BUILDAH:-}" ]; then - if [ "${COSA_BUILD_WITH_BUILDAH:-}" = 1 ]; then +# Common helper to check for features that can be enabled via an env var or +# in the manifest metadata. +_should_enable_feature() { + local env_var_name=$1 + local metadata_key=$2 + local env_var_value + # Indirect expansion + env_var_value=${!env_var_name:-} + + if [ -n "${env_var_value}" ]; then + if [ "${env_var_value}" = 1 ]; then return 0 else return 1 fi fi + + # Make sure we are in the config directory (e.g. cmd-osbuild set a different working directory). + # When called very early (e.g. cmd-fetch), configdir isn't initialized yet so we assume we are in the top + # cosa initialized dir and use `src/config`. + # We redirect the output to /dev/null to avoid the noisy `dirs` output. + set +u + pushd "${configdir:-src/config}" > /dev/null + set -u # this slightly duplicates some logic in `prepare_build`, but meh... - if [[ -f "src/config.json" ]]; then - variant="$(jq --raw-output '."coreos-assembler.config-variant"' src/config.json)" - manifest="src/config/manifest-${variant}.yaml" + if [[ -f "../config.json" ]]; then + variant="$(jq --raw-output '."coreos-assembler.config-variant"' ../config.json)" + manifest="manifest-${variant}.yaml" else - manifest="src/config/manifest.yaml" + manifest="manifest.yaml" fi - if [ "$(yq .metadata.build_with_buildah "${manifest}")" = true ]; then + if [ "$(yq ".metadata.${metadata_key}" "${manifest}")" = true ]; then + popd > /dev/null return 0 fi + popd > /dev/null return 1 } +should_use_bootc_install() { + _should_enable_feature "COSA_OSBUILD_USE_BOOTC_INSTALL" "use_bootc_install" +} + prepare_build() { preflight preflight_kvm From 782526b1afbcc9ced80c1962192892baf499227f Mon Sep 17 00:00:00 2001 From: jbtrystram Date: Tue, 28 Oct 2025 16:21:37 +0100 Subject: [PATCH 4/7] osbuild: use bootc install to deploy the container Instead of deploying the container to the tree then copy all the contents to the disk image, use bootc to directly manage the installation to the target filesystems. Right now this requires to use the image as the buildroot so this requires python (for osbuild). This is tracked in [1]. As we have python in rawhide now I duplicated the manifest and added a switch in the osbuild wrapper script. We can keep the manifest duplicated until we are confident to roll this to all streams. [1] https://github.com/bootc-dev/bootc/issues/1410 Requires: https://github.com/bootc-dev/bootc/pull/1460 https://github.com/bootc-dev/bootc/pull/1451 https://github.com/osbuild/osbuild/pull/2149 https://github.com/osbuild/osbuild/pull/2152 All of which have landed in osbuild-159 and bootc 1.6 --- src/cmd-osbuild | 16 +- src/cmdlib.sh | 4 + .../coreos.osbuild.x86_64.bootc.mpp.yaml | 578 ++++++++++++++++++ 3 files changed, 594 insertions(+), 4 deletions(-) create mode 100644 src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml diff --git a/src/cmd-osbuild b/src/cmd-osbuild index 4aff613fb0..b2f2d1bebd 100755 --- a/src/cmd-osbuild +++ b/src/cmd-osbuild @@ -409,14 +409,22 @@ main() { cmd="runvm_with_cache" fi + # Use the bootc install to-filesystem manifest if applicable + bootc_suffix="" + if should_use_bootc_install; then + bootc_suffix=".bootc" + fi + + manifest_path="/usr/lib/coreos-assembler/osbuild-manifests/coreos.osbuild.${basearch}${bootc_suffix}.mpp.yaml" + # To get a shell in the osbuild supermin VM uncomment this. # osbuild can then be started with `bash tmp/build./cmd.sh` # See comment about checkpoints in runvm-osbuild # RUNVM_SHELL=1 \ - $cmd -- /usr/lib/coreos-assembler/runvm-osbuild \ - --config "${runvm_osbuild_config_json}" \ - --mpp "/usr/lib/coreos-assembler/osbuild-manifests/coreos.osbuild.${basearch}.mpp.yaml" \ - --outdir "${outdir}" \ + $cmd -- /usr/lib/coreos-assembler/runvm-osbuild \ + --config "${runvm_osbuild_config_json}" \ + --mpp "${manifest_path}" \ + --outdir "${outdir}" \ --platforms "$(IFS=,; echo "${platforms[*]}")" for platform in "${platforms[@]}"; do diff --git a/src/cmdlib.sh b/src/cmdlib.sh index 6a4e8f442d..62caa8e0e2 100755 --- a/src/cmdlib.sh +++ b/src/cmdlib.sh @@ -191,6 +191,10 @@ should_use_bootc_install() { _should_enable_feature "COSA_OSBUILD_USE_BOOTC_INSTALL" "use_bootc_install" } +should_build_with_buildah() { + _should_enable_feature "COSA_BUILD_WITH_BUILDAH" "build_with_buildah" +} + prepare_build() { preflight preflight_kvm diff --git a/src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml b/src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml new file mode 100644 index 0000000000..b61cfd6a58 --- /dev/null +++ b/src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml @@ -0,0 +1,578 @@ +version: '2' +mpp-vars: + artifact_name_prefix: $artifact_name_prefix + ociarchive: $ociarchive + osname: $osname + container_imgref: $container_imgref + container_repo: $container_repo + container_tag: $container_tag + extra_kargs: $extra_kargs + metal_image_size_mb: $metal_image_size_mb + cloud_image_size_mb: $cloud_image_size_mb + bios_boot_size_mb: 1 + ppc_prep_size_mb: 4 + reserved_part_size_mb: 1 + efi_system_size_mb: 127 + boot_size_mb: 384 + sector_size: 512 + four_k_sector_size: 4096 + # Filesystem UUID and label definitions. These UUIDs + # are looked for on boot and if found replaced with + # a new random UUID to make each install unique. + boot_fs_uuid: 96d15588-3596-4b3c-adca-a2ff7279ea63 + boot_fs_label: boot + root_fs_uuid: 910678ff-f77e-4a7d-8d53-86f2ac47a823 + root_fs_label: root + # For some stages (i.e. the qemu stages) we'll use the host as + # the buildroot (i.e. COSA in most cases but sometimes just + # the actual HOST filesystem like in coreos/custom-coreos-disk-images). + # This is useful/necessary because we definitely don't include + # qemu-img or tools like zip in the actual CoreOS OS. "" here + # means to use the host as buildroot. It is worth noting that + # the host buildroot is the default if nothing is specified. + # We're still defining it here in an attempt to be explicit. + host_as_buildroot: "" + # Set the buildroot string to use for most operations here. We create + # the buildroot from the target OSTree contents so we have version + # matches. Unfortunately for FCOS there is no python so we can't + # really use FCOS as the buildroot so we'll use the host as the + # buildroot there. + buildroot: + mpp-if: osname in ['rhcos', 'scos'] + then: "name:deployed-tree" + else: + mpp-format-string: '{host_as_buildroot}' +mpp-define-images: + - id: image + sector_size: + mpp-format-int: "{sector_size}" + size: + mpp-format-string: "{metal_image_size_mb * 1024 * 1024}" + table: + uuid: 00000000-0000-4000-a000-000000000001 + label: gpt + partitions: + - name: BIOS-BOOT + type: 21686148-6449-6E6F-744E-656564454649 + bootable: true + size: + mpp-format-int: "{bios_boot_size_mb * 1024 * 1024 / sector_size}" + - name: EFI-SYSTEM + type: C12A7328-F81F-11D2-BA4B-00A0C93EC93B + size: + mpp-format-int: "{efi_system_size_mb * 1024 * 1024 / sector_size}" + - name: boot + type: 0FC63DAF-8483-4772-8E79-3D69D8477DE4 + size: + mpp-format-int: "{boot_size_mb * 1024 * 1024 / sector_size}" + - name: root + type: 0FC63DAF-8483-4772-8E79-3D69D8477DE4 + - id: image4k + sector_size: + mpp-format-int: "{four_k_sector_size}" + size: + mpp-format-string: "{metal_image_size_mb * 1024 * 1024}" + table: + uuid: 00000000-0000-4000-a000-000000000001 + label: gpt + partitions: + - name: BIOS-BOOT + type: 21686148-6449-6E6F-744E-656564454649 + bootable: true + size: + mpp-format-int: "{bios_boot_size_mb * 1024 * 1024 / four_k_sector_size}" + - name: EFI-SYSTEM + type: C12A7328-F81F-11D2-BA4B-00A0C93EC93B + size: + mpp-format-int: "{efi_system_size_mb * 1024 * 1024 / four_k_sector_size}" + - name: boot + type: 0FC63DAF-8483-4772-8E79-3D69D8477DE4 + size: + mpp-format-int: "{boot_size_mb * 1024 * 1024 / four_k_sector_size}" + - name: root + type: 0FC63DAF-8483-4772-8E79-3D69D8477DE4 +pipelines: + # If installing from container then let's pull the container file into a pipeline + - name: oci-archive + stages: + - mpp-if: ociarchive != '' + then: + type: org.osbuild.copy + inputs: + inlinefile: + type: org.osbuild.files + origin: org.osbuild.source + mpp-embed: + id: coreos.ociarchive + url: + mpp-format-string: 'file://{ociarchive}' + options: + paths: + - from: + mpp-format-string: input://inlinefile/{embedded['coreos.ociarchive']} + to: tree:///coreos.ociarchive + else: + type: org.osbuild.noop + # Construct a tree here that is a representation of the filesystem + # that you would see on a running OSTree system. i.e. instead of just + # /ostree and /sysroot at the toplevel we see /usr/ /var/ /etc/ ... that + # you would see inside an OSTree deployment. Having the plain files accessible + # allows for this pipeline to be used as a buildroot for some stages + # or as inputs for others (i.e. file_context input to the org.osbuild.selinux + # stages). This pipeline isn't actually used for built artifacts but + # to help during build. + # + # NOTE: this is only used as a buildroot on RHCOS (FCOS doesn't ship python). + - name: deployed-tree + stages: + - mpp-if: ociarchive != '' + then: + type: org.osbuild.container-deploy + inputs: + images: + type: org.osbuild.containers + origin: org.osbuild.pipeline + references: + name:oci-archive: + name: coreos.ociarchive + else: + type: org.osbuild.container-deploy + inputs: + images: + type: org.osbuild.containers-storage + origin: org.osbuild.source + mpp-resolve-images: + images: + - source: $container_repo + tag: $container_tag + - name: tree + build: + mpp-format-string: '{buildroot}' + source-epoch: 1659397331 + stages: + # Set the context of the root of the tree so that we avoid unlabeled_t files. + # https://github.com/coreos/fedora-coreos-tracker/issues/1772 + - type: org.osbuild.selinux + options: + file_contexts: input://tree/etc/selinux/targeted/contexts/files/file_contexts + target: tree:/// + inputs: + tree: + type: org.osbuild.tree + origin: org.osbuild.pipeline + references: + - name:deployed-tree + - name: raw-image + build: + mpp-format-string: '{buildroot}' + stages: + - type: org.osbuild.truncate + options: + filename: disk.img + size: + mpp-format-string: '{image.size}' + - type: org.osbuild.sfdisk + devices: + device: + type: org.osbuild.loopback + options: + filename: disk.img + options: + mpp-format-json: '{image.layout}' + - type: org.osbuild.mkfs.fat + devices: + device: + type: org.osbuild.loopback + options: + filename: disk.img + start: + mpp-format-int: '{image.layout[''EFI-SYSTEM''].start}' + size: + mpp-format-int: '{image.layout[''EFI-SYSTEM''].size}' + lock: true + options: + label: EFI-SYSTEM + volid: 7B7795E7 + - type: org.osbuild.mkfs.ext4 + devices: + device: + type: org.osbuild.loopback + options: + filename: disk.img + start: + mpp-format-int: '{image.layout[''boot''].start}' + size: + mpp-format-int: '{image.layout[''boot''].size}' + lock: true + options: + uuid: + mpp-format-string: '{boot_fs_uuid}' + label: + mpp-format-string: '{boot_fs_label}' + # Set manually the metadata_csum_seed ext4 option otherwise changing the + # filesystem UUID while it's mounted doesn't work. Can remove this when + # metadata_csum_seed is default in RHEL, which can be checked by looking + # in /etc/mke2fs.conf. + metadata_csum_seed: true + - type: org.osbuild.mkfs.xfs + devices: + device: + type: org.osbuild.loopback + options: + filename: disk.img + start: + mpp-format-int: '{image.layout[''root''].start}' + size: + mpp-format-int: '{image.layout[''root''].size}' + lock: true + options: + uuid: + mpp-format-string: '{root_fs_uuid}' + label: + mpp-format-string: '{root_fs_label}' + # We've created the filesystems. Now let's create the mountpoints (directories) + # on the filesystems and label them with appropriate SELinux labels. This also + # covers things like filesystem autogenerated files like 'lost+found'. The labeling + # will happen once with just the root filesystem mounted and once with the boot + # filesystem mounted too (to make sure we get all potentially hidden mountpoints). + # https://github.com/coreos/fedora-coreos-tracker/issues/1771 + - type: org.osbuild.mkdir + options: + paths: + - path: mount://root/boot + mode: 493 + - path: mount://boot/efi + mode: 493 + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image.layout[''root''].partnum}' + target: /root-mount-point + - name: boot + type: org.osbuild.ext4 + source: disk + partition: + mpp-format-int: '{image.layout[''boot''].partnum}' + target: /boot-mount-point + # Use bootc install to-filesystem to install the ostree content from the container image + # inside our disc image + - type: org.osbuild.bootc.install-to-filesystem + inputs: + images: + mpp-if: ociarchive != '' + then: + type: org.osbuild.containers + origin: org.osbuild.pipeline + references: + name:oci-archive: + name: coreos.ociarchive + else: + type: org.osbuild.containers-storage + origin: org.osbuild.source + mpp-resolve-images: + images: + - source: $container_repo + tag: $container_tag + options: + kernel-args: + - '$ignition_firstboot' + - mpp-format-string: '{extra_kargs}' + target-imgref: + mpp-format-string: '{container_imgref}' + stateroot: + mpp-format-string: '{osname}' + # Empty strings mean mount spec kargs are ommited entirely. + # See github.com/bootc-dev/bootc/issues/1441 + boot-mount-spec: "" + root-mount-spec: "" + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image.layout[''root''].partnum}' + target: / + - name: boot + type: org.osbuild.ext4 + source: disk + partition: + mpp-format-int: '{image.layout[''boot''].partnum}' + target: /boot + - name: efi + type: org.osbuild.fat + source: disk + partition: + mpp-format-int: '{image.layout[''EFI-SYSTEM''].partnum}' + target: /boot/efi + # set up the `ignition.firstboot` stamp at the end because + # bootc want empty filesystems + - type: org.osbuild.ignition + options: + target: mount://boot/ + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image.layout[''root''].partnum}' + target: / + - name: boot + type: org.osbuild.ext4 + source: disk + partition: + mpp-format-int: '{image.layout[''boot''].partnum}' + target: /boot + - name: raw-4k-image + build: + mpp-format-string: '{buildroot}' + stages: + - type: org.osbuild.truncate + options: + filename: disk.img + size: + mpp-format-string: '{image4k.size}' + - type: org.osbuild.sfdisk + devices: + device: + type: org.osbuild.loopback + options: + filename: disk.img + sector-size: + mpp-format-int: "{four_k_sector_size}" + options: + mpp-format-json: '{image4k.layout}' + - type: org.osbuild.mkfs.fat + devices: + device: + type: org.osbuild.loopback + options: + filename: disk.img + start: + mpp-format-int: '{image4k.layout[''EFI-SYSTEM''].start}' + size: + mpp-format-int: '{image4k.layout[''EFI-SYSTEM''].size}' + lock: true + sector-size: + mpp-format-int: "{four_k_sector_size}" + options: + label: EFI-SYSTEM + volid: 7B7795E7 + - type: org.osbuild.mkfs.ext4 + devices: + device: + type: org.osbuild.loopback + options: + filename: disk.img + start: + mpp-format-int: '{image4k.layout[''boot''].start}' + size: + mpp-format-int: '{image4k.layout[''boot''].size}' + lock: true + sector-size: + mpp-format-int: "{four_k_sector_size}" + options: + uuid: + mpp-format-string: '{boot_fs_uuid}' + label: + mpp-format-string: '{boot_fs_label}' + # Set manually the metadata_csum_seed ext4 option otherwise changing the + # filesystem UUID while it's mounted doesn't work. Can remove this when + # metadata_csum_seed is default in RHEL, which can be checked by looking + # in /etc/mke2fs.conf. + metadata_csum_seed: true + - type: org.osbuild.mkfs.xfs + devices: + device: + type: org.osbuild.loopback + options: + filename: disk.img + start: + mpp-format-int: '{image4k.layout[''root''].start}' + size: + mpp-format-int: '{image4k.layout[''root''].size}' + lock: true + sector-size: + mpp-format-int: "{four_k_sector_size}" + options: + uuid: + mpp-format-string: '{root_fs_uuid}' + label: + mpp-format-string: '{root_fs_label}' + # We've created the filesystems. Now let's create the mountpoints (directories) + # on the filesystems and label them with appropriate SELinux labels. This also + # covers things like filesystem autogenerated files like 'lost+found'. The labeling + # will happen once with just the root filesystem mounted and once with the boot + # filesystem mounted too (to make sure we get all potentially hidden mountpoints). + # https://github.com/coreos/fedora-coreos-tracker/issues/1771 + - type: org.osbuild.mkdir + options: + paths: + - path: mount://root/boot + mode: 493 + - path: mount://boot/efi + mode: 493 + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + sector-size: + mpp-format-int: "{four_k_sector_size}" + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image4k.layout[''root''].partnum}' + target: /root-mount-point + - name: boot + type: org.osbuild.ext4 + source: disk + partition: + mpp-format-int: '{image4k.layout[''boot''].partnum}' + target: /boot-mount-point + # Use bootc install to-filesystem to install the ostree content from the container image + # inside our disc image + - type: org.osbuild.bootc.install-to-filesystem + inputs: + images: + mpp-if: ociarchive != '' + then: + type: org.osbuild.containers + origin: org.osbuild.pipeline + references: + name:oci-archive: + name: coreos.ociarchive + else: + type: org.osbuild.containers-storage + origin: org.osbuild.source + mpp-resolve-images: + images: + - source: $container_repo + tag: $container_tag + options: + kernel-args: + - '$ignition_firstboot' + - mpp-format-string: '{extra_kargs}' + target-imgref: + mpp-format-string: '{container_imgref}' + stateroot: + mpp-format-string: '{osname}' + # Empty strings mean mount spec kargs are ommited entirely. + # See github.com/bootc-dev/bootc/issues/1441 + boot-mount-spec: "" + root-mount-spec: "" + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + sector-size: + mpp-format-int: "{four_k_sector_size}" + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image4k.layout[''root''].partnum}' + target: / + - name: boot + type: org.osbuild.ext4 + source: disk + partition: + mpp-format-int: '{image4k.layout[''boot''].partnum}' + target: /boot + - name: efi + type: org.osbuild.fat + source: disk + partition: + mpp-format-int: '{image4k.layout[''EFI-SYSTEM''].partnum}' + target: /boot/efi + # set up the `ignition.firstboot` stamp at the end because + # bootc want empty filesystems + - type: org.osbuild.ignition + options: + target: mount://boot/ + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + sector-size: + mpp-format-int: "{four_k_sector_size}" + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image4k.layout[''root''].partnum}' + target: / + - name: boot + type: org.osbuild.ext4 + source: disk + partition: + mpp-format-int: '{image4k.layout[''boot''].partnum}' + target: /boot + - mpp-import-pipelines: + path: platform.aliyun.ipp.yaml + - mpp-import-pipelines: + path: platform.applehv.ipp.yaml + - mpp-import-pipelines: + path: platform.aws.ipp.yaml + - mpp-import-pipelines: + path: platform.azure.ipp.yaml + - mpp-import-pipelines: + path: platform.azurestack.ipp.yaml + - mpp-import-pipelines: + path: platform.digitalocean.ipp.yaml + - mpp-import-pipelines: + path: platform.exoscale.ipp.yaml + - mpp-import-pipelines: + path: platform.gcp.ipp.yaml + - mpp-import-pipelines: + path: platform.hetzner.ipp.yaml + - mpp-import-pipelines: + path: platform.hyperv.ipp.yaml + - mpp-import-pipelines: + path: platform.ibmcloud.ipp.yaml + - mpp-import-pipelines: + path: platform.kubevirt.ipp.yaml + - mpp-import-pipelines: + path: platform.openstack.ipp.yaml + - mpp-import-pipelines: + path: platform.oraclecloud.ipp.yaml + - mpp-import-pipelines: + path: platform.proxmoxve.ipp.yaml + - mpp-import-pipelines: + path: platform.metal.ipp.yaml + - mpp-import-pipelines: + path: platform.nutanix.ipp.yaml + - mpp-import-pipelines: + path: platform.qemu.ipp.yaml + - mpp-import-pipelines: + path: platform.vultr.ipp.yaml + - mpp-import-pipelines: + path: platform.live.ipp.yaml From 9ffa4d3175b66b972390e69136cbeea65ceaf875 Mon Sep 17 00:00:00 2001 From: jbtrystram Date: Tue, 21 Oct 2025 16:46:05 +0200 Subject: [PATCH 5/7] osbuild/ bootc-install: symlink aleph files Create symlinks to the aleph file created by bootc so our tests and tooling find the aleph at the expected path. --- src/cmdlib.sh | 9 ++-- .../coreos.osbuild.x86_64.bootc.mpp.yaml | 46 +++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/cmdlib.sh b/src/cmdlib.sh index 62caa8e0e2..c9b2426ff0 100755 --- a/src/cmdlib.sh +++ b/src/cmdlib.sh @@ -783,10 +783,11 @@ runvm() { # include COSA in the image find /usr/lib/coreos-assembler/ -type f > "${vmpreparedir}/hostfiles" - cat <> "${vmpreparedir}/hostfiles" -/usr/lib/osbuild/stages/org.osbuild.coreos.live-artifacts.mono -/usr/lib/osbuild/stages/org.osbuild.coreos.live-artifacts.mono.meta.json -EOF + # Include arbitrary files from the host +# cat <> "${vmpreparedir}/hostfiles" +# /usr/lib/osbuild/stages/org.osbuild.ln +# /usr/lib/osbuild/stages/org.osbuild.ln.meta.json +# EOF # and include all GPG keys echo '/etc/pki/rpm-gpg/*' >> "${vmpreparedir}/hostfiles" diff --git a/src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml b/src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml index b61cfd6a58..a47b0c85db 100644 --- a/src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml +++ b/src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml @@ -342,6 +342,28 @@ pipelines: partition: mpp-format-int: '{image.layout[''boot''].partnum}' target: /boot + - type: org.osbuild.ln + options: + paths: + - target: ".bootc-aleph.json" + link_name: "mount://root/.coreos-aleph-version.json" + symbolic: true + - target: ".bootc-aleph.json" + link_name: "mount://root/.aleph-version.json" + symbolic: true + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image.layout[''root''].partnum}' + target: / - name: raw-4k-image build: mpp-format-string: '{buildroot}' @@ -536,6 +558,30 @@ pipelines: partition: mpp-format-int: '{image4k.layout[''boot''].partnum}' target: /boot + - type: org.osbuild.ln + options: + paths: + - target: ".bootc-aleph.json" + link_name: "mount://root/.coreos-aleph-version.json" + symbolic: true + - target: ".bootc-aleph.json" + link_name: "mount://root/.aleph-version.json" + symbolic: true + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + sector-size: + mpp-format-int: "{four_k_sector_size}" + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image4k.layout[''root''].partnum}' + target: / - mpp-import-pipelines: path: platform.aliyun.ipp.yaml - mpp-import-pipelines: From 07b993c4ab576c2600238d4501b6c4ccf9d0c949 Mon Sep 17 00:00:00 2001 From: jbtrystram Date: Mon, 27 Oct 2025 20:11:52 +0100 Subject: [PATCH 6/7] vmdeps: add filesystem to supermin this rpm provides locales under `/usr/share/locale`. grub2 install these files inside the /boot partition using what exist on the host. Mooving to bootc install results in an empty folder because those files don't exist in the buildroot, so add them. In the previous manifest we were using a chroot before calling bootupd which made sure bootupd (and by extension grub2) would pull content from the target root. It would be nicer to have bootc install also chroot before calling bootupd, it would have the added benefit to use the bootupd (and other) binaries that are shipped on the image rather than what is in the buildroot. Again, this is a complication coming from not having python in the image so we can't use ourselves as the buildroot, which would alleviate a lot of pain. See https://github.com/coreos/coreos-assembler/pull/4224#issuecomment-3452307787 And https://github.com/bootc-dev/bootc/issues/1559 --- src/vmdeps.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vmdeps.txt b/src/vmdeps.txt index 1040dcae2c..f19b7cb67b 100644 --- a/src/vmdeps.txt +++ b/src/vmdeps.txt @@ -45,3 +45,6 @@ osbuild osbuild-ostree osbuild-selinux osbuild-tools python3-pyrsistent zip # For resetting the terminal inside supermin shell /usr/bin/reset /usr/bin/clear + +# To have the locales available for grub to install +filesystem From d85142f5ba01f07a2d53b2a4393a3467b3686efc Mon Sep 17 00:00:00 2001 From: jbtrystram Date: Wed, 29 Oct 2025 12:51:48 +0100 Subject: [PATCH 7/7] osbuild/bootc: properly label the mount points Properly label the filesystem mount points before calling bootc, otherwise `/sysroot` and `/boot` end up being `unlabeled_t` --- .../coreos.osbuild.x86_64.bootc.mpp.yaml | 116 ++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml b/src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml index a47b0c85db..9a02052907 100644 --- a/src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml +++ b/src/osbuild-manifests/coreos.osbuild.x86_64.bootc.mpp.yaml @@ -262,6 +262,64 @@ pipelines: partition: mpp-format-int: '{image.layout[''boot''].partnum}' target: /boot-mount-point + # Set the context of the root of disk so that we avoid unlabeled_t files. + # Here we make sure to not mount the boot partition because we want to label + # the directory mount point + # https://github.com/coreos/fedora-coreos-tracker/issues/1772 + - type: org.osbuild.selinux + options: + file_contexts: input://tree/etc/selinux/targeted/contexts/files/file_contexts + target: mount://root/ + inputs: + tree: + type: org.osbuild.tree + origin: org.osbuild.pipeline + references: + - name:deployed-tree + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image.layout[''root''].partnum}' + target: / + # Then we mount le boot parition and label again so the /boot/efi + # mount point is labeled properly + - type: org.osbuild.selinux + options: + file_contexts: input://tree/etc/selinux/targeted/contexts/files/file_contexts + target: mount://root/boot + inputs: + tree: + type: org.osbuild.tree + origin: org.osbuild.pipeline + references: + - name:deployed-tree + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image.layout[''root''].partnum}' + target: / + - name: boot + type: org.osbuild.ext4 + source: disk + partition: + mpp-format-int: '{image.layout[''boot''].partnum}' + target: /boot # Use bootc install to-filesystem to install the ostree content from the container image # inside our disc image - type: org.osbuild.bootc.install-to-filesystem @@ -474,6 +532,64 @@ pipelines: partition: mpp-format-int: '{image4k.layout[''boot''].partnum}' target: /boot-mount-point + # Set the context of the root of disk so that we avoid unlabeled_t files. + # Here we make sure to not mount the boot partition because we want to label + # the directory mount point + # https://github.com/coreos/fedora-coreos-tracker/issues/1772 + - type: org.osbuild.selinux + options: + file_contexts: input://tree/etc/selinux/targeted/contexts/files/file_contexts + target: mount://root/ + inputs: + tree: + type: org.osbuild.tree + origin: org.osbuild.pipeline + references: + - name:deployed-tree + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image.layout[''root''].partnum}' + target: / + # Then we mount le boot parition and label again so the /boot/efi + # mount point is labeled properly + - type: org.osbuild.selinux + options: + file_contexts: input://tree/etc/selinux/targeted/contexts/files/file_contexts + target: mount://root/boot + inputs: + tree: + type: org.osbuild.tree + origin: org.osbuild.pipeline + references: + - name:deployed-tree + devices: + disk: + type: org.osbuild.loopback + options: + filename: disk.img + partscan: true + mounts: + - name: root + type: org.osbuild.xfs + source: disk + partition: + mpp-format-int: '{image.layout[''root''].partnum}' + target: / + - name: boot + type: org.osbuild.ext4 + source: disk + partition: + mpp-format-int: '{image.layout[''boot''].partnum}' + target: /boot # Use bootc install to-filesystem to install the ostree content from the container image # inside our disc image - type: org.osbuild.bootc.install-to-filesystem