Skip to content
This repository has been archived by the owner on Aug 25, 2021. It is now read-only.

Commit

Permalink
Enforce that Ignition run once even if interrupted
Browse files Browse the repository at this point in the history
I have seen in practice us trying to run Ignition multiple times
if the system is forcibly rebooted before we run the firstboot
complete service, which actually today runs in the real rootfs.

Forcibly prevent this by adding a few tiny new shell scripts
which write a state file to `/boot/ignition.state`.  The first
to run is `ignition-prelaunch.service` which runs even before
`fetch` and bombs out directly if we detect the stamp file
exists.

Next, we have a service which writes the stamp file after `fetch`
and before `disks`.  Finally, another service updates the stamp
file just to signal `complete`.

Note none of these services run on live systems, as there's
no `/boot` there, and Ignition runs every boot anyways.
  • Loading branch information
cgwalters committed Mar 24, 2020
1 parent 16bd0c4 commit 7fcbe24
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 1 deletion.
15 changes: 15 additions & 0 deletions dracut/30ignition/ignition-finished.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[Unit]
Description=Ignition (log completion)
DefaultDependencies=false
Before=ignition-complete.target
After=basic.target

After=ignition-files.service

[Service]
Type=oneshot
RemainAfterExit=yes
MountFlags=slave
TemporaryFileSystem=/run/boot
# Flag completion of Ignition, so that we can immediately error out if we detect we started
ExecStart=/bin/sh -c 'mount /dev/disk/by-label/boot /run/boot && echo completed > /run/boot/ignition.state'
5 changes: 5 additions & 0 deletions dracut/30ignition/ignition-generator
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ if $(cmdline_bool 'ignition.firstboot' 0); then
Requires=dev-disk-by\x2dlabel-boot.device
After=dev-disk-by\x2dlabel-boot.device
EOF

# And these units write to /boot too
for unit in prelaunch started finished; do
add_requires ignition-${unit}.service ignition-complete.target
done
fi
else
# If we're doing a non-Ignition (subsequent) boot, then
Expand Down
19 changes: 19 additions & 0 deletions dracut/30ignition/ignition-prelaunch.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[Unit]
Description=Ignition (validate first run)
DefaultDependencies=false
Before=ignition-complete.target
After=basic.target

Before=ignition-fetch.service

Requires=dev-disk-by\x2dlabel-boot.device
After=dev-disk-by\x2dlabel-boot.device

[Service]
Type=oneshot
RemainAfterExit=yes
MountFlags=slave
TemporaryFileSystem=/run/boot
# Flag completion of Ignition, so that we can immediately error out if we detect we started
ExecStart=/bin/sh -c 'mount -o ro /dev/disk/by-label/boot /run/boot && if [ -f /run/boot/ignition.state ]; then echo -n "Detected previous run of Ignition:" $(cat /run/boot/ignition.state); exit 1; fi'

18 changes: 18 additions & 0 deletions dracut/30ignition/ignition-started.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[Unit]
Description=Ignition (log initiation)
DefaultDependencies=false
Before=ignition-complete.target
After=basic.target

# Run after ignition-setup has run because ignition-setup
# may copy in new/different ignition configs for us to consume.
After=ignition-fetch.service
Before=ignition-disks.service

[Service]
Type=oneshot
RemainAfterExit=yes
MountFlags=slave
TemporaryFileSystem=/run/boot
# Flag initiation of Ignition, so that we can immediately error out if we detect we started
ExecStart=/bin/sh -c 'mount /dev/disk/by-label/boot /run/boot && echo started > /run/boot/ignition.state'
3 changes: 2 additions & 1 deletion dracut/30ignition/module-setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ install() {
inst_simple "$moddir/ignition-generator" \
"$systemdutildir/system-generators/ignition-generator"

for x in "complete" "subsequent" "diskful" "diskful-subsequent"; do
for x in "complete" "subsequent" "diskful" "diskful-subsequent"
"prelaunch" "started" "finished"; do
inst_simple "$moddir/ignition-$x.target" \
"$systemdsystemunitdir/ignition-$x.target"
done
Expand Down

0 comments on commit 7fcbe24

Please sign in to comment.