Skip to content
This repository has been archived by the owner on Aug 25, 2021. It is now read-only.

Commit

Permalink
wip 31ignition-ostree
Browse files Browse the repository at this point in the history
For redeploying the rootfs
  • Loading branch information
cgwalters committed Sep 24, 2019
1 parent e093b21 commit cd23232
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 2 deletions.
2 changes: 1 addition & 1 deletion dracut/30ignition/coreos-gpt-setup@.service
Original file line number Diff line number Diff line change
Expand Up @@ -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-rootfs-save.service ignition-disks.service

[Service]
Type=oneshot
Expand Down
1 change: 0 additions & 1 deletion dracut/30ignition/ignition-fetch.service
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
Description=Ignition (fetch)
DefaultDependencies=false
Before=ignition-complete.target
After=basic.target

# Run after ignition-setup has run because ignition-setup
# may copy in new/different ignition configs for us to consume.
Expand Down
41 changes: 41 additions & 0 deletions dracut/31ignition-ostree/ignition-dracut-rootfs-manual.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/bash
set -euo pipefail

rootmnt=/mnt/rootfs
mkdir -p $rootmnt
mount /dev/disk/by-label/root $rootmnt
igntmp=/run/ignition-rootfs

case "${1:-}" in
save)
for toplevel in boot ostree; do
mkdir -p ${igntmp}/${toplevel}
chcon -h --reference=${rootmnt}/${toplevel} ${igntmp}/${toplevel}
done
# We copy the repo, /var and the .origin file; if we tried to copy
# everything with e.g. `cp` we'd end up breaking hardlinks.
repo=${igntmp}/ostree/repo
ostree --repo=${repo} init --mode=bare
cp ${rootmnt}/ostree/repo/config ${repo}/config
ostree --repo=${repo} pull-local ${rootmnt}/ostree/repo
stateroot=$(ls ${rootmnt}/ostree/deploy)
statepath=ostree/deploy/${stateroot}
mkdir -p ${igntmp}/${statepath}
cp -a ${rootmnt}/${statepath}/var ${igntmp}/${statepath}/var
mkdir -p ${igntmp}/${statepath}/deploy
cp -a ${rootmnt}/${statepath}/deploy/*.origin ${igntmp}/${statepath}/deploy/
commit=$(cd ${stateroot} && ls *.0 | cut -f 1 -d '.')
echo "${commit}" > ${igntmp}/ostree-commit
;;
restore)
echo "Restoring ostree repo..."
mv -T ${igntmp}/ostree ${rootmnt}/ostree
echo "...done"
commit=$(cat ${igntmp}/ostree-commit)
echo "Redeploying OSTree commit ${commit} ..."
ostree admin --sysroot=${rootmnt} deploy ${commit}
;;
*)
echo "Unsupported operation: ${1:-}"
;;
esac
49 changes: 49 additions & 0 deletions dracut/31ignition-ostree/ignition-dracut-rootfs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/bin/bash
set -euo pipefail

rootmnt=/sysroot
tmproot=/run/ignition-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
18 changes: 18 additions & 0 deletions dracut/31ignition-ostree/ignition-rootfs-detect.service
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-dracut-rootfs detect
16 changes: 16 additions & 0 deletions dracut/31ignition-ostree/ignition-rootfs-restore.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[Unit]
Description=Ignition OSTree: restore rootfs
DefaultDependencies=false
After=ignition-disks.service
Before=sysroot.mount

ConditionKernelCommandLine=ostree
ConditionPathIsDirectory=/run/ignition-rootfs

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/run/ignition.env
# So we can transiently mount sysroot
MountFlags=slave
ExecStart=/usr/libexec/ignition-dracut-rootfs restore
15 changes: 15 additions & 0 deletions dracut/31ignition-ostree/ignition-rootfs-save.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[Unit]
Description=Ignition OSTree: save rootfs
DefaultDependencies=false
After=ignition-rootfs-detect.service
Before=ignition-disks.service
ConditionKernelCommandLine=ostree
ConditionPathIsDirectory=/run/ignition-rootfs

[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/run/ignition.env
# So we can transiently mount sysroot
MountFlags=slave
ExecStart=/usr/libexec/ignition-dracut-rootfs save
27 changes: 27 additions & 0 deletions dracut/31ignition-ostree/module-setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/bash
# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
# ex: ts=8 sw=4 sts=4 et filetype=sh

depends() {
echo ignition ostree
}

install_ignition_unit() {
local unit="$1"; shift
local target="${1:-ignition-complete.target}"; shift
local instantiated="${1:-$unit}"; shift
inst_simple "$moddir/$unit" "$systemdsystemunitdir/$unit"
mkdir -p "$initdir/$systemdsystemunitdir/$target.requires"
ln_r "../$unit" "$systemdsystemunitdir/$target.requires/$instantiated"
}

install() {
inst_multiple ostree tar chattr jq

inst_script "$moddir/ignition-dracut-rootfs.sh" \
"/usr/libexec/ignition-dracut-rootfs"

install_ignition_unit ignition-rootfs-detect.service
install_ignition_unit ignition-rootfs-save.service
install_ignition_unit ignition-rootfs-restore.service
}

0 comments on commit cd23232

Please sign in to comment.