diff --git a/dracut/30ignition/ignition-complete.target b/dracut/30ignition/ignition-complete.target new file mode 100644 index 0000000..7c447a4 --- /dev/null +++ b/dracut/30ignition/ignition-complete.target @@ -0,0 +1,19 @@ +# This target is reached when Ignition finishes running. Note that it gets +# activated *only* on first boot (or if ignition.firstboot=1 is provided). +# Thus, it is also an API for units to use so that they are activated only on +# first boot. Simply add a link under ignition-complete.target.requires in the +# initrd. +[Unit] +Description=Ignition Complete +Before=initrd.target + +# initrd.target has OnFailureJobMode=replace-irreversibly, which seems to +# cause unit restart loops in the initramfs if one of our units fails. Thus +# we intercept Ignition unit failures here and isolate to emergency.target. +# https://github.com/coreos/ignition-dracut/issues/115 +OnFailure=emergency.target +OnFailureJobMode=isolate + +# 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 diff --git a/dracut/30ignition/ignition-generator b/dracut/30ignition/ignition-generator index 7033e96..897bfd1 100755 --- a/dracut/30ignition/ignition-generator +++ b/dracut/30ignition/ignition-generator @@ -27,7 +27,8 @@ cmdline_bool() { add_requires() { local name="$1"; shift - local requires_dir="${UNIT_DIR}/initrd.target.requires" + local target="$1"; shift + local requires_dir="${UNIT_DIR}/${target}.requires" mkdir -p "${requires_dir}" ln -sf "../${name}" "${requires_dir}/${name}" } @@ -36,11 +37,11 @@ add_requires() { # starts the unit's dependencies. We want to start networkd only on first # boot. if $(cmdline_bool 'ignition.firstboot' 0); then - add_requires ignition-fetch.service - add_requires ignition-disks.service - add_requires ignition-files.service - add_requires ignition-ask-var-mount.service - add_requires coreos-teardown-initramfs-network.service + add_requires ignition-complete.target initrd.target + for svc in fetch disks files mount ask-var-mount; do + add_requires ignition-${svc}.service initrd.target + done + add_requires coreos-teardown-initramfs-network.service initrd.target #if [[ $(cmdline_arg coreos.oem.id) == "packet" ]]; then # add_requires coreos-static-network.service #fi @@ -56,6 +57,12 @@ if $(cmdline_bool 'ignition.firstboot' 0); then #Conflicts=dracut-emergency.service #EOF #fi +else + # If we're doing a non-Ignition (subsequent) boot, then + # queue a different target. This is necessary so that units + # like `ignition-ostree-mount-sysroot.service` + # can cleanly distinguish between the two. + add_requires ignition-subsequent.target initrd.target fi # Write ignition-setup.service customized for PXE/ISO or regular boot diff --git a/dracut/30ignition/ignition-mount.service b/dracut/30ignition/ignition-mount.service new file mode 100644 index 0000000..92ab9ec --- /dev/null +++ b/dracut/30ignition/ignition-mount.service @@ -0,0 +1,31 @@ +[Unit] +Description=Ignition (mount) [stub] +DefaultDependencies=false +Before=ignition-complete.target + +# This a copy of ignition-mount.service from master, but it does +# nothing right now. We just keep the dependencies to ensure +# other services are ordered correctly. + +# 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 the final /sysroot is ready first, since we're mounting under there +Requires=initrd-root-fs.target +After=initrd-root-fs.target + +# Make sure root filesystem is remounted read-write if needed +After=ignition-remount-sysroot.service + +# This is guaranteed through After=initrd-root-fs.target but just to +# be explicit. +After=ignition-disks.service + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/true \ No newline at end of file diff --git a/dracut/30ignition/ignition-subsequent.target b/dracut/30ignition/ignition-subsequent.target new file mode 100644 index 0000000..0282336 --- /dev/null +++ b/dracut/30ignition/ignition-subsequent.target @@ -0,0 +1,14 @@ +# This target is queued to run when Ignition will *not* run. +# It's intended right now for mounting sysroot, which happens in a quite +# different order on the Ignition boot versus "subsequent" boots. +[Unit] +Description=Subsequent (Not Ignition) boot complete +Before=initrd.target + +# See comments in ignition-complete.target +OnFailure=emergency.target +OnFailureJobMode=isolate + +# 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 diff --git a/dracut/30ignition/module-setup.sh b/dracut/30ignition/module-setup.sh index 3ed68d5..4de1937 100755 --- a/dracut/30ignition/module-setup.sh +++ b/dracut/30ignition/module-setup.sh @@ -51,6 +51,9 @@ install() { inst_simple "$moddir/ignition-files.service" \ "$systemdsystemunitdir/ignition-files.service" + inst_simple "$moddir/ignition-mount.service" \ + "$systemdsystemunitdir/ignition-mount.service" + inst_simple "$moddir/ignition-ask-var-mount.service" \ "$systemdsystemunitdir/ignition-ask-var-mount.service" @@ -60,6 +63,11 @@ install() { inst_simple "$moddir/coreos-teardown-initramfs-network.service" \ "$systemdutildir/system/coreos-teardown-initramfs-network.service" + inst_simple "$moddir/ignition-complete.target" \ + "$systemdsystemunitdir/ignition-complete.target" + inst_simple "$moddir/ignition-subsequent.target" \ + "$systemdsystemunitdir/ignition-subsequent.target" + # inst_simple "$moddir/sysroot-boot.service" \ # "$systemdsystemunitdir/sysroot-boot.service"