From 3c5da1fc6521cc67a807b5efc546c0fed227d147 Mon Sep 17 00:00:00 2001 From: Colin Walters Date: Tue, 17 Sep 2019 20:21:10 +0000 Subject: [PATCH] wip 31ignition-ostree For redeploying the rootfs --- dracut/30ignition/coreos-gpt-setup@.service | 2 +- .../ignition-ostree-dracut-rootfs.sh | 49 +++++++++++++++++++ .../ignition-ostree-rootfs-detect.service | 18 +++++++ .../ignition-ostree-rootfs-restore.service | 16 ++++++ .../ignition-ostree-rootfs-save.service | 15 ++++++ dracut/31ignition-ostree/module-setup.sh | 9 +++- 6 files changed, 107 insertions(+), 2 deletions(-) create mode 100755 dracut/31ignition-ostree/ignition-ostree-dracut-rootfs.sh create mode 100644 dracut/31ignition-ostree/ignition-ostree-rootfs-detect.service create mode 100644 dracut/31ignition-ostree/ignition-ostree-rootfs-restore.service create mode 100644 dracut/31ignition-ostree/ignition-ostree-rootfs-save.service diff --git a/dracut/30ignition/coreos-gpt-setup@.service b/dracut/30ignition/coreos-gpt-setup@.service index 30a862f..8c01a2d 100644 --- a/dracut/30ignition/coreos-gpt-setup@.service +++ b/dracut/30ignition/coreos-gpt-setup@.service @@ -8,7 +8,7 @@ Requires=%i.device After=%i.device # Run before services that use device nodes, preventing them from racing # with udev activity generated by sgdisk -Before=ignition-setup-base.service ignition-setup-user.service ignition-disks.service +Before=ignition-setup-base.service ignition-setup-user.service ignition-ostree-rootfs-save.service ignition-disks.service [Service] Type=oneshot diff --git a/dracut/31ignition-ostree/ignition-ostree-dracut-rootfs.sh b/dracut/31ignition-ostree/ignition-ostree-dracut-rootfs.sh new file mode 100755 index 0000000..49c37f2 --- /dev/null +++ b/dracut/31ignition-ostree/ignition-ostree-dracut-rootfs.sh @@ -0,0 +1,49 @@ +#!/bin/bash +set -euo pipefail + +rootmnt=/sysroot +tmproot=/run/ignition-ostree-rootfs + +case "${1:-}" in + detect) + # This is obviously crude; perhaps in the future we could change ignition's `fetch` + # stage to write out a file if the rootfs is being replaced or so. But eh, it + # works for now. + has_rootfs=$(jq '.storage?.filesystems? // [] | map(select(.label == "root")) | length' < /run/ignition.json) + if [ "${has_rootfs}" = "0" ]; then + exit 0 + fi + echo "Detected rootfs replacement in fetched Ignition config: /run/ignition.json" + mkdir "${tmproot}" + ;; + save) + # This one is in a private mount namespace since we're not "offically" mounting + mount /dev/disk/by-label/root $rootmnt + echo "Moving rootfs to RAM..." + # OSTree added the immutable bit on the deployment root, and + # cosa's create_disk added it to the rootfs + chattr -i ${rootmnt} ${rootmnt}/ostree/deploy/*/deploy/*.0 + for x in boot ostree; do + # TODO; copy instead of mv to avoid writes, since we're just + # about to blow away the whole FS anyways? + mv -Tn ${rootmnt}/${x} ${tmproot}/${x} + done + umount ${rootmnt} + echo "Moved rootfs to RAM, pending redeployment: ${tmproot}" + ;; + restore) + # This one is in a private mount namespace since we're not "offically" mounting + mount /dev/disk/by-label/root $rootmnt + echo "Restoring rootfs from RAM..." + for x in boot ostree; do + mv -Tn ${tmproot}/${x} ${rootmnt}/${x} + done + # And restore the immutable bits + chattr +i ${rootmnt}/ostree/deploy/*/deploy/*.0 ${rootmnt} + echo "...done" + umount $rootmnt + ;; + *) + echo "Unsupported operation: ${1:-}" + ;; +esac diff --git a/dracut/31ignition-ostree/ignition-ostree-rootfs-detect.service b/dracut/31ignition-ostree/ignition-ostree-rootfs-detect.service new file mode 100644 index 0000000..5a969a7 --- /dev/null +++ b/dracut/31ignition-ostree/ignition-ostree-rootfs-detect.service @@ -0,0 +1,18 @@ +[Unit] +Description=Ignition OSTree: detect rootfs replacement +DefaultDependencies=false +After=ignition-fetch.service +Before=ignition-disks.service +Before=initrd-root-fs.target +Before=sysroot.mount +ConditionKernelCommandLine=ostree + +# This stage requires udevd to detect disks +Requires=systemd-udevd.service +After=systemd-udevd.service + +[Service] +Type=oneshot +RemainAfterExit=yes +EnvironmentFile=/run/ignition.env +ExecStart=/usr/libexec/ignition-ostree-dracut-rootfs detect diff --git a/dracut/31ignition-ostree/ignition-ostree-rootfs-restore.service b/dracut/31ignition-ostree/ignition-ostree-rootfs-restore.service new file mode 100644 index 0000000..123e9c5 --- /dev/null +++ b/dracut/31ignition-ostree/ignition-ostree-rootfs-restore.service @@ -0,0 +1,16 @@ +[Unit] +Description=Ignition OSTree: restore rootfs +DefaultDependencies=false +After=ignition-disks.service +Before=sysroot.mount + +ConditionKernelCommandLine=ostree +ConditionPathIsDirectory=/run/ignition-ostree-rootfs + +[Service] +Type=oneshot +RemainAfterExit=yes +EnvironmentFile=/run/ignition.env +# So we can transiently mount sysroot +MountFlags=slave +ExecStart=/usr/libexec/ignition-ostree-dracut-rootfs restore diff --git a/dracut/31ignition-ostree/ignition-ostree-rootfs-save.service b/dracut/31ignition-ostree/ignition-ostree-rootfs-save.service new file mode 100644 index 0000000..8bc3eec --- /dev/null +++ b/dracut/31ignition-ostree/ignition-ostree-rootfs-save.service @@ -0,0 +1,15 @@ +[Unit] +Description=Ignition OSTree: save rootfs +DefaultDependencies=false +After=ignition-ostree-rootfs-detect.service +Before=ignition-disks.service +ConditionKernelCommandLine=ostree +ConditionPathIsDirectory=/run/ignition-ostree-rootfs + +[Service] +Type=oneshot +RemainAfterExit=yes +EnvironmentFile=/run/ignition.env +# So we can transiently mount sysroot +MountFlags=slave +ExecStart=/usr/libexec/ignition-ostree-dracut-rootfs save diff --git a/dracut/31ignition-ostree/module-setup.sh b/dracut/31ignition-ostree/module-setup.sh index 8ee6e85..61f9172 100755 --- a/dracut/31ignition-ostree/module-setup.sh +++ b/dracut/31ignition-ostree/module-setup.sh @@ -15,7 +15,9 @@ install_ignition_unit() { install() { inst_multiple \ systemd-sysusers \ - systemd-tmpfiles + systemd-tmpfiles \ + ostree tar chattr \ + jq mkdir -p "$initdir/$systemdsystemunitdir/ignition-complete.target.requires" @@ -26,4 +28,9 @@ install() { install_ignition_unit ignition-ostree-populate-var.service inst_script "$moddir/ignition-ostree-populate-var.sh" \ "/usr/sbin/ignition-ostree-populate-var" + inst_script "$moddir/ignition-ostree-dracut-rootfs.sh" \ + "/usr/libexec/ignition-ostree-dracut-rootfs" + install_ignition_unit ignition-ostree-rootfs-detect.service + install_ignition_unit ignition-ostree-rootfs-save.service + install_ignition_unit ignition-ostree-rootfs-restore.service }