From e86958612b6ff3260b73348d22101ebf2c939895 Mon Sep 17 00:00:00 2001 From: Dusty Mabe Date: Tue, 14 Apr 2020 15:44:24 -0400 Subject: [PATCH] overlay: add 15coreos-copy-firstboot-network dracut module This dracut module delivers a coreos-copy-firstboot-network systemd service and script that will detect when files have been placed into /boot/ by `coreos-installer install --copy-network` and appropriately copy them in place to be used by the initramfs networking. If files are detected within /boot/coreos-firstboot-network/ then they will be considered to be the only source of networking for that ignition boot (i.e. no networking kargs will be applied). --- .../coreos-copy-firstboot-network.service | 45 +++++++++++++++++++ .../coreos-copy-firstboot-network.sh | 28 ++++++++++++ .../module-setup.sh | 16 +++++++ 3 files changed, 89 insertions(+) create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/coreos-copy-firstboot-network.service create mode 100755 overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/coreos-copy-firstboot-network.sh create mode 100644 overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/module-setup.sh diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/coreos-copy-firstboot-network.service b/overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/coreos-copy-firstboot-network.service new file mode 100644 index 0000000000..af23ec7a96 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/coreos-copy-firstboot-network.service @@ -0,0 +1,45 @@ +# This unit will run early in boot and detect if the user copied +# in firstboot networking config files into the installed system +# (most likely by using `coreos-installer install --copy-network`. +# Since this unit is modifying network configuration there are some +# dependencies that we have: +# +# - Need to look for networking configuration on the /boot partition +# - i.e. after /dev/disk/by-label/boot is available +# - Need to run before networking is brought up. +# - This is done in nm-run.sh [1] that runs as part of dracut-initqueue [2] +# - i.e. Before=dracut-initqueue.service +# - Need to make sure karg networking configuration isn't applied +# - There are two ways to do this. +# - One is to run *before* the nm-config.sh [3] that runs as part of +# dracut-cmdline [4] and `ln -sf /bin/true /usr/libexec/nm-initrd-generator`. +# - i.e. Before=dracut-cmdline.service +# - Another is to run *after* nm-config.sh [3] in dracut-cmdline [4] +# and just delete all the files created by nm-initrd-generator. +# - i.e. After=dracut-cmdline.service, but Before=dracut-initqueue.service +# - We'll go with the second option here because the need for the /boot +# device (mentioned above) means we can't start before dracut-cmdline.service +# +# [1] https://github.com/dracutdevs/dracut/blob/master/modules.d/35network-manager/nm-run.sh +# [2] https://github.com/dracutdevs/dracut/blob/master/modules.d/35network-manager/module-setup.sh#L37 +# [3] https://github.com/dracutdevs/dracut/blob/master/modules.d/35network-manager/nm-config.sh +# [4] https://github.com/dracutdevs/dracut/blob/master/modules.d/35network-manager/module-setup.sh#L36 +# +[Unit] +Description=Copy CoreOS Firstboot Networking Config +ConditionPathExists=/usr/lib/initrd-release +DefaultDependencies=false +Before=ignition-diskful.target +Before=dracut-initqueue.service +After=dracut-cmdline.service +# Since we are mounting /boot/, require the device first +Requires=dev-disk-by\x2dlabel-boot.device +After=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/coreos-copy-firstboot-network diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/coreos-copy-firstboot-network.sh b/overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/coreos-copy-firstboot-network.sh new file mode 100755 index 0000000000..9ae960c9a9 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/coreos-copy-firstboot-network.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -euo pipefail + +# For a description of how this is used see coreos-copy-firstboot-network.service + +bootmnt=/mnt/boot_partition +firstboot_network_dir="${bootmnt}/coreos-firstboot-network/" +initramfs_network_dir="/run/NetworkManager/system-connections/" + +# Mount /boot. Note that we mount /boot but we don't unmount boot because we +# are run in a systemd unit with MountFlags=slave so it is unmounted for us. +mkdir -p $bootmnt +# mount as read-only since we don't strictly need write access and we may be +# running alongside other code that also has it mounted ro +mount -o ro /dev/disk/by-label/boot $bootmnt + +if [ -n "$(ls -A ${firstboot_network_dir} 2>/dev/null)" ]; then + # Clear out any files that may have already been generated from + # kargs by nm-initrd-generator + rm -f ${initramfs_network_dir}/* + # Copy files that were placed into boot (most likely by coreos-installer) + # to the appropriate location for NetworkManager to use the configuration. + echo "info: copying files from ${firstboot_network_dir} to ${initramfs_network_dir}" + mkdir -p ${initramfs_network_dir} + cp -v ${firstboot_network_dir}/* ${initramfs_network_dir}/ +else + echo "info: no files to copy from ${firstboot_network_dir}. skipping" +fi diff --git a/overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/module-setup.sh b/overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/module-setup.sh new file mode 100644 index 0000000000..0933554144 --- /dev/null +++ b/overlay.d/05core/usr/lib/dracut/modules.d/15coreos-copy-firstboot-network/module-setup.sh @@ -0,0 +1,16 @@ +install_and_enable_unit() { + unit="$1"; shift + target="$1"; shift + inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit" + mkdir -p "$initdir/$systemdsystemunitdir/$target.requires" + ln_r "../$unit" "$systemdsystemunitdir/$target.requires/$unit" +} + +install() { + inst_simple "$moddir/coreos-copy-firstboot-network.sh" \ + "/usr/sbin/coreos-copy-firstboot-network" + # Only run this when ignition runs and only when the system + # has disks. ignition-diskful.target should suffice. + install_and_enable_unit "coreos-copy-firstboot-network.service" \ + "ignition-diskful.target" +}