diff --git a/README b/README index 0decccc..61eec9d 100644 --- a/README +++ b/README @@ -29,6 +29,7 @@ mount /dev/sdX /mnt mkdir -p /mnt/combustion/ cat >/mnt/combustion/script </mnt/combustion/welcome umount /mnt ``` +The "# combustion: network" comment indicates that network needs to be +configured before running the script. + You can do everything necessary for initial system configuration from this script, including addition of ssh keys, adding users, changing passwords or even doing partitioning changes. @@ -50,13 +54,18 @@ kernel commandline. If this option is found on the kernel cmdline, combustion.service's ConditionKernelCommandLine is fulfilled and it'll be required by initrd.target. -It is started after /sysroot is mounted and network is up (if enabled). This -service tries to activate all mountpoints in the system's /etc/fstab and then -calls transactional-update chrooted. +This pulls in combustion-prepare.service, which runs after the config drive +with LABEL=ignition appears. It is mounted and if the "network" flag comment is +present, enables networking for later. After /sysroot is mounted and network is +up (if enabled), combustion.service runs, which tries to activate all +mountpoints in the system's /etc/fstab and then calls transactional-update +in a chroot. In this transactional-update session the script is started and the exit code recorded. If the script failed, transactional-update rollback is called and -combustion.service marked as failed. +combustion.service marked as failed, which causes booting to fail. Note that a +missing config drive or script is not considered a fatal error and only results +in a warning. /sysroot is unmounted and mounted again, so that the default subvolume gets reevaluated and directly booted into. diff --git a/combustion b/combustion index 0972781..cde00ae 100644 --- a/combustion +++ b/combustion @@ -3,7 +3,39 @@ # SPDX-License-Identifier: GPL-2.0-only set -euo pipefail -config_mount="/mnt/combustion" +config_mount="/run/combustion/mount" + +if [ "${1-}" = "--prepare" ]; then + # Mount config drive + mkdir -p "${config_mount}" + + if ! [ -e /dev/disk/by-label/ignition ]; then + echo "No config drive found" + exit 0 + fi + + if ! mount -o ro /dev/disk/by-label/ignition "${config_mount}"; then + echo "Failed to mount config drive!" + exit 1 + fi + + # Check for the magic flag "# combustion: network" in the script + if [ -e "${config_mount}/combustion/script" ] \ + && grep -qE '^# combustion:(.*)\' "${config_mount}/combustion/script"; then + sh -s < /etc/cmdline.d/40-combustion-neednet.conf + # Re-trigger generation of network rules and apply them + . /lib/dracut/hooks/pre-udev/60-net-genrules.sh + udevadm control --reload + udevadm trigger --subsystem-match net --action add +EOF + fi + + exit 0 +fi + # Use /dev/shm for data exchange exchangedir="/dev/shm/combustion/" delete_resolv_conf=0 @@ -27,13 +59,6 @@ cleanup() { trap cleanup EXIT -# Mount config drive -mkdir -p "${config_mount}" -if ! mount -o ro /dev/disk/by-label/ignition "${config_mount}"; then - echo "Failed to mount config drive!" - exit 1 -fi - if ! [ -d "${config_mount}/combustion" ]; then echo "No config found - doing nothing." exit 0 diff --git a/combustion-prepare.service b/combustion-prepare.service new file mode 100644 index 0000000..4bf524c --- /dev/null +++ b/combustion-prepare.service @@ -0,0 +1,23 @@ +[Unit] +Description=Combustion (preparations) +DefaultDependencies=false + +ConditionKernelCommandLine=ignition.firstboot + +# Config drive has to be available +Wants=dev-disk-by\x2dlabel-ignition.device +After=dev-disk-by\x2dlabel-ignition.device + +# This reconfigures networking, which runs during the initqueue +Before=dracut-initqueue.service + +Conflicts=initrd-switch-root.target umount.target +Conflicts=dracut-emergency.service emergency.service emergency.target + +# Without this it goes into an endless loop on failure +OnFailure=emergency.target +OnFailureJobMode=isolate + +[Service] +Type=oneshot +ExecStart=/usr/bin/combustion --prepare diff --git a/combustion.changes b/combustion.changes index 2a6da21..4a48e2f 100644 --- a/combustion.changes +++ b/combustion.changes @@ -1,3 +1,14 @@ +------------------------------------------------------------------- +Fri Sep 4 14:27:17 UTC 2020 - Fabian Vogt + +- Add combustion-prepare.service to enable network if needed: + M combustion + A combustion-prepare.service + M combustion.service + M module-setup.sh +- Don't fail if no config drive found to not break ignition with + fw_cfg + ------------------------------------------------------------------- Fri Jul 17 12:25:25 UTC 2020 - Fabian Vogt diff --git a/combustion.service b/combustion.service index 79f856e..c0f3e9f 100644 --- a/combustion.service +++ b/combustion.service @@ -7,13 +7,13 @@ ConditionKernelCommandLine=ignition.firstboot Requires=sysroot.mount After=sysroot.mount +# combustion-prepare sets up network, if required +Requires=combustion-prepare.service +After=combustion-prepare.service + # Optionally make network available After=network.target -# Config drive has to be available -Requires=dev-disk-by\x2dlabel-ignition.device -After=dev-disk-by\x2dlabel-ignition.device - # After ignition completed its stuff After=ignition-complete.target @@ -23,6 +23,10 @@ Before=initrd-parse-etc.service Conflicts=initrd-switch-root.target umount.target Conflicts=dracut-emergency.service emergency.service emergency.target +# Without this it goes into an endless loop on failure +OnFailure=emergency.target +OnFailureJobMode=isolate + [Service] Type=oneshot ExecStart=/usr/bin/combustion diff --git a/combustion.spec b/combustion.spec index 1878dd6..86120fa 100644 --- a/combustion.spec +++ b/combustion.spec @@ -27,7 +27,8 @@ Source1: LICENSE Source2: README Source3: module-setup.sh Source4: combustion.service -Source5: combustion +Source5: combustion-prepare.service +Source6: combustion Requires: ignition-dracut-grub2 BuildArch: noarch @@ -51,7 +52,8 @@ mkdir -p %{buildroot}%{_prefix}/lib/dracut/modules.d/35combustion cd %{buildroot}%{_prefix}/lib/dracut/modules.d/35combustion/ install -m0644 %{SOURCE3} module-setup.sh install -m0644 %{SOURCE4} combustion.service -install -m0755 %{SOURCE5} combustion +install -m0644 %{SOURCE5} combustion-prepare.service +install -m0755 %{SOURCE6} combustion %post %{?regenerate_initrd_post} diff --git a/module-setup.sh b/module-setup.sh index bba3a00..55fbb51 100644 --- a/module-setup.sh +++ b/module-setup.sh @@ -4,6 +4,7 @@ depends() { install() { inst_simple "${moddir}/combustion.service" "${systemdsystemunitdir}/combustion.service" + inst_simple "${moddir}/combustion-prepare.service" "${systemdsystemunitdir}/combustion-prepare.service" mkdir -p "${initdir}/${systemdsystemunitdir}/initrd.target.requires/" ln_r "../combustion.service" "${systemdsystemunitdir}/initrd.target.requires/combustion.service" inst_multiple awk chroot findmnt