From 3824577c123bcaa0badd821338127c52a32ac620 Mon Sep 17 00:00:00 2001 From: Emir Beganovic Date: Fri, 9 Oct 2026 23:54:17 +0200 Subject: [PATCH] Mark the boot image migration done only when a boot entry has the parameter limine-mkinitcpio carries on past a kernel it could not build, with a full boot partition for one, and still exits 0. The migration then wrote its marker over an unchanged boot image, and no later update would try again. After the rebuild it now looks at the boot menu: if the menu has command lines and none carries the parameter, the migration fails and stays pending. A menu with no command lines in it, where they are inside the boot images, cannot be checked this way and is accepted as before. --- migrations/1791581004.sh | 14 +++++++++++++ .../console-no-ansi-query-migration-test.sh | 20 +++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/migrations/1791581004.sh b/migrations/1791581004.sh index c95a74ff..2fda0f4f 100644 --- a/migrations/1791581004.sh +++ b/migrations/1791581004.sh @@ -12,6 +12,8 @@ defaults_conf="${OMARCHY_LIMINE_DEFAULTS_CONF:-/etc/limine-entry-tool.d/omarchy- running_cmdline="${OMARCHY_RUNNING_CMDLINE:-/proc/cmdline}" rebuild_marker="${OMARCHY_LIMINE_REBUILD_MARKER:-/var/lib/omarchy/migrations/1791581004}" param="systemd.tty.term.console=dumb" +esp=$(sed -n 's/^ESP_PATH=["'\'']\?\([^"'\'']*\).*/\1/p' /etc/default/limine 2>/dev/null | tail -n 1) +limine_conf="${OMARCHY_LIMINE_CONF:-${esp:-/boot}/limine.conf}" omarchy-cmd-present limine-mkinitcpio || exit 0 [[ -f $defaults_conf && -r $running_cmdline ]] || exit 0 @@ -28,4 +30,16 @@ grep -Eq "^KERNEL_CMDLINE\[default\]\+=\".*${param//./\\.}.*\"" "$defaults_conf" echo "The booted kernel is missing $param; rebuilding the boot image" sudo limine-mkinitcpio + +# limine-mkinitcpio carries on past a kernel it could not build, a full boot +# partition for one, and still exits 0. Done means a boot entry has the +# parameter: without that the migration stays pending and the next update +# tries again. A menu with no command lines in it (they are inside the boot +# images then) has nothing to look at, and is taken at its word. +if sudo grep -Eq '^[[:space:]]*cmdline:' "$limine_conf" 2>/dev/null && + ! sudo grep -Eq "^[[:space:]]*cmdline:.*[[:space:]]${param//./\\.}([[:space:]]|\$)" "$limine_conf"; then + echo "The boot menu still has no entry with $param after the rebuild" >&2 + exit 1 +fi + sudo install -Dm644 /dev/null "$rebuild_marker" diff --git a/test/shell.d/console-no-ansi-query-migration-test.sh b/test/shell.d/console-no-ansi-query-migration-test.sh index e087b0c4..3c977546 100644 --- a/test/shell.d/console-no-ansi-query-migration-test.sh +++ b/test/shell.d/console-no-ansi-query-migration-test.sh @@ -18,7 +18,14 @@ mkdir -p "$stub_bin" # sudo just drops the prefix; limine-mkinitcpio records that it ran, and fails # when told to. printf '#!/bin/bash\nexec "$@"\n' >"$stub_bin/sudo" -printf '#!/bin/bash\necho rebuilt >>"${REBUILDS:?}"\n[[ -z ${REBUILD_FAILS:-} ]]\n' >"$stub_bin/limine-mkinitcpio" +# A rebuild writes the new command line into the boot menu, unless it is the +# kind that builds nothing and still exits 0. +cat >"$stub_bin/limine-mkinitcpio" <<'STUB' +#!/bin/bash +echo rebuilt >>"${REBUILDS:?}" +[[ -z ${REBUILD_FAILS:-} ]] || exit 1 +[[ -n ${REBUILD_BUILDS_NOTHING:-} ]] || printf ' cmdline: %s\n' "${NEW_CMDLINE:?}" >"${LIMINE_CONF:?}" +STUB chmod +x "$stub_bin"/* old_cmdline="root=PARTUUID=1 rw quiet splash initramfs_async=0" @@ -27,7 +34,9 @@ new_cmdline="$old_cmdline systemd.tty.term.console=dumb" run() { # booted cmdline, defaults conf : >"$test_dir/rebuilds" printf '%s\n' "$1" >"$test_dir/cmdline" + printf ' cmdline: %s\n' "$1" >"$test_dir/limine.conf" PATH="$stub_bin:$ROOT/bin:$PATH" REBUILDS="$test_dir/rebuilds" \ + LIMINE_CONF="$test_dir/limine.conf" NEW_CMDLINE="$new_cmdline" OMARCHY_LIMINE_CONF="$test_dir/limine.conf" \ OMARCHY_RUNNING_CMDLINE="$test_dir/cmdline" OMARCHY_LIMINE_DEFAULTS_CONF="$2" \ OMARCHY_LIMINE_REBUILD_MARKER="$test_dir/marker" bash -euo pipefail "$migration" >/dev/null } @@ -41,6 +50,13 @@ fi [[ $(rebuilds) == 1 && ! -e $test_dir/marker ]] || fail "a failed rebuild was marked as done" pass "a rebuild that fails stops the migration and leaves no marker" +# limine-mkinitcpio exits 0 past a kernel it could not build. +if REBUILD_BUILDS_NOTHING=1 run "$old_cmdline" "$ROOT/etc/limine-entry-tool.d/omarchy-defaults.conf"; then + fail "a rebuild that changed nothing was reported as a success" +fi +[[ ! -e $test_dir/marker ]] || fail "a rebuild that changed nothing was marked as done" +pass "a rebuild that exits 0 without changing the boot menu leaves the migration pending" + run "$old_cmdline" "$ROOT/etc/limine-entry-tool.d/omarchy-defaults.conf" [[ $(rebuilds) == 1 && -e $test_dir/marker ]] || fail "a machine booted without the parameter did not get its boot image rebuilt" @@ -65,7 +81,7 @@ pass "a machine whose defaults were edited to leave the parameter out is left al # not found either. rm "$stub_bin/limine-mkinitcpio" mkdir -p "$test_dir/tools" -for tool in bash grep install cat; do ln -s "$(command -v "$tool")" "$test_dir/tools/$tool"; done +for tool in bash grep install cat sed tail; do ln -s "$(command -v "$tool")" "$test_dir/tools/$tool"; done : >"$test_dir/rebuilds" printf '%s\n' "$old_cmdline" >"$test_dir/cmdline" PATH="$stub_bin:$ROOT/bin:$test_dir/tools" REBUILDS="$test_dir/rebuilds" \