From ce2a6390a9b94100deb40a65bcd87a4b4fcf727e Mon Sep 17 00:00:00 2001 From: Bipin B Narayan Date: Wed, 18 Mar 2026 17:18:29 +0530 Subject: [PATCH 1/7] dracut: include 01ignition-scsi-rules from ignition integration This is controlled by a flag and only included if set, intended for ignition-integration subpackage. We can remove this module once these imports are included in fedora-bootc. Related issue: https://github.com/coreos/fedora-coreos-tracker/issues/1582 --- Makefile | 14 ++++++++++---- dracut/01ignition-scsi-rules/module-setup.sh | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 dracut/01ignition-scsi-rules/module-setup.sh diff --git a/Makefile b/Makefile index 1cd905a057..81da3b77ae 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,7 @@ export GO111MODULE=on +INSTALL_ALL_DRACUT_MODULES=0 + # Canonical version of this in https://github.com/coreos/coreos-assembler/blob/6eb97016f4dab7d13aa00ae10846f26c1cd1cb02/Makefile#L19 GOARCH:=$(shell uname -m) ifeq ($(GOARCH),x86_64) @@ -43,10 +45,14 @@ butane-cross: .PHONY: install install: - for x in dracut/*; do \ - bn=$$(basename $$x); \ - install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/$${bn} $$x/*; \ - done + if [ $(INSTALL_ALL_DRACUT_MODULES) -eq 1 ]; then \ + for x in dracut/*; do \ + bn=$$(basename $$x); \ + install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/$${bn} $$x/*; \ + done; \ + else \ + install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/30ignition dracut/30ignition/*; \ + fi chmod a+x $(DESTDIR)/usr/lib/dracut/modules.d/*/*.sh $(DESTDIR)/usr/lib/dracut/modules.d/*/*-generator install -m 0644 -D -t $(DESTDIR)/usr/lib/systemd/system systemd/ignition-delete-config.service diff --git a/dracut/01ignition-scsi-rules/module-setup.sh b/dracut/01ignition-scsi-rules/module-setup.sh new file mode 100644 index 0000000000..eeaeacc230 --- /dev/null +++ b/dracut/01ignition-scsi-rules/module-setup.sh @@ -0,0 +1,19 @@ +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +check() { + if [[ $IN_KDUMP == 1 ]]; then + return 1 + fi +} + +# 1) Fix for https://bugzilla.redhat.com/show_bug.cgi?id=1918244 +# On s390x systems with IBM 2810XIV discs multipath couldn't be configured +# because SCSI_IDENT_* udev properties are not set at boot time +# 2-) Fix for https://bugzilla.redhat.com/show_bug.cgi?id=1990506 +# Missing symlinks to disk install +install() { + inst_simple sg_inq + inst_rules 61-scsi-sg3_id.rules + inst_rules 63-scsi-sg3_symlink.rules +} From d3a7075cd5d598cdbb23b160683c9a8d67d20600 Mon Sep 17 00:00:00 2001 From: Bipin B Narayan Date: Fri, 27 Mar 2026 15:36:08 +0530 Subject: [PATCH 2/7] dracut: include ignition-network module This module is only included only if network-manager is available. Ordering is important here as `network-manager`(or others) is included by `network` dracut module with prefix 40. We need this module to have higher numbered prefix. Contains scripts and services to enable networking if ignition requires it. Removed all parts that uses afterburn. We can switch to using `NetworkManager-config-initrd.service` once it's available. Related to: https://github.com/coreos/fedora-coreos-tracker/issues/1582 --- .../ignition-enable-network.service | 24 ++++++++++++++ .../ignition-enable-network.sh | 31 +++++++++++++++++ dracut/41ignition-network/module-setup.sh | 33 +++++++++++++++++++ 3 files changed, 88 insertions(+) create mode 100644 dracut/41ignition-network/ignition-enable-network.service create mode 100755 dracut/41ignition-network/ignition-enable-network.sh create mode 100644 dracut/41ignition-network/module-setup.sh diff --git a/dracut/41ignition-network/ignition-enable-network.service b/dracut/41ignition-network/ignition-enable-network.service new file mode 100644 index 0000000000..7f1d2a929b --- /dev/null +++ b/dracut/41ignition-network/ignition-enable-network.service @@ -0,0 +1,24 @@ +[Unit] +Description=Ignition Enable Network +ConditionPathExists=/etc/initrd-release +DefaultDependencies=false + +# Triggering conditions for cases where we need network: +# * when Ignition signals that it is required for provisioning. +ConditionPathExists=|/run/ignition/neednet + +# Creates /run/ignition/neednet +After=ignition-fetch-offline.service +# Needs networking +Before=ignition-fetch.service + +# See hack in ignition-enable-network. +After=dracut-cmdline.service +Before=nm-initrd.service +# compat: remove when everyone is on dracut 054+ +Before=dracut-initqueue.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/ignition-enable-network diff --git a/dracut/41ignition-network/ignition-enable-network.sh b/dracut/41ignition-network/ignition-enable-network.sh new file mode 100755 index 0000000000..e9b0d7c50b --- /dev/null +++ b/dracut/41ignition-network/ignition-enable-network.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -euo pipefail + +set +euo pipefail +. /usr/lib/dracut-lib.sh +set -euo pipefail + +dracut_func() { + # dracut is not friendly to set -eu + set +euo pipefail + "$@"; local rc=$? + set -euo pipefail + return $rc +} + +# If networking hasn't been requested yet, request it. +if ! dracut_func getargbool 0 'rd.neednet'; then + echo "rd.neednet=1" > /etc/cmdline.d/40-ignition-neednet.conf + + # Hack: we need to rerun the NM cmdline hook because we run after + # dracut-cmdline.service because we need udev. We should be able to move + # away from this once we run NM as a systemd unit. See also: + # https://github.com/coreos/fedora-coreos-config/pull/346#discussion_r409843428 + # + # NM and dracut will have `NetworkManager-config-initrd.service` which will do + # the same thing, but it's not in rawhide yet. Once that's available, we can + # replace this. + set +euo pipefail + . /usr/lib/dracut/hooks/cmdline/99-nm-config.sh + set -euo pipefail +fi diff --git a/dracut/41ignition-network/module-setup.sh b/dracut/41ignition-network/module-setup.sh new file mode 100644 index 0000000000..2bb49e9e12 --- /dev/null +++ b/dracut/41ignition-network/module-setup.sh @@ -0,0 +1,33 @@ +check() { + if [[ $IN_KDUMP == 1 ]]; then + return 1 + fi + + # This module will only work with NetworkManager now. + # We might add support for other later. + if dracut_module_included "network-manager"; then + return 0 + fi + + return 1 +} + +depends() { + echo network +} + +install_and_enable_unit() { + unit="$1"; shift + target="$1"; shift + inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit" + # note we `|| exit 1` here so we error out if e.g. the units are missing + # see https://github.com/coreos/fedora-coreos-config/issues/799 + $SYSTEMCTL -q --root="$initdir" add-requires "$target" "$unit" || exit 1 +} + +install() { + inst_simple "$moddir/ignition-enable-network.sh" \ + "/usr/sbin/ignition-enable-network" + install_and_enable_unit "ignition-enable-network.service" \ + "ignition-complete.target" +} From 26eace27fc0d66b9dd473abc662170566993efd3 Mon Sep 17 00:00:00 2001 From: Bipin B Narayan Date: Wed, 1 Apr 2026 19:15:38 +0530 Subject: [PATCH 3/7] dracut: include ignition-ostree module This module contains scripts and services to reprovision rootfs, mount and populate /var, etc. Related to: https://github.com/coreos/fedora-coreos-tracker/issues/1582 --- Makefile | 1 + .../ignition-ostree-mount-var.service | 26 ++ .../ignition-ostree-mount-var.sh | 54 +++ .../ignition-ostree-populate-var.service | 16 + .../ignition-ostree-populate-var.sh | 39 +++ ...ignition-ostree-transposefs-detect.service | 20 ++ ...gnition-ostree-transposefs-restore.service | 23 ++ .../ignition-ostree-transposefs-save.service | 19 ++ .../ignition-ostree-transposefs.sh | 322 ++++++++++++++++++ dracut/40ignition-ostree/ignition-relabel | 35 ++ dracut/40ignition-ostree/module-setup.sh | 76 +++++ 11 files changed, 631 insertions(+) create mode 100644 dracut/40ignition-ostree/ignition-ostree-mount-var.service create mode 100755 dracut/40ignition-ostree/ignition-ostree-mount-var.sh create mode 100644 dracut/40ignition-ostree/ignition-ostree-populate-var.service create mode 100755 dracut/40ignition-ostree/ignition-ostree-populate-var.sh create mode 100644 dracut/40ignition-ostree/ignition-ostree-transposefs-detect.service create mode 100644 dracut/40ignition-ostree/ignition-ostree-transposefs-restore.service create mode 100644 dracut/40ignition-ostree/ignition-ostree-transposefs-save.service create mode 100755 dracut/40ignition-ostree/ignition-ostree-transposefs.sh create mode 100755 dracut/40ignition-ostree/ignition-relabel create mode 100755 dracut/40ignition-ostree/module-setup.sh diff --git a/Makefile b/Makefile index 81da3b77ae..12d9befa1a 100644 --- a/Makefile +++ b/Makefile @@ -50,6 +50,7 @@ install: bn=$$(basename $$x); \ install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/$${bn} $$x/*; \ done; \ + chmod a+x $(DESTDIR)/usr/lib/dracut/modules.d/40ignition-ostree/ignition-relabel; \ else \ install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/30ignition dracut/30ignition/*; \ fi diff --git a/dracut/40ignition-ostree/ignition-ostree-mount-var.service b/dracut/40ignition-ostree/ignition-ostree-mount-var.service new file mode 100644 index 0000000000..09d6c15ab3 --- /dev/null +++ b/dracut/40ignition-ostree/ignition-ostree-mount-var.service @@ -0,0 +1,26 @@ +[Unit] +Description=Mount OSTree /var +DefaultDependencies=false +ConditionKernelCommandLine=ostree +ConditionPathExists=!/run/ostree-live + +# Make sure ExecStop= runs before we switch root +Before=initrd-switch-root.target + +# Make sure if ExecStop= fails, the boot fails +OnFailure=emergency.target +OnFailureJobMode=isolate + +# Make sure /sysroot is mounted first, since we're mounting under there +Requires=initrd-root-fs.target +After=initrd-root-fs.target + +# Need to do this before Ignition mounts any other filesystems (potentially +# shadowing our own bind mount). +Before=ignition-mount.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/ignition-ostree-mount-var mount +ExecStop=/usr/sbin/ignition-ostree-mount-var umount diff --git a/dracut/40ignition-ostree/ignition-ostree-mount-var.sh b/dracut/40ignition-ostree/ignition-ostree-mount-var.sh new file mode 100755 index 0000000000..6b80d83db3 --- /dev/null +++ b/dracut/40ignition-ostree/ignition-ostree-mount-var.sh @@ -0,0 +1,54 @@ +#!/bin/bash +set -euo pipefail + +fatal() { + echo "$@" >&2 + exit 1 +} + +if [ $# -ne 1 ] || { [[ $1 != mount ]] && [[ $1 != umount ]]; }; then + fatal "Usage: $0 " +fi + +get_ostree_arg() { + # yes, this doesn't account for spaces within args, e.g. myarg="my val", but + # it still works for our purposes + ( + IFS=$' ' + # shellcheck disable=SC2013 + for arg in $(cat /proc/cmdline); do + if [[ $arg == ostree=* ]]; then + echo "${arg#ostree=}" + fi + done + ) +} + +do_mount() { + ostree=$(get_ostree_arg) + if [ -z "${ostree}" ]; then + fatal "No ostree= kernel argument in /proc/cmdline" + fi + + deployment_path=/sysroot/${ostree} + if [ ! -L "${deployment_path}" ]; then + fatal "${deployment_path} is not a symlink" + fi + + stateroot_var_path=$(realpath "${deployment_path}/../../var") + if [ ! -d "${stateroot_var_path}" ]; then + fatal "${stateroot_var_path} is not a directory" + fi + + echo "Mounting $stateroot_var_path" + # older mount ignore 'rw' when using '-o bind,rw', so make 2 calls for now + mount --bind "$stateroot_var_path" /sysroot/var + mount -o remount,bind,rw /sysroot/var +} + +do_umount() { + echo "Unmounting /sysroot/var" + umount /sysroot/var +} + +"do_$1" diff --git a/dracut/40ignition-ostree/ignition-ostree-populate-var.service b/dracut/40ignition-ostree/ignition-ostree-populate-var.service new file mode 100644 index 0000000000..d7aa622cae --- /dev/null +++ b/dracut/40ignition-ostree/ignition-ostree-populate-var.service @@ -0,0 +1,16 @@ +[Unit] +Description=Populate OSTree /var +DefaultDependencies=false +ConditionKernelCommandLine=|ostree +ConditionPathExists=|/run/ostree-live + +# Need to do this with all mount points active +After=ignition-mount.service + +# But *before* we start dumping files in there +Before=ignition-files.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/ignition-ostree-populate-var diff --git a/dracut/40ignition-ostree/ignition-ostree-populate-var.sh b/dracut/40ignition-ostree/ignition-ostree-populate-var.sh new file mode 100755 index 0000000000..815f8d1db1 --- /dev/null +++ b/dracut/40ignition-ostree/ignition-ostree-populate-var.sh @@ -0,0 +1,39 @@ +#!/bin/bash +set -euo pipefail + +fatal() { + echo "$@" >&2 + exit 1 +} + +if [ $# -ne 0 ]; then + fatal "Usage: $0" +fi + +# See the similar code block in Anaconda, which handles this today for Atomic +# Host and Silverblue: +# https://github.com/rhinstaller/anaconda/blob/b9ea8ce4e68196b30a524c1cc5680dcdc4b89371/pyanaconda/payload/rpmostreepayload.py#L332 + +for varsubdir in lib log home roothome opt srv usrlocal mnt media; do + + # If the directory already existed, just ignore. This addresses the live + # image case with persistent `/var`; we don't want to relabel all the files + # there on each boot. + if [ -d "/sysroot/var/${varsubdir}" ]; then + continue + fi + + if [[ $varsubdir == lib ]] || [[ $varsubdir == log ]]; then + # Simply manually mkdir /var/{lib,log}; the tmpfiles.d entries otherwise + # reference users/groups which we don't have access to from here + # (though... we *could* import them from the sysroot, and have + # nss-altfiles in the initrd, but meh... let's just wait for + # systemd-sysusers which will make this way easier: + # https://github.com/coreos/fedora-coreos-config/pull/56/files#r262592361). + mkdir -p /sysroot/var/${varsubdir} + else + systemd-tmpfiles --create --boot --root=/sysroot --prefix="/var/${varsubdir}" + fi + + ignition-relabel "/var/${varsubdir}" +done diff --git a/dracut/40ignition-ostree/ignition-ostree-transposefs-detect.service b/dracut/40ignition-ostree/ignition-ostree-transposefs-detect.service new file mode 100644 index 0000000000..389dc9eedf --- /dev/null +++ b/dracut/40ignition-ostree/ignition-ostree-transposefs-detect.service @@ -0,0 +1,20 @@ +[Unit] +Description=Ignition OSTree: Detect Partition Transposition +DefaultDependencies=false +After=ignition-fetch.service +Before=ignition-disks.service +Before=initrd-root-fs.target +Before=sysroot.mount +ConditionKernelCommandLine=ostree +OnFailure=emergency.target +OnFailureJobMode=isolate + +# This stage requires udevd to detect disks +Requires=systemd-udevd.service +After=systemd-udevd.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/libexec/ignition-ostree-transposefs detect +ExecStop=/usr/libexec/ignition-ostree-transposefs cleanup diff --git a/dracut/40ignition-ostree/ignition-ostree-transposefs-restore.service b/dracut/40ignition-ostree/ignition-ostree-transposefs-restore.service new file mode 100644 index 0000000000..eef3c064c7 --- /dev/null +++ b/dracut/40ignition-ostree/ignition-ostree-transposefs-restore.service @@ -0,0 +1,23 @@ +[Unit] +Description=Ignition OSTree: Restore Partitions +DefaultDependencies=false +After=ignition-disks.service +# Avoid racing with UUID regeneration +After=ignition-ostree-uuid-root.service +After=ignition-ostree-growfs.service +# https://issues.redhat.com/browse/OCPBUGS-16157 +# On multipath systems mounting the /sysroot before +# the ignition-ostree services causes the transpose to fail. +Before=sysroot.mount +OnFailure=emergency.target +OnFailureJobMode=isolate + +ConditionKernelCommandLine=ostree +ConditionPathIsDirectory=/run/ignition-ostree-transposefs + +[Service] +Type=oneshot +RemainAfterExit=yes +# So we can transiently mount sysroot +MountFlags=slave +ExecStart=/usr/libexec/ignition-ostree-transposefs restore diff --git a/dracut/40ignition-ostree/ignition-ostree-transposefs-save.service b/dracut/40ignition-ostree/ignition-ostree-transposefs-save.service new file mode 100644 index 0000000000..bc03499ecb --- /dev/null +++ b/dracut/40ignition-ostree/ignition-ostree-transposefs-save.service @@ -0,0 +1,19 @@ +[Unit] +Description=Ignition OSTree: Save Partitions +DefaultDependencies=false +After=ignition-ostree-transposefs-detect.service +Before=ignition-disks.service +ConditionKernelCommandLine=ostree +ConditionPathIsDirectory=/run/ignition-ostree-transposefs +# Any services looking at mounts need to order after this +# because it causes device re-probing. +After=coreos-gpt-setup.service +OnFailure=emergency.target +OnFailureJobMode=isolate + +[Service] +Type=oneshot +RemainAfterExit=yes +# So we can transiently mount sysroot +MountFlags=slave +ExecStart=/usr/libexec/ignition-ostree-transposefs save diff --git a/dracut/40ignition-ostree/ignition-ostree-transposefs.sh b/dracut/40ignition-ostree/ignition-ostree-transposefs.sh new file mode 100755 index 0000000000..ec52b21450 --- /dev/null +++ b/dracut/40ignition-ostree/ignition-ostree-transposefs.sh @@ -0,0 +1,322 @@ +#!/bin/bash +set -euo pipefail + +boot_sector_size=440 +esp_typeguid=c12a7328-f81f-11d2-ba4b-00a0c93ec93b +bios_typeguid=21686148-6449-6e6f-744e-656564454649 +prep_typeguid=9e1a2d38-c612-4316-aa26-8b49521e5a8b + +# This is implementation details of Ignition; in the future, we should figure +# out a way to ask Ignition directly whether there's a filesystem with label +# "root" being set up. +ignition_cfg=/run/ignition.json +root_part=/dev/disk/by-label/root +boot_part=/dev/disk/by-label/boot +esp_part=/dev/disk/by-label/EFI-SYSTEM +bios_part=/dev/disk/by-partlabel/BIOS-BOOT +prep_part=/dev/disk/by-partlabel/PowerPC-PReP-boot +saved_data=/run/ignition-ostree-transposefs +saved_root=${saved_data}/root +saved_boot=${saved_data}/boot +saved_esp=${saved_data}/esp +saved_bios=${saved_data}/bios +saved_prep=${saved_data}/prep +zram_dev=${saved_data}/zram_dev +partstate_root=/run/ignition-ostree-rootfs-partstate.sh + +is_rhcos9() { + source /etc/os-release + [ "${ID}" == "rhcos" ] && [ "${RHEL_VERSION%%.*}" -eq 9 ] +} + +# Print jq query string for wiped filesystems with label $1 +query_fslabel() { + echo ".storage?.filesystems? // [] | map(select(.label == \"$1\" and .wipeFilesystem == true))" +} + +# Print jq query string for partitions with type GUID $1 +query_parttype() { + echo ".storage?.disks? // [] | map(.partitions?) | flatten | map(select(has(\"typeGuid\") and (.typeGuid | ascii_downcase == \"$1\")))" +} + +# Print partition labels for partitions with type GUID $1 +get_partlabels_for_parttype() { + jq -r "$(query_parttype $1) | .[].label" "${ignition_cfg}" +} + +# Mounts device to directory, with extra logging of the src device +mount_verbose() { + local srcdev=$1; shift + local destdir=$1; shift + local mode=${1:-ro} + echo "Mounting ${srcdev} ${mode} ($(realpath "$srcdev")) to $destdir" + mkdir -p "${destdir}" + mount -o "${mode}" "${srcdev}" "${destdir}" +} + +# Sometimes, for some reason the by-label symlinks aren't updated. Detect these +# cases, and explicitly `udevadm trigger`. +# See: https://bugzilla.redhat.com/show_bug.cgi?id=1908780 +udev_trigger_on_label_mismatch() { + local label=$1; shift + local expected_dev=$1; shift + local actual_dev + expected_dev=$(realpath "${expected_dev}") + # We `|| :` here because sometimes /dev/disk/by-label/$label is missing. + # We've seen this on Fedora kernels with debug enabled (common in `rawhide`). + # See https://github.com/coreos/fedora-coreos-tracker/issues/1092 + actual_dev=$(realpath "/dev/disk/by-label/$label" || :) + if [ "$actual_dev" != "$expected_dev" ]; then + echo "Expected /dev/disk/by-label/$label to point to $expected_dev, but points to $actual_dev; triggering udev" + udevadm trigger --settle "$expected_dev" + fi +} + +# Print partition offset for device node $1 +get_partition_offset() { + local devpath=$(udevadm info --query=path "$1") + cat "/sys${devpath}/start" +} + +# copied from generator-lib.sh +karg() { + local name="$1" value="${2:-}" + local cmdline=( $(&2 + exit 1 + fi + modprobe zram num_devices=0 + read dev < /sys/class/zram-control/hot_add + # disksize is set arbitrarily large, as zram is capped by mem_limit + echo 10G > /sys/block/zram"${dev}"/disksize + # Limit zram to 90% of available RAM: we want to be greedy since the + # boot breaks anyway, but we still want to leave room for everything + # else so it hits ENOSPC and doesn't invoke the OOM killer + echo $(( mem_available * 90 / 100 ))K > /sys/block/zram"${dev}"/mem_limit + mkfs.xfs -q /dev/zram"${dev}" + mkdir "${saved_data}" + mount -t xfs /dev/zram"${dev}" "${saved_data}" + # save the zram device number created for when called to cleanup + echo "${dev}" > "${zram_dev}" +} + +print_zram_mm_stat() { + echo "zram usage:" + read dev < "${zram_dev}" + cat /sys/block/zram"${dev}"/mm_stat +} + +case "${1:-}" in + detect) + # Mounts are not in a private namespace so we can mount ${saved_data} + wipes_root=$(jq "$(query_fslabel root) | length" "${ignition_cfg}") + wipes_boot=$(jq "$(query_fslabel boot) | length" "${ignition_cfg}") + creates_esp=$(jq "$(query_parttype ${esp_typeguid}) | length" "${ignition_cfg}") + creates_bios=$(jq "$(query_parttype ${bios_typeguid}) | length" "${ignition_cfg}") + creates_prep=$(jq "$(query_parttype ${prep_typeguid}) | length" "${ignition_cfg}") + if [ "${wipes_root}${wipes_boot}${creates_esp}${creates_bios}${creates_prep}" = "00000" ]; then + exit 0 + fi + echo "Detected partition replacement in fetched Ignition config: /run/ignition.json" + # verify all ESP, BIOS, and PReP partitions have non-null unique labels + unique_esp=$(jq -r "$(query_parttype ${esp_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}") + unique_bios=$(jq -r "$(query_parttype ${bios_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}") + unique_prep=$(jq -r "$(query_parttype ${prep_typeguid}) | [.[].label | values] | unique | length" "${ignition_cfg}") + if [ "${creates_esp}" != "${unique_esp}" -o "${creates_bios}" != "${unique_bios}" -o "${creates_prep}" != "${unique_prep}" ]; then + echo "Found duplicate or missing ESP, BIOS-BOOT, or PReP labels in config" >&2 + exit 1 + fi + + ensure_zram_dev + + if [ "${wipes_root}" != "0" ]; then + mkdir "${saved_root}" + fi + if [ "${wipes_boot}" != "0" ]; then + mkdir "${saved_boot}" + fi + if [ "${creates_esp}" != "0" ]; then + mkdir "${saved_esp}" + fi + if [ "${creates_bios}" != "0" ]; then + mkdir "${saved_bios}" + fi + if [ "${creates_prep}" != "0" ]; then + mkdir "${saved_prep}" + fi + ;; + save) + # Mounts happen in a private mount namespace since we're not "offically" mounting + if [ -d "${saved_root}" ]; then + echo "Moving rootfs to RAM..." + mount_and_save_filesystem_by_label root "${saved_root}" + # also store the state of the partition + lsblk "${root_part}" --nodeps --pairs -b --paths -o NAME,TYPE,SIZE > "${partstate_root}" + fi + if [ -d "${saved_boot}" ]; then + echo "Moving bootfs to RAM..." + mount_and_save_filesystem_by_label boot "${saved_boot}" + fi + if [ -d "${saved_esp}" ]; then + echo "Moving EFI System Partition to RAM..." + mount_verbose "${esp_part}" /sysroot/boot/efi + cp -aT /sysroot/boot/efi "${saved_esp}" + fi + if [ -d "${saved_bios}" ]; then + echo "Moving BIOS Boot partition and boot sector to RAM..." + # save partition + cat "${bios_part}" > "${saved_bios}/partition" + # save boot sector + bios_disk=$(lsblk --noheadings --output PKNAME --paths "${bios_part}") + dd if="${bios_disk}" of="${saved_bios}/boot-sector" bs="${boot_sector_size}" count=1 status=none + # store partition start offset so we can check it later + get_partition_offset "${bios_part}" > "${saved_bios}/start" + fi + if [ -d "${saved_prep}" ]; then + echo "Moving PReP partition to RAM..." + cat "${prep_part}" > "${saved_prep}/partition" + fi + print_zram_mm_stat + ;; + restore) + # Mounts happen in a private mount namespace since we're not "offically" mounting + 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/*/) + fi + if [ -d "${saved_boot}" ]; then + echo "Restoring bootfs from RAM..." + mount_and_restore_filesystem_by_label boot /sysroot/boot "${saved_boot}" + chcon -v --reference "${saved_boot}" /sysroot/boot # the root of the fs itself + fi + if [ -d "${saved_esp}" ]; then + echo "Restoring EFI System Partition from RAM..." + get_partlabels_for_parttype "${esp_typeguid}" | while read label; do + # Don't use mount_and_restore_filesystem_by_label because: + # 1. We're mounting by partlabel, not FS label + # 2. We need to copy the contents to each partition, not move + # them once + # 3. We don't need the by-label symlink to be correct and + # nothing later in boot will be mounting the filesystem + mountpoint="/mnt/esp-${label}" + mount_verbose "/dev/disk/by-partlabel/${label}" "${mountpoint}" rw + find "${saved_esp}" -mindepth 1 -maxdepth 1 -exec cp -at "${mountpoint}" {} + + done + fi + if [ -d "${saved_bios}" ]; then + echo "Restoring BIOS Boot partition and boot sector from RAM..." + expected_start=$(cat "${saved_bios}/start") + get_partlabels_for_parttype "${bios_typeguid}" | while read label; do + cur_part="/dev/disk/by-partlabel/${label}" + # boot sector hardcodes the partition start; ensure it matches + cur_start=$(get_partition_offset "${cur_part}") + if [ "${cur_start}" != "${expected_start}" ]; then + echo "Partition ${cur_part} starts at ${cur_start}; expected ${expected_start}" >&2 + exit 1 + fi + # copy partition contents + cat "${saved_bios}/partition" > "${cur_part}" + # copy boot sector + cur_disk=$(lsblk --noheadings --output PKNAME --paths "${cur_part}") + cat "${saved_bios}/boot-sector" > "${cur_disk}" + done + fi + if [ -d "${saved_prep}" ]; then + echo "Restoring PReP partition from RAM..." + get_partlabels_for_parttype "${prep_typeguid}" | while read label; do + cat "${saved_prep}/partition" > "/dev/disk/by-partlabel/${label}" + done + fi + ;; + cleanup) + # Mounts are not in a private namespace so we can unmount ${saved_data} + if [ -d "${saved_data}" ]; then + read dev < "${zram_dev}" + umount "${saved_data}" + rm -rf "${saved_data}" "${partstate_root}" + # After unmounting, make sure zram device state is stable before we remove it. + # See https://github.com/openshift/os/issues/1149 + # Should remove when https://bugzilla.redhat.com/show_bug.cgi?id=2172058 is fixed. + # Seems the previous workaround https://github.com/coreos/fedora-coreos-config/pull/2226 + # can not completely resolve the race issue, try in loop with a small sleep for el9 + !x86_64. + if [ $(uname -m) != x86_64 ] && is_rhcos9; then + for x in {0..10}; do + if ! echo "${dev}" > /sys/class/zram-control/hot_remove 2>/dev/null; then + sleep 0.1 + else + dev= + break + fi + done + # try it one last time and let it possibly fail + if [ -n "${dev}" ]; then + echo "${dev}" > /sys/class/zram-control/hot_remove + fi + else + echo "${dev}" > /sys/class/zram-control/hot_remove + fi + fi + ;; + *) + echo "Unsupported operation: ${1:-}" 1>&2; exit 1 + ;; +esac diff --git a/dracut/40ignition-ostree/ignition-relabel b/dracut/40ignition-ostree/ignition-relabel new file mode 100755 index 0000000000..f4397551c0 --- /dev/null +++ b/dracut/40ignition-ostree/ignition-relabel @@ -0,0 +1,35 @@ +#!/bin/bash +set -euo pipefail + +err() { + echo "$@" >&2 +} + +fatal() { + err "$@" + exit 1 +} + +if [ $# -eq 0 ]; then + err "Usage: $0 [PATTERN...]" + err " e.g.: $0 /etc/passwd '/etc/group*'" +fi + +if [ ! -f /sysroot/etc/selinux/config ]; then + exit 0 +fi + +source /sysroot/etc/selinux/config + +if [ -z "${SELINUXTYPE:-}" ]; then + fatal "Couldn't find SELINUXTYPE in /sysroot/etc/selinux/config" +fi + +file_contexts="/sysroot/etc/selinux/${SELINUXTYPE}/contexts/files/file_contexts" + +prefixed_patterns=() +while [ $# -ne 0 ]; do + pattern=$1; shift + prefixed_patterns+=("/sysroot/$pattern") +done +setfiles -vFi0 -r /sysroot "$file_contexts" "${prefixed_patterns[@]}" diff --git a/dracut/40ignition-ostree/module-setup.sh b/dracut/40ignition-ostree/module-setup.sh new file mode 100755 index 0000000000..3423e39c27 --- /dev/null +++ b/dracut/40ignition-ostree/module-setup.sh @@ -0,0 +1,76 @@ +#!/bin/bash +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +check() { + if [[ $IN_KDUMP == 1 ]]; then + return 1 + fi +} + +depends() { + echo ignition +} + +install_ignition_unit() { + local unit=$1; shift + local target=${1:-complete} + inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit" + # note we `|| exit 1` here so we error out if e.g. the units are missing + # see https://github.com/coreos/fedora-coreos-config/issues/799 + systemctl -q --root="$initdir" add-requires "ignition-${target}.target" "$unit" || exit 1 +} + +installkernel() { + # Used by ignition-ostree-transposefs + instmods -c zram +} + +install() { + inst_multiple \ + realpath \ + setfiles \ + chcon \ + systemd-sysusers \ + systemd-tmpfiles + + if [[ $(uname -m) = s390x ]]; then + # for Secure Execution + inst_multiple \ + veritysetup + fi + + # growpart deps + # Mostly generated from the following command: + # $ bash --rpm-requires /usr/bin/growpart | sort | uniq | grep executable + # with a few false positives (rq, rqe, -v) and one missed (mktemp) + inst_multiple \ + awk \ + cat \ + dd \ + grep \ + rm \ + find + + # In some cases we had to vendor gdisk in Ignition. + # If this is the case here use that one. + # See https://issues.redhat.com/browse/RHEL-56080 + if [ -f /usr/libexec/ignition-sgdisk ]; then + inst /usr/libexec/ignition-sgdisk /usr/sbin/sgdisk + else + inst sgdisk + fi + + for x in mount populate; do + install_ignition_unit ignition-ostree-${x}-var.service + inst_script "$moddir/ignition-ostree-${x}-var.sh" "/usr/sbin/ignition-ostree-${x}-var" + done + + inst_multiple jq chattr + inst_script "$moddir/ignition-ostree-transposefs.sh" "/usr/libexec/ignition-ostree-transposefs" + for x in detect save restore; do + install_ignition_unit ignition-ostree-transposefs-${x}.service + done + + inst_script "$moddir/ignition-relabel" /usr/bin/ignition-relabel +} From ca023c8b8b33459693bdedaa07d674518609dce7 Mon Sep 17 00:00:00 2001 From: Bipin B Narayan Date: Wed, 15 Apr 2026 17:09:44 +0530 Subject: [PATCH 4/7] systemd: include scripts, systemd services and presets 1. ignition-write-issues & ignition-write-issue.service To write issues files with info about ignition runwq Include systemd presets to enable the above services (and a few others too). Related to: https://github.com/coreos/fedora-coreos-tracker/issues/1582 --- Makefile | 3 ++ scripts/libexec/ignition-write-issues | 67 ++++++++++++++++++++++++ systemd/ignition-write-issues.service | 16 ++++++ systemd/system-preset/40-ignition.preset | 6 +++ 4 files changed, 92 insertions(+) create mode 100755 scripts/libexec/ignition-write-issues create mode 100644 systemd/ignition-write-issues.service create mode 100644 systemd/system-preset/40-ignition.preset diff --git a/Makefile b/Makefile index 12d9befa1a..67790b0ff4 100644 --- a/Makefile +++ b/Makefile @@ -50,6 +50,9 @@ install: bn=$$(basename $$x); \ install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/$${bn} $$x/*; \ done; \ + install -m 755 -D -t $(DESTDIR)/usr/libexec scripts/libexec/ignition-write-issues; \ + install -m 0644 -D -t $(DESTDIR)/usr/lib/systemd/system systemd/ignition-write-issues.service; \ + install -m 0644 -D -t $(DESTDIR)/usr/lib/systemd/system-preset systemd/system-preset/40-ignition.preset; \ chmod a+x $(DESTDIR)/usr/lib/dracut/modules.d/40ignition-ostree/ignition-relabel; \ else \ install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/30ignition dracut/30ignition/*; \ diff --git a/scripts/libexec/ignition-write-issues b/scripts/libexec/ignition-write-issues new file mode 100755 index 0000000000..8e4d6ef5da --- /dev/null +++ b/scripts/libexec/ignition-write-issues @@ -0,0 +1,67 @@ +#!/usr/bin/bash +set -euo pipefail + +IGNITION_RESULT=/etc/.ignition-result.json + +WARN='\033[0;33m' # yellow +RESET='\033[0m' # reset + +mkdir -p /run/issue.d +touch /run/issue.d/30_ignition_provisioning.issue + +d=$(date --date "$(jq -r .provisioningDate "${IGNITION_RESULT}")" +"%Y/%m/%d %H:%M:%S %Z") +ignitionBoot=$(jq -r .provisioningBootID "${IGNITION_RESULT}") +if [ $(cat /proc/sys/kernel/random/boot_id) = "${ignitionBoot}" ]; then + echo "Ignition: ran on ${d} (this boot)" \ + > /run/issue.d/30_ignition_provisioning.issue + + # checking for /run/ostree-live as the live system with persistent storage can run Ignition more than once + if ! test -f /run/ostree-live && jq -e .previousReport.provisioningDate "${IGNITION_RESULT}" &>/dev/null; then + prevdate=$(date --date "$(jq -r .previousReport.provisioningDate "${IGNITION_RESULT}")" +"%Y/%m/%d %H:%M:%S %Z") + cat << EOF > /etc/issue.d/30_ignition_run_more_than_once.issue +${WARN} +############################################################################ +WARNING: Ignition previously ran on ${prevdate}. Unexpected +behavior may occur. Ignition is not designed to run more than once per system. +############################################################################ +${RESET} +EOF + fi + # In Ignition, we've two config validation checks, the one after + # fetching a config and the second after merging configs. Sometimes, + # a warning goes away after merging, however, it's possible that a + # warning appears in case merging creates a contradiction between + # two fields. So this workflow eventually sends duplicate warnings + # in journal entries. Hence, we need to avoid displaying duplicate + # Ignition warnings on the console. + # For e.g. In the journal entries, we might see the following logs: + # + # warning at $.systemd.units.0.contents, line 1 col 997: unit "echo@.service" is enabled, but has no install section so enable does nothing + # warning at $.systemd.units.0.contents: unit "echo@.service" is enabled, but has no install section so enable does nothing + # + # In order to normalize these logs, we'd need to get rid of the line + # and column numbers entirely using the sed command, and then use + # `sort -u` to remove duplicate content. After this, we'd see the + # following warning on the console: + # + # warning at $.systemd.units.0.contents: unit "echo@.service" is enabled, but has no install section so enable does nothing + # + # TODO: find a way to query journal entries recorded before the + # system switches to real root + journalctl -t ignition -o cat -p warning | sed -r 's/, line [0-9]+ col [0-9]+//g' | sort -u | while read line; do + echo -e "${WARN}Ignition: $line${RESET}" >> /etc/issue.d/30_ignition_warnings.issue + done +else + nreboots=$(($(journalctl --list-boots | wc -l) - 1)) + [ "${nreboots}" -eq 1 ] && boot="boot" || boot="boots" + echo "Ignition: ran on ${d} (at least $nreboots $boot ago)" \ + > /run/issue.d/30_ignition_provisioning.issue +fi + +if jq -e .userConfigProvided "${IGNITION_RESULT}" &>/dev/null; then + echo "Ignition: user-provided config was applied" \ + >> /run/issue.d/30_ignition_provisioning.issue +else + echo -e "${WARN}Ignition: no config provided by user${RESET}" \ + >> /run/issue.d/30_ignition_provisioning.issue +fi diff --git a/systemd/ignition-write-issues.service b/systemd/ignition-write-issues.service new file mode 100644 index 0000000000..9127861ee9 --- /dev/null +++ b/systemd/ignition-write-issues.service @@ -0,0 +1,16 @@ +# This service writes issue files describing status +# information about the Ignition run, which includes +# Ignition warnings and information if no Ignition +# config is provided. +[Unit] +Description=Create Ignition Status Issue Files +Before=systemd-user-sessions.service +ConditionPathExists=/etc/.ignition-result.json + +[Service] +Type=oneshot +ExecStart=/usr/libexec/ignition-write-issues +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/systemd/system-preset/40-ignition.preset b/systemd/system-preset/40-ignition.preset new file mode 100644 index 0000000000..3b9c546f39 --- /dev/null +++ b/systemd/system-preset/40-ignition.preset @@ -0,0 +1,6 @@ +# Delete Ignition config from provider on platforms where it's possible +# https://github.com/coreos/ignition/pull/1350 +enable ignition-delete-config.service + +# Provide status information about the Ignition run +enable ignition-write-issues.service From 3c58e69913368544c04de0fffa69f20a1c3cf522 Mon Sep 17 00:00:00 2001 From: Bipin B Narayan Date: Wed, 15 Apr 2026 17:28:57 +0530 Subject: [PATCH 5/7] dracut: Include dracut conf to omit nfs and change dir layout Omitting `nfs` is important here as it prevents `/var` from being mounted and eventually causing boot failure. Moved module to subdir `modules.d`. Related to: https://github.com/coreos/fedora-coreos-tracker/issues/1582 --- Makefile | 5 +++-- dracut/dracut.conf.d/60-omit-nfs.conf | 6 ++++++ .../{ => modules.d}/01ignition-scsi-rules/module-setup.sh | 0 .../30ignition/99-xx-ignition-systemd-cryptsetup.rules | 0 dracut/{ => modules.d}/30ignition/ignition-cex | 0 dracut/{ => modules.d}/30ignition/ignition-complete.target | 0 .../30ignition/ignition-diskful-subsequent.target | 0 dracut/{ => modules.d}/30ignition/ignition-diskful.target | 0 dracut/{ => modules.d}/30ignition/ignition-disks.service | 0 .../30ignition/ignition-fetch-offline.service | 0 dracut/{ => modules.d}/30ignition/ignition-fetch.service | 0 dracut/{ => modules.d}/30ignition/ignition-files.service | 0 dracut/{ => modules.d}/30ignition/ignition-generator | 0 dracut/{ => modules.d}/30ignition/ignition-kargs-helper.sh | 0 dracut/{ => modules.d}/30ignition/ignition-kargs.service | 0 dracut/{ => modules.d}/30ignition/ignition-luks.conf | 0 dracut/{ => modules.d}/30ignition/ignition-mount.service | 0 .../30ignition/ignition-remount-sysroot.service | 0 .../{ => modules.d}/30ignition/ignition-subsequent.target | 0 dracut/{ => modules.d}/30ignition/module-setup.sh | 0 .../40ignition-ostree/ignition-ostree-mount-var.service | 0 .../40ignition-ostree/ignition-ostree-mount-var.sh | 0 .../40ignition-ostree/ignition-ostree-populate-var.service | 0 .../40ignition-ostree/ignition-ostree-populate-var.sh | 0 .../ignition-ostree-transposefs-detect.service | 0 .../ignition-ostree-transposefs-restore.service | 0 .../ignition-ostree-transposefs-save.service | 0 .../40ignition-ostree/ignition-ostree-transposefs.sh | 0 dracut/{ => modules.d}/40ignition-ostree/ignition-relabel | 0 dracut/{ => modules.d}/40ignition-ostree/module-setup.sh | 0 .../41ignition-network/ignition-enable-network.service | 0 .../41ignition-network/ignition-enable-network.sh | 0 dracut/{ => modules.d}/41ignition-network/module-setup.sh | 0 33 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 dracut/dracut.conf.d/60-omit-nfs.conf rename dracut/{ => modules.d}/01ignition-scsi-rules/module-setup.sh (100%) rename dracut/{ => modules.d}/30ignition/99-xx-ignition-systemd-cryptsetup.rules (100%) rename dracut/{ => modules.d}/30ignition/ignition-cex (100%) rename dracut/{ => modules.d}/30ignition/ignition-complete.target (100%) rename dracut/{ => modules.d}/30ignition/ignition-diskful-subsequent.target (100%) rename dracut/{ => modules.d}/30ignition/ignition-diskful.target (100%) rename dracut/{ => modules.d}/30ignition/ignition-disks.service (100%) rename dracut/{ => modules.d}/30ignition/ignition-fetch-offline.service (100%) rename dracut/{ => modules.d}/30ignition/ignition-fetch.service (100%) rename dracut/{ => modules.d}/30ignition/ignition-files.service (100%) rename dracut/{ => modules.d}/30ignition/ignition-generator (100%) rename dracut/{ => modules.d}/30ignition/ignition-kargs-helper.sh (100%) rename dracut/{ => modules.d}/30ignition/ignition-kargs.service (100%) rename dracut/{ => modules.d}/30ignition/ignition-luks.conf (100%) rename dracut/{ => modules.d}/30ignition/ignition-mount.service (100%) rename dracut/{ => modules.d}/30ignition/ignition-remount-sysroot.service (100%) rename dracut/{ => modules.d}/30ignition/ignition-subsequent.target (100%) rename dracut/{ => modules.d}/30ignition/module-setup.sh (100%) rename dracut/{ => modules.d}/40ignition-ostree/ignition-ostree-mount-var.service (100%) rename dracut/{ => modules.d}/40ignition-ostree/ignition-ostree-mount-var.sh (100%) rename dracut/{ => modules.d}/40ignition-ostree/ignition-ostree-populate-var.service (100%) rename dracut/{ => modules.d}/40ignition-ostree/ignition-ostree-populate-var.sh (100%) rename dracut/{ => modules.d}/40ignition-ostree/ignition-ostree-transposefs-detect.service (100%) rename dracut/{ => modules.d}/40ignition-ostree/ignition-ostree-transposefs-restore.service (100%) rename dracut/{ => modules.d}/40ignition-ostree/ignition-ostree-transposefs-save.service (100%) rename dracut/{ => modules.d}/40ignition-ostree/ignition-ostree-transposefs.sh (100%) rename dracut/{ => modules.d}/40ignition-ostree/ignition-relabel (100%) rename dracut/{ => modules.d}/40ignition-ostree/module-setup.sh (100%) rename dracut/{ => modules.d}/41ignition-network/ignition-enable-network.service (100%) rename dracut/{ => modules.d}/41ignition-network/ignition-enable-network.sh (100%) rename dracut/{ => modules.d}/41ignition-network/module-setup.sh (100%) diff --git a/Makefile b/Makefile index 67790b0ff4..b159e55443 100644 --- a/Makefile +++ b/Makefile @@ -46,16 +46,17 @@ butane-cross: .PHONY: install install: if [ $(INSTALL_ALL_DRACUT_MODULES) -eq 1 ]; then \ - for x in dracut/*; do \ + for x in dracut/modules.d/*; do \ bn=$$(basename $$x); \ install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/$${bn} $$x/*; \ done; \ install -m 755 -D -t $(DESTDIR)/usr/libexec scripts/libexec/ignition-write-issues; \ install -m 0644 -D -t $(DESTDIR)/usr/lib/systemd/system systemd/ignition-write-issues.service; \ install -m 0644 -D -t $(DESTDIR)/usr/lib/systemd/system-preset systemd/system-preset/40-ignition.preset; \ + install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/dracut.conf.d dracut/dracut.conf.d/*; \ chmod a+x $(DESTDIR)/usr/lib/dracut/modules.d/40ignition-ostree/ignition-relabel; \ else \ - install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/30ignition dracut/30ignition/*; \ + install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/30ignition dracut/modules.d/30ignition/*; \ fi chmod a+x $(DESTDIR)/usr/lib/dracut/modules.d/*/*.sh $(DESTDIR)/usr/lib/dracut/modules.d/*/*-generator diff --git a/dracut/dracut.conf.d/60-omit-nfs.conf b/dracut/dracut.conf.d/60-omit-nfs.conf new file mode 100644 index 0000000000..907e7fd61d --- /dev/null +++ b/dracut/dracut.conf.d/60-omit-nfs.conf @@ -0,0 +1,6 @@ +# We don't support root on NFS, so we don't need it in the initramfs. It also +# conflicts with /var mount support in ignition because NFS tries to mount stuff +# in /var/ and then ignition can't cleanly unmount it. For example: +# https://github.com/dracutdevs/dracut/blob/1856ae95c873a6fe855b3dccd0144f1a96b9e71c/modules.d/95nfs/nfs-start-rpc.sh#L7 +# See also discussion in https://github.com/coreos/fedora-coreos-config/pull/60 +omit_dracutmodules+=" nfs " diff --git a/dracut/01ignition-scsi-rules/module-setup.sh b/dracut/modules.d/01ignition-scsi-rules/module-setup.sh similarity index 100% rename from dracut/01ignition-scsi-rules/module-setup.sh rename to dracut/modules.d/01ignition-scsi-rules/module-setup.sh diff --git a/dracut/30ignition/99-xx-ignition-systemd-cryptsetup.rules b/dracut/modules.d/30ignition/99-xx-ignition-systemd-cryptsetup.rules similarity index 100% rename from dracut/30ignition/99-xx-ignition-systemd-cryptsetup.rules rename to dracut/modules.d/30ignition/99-xx-ignition-systemd-cryptsetup.rules diff --git a/dracut/30ignition/ignition-cex b/dracut/modules.d/30ignition/ignition-cex similarity index 100% rename from dracut/30ignition/ignition-cex rename to dracut/modules.d/30ignition/ignition-cex diff --git a/dracut/30ignition/ignition-complete.target b/dracut/modules.d/30ignition/ignition-complete.target similarity index 100% rename from dracut/30ignition/ignition-complete.target rename to dracut/modules.d/30ignition/ignition-complete.target diff --git a/dracut/30ignition/ignition-diskful-subsequent.target b/dracut/modules.d/30ignition/ignition-diskful-subsequent.target similarity index 100% rename from dracut/30ignition/ignition-diskful-subsequent.target rename to dracut/modules.d/30ignition/ignition-diskful-subsequent.target diff --git a/dracut/30ignition/ignition-diskful.target b/dracut/modules.d/30ignition/ignition-diskful.target similarity index 100% rename from dracut/30ignition/ignition-diskful.target rename to dracut/modules.d/30ignition/ignition-diskful.target diff --git a/dracut/30ignition/ignition-disks.service b/dracut/modules.d/30ignition/ignition-disks.service similarity index 100% rename from dracut/30ignition/ignition-disks.service rename to dracut/modules.d/30ignition/ignition-disks.service diff --git a/dracut/30ignition/ignition-fetch-offline.service b/dracut/modules.d/30ignition/ignition-fetch-offline.service similarity index 100% rename from dracut/30ignition/ignition-fetch-offline.service rename to dracut/modules.d/30ignition/ignition-fetch-offline.service diff --git a/dracut/30ignition/ignition-fetch.service b/dracut/modules.d/30ignition/ignition-fetch.service similarity index 100% rename from dracut/30ignition/ignition-fetch.service rename to dracut/modules.d/30ignition/ignition-fetch.service diff --git a/dracut/30ignition/ignition-files.service b/dracut/modules.d/30ignition/ignition-files.service similarity index 100% rename from dracut/30ignition/ignition-files.service rename to dracut/modules.d/30ignition/ignition-files.service diff --git a/dracut/30ignition/ignition-generator b/dracut/modules.d/30ignition/ignition-generator similarity index 100% rename from dracut/30ignition/ignition-generator rename to dracut/modules.d/30ignition/ignition-generator diff --git a/dracut/30ignition/ignition-kargs-helper.sh b/dracut/modules.d/30ignition/ignition-kargs-helper.sh similarity index 100% rename from dracut/30ignition/ignition-kargs-helper.sh rename to dracut/modules.d/30ignition/ignition-kargs-helper.sh diff --git a/dracut/30ignition/ignition-kargs.service b/dracut/modules.d/30ignition/ignition-kargs.service similarity index 100% rename from dracut/30ignition/ignition-kargs.service rename to dracut/modules.d/30ignition/ignition-kargs.service diff --git a/dracut/30ignition/ignition-luks.conf b/dracut/modules.d/30ignition/ignition-luks.conf similarity index 100% rename from dracut/30ignition/ignition-luks.conf rename to dracut/modules.d/30ignition/ignition-luks.conf diff --git a/dracut/30ignition/ignition-mount.service b/dracut/modules.d/30ignition/ignition-mount.service similarity index 100% rename from dracut/30ignition/ignition-mount.service rename to dracut/modules.d/30ignition/ignition-mount.service diff --git a/dracut/30ignition/ignition-remount-sysroot.service b/dracut/modules.d/30ignition/ignition-remount-sysroot.service similarity index 100% rename from dracut/30ignition/ignition-remount-sysroot.service rename to dracut/modules.d/30ignition/ignition-remount-sysroot.service diff --git a/dracut/30ignition/ignition-subsequent.target b/dracut/modules.d/30ignition/ignition-subsequent.target similarity index 100% rename from dracut/30ignition/ignition-subsequent.target rename to dracut/modules.d/30ignition/ignition-subsequent.target diff --git a/dracut/30ignition/module-setup.sh b/dracut/modules.d/30ignition/module-setup.sh similarity index 100% rename from dracut/30ignition/module-setup.sh rename to dracut/modules.d/30ignition/module-setup.sh diff --git a/dracut/40ignition-ostree/ignition-ostree-mount-var.service b/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.service similarity index 100% rename from dracut/40ignition-ostree/ignition-ostree-mount-var.service rename to dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.service diff --git a/dracut/40ignition-ostree/ignition-ostree-mount-var.sh b/dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.sh similarity index 100% rename from dracut/40ignition-ostree/ignition-ostree-mount-var.sh rename to dracut/modules.d/40ignition-ostree/ignition-ostree-mount-var.sh diff --git a/dracut/40ignition-ostree/ignition-ostree-populate-var.service b/dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.service similarity index 100% rename from dracut/40ignition-ostree/ignition-ostree-populate-var.service rename to dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.service diff --git a/dracut/40ignition-ostree/ignition-ostree-populate-var.sh b/dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.sh similarity index 100% rename from dracut/40ignition-ostree/ignition-ostree-populate-var.sh rename to dracut/modules.d/40ignition-ostree/ignition-ostree-populate-var.sh diff --git a/dracut/40ignition-ostree/ignition-ostree-transposefs-detect.service b/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-detect.service similarity index 100% rename from dracut/40ignition-ostree/ignition-ostree-transposefs-detect.service rename to dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-detect.service diff --git a/dracut/40ignition-ostree/ignition-ostree-transposefs-restore.service b/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service similarity index 100% rename from dracut/40ignition-ostree/ignition-ostree-transposefs-restore.service rename to dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-restore.service diff --git a/dracut/40ignition-ostree/ignition-ostree-transposefs-save.service b/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-save.service similarity index 100% rename from dracut/40ignition-ostree/ignition-ostree-transposefs-save.service rename to dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs-save.service diff --git a/dracut/40ignition-ostree/ignition-ostree-transposefs.sh b/dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh similarity index 100% rename from dracut/40ignition-ostree/ignition-ostree-transposefs.sh rename to dracut/modules.d/40ignition-ostree/ignition-ostree-transposefs.sh diff --git a/dracut/40ignition-ostree/ignition-relabel b/dracut/modules.d/40ignition-ostree/ignition-relabel similarity index 100% rename from dracut/40ignition-ostree/ignition-relabel rename to dracut/modules.d/40ignition-ostree/ignition-relabel diff --git a/dracut/40ignition-ostree/module-setup.sh b/dracut/modules.d/40ignition-ostree/module-setup.sh similarity index 100% rename from dracut/40ignition-ostree/module-setup.sh rename to dracut/modules.d/40ignition-ostree/module-setup.sh diff --git a/dracut/41ignition-network/ignition-enable-network.service b/dracut/modules.d/41ignition-network/ignition-enable-network.service similarity index 100% rename from dracut/41ignition-network/ignition-enable-network.service rename to dracut/modules.d/41ignition-network/ignition-enable-network.service diff --git a/dracut/41ignition-network/ignition-enable-network.sh b/dracut/modules.d/41ignition-network/ignition-enable-network.sh similarity index 100% rename from dracut/41ignition-network/ignition-enable-network.sh rename to dracut/modules.d/41ignition-network/ignition-enable-network.sh diff --git a/dracut/41ignition-network/module-setup.sh b/dracut/modules.d/41ignition-network/module-setup.sh similarity index 100% rename from dracut/41ignition-network/module-setup.sh rename to dracut/modules.d/41ignition-network/module-setup.sh From dd9ec7fe8c68bfac1a8e612df9537ceacacb975c Mon Sep 17 00:00:00 2001 From: Bipin B Narayan Date: Thu, 30 Apr 2026 17:41:22 +0530 Subject: [PATCH 6/7] dracut: Add ignition-log-kmsg module This module replaces global log forwarding from https://github.com/coreos/fedora-coreos-config/tree/0a9be179334d809ba034468e238d0e7f6d1cac0a/overlay.d/05core/usr/lib/dracut/modules.d/99journal-conf and enable logging to kmsg to unit level configuration. Related to: https://github.com/coreos/fedora-coreos-tracker/issues/1582 --- .../00-journal-log-level-kmsg.conf | 4 +++ .../99ignition-log-kmsg/10-stdout-kmsg.conf | 4 +++ .../99ignition-log-kmsg/module-setup.sh | 28 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 dracut/modules.d/99ignition-log-kmsg/00-journal-log-level-kmsg.conf create mode 100644 dracut/modules.d/99ignition-log-kmsg/10-stdout-kmsg.conf create mode 100644 dracut/modules.d/99ignition-log-kmsg/module-setup.sh diff --git a/dracut/modules.d/99ignition-log-kmsg/00-journal-log-level-kmsg.conf b/dracut/modules.d/99ignition-log-kmsg/00-journal-log-level-kmsg.conf new file mode 100644 index 0000000000..a09cc0c276 --- /dev/null +++ b/dracut/modules.d/99ignition-log-kmsg/00-journal-log-level-kmsg.conf @@ -0,0 +1,4 @@ +# The default MaxLevelKMsg is 'notice'. +# Set it to 'info' to see all Ignition logs in the kernel log. +[Journal] +MaxLevelKMsg=info diff --git a/dracut/modules.d/99ignition-log-kmsg/10-stdout-kmsg.conf b/dracut/modules.d/99ignition-log-kmsg/10-stdout-kmsg.conf new file mode 100644 index 0000000000..1924c0c2b7 --- /dev/null +++ b/dracut/modules.d/99ignition-log-kmsg/10-stdout-kmsg.conf @@ -0,0 +1,4 @@ +# Redirect all ignition logs to kmsg. +[Service] +StandardOutput=kmsg +StandardError=kmsg diff --git a/dracut/modules.d/99ignition-log-kmsg/module-setup.sh b/dracut/modules.d/99ignition-log-kmsg/module-setup.sh new file mode 100644 index 0000000000..bafbdad103 --- /dev/null +++ b/dracut/modules.d/99ignition-log-kmsg/module-setup.sh @@ -0,0 +1,28 @@ +#!/bin/bash +# Installs systemd drop-ins so Ignition dracut units log to kmsg. + +install() { + services=( + ignition-disks.service + ignition-enable-network.service + ignition-fetch-offline.service + ignition-fetch.service + ignition-files.service + ignition-kargs.service + ignition-mount.service + ignition-ostree-mount-var.service + ignition-ostree-populate-var.service + ignition-ostree-transposefs-detect.service + ignition-ostree-transposefs-restore.service + ignition-ostree-transposefs-save.service + ignition-remount-sysroot.service + ) + for u in "${services[@]}"; do + inst_dir "$systemdsystemunitdir/${u}.d" + inst_simple "$moddir/10-stdout-kmsg.conf" \ + "$systemdsystemunitdir/${u}.d/10-stdout-kmsg.conf" + done + + inst_simple "$moddir/00-journal-log-level-kmsg.conf" \ + "/etc/systemd/journald.conf.d/00-journal-log-level-kmsg.conf" +} From 62af63decdde3723275e69a78bf76cc7668340ea Mon Sep 17 00:00:00 2001 From: Bipin B Narayan Date: Mon, 4 May 2026 17:14:28 +0530 Subject: [PATCH 7/7] Makefile: Rename flag to install integration dracut modules, units and scripts --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index b159e55443..685a6c86f8 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ export GO111MODULE=on -INSTALL_ALL_DRACUT_MODULES=0 +WITH_INTEGRATION ?= 0 # Canonical version of this in https://github.com/coreos/coreos-assembler/blob/6eb97016f4dab7d13aa00ae10846f26c1cd1cb02/Makefile#L19 GOARCH:=$(shell uname -m) @@ -45,7 +45,7 @@ butane-cross: .PHONY: install install: - if [ $(INSTALL_ALL_DRACUT_MODULES) -eq 1 ]; then \ + if [ $(WITH_INTEGRATION) -eq 1 ]; then \ for x in dracut/modules.d/*; do \ bn=$$(basename $$x); \ install -m 0644 -D -t $(DESTDIR)/usr/lib/dracut/modules.d/$${bn} $$x/*; \