diff --git a/tier-1/bootc-generic-growpart b/tier-1/bootc-generic-growpart new file mode 100755 index 0000000..c2277ba --- /dev/null +++ b/tier-1/bootc-generic-growpart @@ -0,0 +1,41 @@ +#!/bin/bash +set -eu + +backing_device=$(findmnt -vno SOURCE /sysroot) +echo "Backing device: ${backing_device}" +syspath=/sys/class/block/$(basename "${backing_device}") +if ! test -d "${syspath}"; then + echo "failed to find backing device ${syspath}"; exit 1 +fi + +# Handling devicemapper targets is a whole other thing +case $backing_device in + /dev/mapper/*) "Not growing $backing_device"; exit 0 ;; +esac + +# Note that we expect that the rootfs is on a partition +partition=$(cat "${syspath}"/partition) + +# Walk up to find the parent blockdev +parentpath=$(dirname "$(realpath "${syspath}")") +devmajmin=$(cat "${parentpath}"/dev) +parent="/dev/block/${devmajmin}" + +# Grow the partition +tmpf=$(mktemp) +# Ignore errors because growpart exits 1 if nothing changed; +# we need to check the output for NOCHANGE: +if ! /usr/bin/growpart "${parent}" "${partition}" > "${tmpf}"; then + cat "${tmpf}" + if grep -qEe '^NOCHANGE: ' "${tmpf}"; then + exit 0 + fi + echo "growpart failed" + exit 1 +fi +cat "${tmpf}" +# Now, temporarily remount the sysroot writable in our mount namespace +mount -o remount,rw /sysroot +# And defer to systemd's growfs wrapper which handles dispatching on +# the target filesystem type. +/usr/lib/systemd/systemd-growfs /sysroot diff --git a/tier-1/bootc-generic-growpart.service b/tier-1/bootc-generic-growpart.service new file mode 100644 index 0000000..77bb310 --- /dev/null +++ b/tier-1/bootc-generic-growpart.service @@ -0,0 +1,20 @@ +[Unit] +Description=Bootc Fallback Root Filesystem Grow +Documentation=https://gitlab.com/fedora/bootc/docs +# For now we skip bare metal cases, and we also have nothing to do +# for containers. +ConditionVirtualization=vm +# This helps verify that we're running in a bootc/ostree based target. +ConditionPathIsMountPoint=/sysroot +# We want to run before any e.g. large container images might be pulled. +DefaultDependencies=no +Requires=sysinit.target +After=sysinit.target +Before=basic.target + +[Service] +ExecStart=/usr/libexec/bootc-generic-growpart +# So we can temporarily remount the sysroot writable +MountFlags=slave +# Just to auto-cleanup our temporary files +PrivateTmp=yes diff --git a/tier-1/generic-growfs.yaml b/tier-1/generic-growfs.yaml new file mode 100644 index 0000000..f64be92 --- /dev/null +++ b/tier-1/generic-growfs.yaml @@ -0,0 +1,12 @@ +add-files: + - - bootc-generic-growpart + - /usr/libexec/bootc-generic-growpart + - - bootc-generic-growpart.service + - /usr/lib/systemd/system/bootc-generic-growpart.service + +postprocess: + - | + #!/bin/bash + set -euo pipefail + mkdir -p /usr/lib/systemd/system/local-fs.target.wants + ln -s ../bootc-generic-growpart.service /usr/lib/systemd/system/local-fs.target.wants/bootc-generic-growpart.service diff --git a/tier-1/manifest.yaml b/tier-1/manifest.yaml index 99f807d..c8982a0 100644 --- a/tier-1/manifest.yaml +++ b/tier-1/manifest.yaml @@ -13,6 +13,7 @@ include: - fwupd.yaml - persistent-journal.yaml - initramfs-full.yaml + - generic-growfs.yaml packages: # Include and set the default editor