From: Lennart Poettering Date: Wed, 29 Apr 2026 19:49:58 +0000 (+0200) Subject: ci: add CI test for systemd-sysinstall X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ca5b4f3f705ebceb136baea74dd45e625edb8dcc;p=thirdparty%2Fsystemd.git ci: add CI test for systemd-sysinstall --- diff --git a/test/units/TEST-87-AUX-UTILS-VM.sysinstall.sh b/test/units/TEST-87-AUX-UTILS-VM.sysinstall.sh new file mode 100755 index 00000000000..d4ca6e0a0d1 --- /dev/null +++ b/test/units/TEST-87-AUX-UTILS-VM.sysinstall.sh @@ -0,0 +1,183 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +if ! command -v systemd-sysinstall >/dev/null; then + echo "systemd-sysinstall not found, skipping." + exit 0 +fi + +if ! command -v systemd-repart >/dev/null; then + echo "systemd-repart not found, skipping." + exit 0 +fi + +if ! command -v bootctl >/dev/null; then + echo "bootctl not found, skipping." + exit 0 +fi + +if ! command -v ukify >/dev/null; then + echo "ukify not found, skipping." + exit 0 +fi + +if [[ ! -d /usr/lib/systemd/boot/efi ]]; then + echo "sd-boot is not installed, skipping." + exit 0 +fi + +# We need a real environment to fiddle with loop devices. +if systemd-detect-virt -cq; then + echo "Running in a container, skipping." + exit 0 +fi + +# shellcheck source=test/units/util.sh +. "$(dirname "$0")"/util.sh + +WORKDIR="$(mktemp --directory /tmp/test-sysinstall.XXXXXXXXXX)" +LOOPDEV="" +MOUNTED=0 + +cleanup() { + set +e + if [[ "$MOUNTED" -eq 1 ]]; then + umount -R "$WORKDIR/mnt" + MOUNTED=0 + fi + if [[ -n "$LOOPDEV" ]]; then + systemd-dissect --detach "$LOOPDEV" + LOOPDEV="" + fi + rm -rf "$WORKDIR" +} +trap cleanup EXIT + +# 1) Build a small fake "OS source" tree. systemd-sysinstall picks this up via +# the repart.sysinstall.d definitions: CopyFiles= seeds the new root +# partition with these files. +SOURCE_ROOT="$WORKDIR/sourceroot" +mkdir -p "$SOURCE_ROOT/usr/lib" "$SOURCE_ROOT/etc" + +cat >"$SOURCE_ROOT/usr/lib/os-release" <<'EOF' +ID=testos +NAME="Test OS" +PRETTY_NAME="Test OS for systemd-sysinstall" +VERSION_ID=1 +EOF +ln -s ../usr/lib/os-release "$SOURCE_ROOT/etc/os-release" + +# 2) Build a minimal UKI. bootctl link only requires a valid PE with .osrel and +# the systemd-stub SBAT marker, so the .linux/.initrd contents do not need +# to be a real kernel. +echo "fake-kernel" >"$WORKDIR/vmlinuz" +echo "fake-initrd" >"$WORKDIR/initrd" + +ukify build \ + --linux "$WORKDIR/vmlinuz" \ + --initrd "$WORKDIR/initrd" \ + --os-release "@$SOURCE_ROOT/usr/lib/os-release" \ + --uname "1.2.3-testkernel" \ + --cmdline "quiet" \ + --output "$WORKDIR/testuki.efi" + +# 3) Build a sysinstall partition definition: a single ESP plus a root +# partition seeded from the fake source tree. +DEFS="$WORKDIR/sysinstall.d" +mkdir -p "$DEFS" + +cat >"$DEFS/10-esp.conf" <"$DEFS/20-root.conf" </dev/null + +# The UKI file referenced in the entry must exist on the ESP. +UKI_PATH=$(awk '/^uki / { print $2 }' "$ENTRY") +test -n "$UKI_PATH" +test -f "$ESP$UKI_PATH" + +# bootctl install should have placed sd-boot on the ESP. +find "$ESP/EFI/systemd" -type f -iname 'systemd-boot*.efi' | grep . >/dev/null + +# The credential we passed via --set-credential= must have been encrypted and +# placed next to the UKI, and must be referenced as 'extra' from the entry. +UKI_DIR="$(dirname "$ESP$UKI_PATH")" +TOKEN_DIR="$(basename "$UKI_DIR")" +test -s "$UKI_DIR/marker.cred" +grep -E "^extra /$TOKEN_DIR/marker\.cred$" "$ENTRY" >/dev/null + +# Locale/keymap/timezone propagation is off, so those .cred files must NOT +# exist on the ESP. +test ! -e "$UKI_DIR/firstboot.locale.cred" +test ! -e "$UKI_DIR/firstboot.keymap.cred" +test ! -e "$UKI_DIR/firstboot.timezone.cred" + +# 8) The seeded files from the fake source tree must end up in the new root. +test -f "$MNT/usr/lib/os-release" +grep '^ID=testos$' "$MNT/usr/lib/os-release" >/dev/null