diff --git a/dracut/03flatcar-network/afterburn-network-kargs.service b/dracut/03flatcar-network/afterburn-network-kargs.service index 9eb9a71..595e831 100644 --- a/dracut/03flatcar-network/afterburn-network-kargs.service +++ b/dracut/03flatcar-network/afterburn-network-kargs.service @@ -5,7 +5,7 @@ Documentation=https://coreos.github.io/afterburn/usage/initrd-network-cmdline/ # This service may produce additional kargs fragments, # which are then consumed by dracut-cmdline(8). DefaultDependencies=no -Before=dracut-cmdline.service systemd-networkd.service +Before=parse-ip-for-networkd.service systemd-networkd.service PartOf=systemd-networkd.service # For extra safety ConditionKernelCommandLine=|coreos.oem.id=vmware @@ -13,6 +13,10 @@ ConditionKernelCommandLine=|flatcar.oem.id=vmware OnFailure=emergency.target OnFailureJobMode=isolate +# Flatcar: Load coreos-metadata binary +Requires=sysusr-usr.mount +After=sysusr-usr.mount + [Service] ExecStart=/usr/bin/coreos-metadata exp rd-network-kargs --cmdline --default-value '' Type=oneshot diff --git a/dracut/03flatcar-network/module-setup.sh b/dracut/03flatcar-network/module-setup.sh index baeb929..5649166 100755 --- a/dracut/03flatcar-network/module-setup.sh +++ b/dracut/03flatcar-network/module-setup.sh @@ -10,8 +10,6 @@ depends() { # called by dracut install() { - inst_multiple coreos-metadata - inst_multiple -o \ $systemdutildir/systemd-resolved \ $systemdsystemunitdir/systemd-resolved.service \ @@ -20,6 +18,9 @@ install() { inst_simple "$moddir/network-cleanup.service" \ "$systemdsystemunitdir/network-cleanup.service" + inst_simple "$moddir/parse-ip-for-networkd.service" \ + "$systemdsystemunitdir/parse-ip-for-networkd.service" + inst_simple "$moddir/afterburn-network-kargs.service" \ "$systemdsystemunitdir/afterburn-network-kargs.service" @@ -61,5 +62,6 @@ install() { systemctl --root "$initdir" disable systemd-networkd.socket systemctl --root "$initdir" enable network-cleanup.service + systemctl --root "$initdir" enable parse-ip-for-networkd.service systemctl --root "$initdir" enable afterburn-network-kargs.service } diff --git a/dracut/03flatcar-network/parse-ip-for-networkd.service b/dracut/03flatcar-network/parse-ip-for-networkd.service new file mode 100644 index 0000000..bebf18c --- /dev/null +++ b/dracut/03flatcar-network/parse-ip-for-networkd.service @@ -0,0 +1,18 @@ +[Unit] +Description=Write systemd-networkd units from cmdline +DefaultDependencies=false + +After=afterburn-network-kargs.service +PartOf=systemd-networkd.service +Before=systemd-networkd.service initrd-switch-root.target +# Switching the root filesystem terminates all running services with binaries from the initramfs, we need to finish before that happens +Conflicts=initrd-switch-root.target + +[Service] +Type=oneshot +RemainAfterExit=true +Environment="APPLY=1" +ExecStart=/lib/dracut/hooks/cmdline/99-parse-ip-for-networkd.sh + +[Install] +WantedBy=systemd-networkd.service diff --git a/dracut/03flatcar-network/parse-ip-for-networkd.sh b/dracut/03flatcar-network/parse-ip-for-networkd.sh old mode 100644 new mode 100755 index b94ca79..6bb015e --- a/dracut/03flatcar-network/parse-ip-for-networkd.sh +++ b/dracut/03flatcar-network/parse-ip-for-networkd.sh @@ -1,17 +1,59 @@ -#!/bin/sh +#!/bin/bash # # This script was mostly stolen from 40network/parse-ip-opts.sh. Its # actions are adapted to write .network files to /etc/systemd/network # in the initramfs instead of using separate DHCP commands, etc. Note -# the bashisms. +# the bashisms. It used to be run as a dracut hook, relying on afterburn to +# process kargs for the dracut cmdline target. Now that we start afterburn +# from /sysusr instead of ramdisk root, we need to mount /sysusr first. Mounting +# happens later than the dracut hook we used. Thus we added a systemd unit for +# this script. The unit runs shortly before systemd-networkd. +# However, since the "netroot" variable is set up by another dracut +# hook, this script here will still get executed once as dracut hook +# to save the "netroot" variable to an env file and exit. +# Could the script instead be a hook at a later stage? There doesn't +# seem to be a suitable later stage and also then the env could be +# different. As long as we want to rely on dracut-lib/net-lib for +# parsing the env var topic is not easily avoided. # +if [ "${APPLY-}" != "1" ]; then + # First run, called as dracut hook + { + # While the script only makes use of the env vars "NEEDBOOTDEV" and "netroot" + # we actually don't really know what env vars dracut-lib.sh and net-lib.sh + # will depend on in future versions and therefore, we try to preserve the + # environment as is. + for VARNAME in $(compgen -v); do + # Prevent leaking HEREEOF into VAL ($_ is the argument of the prev. command, and in this loop contains HEREOF) + [ "${VARNAME}" = "_" ] && continue + # Skip unnecessary variables + [[ "${VARNAME}" = "BASH"* ]] && continue + # Skip errors from read-only variables + (unset "${VARNAME}" 2> /dev/null) || continue + VAL="${!VARNAME}" + echo "${VARNAME}=\$(cat <<'HEREEOF' +${VAL} +HEREEOF +)" + done + } > /saved-parse-ip.env + return; +else + # Second run, expected to be called as systemd unit + # Make it a hard error if we forgot to exclude some problematic variables and thus the sourcing terminates without setting all variables + . /saved-parse-ip.env || { echo "Error: failed sourcing all variables"; exit 1 ; } +fi + +# The getarg uses getcmdline which assembles the cmdline on-the-fly +# from /proc/cmdline and the drop-in files under /etc/cmdline.d/ +# where afterburn could have written the kargs values command -v getarg >/dev/null || . /lib/dracut-lib.sh command -v ip_to_var >/dev/null || . /lib/net-lib.sh if [ -n "$netroot" ] && [ -z "$(getarg ip=)" ] && [ -z "$(getarg BOOTIF=)" ]; then # No ip= argument(s) for netroot provided, defaulting to DHCP - return; + exit 0 fi function mask2cidr() { @@ -30,6 +72,9 @@ function mask2cidr() { # XXX Would be nice if we could errorcheck ip addresses here as well for p in $(getargs ip=); do ip_to_var $p + # From here on the variables "ip", "mask" etc are set up (or are cleared) + # from 'unset ip srv gw mask hostname dev autoconf macaddr mtu dns1 dns2' in ip_to_var + # ("cidr" is defined below) # Empty autoconf defaults to 'dhcp' if [ -z "$autoconf" ] ; then @@ -89,3 +134,5 @@ for p in $(getargs ip=); do echo '[DHCP]' >> $_net_file [ -n "$hostname" ] && echo "Hostname=$hostname" >> $_net_file done +# Have a clear exit code instead of propagating the one from [ -n "$hostname" ] +exit 0 diff --git a/dracut/10diskless-generator/diskless-generator b/dracut/10diskless-generator/diskless-generator index ca997a3..e5daea9 100755 --- a/dracut/10diskless-generator/diskless-generator +++ b/dracut/10diskless-generator/diskless-generator @@ -52,6 +52,22 @@ After=systemd-tmpfiles-setup-dev.service What=/usr.squashfs Where=/sysroot/usr Type=squashfs +EOF + mkdir -p /sysusr/usr + cat >"${UNIT_DIR}/sysusr-usr.mount" < /run/systemd/system/systemd-fsck-usr.service <"${UNIT_DIR}/sysroot-usr.mount.d/10-norecovery.conf" <"${UNIT_DIR}/sysusr-usr.mount.d/10-norecovery.conf" <"${UNIT_DIR}/sysusr-usr.mount" < ${UNIT_DIR}/ignition-setup.service <