From c524dd8d7cbef61e5209a42ea267ad2fc19fd632 Mon Sep 17 00:00:00 2001 From: Pragyan Poudyal Date: Mon, 16 Mar 2026 15:22:17 +0530 Subject: [PATCH 1/6] systemd: Replace boot device dependencies with discovery service Replace direct boot device dependencies (dev-disk-by-label-boot.device) with a new boot partition discovery mechanism across multiple services: - Add boot-part-discovery.service and boot-part-discovered.target to dynamically detect XBOOTLDR partition availability - Update ignition-ostree services to use conditional boot partition dependencies instead of hard requirements - Add composefs condition support to ignition-ostree services - Update coreos-boot-mount-generator to respect boot partition status This change is needed for booting composefs systems with ignition as not all composefs systems will have a boot parition Signed-off-by: Pragyan Poudyal --- .../coreos-boot-edit.service | 9 +++++-- .../coreos-diskful-generator | 4 +-- .../coreos-gpt-setup.service | 7 +++-- .../coreos-ignition-unique-boot.service | 8 ++++-- .../coreos-unique-boot.service | 8 ++++-- .../lib/dracut/modules.d/37bootc/.gitignore | 1 + .../37bootc/bootc-root-setup.service | 21 +++++++++++++++ .../dracut/modules.d/37bootc/module-setup.sh | 20 ++++++++++++++ .../boot-part-discovered.target | 7 +++++ .../boot-part-discovery.service | 11 ++++++++ .../40ignition-ostree/boot-part-discovery.sh | 26 +++++++++++++++++++ .../ignition-ostree-check-rootfs-size.service | 4 ++- .../ignition-ostree-growfs.service | 3 ++- .../ignition-ostree-uuid-boot.service | 8 ++++-- .../ignition-ostree-uuid-root.service | 3 ++- .../40ignition-ostree/module-setup.sh | 6 +++++ .../coreos-boot-mount-generator | 3 +++ ...coreos-ignition-firstboot-complete.service | 2 ++ 18 files changed, 136 insertions(+), 15 deletions(-) create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/37bootc/.gitignore create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/37bootc/bootc-root-setup.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/37bootc/module-setup.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/boot-part-discovered.target create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/boot-part-discovery.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/boot-part-discovery.sh diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.service b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.service index bc2d9ec9ea..ad9a66b34e 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-boot-edit.service @@ -10,8 +10,13 @@ OnFailureJobMode=isolate # Since we are mounting /boot, require the device first. This isn't strictly # necessary since we run late, but on principle let's make clear the dependency. -Requires=dev-disk-by\x2dlabel-boot.device -After=dev-disk-by\x2dlabel-boot.device + +# Requires=dev-disk-by\x2dlabel-boot.device +# After=dev-disk-by\x2dlabel-boot.device + +After=boot-part-discovered.target +ConditionFileNotEmpty=/run/coreos/boot-partition-status + # Start after Ignition has finished After=ignition-files.service # As above, this isn't strictly necessary, but on principle. diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-diskful-generator b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-diskful-generator index b869866431..1d741853c3 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-diskful-generator +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-ignition/coreos-diskful-generator @@ -109,8 +109,8 @@ mkdir -p "${UNIT_DIR}/coreos-ignition-setup-user.service.d" mkdir -p "${UNIT_DIR}/coreos-copy-firstboot-network.service.d" cat > "${UNIT_DIR}/coreos-ignition-setup-user.service.d/diskful.conf" < "$BOOT_STATUS_FILE" + break + else + echo "not boot" + fi +done < <(echo "$LSBLK_JSON" | jq -c '.blockdevices[].children[]?') diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-check-rootfs-size.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-check-rootfs-size.service index 340b4d4251..6db08a6320 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-check-rootfs-size.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-check-rootfs-size.service @@ -2,10 +2,12 @@ Description=Ignition OSTree: Check Root Filesystem Size Documentation=https://docs.fedoraproject.org/en-US/fedora-coreos/storage/ DefaultDependencies=false -ConditionKernelCommandLine=ostree +ConditionKernelCommandLine=|ostree +ConditionKernelCommandLine=|composefs ConditionPathExists=!/run/ostree-live After=ignition-ostree-growfs.service After=ostree-prepare-root.service +# TODO(Johan-Liebert1): We need bootc-initramfs-setup.service here Requires=ostree-prepare-root.service # Allow Ignition config to blank out the warning Before=ignition-files.service diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service index 3674431ff8..1ea3084b9f 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-growfs.service @@ -1,7 +1,8 @@ [Unit] Description=Ignition OSTree: Grow Root Filesystem DefaultDependencies=false -ConditionKernelCommandLine=ostree +ConditionKernelCommandLine=|ostree +ConditionKernelCommandLine=|composefs ConditionPathExists=!/run/ostree-live Before=initrd-root-fs.target Before=sysroot.mount diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service index 85448c2a67..e3ecb7569c 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service @@ -14,8 +14,12 @@ Before=ignition-kargs.service ConditionKernelCommandLine=!bootfs.roothash Before=systemd-fsck@dev-disk-by\x2dlabel-boot.service -Requires=dev-disk-by\x2dlabel-boot.device -After=dev-disk-by\x2dlabel-boot.device +# Requires=dev-disk-by\x2dlabel-boot.device +# After=dev-disk-by\x2dlabel-boot.device + +# Make sure boot partition actually exists +After=boot-part-discovered.target +ConditionFileNotEmpty=/run/coreos/boot-partition-status [Service] Type=oneshot diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-root.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-root.service index 80ecf9d42a..0198a81961 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-root.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-root.service @@ -2,7 +2,8 @@ Description=Ignition OSTree: Regenerate Filesystem UUID (root) # These conditions match those generated in coreos-diskful-generator DefaultDependencies=false -ConditionKernelCommandLine=ostree +ConditionKernelCommandLine=|ostree +ConditionKernelCommandLine=|composefs ConditionPathExists=!/run/ostree-live Before=sysroot.mount initrd-root-fs.target After=ignition-disks.service diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh index ba22090993..7c4252f2c1 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh @@ -121,5 +121,11 @@ install() { inst_script "$moddir/ignition-ostree-mount-state-overlays.sh" \ /usr/libexec/ignition-ostree-mount-state-overlays + inst_simple "$moddir/boot-part-discovery.target" "$systemdsystemunitdir/boot-part-discovery.target" + + install_ignition_unit boot-part-discovery.service + inst_script "$moddir/boot-part-discovery.sh" \ + /usr/libexec/boot-part-discovery.sh + inst_script "$moddir/coreos-relabel" /usr/bin/coreos-relabel } diff --git a/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator b/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator index 7955f903ac..fb06b00e2a 100755 --- a/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator +++ b/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator @@ -60,6 +60,9 @@ Before=local-fs.target Requires=systemd-fsck@${devservice} After=systemd-fsck@${devservice} +After=boot-part-discovered.target +ConditionFileNotEmpty=/run/coreos/boot-partition-status + [Mount] What=${path} Where=${mount_pt} diff --git a/overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service b/overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service index be0456fa22..5ef06a7d88 100644 --- a/overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service +++ b/overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service @@ -6,6 +6,8 @@ ConditionPathExists=!/run/ostree-live # This condition is required for cases where a soft-reboot is issued on the # firstboot. Soft reboot do not change the kernel or its command-line arguments, # which would cause this service to fail after the soft-reboot completes. +# +# TODO(Johan-Liebert1): This needs to be changed for UKI/BLS ConditionPathExists=/boot/ignition.firstboot RequiresMountsFor=/boot From 6faa5bdc26c95a939e062d552bcbb9171510f13f Mon Sep 17 00:00:00 2001 From: Pragyan Poudyal Date: Fri, 20 Mar 2026 14:31:50 +0530 Subject: [PATCH 2/6] systemd: Override systemd-fsck@dev-disk-by\x2dlabel-boot Add override for systemd-fsck@dev-disk-by\x2dlabel-boot so that it'll only run after boot-part-discovered.target and the file /run/coreos/boot-partition-status is not empty, i.e. only run the service if boot partition exists Signed-off-by: Pragyan Poudyal --- .../override.conf" | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 "overlay.d/05core/usr/lib/systemd/system/systemd-fsck@dev-disk-by\\x2dlabel-boot.service.d/override.conf" diff --git "a/overlay.d/05core/usr/lib/systemd/system/systemd-fsck@dev-disk-by\\x2dlabel-boot.service.d/override.conf" "b/overlay.d/05core/usr/lib/systemd/system/systemd-fsck@dev-disk-by\\x2dlabel-boot.service.d/override.conf" new file mode 100644 index 0000000000..b36c5fb9dd --- /dev/null +++ "b/overlay.d/05core/usr/lib/systemd/system/systemd-fsck@dev-disk-by\\x2dlabel-boot.service.d/override.conf" @@ -0,0 +1,3 @@ +[Unit] +After=boot-part-discovered.target +ConditionFileNotEmpty=/run/coreos/boot-partition-status From ee3b6f1b754e875a1758c871eac49fd99b578c64 Mon Sep 17 00:00:00 2001 From: Pragyan Poudyal Date: Fri, 20 Mar 2026 14:52:28 +0530 Subject: [PATCH 3/6] Only run coreos-boot-mount-generator if boot part is present systemd will still wait for /dev/disk/by-label/boot if we have it in the Mount section even if we don't have a boot partition Refactor boot-part-discovery.sh to have a `boot_part_exists` function so that we can source the script and use it in a bunch of other places Signed-off-by: Pragyan Poudyal --- .../40ignition-ostree/boot-part-discovery.sh | 32 +++++++++++-------- .../ignition-ostree-uuid-boot.service | 1 + .../coreos-boot-mount-generator | 14 ++++++-- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/boot-part-discovery.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/boot-part-discovery.sh index 87cfd2a02e..63f23d7652 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/boot-part-discovery.sh +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/boot-part-discovery.sh @@ -1,26 +1,32 @@ #!/bin/bash -set -euo pipefail - +XBOOTLDR_UUID="BC13C2FF-59E6-4262-A352-B275FD6F7172" BOOT_STATUS_DIR="/run/coreos" BOOT_STATUS_FILE="${BOOT_STATUS_DIR}/boot-partition-status" -mkdir -p "$BOOT_STATUS_DIR" +boot_part_exists() { + LSBLK_JSON="$(lsblk -o name,parttype,uuid,mountpoint,parttypename,label --json)" -XBOOTLDR_UUID="BC13C2FF-59E6-4262-A352-B275FD6F7172" + while read -r part; do + parttype="$(jq -r '.parttype // empty' <<<"$part" | tr '[:lower:]' '[:upper:]')" + name="$(jq -r '.name' <<<"$part")" -LSBLK_JSON="$(lsblk -o name,parttype,uuid,mountpoint,parttypename,label --json)" + [[ -n "$parttype" ]] || echo "Partition '$name' has no parttype" -while read -r part; do - parttype="$(jq -r '.parttype // empty' <<<"$part" | tr '[:lower:]' '[:upper:]')" - name="$(jq -r '.name' <<<"$part")" + if [[ "$parttype" == "$XBOOTLDR_UUID" ]]; then + return 0 + fi + done < <(echo "$LSBLK_JSON" | jq -c '.blockdevices[].children[]?') - [[ -n "$parttype" ]] || echo "Partition '$name' has no parttype" + return 1 +} - if [[ "$parttype" == "$XBOOTLDR_UUID" ]]; then +# Only run when executed directly, not when sourced +if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then + if boot_part_exists; then + mkdir -p "$BOOT_STATUS_DIR" echo "available" > "$BOOT_STATUS_FILE" - break else - echo "not boot" + echo "Boot partition not found" fi -done < <(echo "$LSBLK_JSON" | jq -c '.blockdevices[].children[]?') +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service index e3ecb7569c..7ce368ad80 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-uuid-boot.service @@ -13,6 +13,7 @@ Before=ignition-kargs.service # If we're going to reprovision the bootfs, then there's no need to restamp ConditionKernelCommandLine=!bootfs.roothash +# TODO(Johan-Lieber1): This Before=systemd-fsck@dev-disk-by\x2dlabel-boot.service # Requires=dev-disk-by\x2dlabel-boot.device # After=dev-disk-by\x2dlabel-boot.device diff --git a/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator b/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator index fb06b00e2a..87fc29482f 100755 --- a/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator +++ b/overlay.d/05core/usr/lib/systemd/system-generators/coreos-boot-mount-generator @@ -3,6 +3,7 @@ export PATH="/usr/bin:/usr/sbin:${PATH}" set -euo pipefail . /usr/lib/coreos/generator-lib.sh +. /usr/libexec/boot-part-discovery.sh # Turn out if you boot with "root=..." $UNIT_DIR is not writable. [ -w "${UNIT_DIR}" ] || { @@ -31,6 +32,16 @@ if [ "${rootfstype}" = "virtiofs" ]; then exit 0 fi +# Do not create dynamic mount service for /boot if there +# is no /boot partition +# +# Using just After=boot-part-discovery.target won't work +# as we have What=/dev/disk/by-label/boot in the Mount section +# which prompts systemd to wait for udev +if ! boot_part_exists; then + exit 0 +fi + add_wants() { local name="$1"; shift local wants_dir="${UNIT_DIR}/local-fs.target.wants" @@ -60,9 +71,6 @@ Before=local-fs.target Requires=systemd-fsck@${devservice} After=systemd-fsck@${devservice} -After=boot-part-discovered.target -ConditionFileNotEmpty=/run/coreos/boot-partition-status - [Mount] What=${path} Where=${mount_pt} From e8f6bc2898f153a3fc9252c7e1ef0afdd1f22750 Mon Sep 17 00:00:00 2001 From: Pragyan Poudyal Date: Tue, 24 Mar 2026 18:07:17 +0530 Subject: [PATCH 4/6] Introduce `coreos-root-setup.service` We need a single service that would handle the /sysroot mount for ostree backend and for composefs backend. This service does that. Depending upon the kernel cmdline, it would either proxy to ostree or bootc Signed-off-by: Pragyan Poudyal --- .../modules.d/35coreos-live/live-generator | 17 +++++++------- .../dracut/modules.d/37bootc/module-setup.sh | 20 ----------------- .../.gitignore | 0 .../coreos-root-setup.service} | 8 +++---- .../37coreos-root-setup/coreos-root-setup.sh | 22 +++++++++++++++++++ .../37coreos-root-setup/module-setup.sh | 22 +++++++++++++++++++ .../ignition-ostree-check-rootfs-size.service | 5 ++--- tests/kola/composefs/enabled | 2 +- 8 files changed, 59 insertions(+), 37 deletions(-) delete mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/37bootc/module-setup.sh rename overlay.d/05core/usr/lib/dracut/modules.d/{37bootc => 37coreos-root-setup}/.gitignore (100%) rename overlay.d/05core/usr/lib/dracut/modules.d/{37bootc/bootc-root-setup.service => 37coreos-root-setup/coreos-root-setup.service} (68%) create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/37coreos-root-setup/coreos-root-setup.sh create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/37coreos-root-setup/module-setup.sh diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/live-generator b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/live-generator index c10fd1694b..571278d75d 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/live-generator +++ b/overlay.d/05core/usr/lib/dracut/modules.d/35coreos-live/live-generator @@ -34,13 +34,12 @@ add_requires sysroot-var.mount initrd-root-fs.target # https://github.com/coreos/fedora-coreos-tracker/issues/1423 add_requires coreos-enable-network.service initrd-root-fs.target -mkdir -p "${UNIT_DIR}/ostree-prepare-root.service.d" -cat > "${UNIT_DIR}/ostree-prepare-root.service.d/10-live.conf" < "${UNIT_DIR}/coreos-root-setup.service.d/10-live.conf" < Date: Wed, 25 Mar 2026 12:09:35 +0530 Subject: [PATCH 5/6] transposefs: Handle composefs Run transposefs services for composefs systems as well by adding "composefs" as a commandline condition In "restore" option make sure to re-enable fsverity on the composefs objects if the kernel commandlne enforces fsverity, i.e. doesn't have "?" before the fsverity digest Signed-off-by: Pragyan Poudyal --- ...on-ostree-transposefs-autosave-xfs.service | 3 ++- ...ignition-ostree-transposefs-detect.service | 3 ++- ...gnition-ostree-transposefs-restore.service | 3 ++- .../ignition-ostree-transposefs-save.service | 3 ++- .../ignition-ostree-transposefs.sh | 25 ++++++++++++++++++- .../40ignition-ostree/module-setup.sh | 3 ++- 6 files changed, 34 insertions(+), 6 deletions(-) diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-autosave-xfs.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-autosave-xfs.service index e955c4a69a..8a5272b752 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-autosave-xfs.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-autosave-xfs.service @@ -13,7 +13,8 @@ Before=ignition-ostree-transposefs-restore.service OnFailure=emergency.target OnFailureJobMode=isolate -ConditionKernelCommandLine=ostree +ConditionKernelCommandLine=|ostree +ConditionKernelCommandLine=|composefs # only run if ignition-ostree-growfs ran since that's when pathological cases occur ConditionPathExists=/run/ignition-ostree-growfs.stamp diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-detect.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-detect.service index 389dc9eedf..cde1efd379 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-detect.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-detect.service @@ -5,7 +5,8 @@ After=ignition-fetch.service Before=ignition-disks.service Before=initrd-root-fs.target Before=sysroot.mount -ConditionKernelCommandLine=ostree +ConditionKernelCommandLine=|ostree +ConditionKernelCommandLine=|composefs OnFailure=emergency.target OnFailureJobMode=isolate diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service index eef3c064c7..349155ce0d 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service @@ -12,7 +12,8 @@ Before=sysroot.mount OnFailure=emergency.target OnFailureJobMode=isolate -ConditionKernelCommandLine=ostree +ConditionKernelCommandLine=|ostree +ConditionKernelCommandLine=|composefs ConditionPathIsDirectory=/run/ignition-ostree-transposefs [Service] diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-save.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-save.service index bc03499ecb..02b8d5478a 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-save.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-save.service @@ -3,7 +3,8 @@ Description=Ignition OSTree: Save Partitions DefaultDependencies=false After=ignition-ostree-transposefs-detect.service Before=ignition-disks.service -ConditionKernelCommandLine=ostree +ConditionKernelCommandLine=|ostree +ConditionKernelCommandLine=|composefs ConditionPathIsDirectory=/run/ignition-ostree-transposefs # Any services looking at mounts need to order after this # because it causes device re-probing. diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh index 7bec45c936..e21c7bca5a 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh @@ -306,9 +306,32 @@ case "${1:-}" in if [ -d "${saved_root}" ]; then echo "Restoring rootfs from RAM..." mount_and_restore_filesystem_by_label root /sysroot "${saved_root}" + chcon -v --reference "${saved_root}" /sysroot # the root of the fs itself - chattr +i $(ls -d /sysroot/ostree/deploy/*/deploy/*/) + + cfs_digest=$(karg composefs) + + if [[ "$cfs_digest" == "" ]]; then + chattr +i $(ls -d /sysroot/ostree/deploy/*/deploy/*/) + elif [[ ${cfs_digest:0:1} != "?" ]]; then + echo "Re-enabling fsverity on composefs repo..." + # tmpfs has no fsverity, so we need to reenable fsverity + hash_alg="" + + if [[ $cfs_digest =~ ^[0-9a-fA-F]{64}$ ]]; then + hash_alg="sha256" + elif [[ $cfs_digest =~ ^[0-9a-fA-F]{128}$ ]]; then + hash_alg="sha512" + else + echo "Bad verity in cmdline '$cfs_digest'" + exit 1 + fi + + echo "Enabling fs-verity again..." + find /sysroot/composefs/objects -type f -exec fsverity enable {} --hash-alg $hash_alg \; + fi fi + if [ -d "${saved_boot}" ]; then echo "Restoring bootfs from RAM..." mount_and_restore_filesystem_by_label boot /sysroot/boot "${saved_boot}" diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh index 7c4252f2c1..7cbcbce1a8 100755 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/module-setup.sh @@ -77,7 +77,8 @@ install() { rm \ sed \ sfdisk \ - find + find \ + fsverity # In some cases we had to vendor gdisk in Ignition. # If this is the case here use that one. From 5d28cf530318bb49a173a0c2e3fc5199882bba45 Mon Sep 17 00:00:00 2001 From: Pragyan Poudyal Date: Wed, 25 Mar 2026 16:31:40 +0530 Subject: [PATCH 6/6] Handle ignition-firstboot-complete We now will have quite a few combinations that need to be taken care of after ignition's first boot. Update the ignition-firstboot-complete script to handle these cases, viz systemd-boot BLS, systemd-boot UKI, grub UKI and grub BLS. The UKI cases are pretty simple and consist of only removing one single UKI addon. The grub BLS case does not change and we still just remove /boot/ignition.firstboot For systemd-boot BLS, we manually remove `ignition.firstboot` from BLS config file Signed-off-by: Pragyan Poudyal --- .../ignition-ostree-mount-var.service | 1 + ...coreos-ignition-firstboot-complete.service | 4 - .../coreos-ignition-firstboot-complete | 128 ++++++++++++++++-- 3 files changed, 120 insertions(+), 13 deletions(-) diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.service b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.service index 09d6c15ab3..1cb3d39d14 100644 --- a/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.service +++ b/overlay.d/05core/usr/lib/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.service @@ -1,6 +1,7 @@ [Unit] Description=Mount OSTree /var DefaultDependencies=false +# We do not need this for composefs ConditionKernelCommandLine=ostree ConditionPathExists=!/run/ostree-live diff --git a/overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service b/overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service index 5ef06a7d88..7f615b39ed 100644 --- a/overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service +++ b/overlay.d/05core/usr/lib/systemd/system/coreos-ignition-firstboot-complete.service @@ -6,10 +6,6 @@ ConditionPathExists=!/run/ostree-live # This condition is required for cases where a soft-reboot is issued on the # firstboot. Soft reboot do not change the kernel or its command-line arguments, # which would cause this service to fail after the soft-reboot completes. -# -# TODO(Johan-Liebert1): This needs to be changed for UKI/BLS -ConditionPathExists=/boot/ignition.firstboot -RequiresMountsFor=/boot [Service] Type=oneshot diff --git a/overlay.d/05core/usr/libexec/coreos-ignition-firstboot-complete b/overlay.d/05core/usr/libexec/coreos-ignition-firstboot-complete index e1963f08d8..40424c67b8 100755 --- a/overlay.d/05core/usr/libexec/coreos-ignition-firstboot-complete +++ b/overlay.d/05core/usr/libexec/coreos-ignition-firstboot-complete @@ -1,17 +1,127 @@ #!/bin/bash set -euo pipefail -mount -o remount,rw /boot +ESP_MOUNT=/var/tmp/efi -# We're done provisioning. Remove the whole /boot/ignition directory if present, -# which may include a baked Ignition config. See -# https://github.com/coreos/fedora-coreos-tracker/issues/889. -rm -rf /boot/ignition +BOOTC_STATUS="$(bootc status --json)" -# Regarding the lack of `-f` for rm ; we should have only run if GRUB detected -# this file. Fail if we are unable to remove it, rather than risking rerunning -# Ignition at next boot. -rm /boot/ignition.firstboot +IS_COMPOSEFS=false +BOOTLOADER="" +BOOT_TYPE="" + +if [[ $(jq -r '.status.booted.composefs' <<< "$BOOTC_STATUS") != null ]]; then + IS_COMPOSEFS=true + BOOT_TYPE=$(jq -r '.status.booted.composefs.bootType' <<< "$BOOTC_STATUS" | tr '[:upper:]' '[:lower:]') + BOOTLOADER=$(jq -r '.status.booted.composefs.bootloader' <<< "$BOOTC_STATUS" | tr '[:upper:]' '[:lower:]') +fi + +handle_ignition_grub() { + mount -o remount,rw /boot + + # We're done provisioning. Remove the whole /boot/ignition directory if present, + # which may include a baked Ignition config. See + # https://github.com/coreos/fedora-coreos-tracker/issues/889. + rm -rf /boot/ignition + + # Regarding the lack of `-f` for rm ; we should have only run if GRUB detected + # this file. Fail if we are unable to remove it, rather than risking rerunning + # Ignition at next boot. + rm /boot/ignition.firstboot +} + +# Mounts ESP at /var/tmp/efi +mount_esp() { + mkdir -p $ESP_MOUNT + + local LSBLK_JSON + local ESP_DEV + LSBLK_JSON="$(lsblk -o path,parttype,name --json)" + + while read -r part; do + parttype="$(jq -r '.parttype // empty' <<<"$part" | tr '[:lower:]' '[:upper:]')" + path="$(jq -r '.path // empty' <<<"$part")" + + if [[ -z "$parttype" ]]; then + echo "Partition '$path' has no parttype" + continue + fi + + if [[ "$parttype" == "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" ]]; then + ESP_DEV="$path" + break + fi + done < <(echo "$LSBLK_JSON" | jq -c '.blockdevices[].children[]?') + + if [[ "$ESP_DEV" == "" ]]; then + echo "ESP not found" + exit 1 + fi + + mount "$ESP_DEV" $ESP_MOUNT +} + +# Unounts ESP and deletes /var/tmp/efi +unmount_esp() { + umount $ESP_MOUNT + rmdir $ESP_MOUNT +} + +# simply remove the UKI addon +# TODO: Maybe this can be done in bootc +handle_ignition_uki() { + mount_esp + + local verity + verity=$(jq -r '.status.booted.composefs.verity' <<< "$BOOTC_STATUS") + + rm -rf "/var/tmp/efi/EFI/Linux/bootc/bootc_composefs-${verity}.efi.extra.d/ignition.addon.efi" + + unmount_esp +} + +handle_ignition_composefs() { + # We have a few cases here + # 1. systemd-boot + BLS + # 2. systemd-boot + UKI + # 3. grub + BLS + # 4. grub + UKI + # + # Both the UKI cases are the same and we just need to + # remove the UKI addon + # + # systemd-boot BLS doesn't accept variables in the config files + # so we handle it differently + # + # grub BLS should be the same as ostree + if [[ $BOOTLOADER == "grub" && $BOOT_TYPE == "bls" ]]; then + handle_ignition_grub + return + fi + + # UKI + if [[ $BOOT_TYPE == "uki" ]]; then + handle_ignition_uki + return + fi + + # systemd-boot BLS + # TODO: Maybe better to put this in bootc + mount_esp + + local verity + verity=$(jq -r '.status.booted.composefs.verity' <<< "$BOOTC_STATUS") + + boot_entry=$(ls "$ESP_MOUNT/loader/entries") + sed -i 's;ignition.firstboot;;' "$ESP_MOUNT/loader/entries/$boot_entry" + + unmount_esp +} + +if $IS_COMPOSEFS; then + handle_ignition_composefs +else + handle_ignition_grub +fi # rdcore zipl checks for /boot/ignition.firstboot if [[ $(uname -m) = s390x ]]; then