From 12a492e5a7fa03141af373809d63daae7da890ae Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 24 Sep 2019 21:08:38 +0000 Subject: [PATCH] dracut: Add 31ignition-ostree module I'm working on supporting reprovisioning the rootfs with Ignition on OSTree based systems like Fedora CoreOS, and this will add a lot of tricky logic that relates the two. While we want to support Ignition independent of OSTree and vice versa, it will be a lot cleaner if we centralize the dracut logic in one place. This adds a `31ignition-ostree` module that imports the code from https://github.com/coreos/fedora-coreos-config/tree/092f680a5c75324e3efcd5e50374a2c1b5d4b057/overlay.d/05core/usr/lib/dracut/modules.d/40coreos-var Most notably, this is: 1) A separate dracut module easily skippable 2) The units use `ConditionKernelCommandline=ostree` so will be harmless even if included The units imported here also do this: ``` ConditionPathExists=!/usr/sbin/coreos-mount-var ``` So this change can be safely merged, built and shipped as an RPM, then we can drop the FCOS config bits and enable it later. Tested both ways (inert and enabled). And to clarify, the later ignition-ostree-rootfs stuff will land in this same dracut module. --- .../ignition-ostree-mount-var.service | 29 +++++++++++ .../ignition-ostree-mount-var.sh | 52 +++++++++++++++++++ .../ignition-ostree-populate-var.service | 18 +++++++ .../ignition-ostree-populate-var.sh | 49 +++++++++++++++++ dracut/31ignition-ostree/module-setup.sh | 29 +++++++++++ 5 files changed, 177 insertions(+) create mode 100644 dracut/31ignition-ostree/ignition-ostree-mount-var.service create mode 100755 dracut/31ignition-ostree/ignition-ostree-mount-var.sh create mode 100644 dracut/31ignition-ostree/ignition-ostree-populate-var.service create mode 100755 dracut/31ignition-ostree/ignition-ostree-populate-var.sh create mode 100755 dracut/31ignition-ostree/module-setup.sh diff --git a/dracut/31ignition-ostree/ignition-ostree-mount-var.service b/dracut/31ignition-ostree/ignition-ostree-mount-var.service new file mode 100644 index 0000000..4b6a667 --- /dev/null +++ b/dracut/31ignition-ostree/ignition-ostree-mount-var.service @@ -0,0 +1,29 @@ +[Unit] +Description=Ignition OSTree: Mount /var +DefaultDependencies=false +ConditionKernelCommandLine=ostree +ConditionPathExists=!/run/ostree-live +# To enable version skew, don't run this unit if the copy in +# fedora-coreos-config still exists. +ConditionPathExists=!/usr/sbin/coreos-mount-var + +# 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/31ignition-ostree/ignition-ostree-mount-var.sh b/dracut/31ignition-ostree/ignition-ostree-mount-var.sh new file mode 100755 index 0000000..885598e --- /dev/null +++ b/dracut/31ignition-ostree/ignition-ostree-mount-var.sh @@ -0,0 +1,52 @@ +#!/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" + mount --bind "$stateroot_var_path" /sysroot/var +} + +do_umount() { + echo "Unmounting /sysroot/var" + umount /sysroot/var +} + +"do_$1" diff --git a/dracut/31ignition-ostree/ignition-ostree-populate-var.service b/dracut/31ignition-ostree/ignition-ostree-populate-var.service new file mode 100644 index 0000000..43e997f --- /dev/null +++ b/dracut/31ignition-ostree/ignition-ostree-populate-var.service @@ -0,0 +1,18 @@ +[Unit] +Description=Ignition OSTree: Populate /var +ConditionKernelCommandLine=ostree +DefaultDependencies=false +# To enable version skew, don't run this unit if the copy in +# fedora-coreos-config still exists. +ConditionPathExists=!/usr/sbin/coreos-mount-var + +# 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/31ignition-ostree/ignition-ostree-populate-var.sh b/dracut/31ignition-ostree/ignition-ostree-populate-var.sh new file mode 100755 index 0000000..d719b10 --- /dev/null +++ b/dracut/31ignition-ostree/ignition-ostree-populate-var.sh @@ -0,0 +1,49 @@ +#!/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 + +# 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/lib /sysroot/var/log + +systemd-tmpfiles --create --boot --root=/sysroot \ + --prefix=/var/home \ + --prefix=/var/roothome \ + --prefix=/var/opt \ + --prefix=/var/srv \ + --prefix=/var/usrlocal \ + --prefix=/var/mnt \ + --prefix=/var/media + +# Ask for /var to be relabeled. +# See also: https://github.com/coreos/ignition/issues/635. +mkdir -p /run/tmpfiles.d +echo "Z /var - - -" > /run/tmpfiles.d/var-relabel.conf + +# XXX: https://github.com/systemd/systemd/pull/11903 +for unit in systemd-{journal-catalog-update,random-seed}.service; do + mkdir -p /run/systemd/system/${unit}.d + cat > /run/systemd/system/${unit}.d/after-tmpfiles.conf <