Skip to content

Commit

Permalink
TRANSITIONAL COMMIT: adopt future dracut modules for Ignition
Browse files Browse the repository at this point in the history
This is to ease the transition of moving to Ignition v2.5.0; it is a
copy of dracut/30ignition from the forth-coming Ignition.

This commit should be removed with summary and extreme prejudicous once
Ignition v.2.5.0 lands.

HACK WARNING: since Ignition is packaged to
/usr/lib/dracut/modules.d/30ignition this includes a symlink to from
/usr/lib/dracut/modules.d/31ignition/ignition to the ../30ignition
location.

Signed-off-by: Ben Howard <ben.howard@redhat.com>
  • Loading branch information
Ben Howard committed Jul 23, 2020
1 parent c621598 commit ead5fce
Show file tree
Hide file tree
Showing 20 changed files with 492 additions and 0 deletions.
3 changes: 3 additions & 0 deletions manifests/ignition-and-ostree.yaml
Expand Up @@ -32,6 +32,9 @@ remove-from-packages:
# We don't want auto-generated mount units. See also
# https://github.com/systemd/systemd/issues/13099
- [systemd-udev, /usr/lib/systemd/system-generators/systemd-gpt-auto-generator]
# TRANSITIONAL: to support moving Ignition-Dracut into Ingition, remove the dracut modules
- [ignition, /usr/lib/dracut/modules.d/30ignition/module-setup.sh
/usr/lib/dracut/modules.d/99.*]

postprocess:
# Undo RPM scripts enabling units; we want the presets to be canonical
Expand Down
@@ -0,0 +1,8 @@
SUBSYSTEM!="block", GOTO="systemd_cryptsetup_end"

# This overrides systemd default behavior from 99-systemd.rules, which ignores unformatted crypto devices.
# https://github.com/systemd/systemd/commit/90e6abaea0cfd25093aae1ad862c5c909ae55829
# Ignition relies on unformatted crypto devices being discovered to trigger formatting
SUBSYSTEM=="block", ENV{DM_UUID}=="CRYPT-*", ENV{ID_PART_TABLE_TYPE}=="", ENV{ID_FS_USAGE}=="", ENV{SYSTEMD_READY}="1"

LABEL="systemd_cryptsetup_end"
@@ -0,0 +1,14 @@
# 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
Documentation=https://github.com/coreos/ignition
ConditionPathExists=/etc/initrd-release
Before=initrd.target

# 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
@@ -0,0 +1,12 @@
# This target is a combination of ignition-subsequent.target and
# ignition-diskful.target - units here should only run when we have a
# boot disk and *aren't* doing the first boot.
[Unit]
Description=Ignition Subsequent Boot Disk Setup
Documentation=https://github.com/coreos/ignition
ConditionPathExists=/etc/initrd-release
Before=ignition-subsequent.target

# 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
@@ -0,0 +1,12 @@
# This target contains Ignition units that should only run when we have a
# boot disk, i.e. when we're not running diskless from a live image in RAM.
# Like ignition-complete.target, it only runs on first boot.
[Unit]
Description=Ignition Boot Disk Setup
Documentation=https://github.com/coreos/ignition
ConditionPathExists=/etc/initrd-release
Before=ignition-complete.target

# 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
@@ -0,0 +1,35 @@
[Unit]
Description=Ignition (disks)
Documentation=https://github.com/coreos/ignition
ConditionPathExists=/etc/initrd-release
DefaultDependencies=false
Before=ignition-complete.target

# Stage order: setup -> fetch-offline [-> fetch] -> disks -> mount -> files.
After=ignition-fetch.service
Before=ignition-mount.service

# This stage runs between `basic.target` and `initrd-root-device.target`,
# see https://www.freedesktop.org/software/systemd/man/bootup.html
# Make sure to run before the file system checks, as sgdisk will trigger
# udev events, potentially resulting in race conditions due to disappearing
# devices.

# Note that CL runs this before `local-fs-pre.target` to allow for configs that
# completely wipe the rootfs. Though we're not there yet. But we still run
# before `sysroot.mount` on principle.
Before=initrd-root-device.target
Before=sysroot.mount

OnFailure=emergency.target
OnFailureJobMode=isolate

# This stage requires udevd to detect disk partitioning changes.
Requires=systemd-udevd.service
After=systemd-udevd.service

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/run/ignition.env
ExecStart=/usr/bin/ignition --root=/sysroot --platform=${PLATFORM_ID} --stage=disks
@@ -0,0 +1,28 @@
# This unit creates /run/ignition/neednet if networking needs to be enabled.
# The distro is responsible for sequencing a unit between
# ignition-fetch-offline.service and ignition-fetch.service, detecting the
# flag file with ConditionPathExists=, and enabling networking.

[Unit]
Description=Ignition (fetch-offline)
Documentation=https://github.com/coreos/ignition
ConditionPathExists=/etc/initrd-release
DefaultDependencies=false
Before=ignition-complete.target
After=basic.target

# Stage order: setup -> fetch-offline [-> fetch] -> disks -> mount -> files.
# We run after the setup stage has run because it may copy in new/different
# ignition configs for us to consume.
After=ignition-setup-base.service
After=ignition-setup-user.service
Before=ignition-fetch.service

OnFailure=emergency.target
OnFailureJobMode=isolate

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/run/ignition.env
ExecStart=/usr/bin/ignition --root=/sysroot --platform=${PLATFORM_ID} --stage=fetch-offline
@@ -0,0 +1,26 @@
[Unit]
Description=Ignition (fetch)
Documentation=https://github.com/coreos/ignition
ConditionPathExists=/etc/initrd-release
DefaultDependencies=false
Before=ignition-complete.target
After=basic.target
ConditionPathExists=/run/ignition/neednet

# Stage order: setup -> fetch-offline [-> fetch] -> disks -> mount -> files.
# We run after the setup stage has run because it may copy in new/different
# ignition configs for us to consume.
After=ignition-fetch-offline.service
Before=ignition-disks.service

OnFailure=emergency.target
OnFailureJobMode=isolate

# If we run, we definitely need network, so make sure we run after.
After=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/run/ignition.env
ExecStart=/usr/bin/ignition --root=/sysroot --platform=${PLATFORM_ID} --stage=fetch
@@ -0,0 +1,21 @@
[Unit]
Description=Ignition (files)
Documentation=https://github.com/coreos/ignition
ConditionPathExists=/etc/initrd-release
DefaultDependencies=false
Before=ignition-complete.target

OnFailure=emergency.target
OnFailureJobMode=isolate

# Stage order: setup -> fetch-offline [-> fetch] -> disks -> mount -> files.
After=ignition-mount.service

# Run before initrd-parse-etc so that we can drop files it then picks up.
Before=initrd-parse-etc.service

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/run/ignition.env
ExecStart=/usr/bin/ignition --root=/sysroot --platform=${PLATFORM_ID} --stage=files --log-to-stdout
@@ -0,0 +1,71 @@
#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh

set -e

# Generators don't have logging right now
# https://github.com/systemd/systemd/issues/15638
exec 1>/dev/kmsg; exec 2>&1

UNIT_DIR="${1:-/tmp}"

cmdline=( $(</proc/cmdline) )
cmdline_arg() {
local name="$1" value="$2"
for arg in "${cmdline[@]}"; do
if [[ "${arg%%=*}" == "${name}" ]]; then
value="${arg#*=}"
fi
done
echo "${value}"
}

cmdline_bool() {
local value=$(cmdline_arg "$@")
case "$value" in
""|0|no|off) return 1;;
*) return 0;;
esac
}

add_requires() {
local name="$1"; shift
local target="$1"; shift
local requires_dir="${UNIT_DIR}/${target}.requires"
mkdir -p "${requires_dir}"
ln -sf "../${name}" "${requires_dir}/${name}"
}

# This can't be done with ConditionKernelCommandLine because that always
# starts the unit's dependencies. We want to start networking only on first
# boot.
if $(cmdline_bool 'ignition.firstboot' 0); then
add_requires ignition-complete.target initrd.target

# Invoke distro hook for detecting whether we're booted from a live image,
# and therefore won't have a root disk.
if ! command -v is-live-image >/dev/null || ! is-live-image; then
add_requires ignition-diskful.target ignition-complete.target

# ignition-setup-user.service should depend on the boot device node
# only on diskful boots
mkdir -p "${UNIT_DIR}/ignition-setup-user.service.d"
cat > "${UNIT_DIR}/ignition-setup-user.service.d/diskful.conf" <<EOF
[Unit]
Requires=dev-disk-by\x2dlabel-boot.device
After=dev-disk-by\x2dlabel-boot.device
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
if ! command -v is-live-image >/dev/null || ! is-live-image; then
add_requires ignition-diskful-subsequent.target ignition-subsequent.target
fi
fi

echo "PLATFORM_ID=$(cmdline_arg ignition.platform.id)" > /run/ignition.env
@@ -0,0 +1,3 @@
# We don't ship cracklib dicts in the initramfs, so don't check
# generated clevis keys against them
dictcheck = 0
@@ -0,0 +1,33 @@
[Unit]
Description=Ignition (mount)
Documentation=https://github.com/coreos/ignition
ConditionPathExists=/etc/initrd-release
DefaultDependencies=false
Before=ignition-complete.target

# Stage order: setup -> fetch-offline [-> fetch] -> disks -> mount -> files.
# We need to make sure the partitions and filesystems are set up before
# mounting. This is also guaranteed through After=initrd-root-fs.target but
# just to be explicit.
After=ignition-disks.service
Before=ignition-files.service

# Make sure ExecStop= runs before we switch root
Before=initrd-switch-root.target

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

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/run/ignition.env
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
@@ -0,0 +1,20 @@
[Unit]
Description=Remount /sysroot read-write for Ignition
Documentation=https://github.com/coreos/ignition
ConditionPathExists=/etc/initrd-release
# Some Linux Distributions don't pass a rw option on the kernel
# commandline and thus mount the root filesystem ro by default. In
# this case, remount /sysroot to rw (issue #37)
DefaultDependencies=no
Before=ignition-diskful.target

OnFailure=emergency.target
OnFailureJobMode=isolate

After=sysroot.mount
ConditionPathIsReadWrite=!/sysroot

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/mount -o remount,rw /sysroot
@@ -0,0 +1,18 @@
[Unit]
Description=Ignition (setup base config)
Documentation=https://github.com/coreos/ignition
ConditionPathExists=/etc/initrd-release
DefaultDependencies=false
Before=ignition-complete.target

OnFailure=emergency.target
OnFailureJobMode=isolate

# Stage order: setup -> fetch-offline [-> fetch] -> disks -> mount -> files.
Before=ignition-fetch-offline.service

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/run/ignition.env
ExecStart=/usr/sbin/ignition-setup-base
@@ -0,0 +1,19 @@
#!/bin/bash
set -euo pipefail

copy_file_if_exists() {
src="${1}"; dst="${2}"
if [ -f "${src}" ]; then
echo "Copying ${src} to ${dst}"
cp "${src}" "${dst}"
else
echo "File ${src} does not exist.. Skipping copy"
fi
}

destination=/usr/lib/ignition
mkdir -p $destination

# We will support grabbing a platform specific base.ign config
# from the initrd at /usr/lib/ignition/platform/${PLATFORM_ID}/base.ign
copy_file_if_exists "/usr/lib/ignition/platform/${PLATFORM_ID}/base.ign" "${destination}/base.ign"
@@ -0,0 +1,27 @@
[Unit]
Description=Ignition (setup user config)
Documentation=https://github.com/coreos/ignition
ConditionPathExists=/etc/initrd-release
DefaultDependencies=false
Before=ignition-complete.target

OnFailure=emergency.target
OnFailureJobMode=isolate

# Stage order: setup -> fetch-offline [-> fetch] -> disks -> mount -> files.
Before=ignition-fetch-offline.service

# We want to make sure we're not racing with multipath taking ownership of the
# boot device.
Before=multipathd.service

# On diskful boots, ignition-generator adds Requires/After on
# dev-disk-by\x2dlabel-boot.device

[Service]
Type=oneshot
RemainAfterExit=yes
# The MountFlags=slave is so the umount of /boot is guaranteed to happen
# /boot will only be mounted for the lifetime of the unit.
MountFlags=slave
ExecStart=/usr/sbin/ignition-setup-user

0 comments on commit ead5fce

Please sign in to comment.