Skip to content

Commit

Permalink
40ignition-ostree: Initial support for rootfs replacement
Browse files Browse the repository at this point in the history
This adds basic infrastructure units for "re-provisioning"
the root filesystem.  See:
coreos/fedora-coreos-tracker#94

A unit first detects if the Ignition configuration has a filesystem
with the label `root` - if so, we save the rootfs into RAM, let
`ignition-disks.service` run, then restore it from RAM.

Earlier attempts used the `brd` kernel module which is a RAM-backed
block device so we can just `dd`.  However, this has some limitations,
such as the need to save the full disk in RAM, and the inability for any
other initrd code to use `brd` devices. As well, `brd` doesn't support
discards, so we require at minimum $rootfs_size RAM (e.g. 3G) until
reprovisioning is complete.

Future work here will likely move the `restore` phase into `rpm-ostree`.

Co-authored-by: Jonathan Lebon <jonathan@jlebon.com>
  • Loading branch information
cgwalters and jlebon committed Aug 27, 2020
1 parent ab63ad3 commit a444e69
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/bin/bash
set -euo pipefail

# This is implementation details of Ignition; in the future, we should figure
# out a way to ask Ignition directly whether there's a filesystem with label
# "root" being set up.
ignition_cfg=/run/ignition.json
rootdisk=/dev/disk/by-label/root
saved_sysroot=/run/ignition-ostree-rootfs

case "${1:-}" in
detect)
wipes_root=$(jq '.storage?.filesystems? // [] | map(select(.label == "root" and .wipeFilesystem == true)) | length' "${ignition_cfg}")
if [ "${wipes_root}" = "0" ]; then
exit 0
fi
echo "Detected rootfs replacement in fetched Ignition config: /run/ignition.json"
mkdir "${saved_sysroot}"
;;
save)
mount "${rootdisk}" /sysroot
echo "Moving rootfs to RAM..."
cp -aT /sysroot "${saved_sysroot}"
;;
restore)
# This one is in a private mount namespace since we're not "offically" mounting
mount "${rootdisk}" /sysroot
echo "Restoring rootfs from RAM..."
cd "${saved_sysroot}"
find . -mindepth 1 -maxdepth 1 -exec mv -t /sysroot {} \;
chattr +i $(ls -d /sysroot/ostree/deploy/*/deploy/*/)
;;
*)
echo "Unsupported operation: ${1:-}" 1>&2; exit 1
;;
esac
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[Unit]
Description=Ignition OSTree: restore rootfs
DefaultDependencies=false
After=ignition-disks.service
Before=ignition-ostree-growfs.service
Before=ignition-ostree-mount-firstboot-sysroot.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 restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[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
# Any services looking at mounts need to order after this
# because it causes device re-probing.
After=coreos-gpt-setup.service

[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
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ install() {
rm \
sed \
sfdisk \
sgdisk
sgdisk \
find

for x in mount populate; do
install_ignition_unit ignition-ostree-${x}-var.service
Expand All @@ -66,6 +67,12 @@ install() {
inst_simple "$moddir/multipath-generator" \
"$systemdutildir/system-generators/multipath-generator"

inst_multiple jq chattr
inst_script "$moddir/ignition-ostree-dracut-rootfs.sh" "/usr/libexec/ignition-ostree-dracut-rootfs"
for x in detect save restore; do
install_ignition_unit ignition-ostree-rootfs-${x}.service
done

# Disk support
install_ignition_unit ignition-ostree-mount-firstboot-sysroot.service diskful
install_ignition_unit ignition-ostree-mount-subsequent-sysroot.service diskful-subsequent
Expand Down

0 comments on commit a444e69

Please sign in to comment.