From 97ab4c6090c353b1986eaba6460d2011d99dbc28 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Mon, 6 Apr 2026 11:21:15 +0100 Subject: [PATCH 1/6] Add missing executable permissions to scripts Signed-off-by: James Le Cuirot --- dracut/53ignition/ignition-kargs-helper | 0 dracut/55ca-certs/module-setup.sh | 0 dracut/99dracut-root/parse-stub.sh | 0 dracut/99flatcar-debloat/module-setup.sh | 0 dracut/99switch-root/module-setup.sh | 0 5 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 dracut/53ignition/ignition-kargs-helper mode change 100644 => 100755 dracut/55ca-certs/module-setup.sh mode change 100644 => 100755 dracut/99dracut-root/parse-stub.sh mode change 100644 => 100755 dracut/99flatcar-debloat/module-setup.sh mode change 100644 => 100755 dracut/99switch-root/module-setup.sh diff --git a/dracut/53ignition/ignition-kargs-helper b/dracut/53ignition/ignition-kargs-helper old mode 100644 new mode 100755 diff --git a/dracut/55ca-certs/module-setup.sh b/dracut/55ca-certs/module-setup.sh old mode 100644 new mode 100755 diff --git a/dracut/99dracut-root/parse-stub.sh b/dracut/99dracut-root/parse-stub.sh old mode 100644 new mode 100755 diff --git a/dracut/99flatcar-debloat/module-setup.sh b/dracut/99flatcar-debloat/module-setup.sh old mode 100644 new mode 100755 diff --git a/dracut/99switch-root/module-setup.sh b/dracut/99switch-root/module-setup.sh old mode 100644 new mode 100755 From d8e211015c3b1a927ad3181975951c223f7192e5 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Wed, 8 Apr 2026 10:11:14 +0100 Subject: [PATCH 2/6] Change emergency.target job mode from isolate to replace-irreversibly The "isolate" job mode causes dev-mapper-usr.device and therefore sysusr-usr.mount to stop. We cannot stop the latter though because the emergency shell is hosted within it. It's not entirely clear why this happens because both units have IgnoreOnIsolate=yes. Trying to unmount doesn't break the shell, but it does show an unexpected error. The usual approach of preventing the above with drop-in units doesn't seem to work for auto-generated mount units. However, I noticed that systemd itself has not used the isolate job mode for emergency.target since 2013. replace-irreversibly does not proactively stop all the other units, just the ones that would block the new target. This can actually make debugging easier in the event of an Ignition failure because the system will be in a closer state to the one when the failure occurred. Signed-off-by: James Le Cuirot --- dracut/50flatcar-network/afterburn-network-kargs.service | 2 +- dracut/53ignition/flatcar-metadata-hostname.service | 2 +- dracut/53ignition/ignition-disks.service | 2 +- dracut/53ignition/ignition-fetch-offline.service | 2 +- dracut/53ignition/ignition-fetch.service | 2 +- dracut/53ignition/ignition-files.service | 2 +- dracut/53ignition/ignition-generator | 2 +- dracut/53ignition/ignition-kargs.service | 2 +- dracut/53ignition/ignition-mount.service | 2 +- dracut/53ignition/ignition-remount-sysroot.service | 2 +- dracut/99setup-root/initrd-setup-root-after-ignition.service | 2 +- dracut/99setup-root/initrd-setup-root.service | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dracut/50flatcar-network/afterburn-network-kargs.service b/dracut/50flatcar-network/afterburn-network-kargs.service index 595e831..a382e59 100644 --- a/dracut/50flatcar-network/afterburn-network-kargs.service +++ b/dracut/50flatcar-network/afterburn-network-kargs.service @@ -11,7 +11,7 @@ PartOf=systemd-networkd.service ConditionKernelCommandLine=|coreos.oem.id=vmware ConditionKernelCommandLine=|flatcar.oem.id=vmware OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly # Flatcar: Load coreos-metadata binary Requires=sysusr-usr.mount diff --git a/dracut/53ignition/flatcar-metadata-hostname.service b/dracut/53ignition/flatcar-metadata-hostname.service index 0975e29..be75de1 100644 --- a/dracut/53ignition/flatcar-metadata-hostname.service +++ b/dracut/53ignition/flatcar-metadata-hostname.service @@ -40,7 +40,7 @@ ConditionKernelCommandLine=|flatcar.oem.id=proxmoxve ConditionKernelCommandLine=|flatcar.oem.id=scaleway OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly [Service] Type=oneshot diff --git a/dracut/53ignition/ignition-disks.service b/dracut/53ignition/ignition-disks.service index 4e2b783..3cb92fe 100644 --- a/dracut/53ignition/ignition-disks.service +++ b/dracut/53ignition/ignition-disks.service @@ -28,7 +28,7 @@ Before=initrd-root-device.target Before=sysroot.mount OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly # This stage requires udevd to detect disk partitioning changes. Requires=systemd-udevd.service diff --git a/dracut/53ignition/ignition-fetch-offline.service b/dracut/53ignition/ignition-fetch-offline.service index 3a4b010..6fb5002 100644 --- a/dracut/53ignition/ignition-fetch-offline.service +++ b/dracut/53ignition/ignition-fetch-offline.service @@ -24,7 +24,7 @@ After=ignition-setup.service Before=ignition-fetch.service OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly [Service] Type=oneshot diff --git a/dracut/53ignition/ignition-fetch.service b/dracut/53ignition/ignition-fetch.service index 8adf32b..35057ed 100644 --- a/dracut/53ignition/ignition-fetch.service +++ b/dracut/53ignition/ignition-fetch.service @@ -17,7 +17,7 @@ After=ignition-fetch-offline.service Before=ignition-disks.service OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly # If we run, we definitely need network, so make sure we run after. After=network.target diff --git a/dracut/53ignition/ignition-files.service b/dracut/53ignition/ignition-files.service index b0c11b6..391ca55 100644 --- a/dracut/53ignition/ignition-files.service +++ b/dracut/53ignition/ignition-files.service @@ -18,7 +18,7 @@ After=initrd-setup-root.service RequiresMountsFor=/sysroot/usr/ /sysroot/oem/ OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly # Stage order: fetch-offline [-> fetch] [-> kargs] -> disks -> mount -> files. After=ignition-mount.service diff --git a/dracut/53ignition/ignition-generator b/dracut/53ignition/ignition-generator index 9de35ed..f8f1b9e 100755 --- a/dracut/53ignition/ignition-generator +++ b/dracut/53ignition/ignition-generator @@ -107,7 +107,7 @@ Requires=local-fs-pre.target Before=local-fs-pre.target OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly [Service] Type=oneshot diff --git a/dracut/53ignition/ignition-kargs.service b/dracut/53ignition/ignition-kargs.service index fb15ec4..48cda23 100644 --- a/dracut/53ignition/ignition-kargs.service +++ b/dracut/53ignition/ignition-kargs.service @@ -15,7 +15,7 @@ Requires=ignition-setup.service After=ignition-setup.service OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly [Service] Type=oneshot diff --git a/dracut/53ignition/ignition-mount.service b/dracut/53ignition/ignition-mount.service index 5476dba..f104eb5 100644 --- a/dracut/53ignition/ignition-mount.service +++ b/dracut/53ignition/ignition-mount.service @@ -22,7 +22,7 @@ Before=initrd-switch-root.target After=network.target OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly # Make sure the final /sysroot is ready first, since we're mounting under there Requires=initrd-root-fs.target diff --git a/dracut/53ignition/ignition-remount-sysroot.service b/dracut/53ignition/ignition-remount-sysroot.service index f004d20..47759ac 100644 --- a/dracut/53ignition/ignition-remount-sysroot.service +++ b/dracut/53ignition/ignition-remount-sysroot.service @@ -9,7 +9,7 @@ DefaultDependencies=no Before=ignition-diskful.target OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly After=sysroot.mount ConditionPathIsReadWrite=!/sysroot diff --git a/dracut/99setup-root/initrd-setup-root-after-ignition.service b/dracut/99setup-root/initrd-setup-root-after-ignition.service index 69039c0..a8ecdd9 100644 --- a/dracut/99setup-root/initrd-setup-root-after-ignition.service +++ b/dracut/99setup-root/initrd-setup-root-after-ignition.service @@ -5,7 +5,7 @@ RequiresMountsFor=/sysroot/usr/ /sysroot/oem/ After=initrd-root-fs.target ignition-files.service initrd-setup-root.service Before=initrd-parse-etc.service OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly [Service] Type=oneshot diff --git a/dracut/99setup-root/initrd-setup-root.service b/dracut/99setup-root/initrd-setup-root.service index 374d112..a464e2f 100644 --- a/dracut/99setup-root/initrd-setup-root.service +++ b/dracut/99setup-root/initrd-setup-root.service @@ -5,7 +5,7 @@ RequiresMountsFor=/sysroot/usr/ After=initrd-root-fs.target Before=initrd-parse-etc.service OnFailure=emergency.target -OnFailureJobMode=isolate +OnFailureJobMode=replace-irreversibly [Service] Type=oneshot From a2019dad90ba1b540f4bc3702064b8ab2337c378 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Wed, 1 Apr 2026 16:44:48 +0100 Subject: [PATCH 3/6] ignition: Bake is-live-image script into the initrd No need to wait until ignition-setup.service runs. Signed-off-by: James Le Cuirot --- dracut/53ignition/ignition-generator | 12 ++++++------ dracut/53ignition/ignition-setup.sh | 6 ------ dracut/53ignition/is-live-image.sh | 4 ++++ dracut/53ignition/module-setup.sh | 4 ++++ 4 files changed, 14 insertions(+), 12 deletions(-) create mode 100755 dracut/53ignition/is-live-image.sh diff --git a/dracut/53ignition/ignition-generator b/dracut/53ignition/ignition-generator index f8f1b9e..41f0789 100755 --- a/dracut/53ignition/ignition-generator +++ b/dracut/53ignition/ignition-generator @@ -85,19 +85,19 @@ fi # Write ignition-setup.service customized for PXE/ISO or regular boot pxe= nopxe= -usr=$(cmdline_arg mount.usr "$(cmdline_arg usr)") -if [[ -z "${usr}" && -f /usr.squashfs ]]; then - # PXE-booted system, with or without persistent root - # (see 10diskless-generator) - pxe=1 -else +if is-live-image; then nopxe=1 if $(cmdline_bool flatcar.first_boot 0) || $(cmdline_bool coreos.first_boot 0); then add_requires ignition-diskful.target ignition-complete.target else add_requires ignition-diskful-subsequent.target ignition-subsequent.target fi +else + # PXE-booted system, with or without persistent root + # (see 10diskless-generator) + pxe=1 fi + cat > ${UNIT_DIR}/ignition-setup-pre.service < /bin/is-live-image ;; pxe) # OEM directory in the initramfs itself. src=/oem - # Workaround, "chmod" is not available - cp -a /bin/cat /bin/is-live-image - printf '#!/bin/sh\nexit 0\n' > /bin/is-live-image ;; *) echo "Usage: $0 {normal|pxe}" >&2 diff --git a/dracut/53ignition/is-live-image.sh b/dracut/53ignition/is-live-image.sh new file mode 100755 index 0000000..d7b8b64 --- /dev/null +++ b/dracut/53ignition/is-live-image.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +re='\b(mount\.)?usr=\S' +[[ $(< /proc/cmdline) =~ ${re} || ! -f /usr.squashfs ]] diff --git a/dracut/53ignition/module-setup.sh b/dracut/53ignition/module-setup.sh index 1c3e0d7..140f6c7 100755 --- a/dracut/53ignition/module-setup.sh +++ b/dracut/53ignition/module-setup.sh @@ -92,6 +92,10 @@ install() { inst_script "$moddir/retry-umount.sh" \ "/usr/sbin/retry-umount" + # Ignition calls is-live-image. + inst_script "$moddir/is-live-image.sh" \ + /bin/is-live-image + inst_simple "$moddir/ignition-generator" \ "$systemdutildir/system-generators/ignition-generator" From 040c177e0c72a965cfb34ae745eeb6200fb617a8 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Thu, 2 Apr 2026 17:26:41 +0100 Subject: [PATCH 4/6] ignition: Drop ignition-setup config.ign is still used as the default OEM-based configuration file. Stock Flatcar no longer ships base.ign or default.ign, but custom images in the wild may use these, and Ignition still checks for them. Supporting these can be done more easily using symlinks baked into the initrd though. It doesn't matter that they are broken most of the time. Note that upstream Ignition has already dropped this service. Signed-off-by: James Le Cuirot --- dracut/53disk-uuid/disk-uuid.service | 2 +- dracut/53ignition/ignition-disks.service | 5 ++- .../53ignition/ignition-fetch-offline.service | 5 ++- dracut/53ignition/ignition-fetch.service | 5 ++- dracut/53ignition/ignition-files.service | 4 +- dracut/53ignition/ignition-generator | 42 +------------------ dracut/53ignition/ignition-kargs.service | 5 ++- dracut/53ignition/ignition-mount.service | 5 ++- dracut/53ignition/ignition-setup.sh | 34 --------------- dracut/53ignition/module-setup.sh | 10 +++-- 10 files changed, 26 insertions(+), 91 deletions(-) delete mode 100755 dracut/53ignition/ignition-setup.sh diff --git a/dracut/53disk-uuid/disk-uuid.service b/dracut/53disk-uuid/disk-uuid.service index aa14518..019d7c3 100644 --- a/dracut/53disk-uuid/disk-uuid.service +++ b/dracut/53disk-uuid/disk-uuid.service @@ -10,7 +10,7 @@ After=systemd-udevd.service dev-disk-by\x2dpartlabel-USR\x2dA.device # Run before services that use device nodes, preventing them from racing # with udev activity generated by sgdisk -Before=ignition-setup.service ignition-disks.service verity-setup.service +Before=ignition-disks.service verity-setup.service [Service] Type=oneshot diff --git a/dracut/53ignition/ignition-disks.service b/dracut/53ignition/ignition-disks.service index 3cb92fe..c9c9017 100644 --- a/dracut/53ignition/ignition-disks.service +++ b/dracut/53ignition/ignition-disks.service @@ -8,8 +8,9 @@ Before=ignition-complete.target # Flatcar: Requires=local-fs-pre.target Before=local-fs-pre.target -Requires=ignition-setup.service -After=ignition-setup.service +Requires=ignition-setup-pre.service +After=ignition-setup-pre.service +RequiresMountsFor=/sysusr/usr/ # Stage order: fetch-offline [-> fetch] [-> kargs] -> disks -> mount -> files. After=ignition-fetch.service diff --git a/dracut/53ignition/ignition-fetch-offline.service b/dracut/53ignition/ignition-fetch-offline.service index 6fb5002..a4990a9 100644 --- a/dracut/53ignition/ignition-fetch-offline.service +++ b/dracut/53ignition/ignition-fetch-offline.service @@ -17,8 +17,9 @@ After=sockets.target paths.target slices.target # Flatcar: Requires=local-fs-pre.target Before=local-fs-pre.target -Requires=ignition-setup.service -After=ignition-setup.service +Requires=ignition-setup-pre.service +After=ignition-setup-pre.service +RequiresMountsFor=/sysusr/usr/ # Stage order: fetch-offline [-> fetch] [-> kargs] -> disks -> mount -> files. Before=ignition-fetch.service diff --git a/dracut/53ignition/ignition-fetch.service b/dracut/53ignition/ignition-fetch.service index 35057ed..d04aef8 100644 --- a/dracut/53ignition/ignition-fetch.service +++ b/dracut/53ignition/ignition-fetch.service @@ -28,8 +28,9 @@ Wants=systemd-resolved.service After=systemd-resolved.service Requires=local-fs-pre.target Before=local-fs-pre.target -Requires=ignition-setup.service -After=ignition-setup.service +Requires=ignition-setup-pre.service +After=ignition-setup-pre.service +RequiresMountsFor=/sysusr/usr/ [Service] Type=oneshot diff --git a/dracut/53ignition/ignition-files.service b/dracut/53ignition/ignition-files.service index 391ca55..1b846da 100644 --- a/dracut/53ignition/ignition-files.service +++ b/dracut/53ignition/ignition-files.service @@ -8,8 +8,8 @@ Before=ignition-complete.target # Flatcar: Requires=initrd-root-fs.target After=initrd-root-fs.target -Requires=ignition-setup.service ignition-disks.service -After=ignition-setup.service ignition-disks.service +Requires=ignition-disks.service +After=ignition-disks.service # setup the root filesystem before we try do things like create users on it. Requires=initrd-setup-root.service After=initrd-setup-root.service diff --git a/dracut/53ignition/ignition-generator b/dracut/53ignition/ignition-generator index 41f0789..7c613cc 100755 --- a/dracut/53ignition/ignition-generator +++ b/dracut/53ignition/ignition-generator @@ -82,20 +82,14 @@ else add_requires ignition-subsequent.target initrd.target fi -# Write ignition-setup.service customized for PXE/ISO or regular boot -pxe= -nopxe= +# Do disk-based steps for non-PXE/ISO boot. if is-live-image; then - nopxe=1 + add_requires disk-uuid.service initrd.target if $(cmdline_bool flatcar.first_boot 0) || $(cmdline_bool coreos.first_boot 0); then add_requires ignition-diskful.target ignition-complete.target else add_requires ignition-diskful-subsequent.target ignition-subsequent.target fi -else - # PXE-booted system, with or without persistent root - # (see 10diskless-generator) - pxe=1 fi cat > ${UNIT_DIR}/ignition-setup-pre.service < ${UNIT_DIR}/ignition-setup.service <&2 - exit 1 -esac - -dst=/usr/lib/ignition -mkdir -p "${dst}/base.d" - -if [[ -e "${src}/base/base.ign" ]]; then - cp "${src}/base/base.ign" "${dst}/base.d/" -fi -if [[ -e "${src}/config.ign" ]]; then - cp "${src}/config.ign" "${dst}/user.ign" -fi diff --git a/dracut/53ignition/module-setup.sh b/dracut/53ignition/module-setup.sh index 140f6c7..61f818a 100755 --- a/dracut/53ignition/module-setup.sh +++ b/dracut/53ignition/module-setup.sh @@ -72,10 +72,6 @@ install() { inst_script "$moddir/ignition-kargs-helper" \ "/usr/sbin/ignition-kargs-helper" - # Flatcar: add ignition-setup - inst_script "$moddir/ignition-setup.sh" \ - "/usr/sbin/ignition-setup" - # Flatcar: add ignition-setup-pre inst_script "$moddir/ignition-setup-pre.sh" \ "/usr/sbin/ignition-setup-pre" @@ -173,6 +169,12 @@ EOF # Ensure /sysusr/usr is mounted before decrypting root. inst_simple "$moddir/sysusr-usr-revdeps.conf" \ "$systemdsystemunitdir/systemd-cryptsetup@rootencrypted.service.d/sysusr-usr.conf" + + # Ignition reads user.ign and base.d/* in /usr/lib/ignition by default, but + # our initrd is not writeable. Create symlinks pointing to /oem in advance. + mkdir -m0755 -p "${initdir}"/usr/lib/ignition + ln -snf /oem/config.ign "${initdir}"/usr/lib/ignition/user.ign + ln -snf /oem/base/ "${initdir}"/usr/lib/ignition/base.d } # See: https://github.com/coreos/ignition/commit/d304850c3d3696822bc05e0833ee4b27df9d7a38 From 33d562f4a01066a02d614d412a16471afb810818 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Fri, 10 Apr 2026 15:54:47 +0100 Subject: [PATCH 5/6] ignition: Make systemd units easier to compare against upstream Ignition This just reordering and consolidating lines. Signed-off-by: James Le Cuirot --- dracut/53ignition/ignition-complete.target | 8 ++++---- dracut/53ignition/ignition-disks.service | 14 ++++++------- .../53ignition/ignition-fetch-offline.service | 17 ++++++++-------- dracut/53ignition/ignition-fetch.service | 10 ++++------ dracut/53ignition/ignition-files.service | 20 ++++++++----------- dracut/53ignition/ignition-kargs.service | 7 ++++--- 6 files changed, 35 insertions(+), 41 deletions(-) diff --git a/dracut/53ignition/ignition-complete.target b/dracut/53ignition/ignition-complete.target index 686761e..84b0bdc 100644 --- a/dracut/53ignition/ignition-complete.target +++ b/dracut/53ignition/ignition-complete.target @@ -9,10 +9,10 @@ Documentation=https://github.com/coreos/ignition ConditionPathExists=/etc/initrd-release Before=initrd.target -# Run the generic rootfs setup helpers -Requires=initrd-setup-root.service initrd-setup-root-after-ignition.service -After=initrd-setup-root.service initrd-setup-root-after-ignition.service - # Make sure we stop all the units before switching root Conflicts=initrd-switch-root.target umount.target Conflicts=dracut-emergency.service emergency.service emergency.target + +# Run the generic rootfs setup helpers +Requires=initrd-setup-root.service initrd-setup-root-after-ignition.service +After=initrd-setup-root.service initrd-setup-root-after-ignition.service diff --git a/dracut/53ignition/ignition-disks.service b/dracut/53ignition/ignition-disks.service index c9c9017..cf16b14 100644 --- a/dracut/53ignition/ignition-disks.service +++ b/dracut/53ignition/ignition-disks.service @@ -5,13 +5,6 @@ ConditionPathExists=/etc/initrd-release DefaultDependencies=false Before=ignition-complete.target -# Flatcar: -Requires=local-fs-pre.target -Before=local-fs-pre.target -Requires=ignition-setup-pre.service -After=ignition-setup-pre.service -RequiresMountsFor=/sysusr/usr/ - # Stage order: fetch-offline [-> fetch] [-> kargs] -> disks -> mount -> files. After=ignition-fetch.service Before=ignition-mount.service @@ -35,6 +28,13 @@ OnFailureJobMode=replace-irreversibly Requires=systemd-udevd.service After=systemd-udevd.service +# Flatcar: +Requires=local-fs-pre.target +Before=local-fs-pre.target +Requires=ignition-setup-pre.service +After=ignition-setup-pre.service +RequiresMountsFor=/sysusr/usr/ + [Service] Type=oneshot RemainAfterExit=yes diff --git a/dracut/53ignition/ignition-fetch-offline.service b/dracut/53ignition/ignition-fetch-offline.service index a4990a9..9565991 100644 --- a/dracut/53ignition/ignition-fetch-offline.service +++ b/dracut/53ignition/ignition-fetch-offline.service @@ -9,24 +9,23 @@ Documentation=https://github.com/coreos/ignition ConditionPathExists=/etc/initrd-release DefaultDependencies=false Before=ignition-complete.target +#After=basic.target # Flatcar + +# Stage order: fetch-offline [-> fetch] [-> kargs] -> disks -> mount -> files. +Before=ignition-fetch.service + +OnFailure=emergency.target +OnFailureJobMode=replace-irreversibly + # Flatcar: -#After=basic.target Wants=sockets.target paths.target slices.target After=sockets.target paths.target slices.target - -# Flatcar: Requires=local-fs-pre.target Before=local-fs-pre.target Requires=ignition-setup-pre.service After=ignition-setup-pre.service RequiresMountsFor=/sysusr/usr/ -# Stage order: fetch-offline [-> fetch] [-> kargs] -> disks -> mount -> files. -Before=ignition-fetch.service - -OnFailure=emergency.target -OnFailureJobMode=replace-irreversibly - [Service] Type=oneshot RemainAfterExit=yes diff --git a/dracut/53ignition/ignition-fetch.service b/dracut/53ignition/ignition-fetch.service index d04aef8..6cb3bae 100644 --- a/dracut/53ignition/ignition-fetch.service +++ b/dracut/53ignition/ignition-fetch.service @@ -4,8 +4,7 @@ Documentation=https://github.com/coreos/ignition ConditionPathExists=/etc/initrd-release DefaultDependencies=false Before=ignition-complete.target -# Flatcar: -#After=basic.target +#After=basic.target # Flatcar ConditionPathExists=/run/ignition/neednet # Don't run if the `fetch-offline` stage successfully fetched a config ConditionPathExists=!/run/ignition.json @@ -21,11 +20,10 @@ OnFailureJobMode=replace-irreversibly # If we run, we definitely need network, so make sure we run after. After=network.target + # Flatcar: -Wants=systemd-networkd.service -After=systemd-networkd.service -Wants=systemd-resolved.service -After=systemd-resolved.service +Wants=systemd-networkd.service systemd-resolved.service +After=systemd-networkd.service systemd-resolved.service Requires=local-fs-pre.target Before=local-fs-pre.target Requires=ignition-setup-pre.service diff --git a/dracut/53ignition/ignition-files.service b/dracut/53ignition/ignition-files.service index 1b846da..b3e81ad 100644 --- a/dracut/53ignition/ignition-files.service +++ b/dracut/53ignition/ignition-files.service @@ -5,18 +5,6 @@ ConditionPathExists=/etc/initrd-release DefaultDependencies=false Before=ignition-complete.target -# Flatcar: -Requires=initrd-root-fs.target -After=initrd-root-fs.target -Requires=ignition-disks.service -After=ignition-disks.service -# setup the root filesystem before we try do things like create users on it. -Requires=initrd-setup-root.service -After=initrd-setup-root.service -# Already mount the OEM partition here so that it works to write files -# without having to declare it as initrd mount in Ignition -RequiresMountsFor=/sysroot/usr/ /sysroot/oem/ - OnFailure=emergency.target OnFailureJobMode=replace-irreversibly @@ -26,6 +14,14 @@ After=ignition-mount.service # Run before initrd-parse-etc so that we can drop files it then picks up. Before=initrd-parse-etc.service +# Flatcar: +# setup the root filesystem before we try do things like create users on it. +Requires=initrd-setup-root.service +After=initrd-setup-root.service +# Already mount the OEM partition here so that it works to write files +# without having to declare it as initrd mount in Ignition +RequiresMountsFor=/sysroot/usr/ /sysroot/oem/ + [Service] Type=oneshot RemainAfterExit=yes diff --git a/dracut/53ignition/ignition-kargs.service b/dracut/53ignition/ignition-kargs.service index d552fac..bbf8543 100644 --- a/dracut/53ignition/ignition-kargs.service +++ b/dracut/53ignition/ignition-kargs.service @@ -8,6 +8,10 @@ Before=ignition-complete.target # Stage order: fetch-offline [-> fetch] [-> kargs] -> disks -> mount -> files. After=ignition-fetch.service Before=ignition-disks.service + +OnFailure=emergency.target +OnFailureJobMode=replace-irreversibly + # Flatcar: Requires=local-fs-pre.target Before=local-fs-pre.target @@ -15,9 +19,6 @@ Requires=ignition-setup-pre.service After=ignition-setup-pre.service RequiresMountsFor=/sysusr/usr/ -OnFailure=emergency.target -OnFailureJobMode=replace-irreversibly - [Service] Type=oneshot RemainAfterExit=yes From 1b557b4c39c5af1064da60c7b82996acf6009bc4 Mon Sep 17 00:00:00 2001 From: James Le Cuirot Date: Thu, 2 Apr 2026 17:29:22 +0100 Subject: [PATCH 6/6] ignition: Mount OEM partition so that Ignition doesn't have to do it Ignition no longer does its own mounting of the OEM partition for the oem:// scheme, so bootengine needs to mount it in advance. The oem:// scheme therefore now maps to /realinit/oem, but Ignition may also write to the same partition at /realinit/sysroot/oem. Rather than shunting OEM data between /oem, /realinit/oem, and /realinit/sysroot/oem, mount /realinit/oem as a tmpfs from the start (for PXE) and turn /realinit/sysroot/oem into a bind mount. We want to unmount the disk-based OEM partition before Ignition's disk stage, in case it gets wiped, and its mount stage, in case it gets remounted. This can be done more simply with findmnt. However, we do want the disk-based OEM partition to be mounted while Ignition's fetch-offline and fetch stages run in case the user has put config there. This is now done with RequiresMountsFor now that Ignition no longer does it for us. The kargs stage can also use this mount to write grub.cfg rather than mounting it again in its own namespace. The `nodev` option wasn't applied to PXE. We only expect a disk-based OEM partition to be btrfs or ext4, so don't rely on the `auto` type. Signed-off-by: James Le Cuirot --- .../51diskless-generator/diskless-generator | 54 +++++++------------ dracut/51diskless-generator/module-setup.sh | 2 + dracut/51diskless-generator/sysroot-oem.mount | 8 +++ dracut/53ignition/ignition-disks.service | 2 + .../53ignition/ignition-fetch-offline.service | 2 +- dracut/53ignition/ignition-fetch.service | 2 +- dracut/53ignition/ignition-files.service | 6 ++- dracut/53ignition/ignition-kargs-helper | 13 ++--- dracut/53ignition/ignition-kargs.service | 2 +- dracut/53ignition/ignition-mount.service | 4 +- dracut/99setup-root/initrd-setup-root | 5 -- .../initrd-setup-root-after-ignition.service | 6 ++- minimal-init | 6 ++- 13 files changed, 54 insertions(+), 58 deletions(-) create mode 100644 dracut/51diskless-generator/sysroot-oem.mount diff --git a/dracut/51diskless-generator/diskless-generator b/dracut/51diskless-generator/diskless-generator index 7410702..d45bf8c 100755 --- a/dracut/51diskless-generator/diskless-generator +++ b/dracut/51diskless-generator/diskless-generator @@ -29,8 +29,6 @@ add_requires() { ln -sf "../${name}" "${requires_dir}/${name}" } -# set to 1 to enable copying /oem from the initrd -copy_oem=0 # check both the new mount.usr and our old usr kernel options usr=$(cmdline_arg mount.usr "$(cmdline_arg usr)") root=$(cmdline_arg root) @@ -39,7 +37,6 @@ rootflags=$(cmdline_arg rootflags) # If usr= was not specified and a squashfs is bundled in the initrd use it. if [[ -z "${usr}" && -f /usr.squashfs ]]; then - copy_oem=1 add_requires sysroot-usr.mount cat >"${UNIT_DIR}/sysroot-usr.mount" <"${UNIT_DIR}/oem.mount" <"${UNIT_DIR}/sysroot-oem.mount" <"${UNIT_DIR}/sysroot-oem.mount" </dev/null || systemctl stop oem.mount' ExecStart=/usr/bin/ignition --root=/sysroot --platform=${PLATFORM_ID} --stage=disks diff --git a/dracut/53ignition/ignition-fetch-offline.service b/dracut/53ignition/ignition-fetch-offline.service index 9565991..0c5beea 100644 --- a/dracut/53ignition/ignition-fetch-offline.service +++ b/dracut/53ignition/ignition-fetch-offline.service @@ -24,7 +24,7 @@ Requires=local-fs-pre.target Before=local-fs-pre.target Requires=ignition-setup-pre.service After=ignition-setup-pre.service -RequiresMountsFor=/sysusr/usr/ +RequiresMountsFor=/sysusr/usr/ /oem/ [Service] Type=oneshot diff --git a/dracut/53ignition/ignition-fetch.service b/dracut/53ignition/ignition-fetch.service index 6cb3bae..72b8349 100644 --- a/dracut/53ignition/ignition-fetch.service +++ b/dracut/53ignition/ignition-fetch.service @@ -28,7 +28,7 @@ Requires=local-fs-pre.target Before=local-fs-pre.target Requires=ignition-setup-pre.service After=ignition-setup-pre.service -RequiresMountsFor=/sysusr/usr/ +RequiresMountsFor=/sysusr/usr/ /oem/ [Service] Type=oneshot diff --git a/dracut/53ignition/ignition-files.service b/dracut/53ignition/ignition-files.service index b3e81ad..e511666 100644 --- a/dracut/53ignition/ignition-files.service +++ b/dracut/53ignition/ignition-files.service @@ -20,12 +20,14 @@ Requires=initrd-setup-root.service After=initrd-setup-root.service # Already mount the OEM partition here so that it works to write files # without having to declare it as initrd mount in Ignition -RequiresMountsFor=/sysroot/usr/ /sysroot/oem/ +RequiresMountsFor=/sysroot/usr/ [Service] Type=oneshot RemainAfterExit=yes EnvironmentFile=/run/ignition.env -# Flatcar: Make sure that the OEM mount point is there even if it shortly was away +# Flatcar: Start the /sysroot/oem bind mount and its underlying /oem mount. +# Don't use RequiresMountsFor for this because /oem may get unmounted earlier in +# the same systemd transaction, preventing this unit from starting. ExecStartPre=-systemctl start sysroot-oem.mount ExecStart=/usr/bin/ignition --root=/sysroot --platform=${PLATFORM_ID} --stage=files --log-to-stdout diff --git a/dracut/53ignition/ignition-kargs-helper b/dracut/53ignition/ignition-kargs-helper index 48f420f..01ae0f6 100755 --- a/dracut/53ignition/ignition-kargs-helper +++ b/dracut/53ignition/ignition-kargs-helper @@ -4,19 +4,14 @@ set -euxo pipefail -# Handle PXE boots gracefully by not mounting any disk and instead error out early -if [ "${OEM_ID}" = "pxe" ]; then +# Bail out early when PXE booting. OEM is a tmpfs in this case, so a new +# grub.cfg would be lost on reboot. +if [[ ${OEM_ID} == pxe ]]; then echo "error: can't set kargs for PXE boots" >&2 exit 1 fi -# Mount the OEM partition. Note that we mount but we don't unmount it because we -# are run in a systemd unit with MountFlags=slave so it is unmounted for us. -oemmnt=/mnt/oem_partition -mkdir -p ${oemmnt} -oemdev=/dev/disk/by-label/OEM -mount -o rw ${oemdev} ${oemmnt} -grubcfg="${oemmnt}/grub.cfg" +grubcfg="/oem/grub.cfg" # Ensure that it exists before we read from it (needed for the generic Flatcar image), "touch" does not exist in initramfs true >> $grubcfg diff --git a/dracut/53ignition/ignition-kargs.service b/dracut/53ignition/ignition-kargs.service index bbf8543..ebedeb9 100644 --- a/dracut/53ignition/ignition-kargs.service +++ b/dracut/53ignition/ignition-kargs.service @@ -17,7 +17,7 @@ Requires=local-fs-pre.target Before=local-fs-pre.target Requires=ignition-setup-pre.service After=ignition-setup-pre.service -RequiresMountsFor=/sysusr/usr/ +RequiresMountsFor=/sysusr/usr/ /oem/ [Service] Type=oneshot diff --git a/dracut/53ignition/ignition-mount.service b/dracut/53ignition/ignition-mount.service index 08c8306..86a3410 100644 --- a/dracut/53ignition/ignition-mount.service +++ b/dracut/53ignition/ignition-mount.service @@ -42,7 +42,7 @@ RequiresMountsFor=/sysusr/usr/ Type=oneshot RemainAfterExit=yes EnvironmentFile=/run/ignition.env -# Flatcar: Unmount any OEM mount in case the Ignition config has one defined -ExecStartPre=/bin/bash -c 'if ! mount | grep -m 1 /sysroot/oem | grep tmpfs; then umount /sysroot/oem || true; fi' +# Flatcar: Unmount any disk-based OEM partition in case the Ignition config wants to mount it. +ExecStartPre=sh -c 'findmnt -t tmpfs /oem >/dev/null || systemctl stop oem.mount' ExecStart=/usr/bin/ignition --root=/sysroot --platform=${PLATFORM_ID} --stage=mount --log-to-stdout ExecStop=/usr/bin/ignition --root=/sysroot --platform=${PLATFORM_ID} --stage=umount --log-to-stdout diff --git a/dracut/99setup-root/initrd-setup-root b/dracut/99setup-root/initrd-setup-root index 1d68418..d028b33 100755 --- a/dracut/99setup-root/initrd-setup-root +++ b/dracut/99setup-root/initrd-setup-root @@ -174,8 +174,3 @@ SYSTEMD_IN_INITRD=0 systemd-confext --root=/sysroot status | grep flatcar-defaul # to have default files but then we need to reload for any user confexts # to be applied and we can later rely on the confext/sysext .services # for that while the above call is specific to Flatcar/Ignition. - -# PXE initrds may provide OEM. -if [ -d /oem ] && mountpoint --quiet /sysroot/oem; then - cp -Ra /oem/. /sysroot/oem -fi diff --git a/dracut/99setup-root/initrd-setup-root-after-ignition.service b/dracut/99setup-root/initrd-setup-root-after-ignition.service index a8ecdd9..59f4d59 100644 --- a/dracut/99setup-root/initrd-setup-root-after-ignition.service +++ b/dracut/99setup-root/initrd-setup-root-after-ignition.service @@ -1,7 +1,7 @@ [Unit] Description=Root filesystem completion DefaultDependencies=no -RequiresMountsFor=/sysroot/usr/ /sysroot/oem/ +RequiresMountsFor=/sysroot/usr/ After=initrd-root-fs.target ignition-files.service initrd-setup-root.service Before=initrd-parse-etc.service OnFailure=emergency.target @@ -10,6 +10,10 @@ OnFailureJobMode=replace-irreversibly [Service] Type=oneshot RemainAfterExit=yes +# Flatcar: Start the /sysroot/oem bind mount and its underlying /oem mount. +# Don't use RequiresMountsFor for this because /oem may get unmounted earlier in +# the same systemd transaction, preventing this unit from starting. +ExecStartPre=-systemctl start sysroot-oem.mount ExecStart=/sbin/initrd-setup-root-after-ignition [Install] diff --git a/minimal-init b/minimal-init index 9a0652b..1145a2d 100755 --- a/minimal-init +++ b/minimal-init @@ -190,8 +190,10 @@ mount -t overlay -o rw,lowerdir=/underlay,upperdir=/work/realinit,workdir=/work/ mkdir -p /realinit/sysusr/usr mount -o move /sysusr/usr /realinit/sysusr/usr if [ "${usr}" = /usr.squashfs ]; then - # Move either /oem (preferred) or /usr/share/oem (legacy) into the new root. - mv /oem /realinit || mv /usr/share/oem /realinit || true + mkdir -p /realinit/oem + mount -t tmpfs -o size=0,mode=755,nodev tmpfs /realinit/oem + # Copy /oem (preferred) or /usr/share/oem (legacy) into the new root. + cp -a /oem/. /realinit/oem || cp -a /usr/share/oem/. /realinit/oem || true mv /usr.squashfs /realinit fi debug_sh 4/4: before switch_root to /realinit