preflight+install: the default entry is CUBELinux now, and two checks said otherwise
Inverting the default (GRUB_DEFAULT='cubelinux', workhorse kernel as grubenv's
`fallback`) invalidated an assertion rather than tripping it, which is the worse
failure of the two.
verify-box-preflight.sh asked whether the DEFAULT string contains the release:
`default_boots() { case "$DEFAULT" in *"$1"*) ... }`. That works for the form the id
used to have — `gnulinux-<release>-advanced-<uuid>` carries the release verbatim — and
is simply false for `cubelinux`, which does not. So on a same-release reinstall the
check answered "the default boots another kernel, so the way back is untouched" about
an entry that boots exactly the release being replaced: a green light over the one
thing it exists to catch. It now resolves the default entry to the kernel on its
`linux` line (entry_kernel(): grub.cfg and the sourced custom.cfg, stripping a
`submenu>` prefix), and keeps the id's text only as a fallback for a default it cannot
resolve. It reports what is true: NOT READY — 2 of 16. A consequence worth stating
plainly: the next kernel build needs a new release name, because a same-release
reinstall is now refused on purpose.
install-box.sh carried the old arrangement in two comments that are now the opposite
of the truth:
* pass 1 writes the kernel the DEFAULT entry names while pass 2 has not yet written
its initramfs, so the window between them is no longer covered by "a reboot lands
on some other kernel". Nothing reboots in between and each pass writes whole, but
the window is real where it was not.
* the closing message told the operator that a panic reboots the machine back to the
default entry, as if that were safe. The default IS this entry, so panic=30
reboots straight back into the kernel that just panicked and GRUB's fallback never
runs. The message now names the boot menu and the grub-reboot command that
actually get the machine back.
Both files also name the divergence this change exposed and did not fix: install-root.sh
maintains /boot/grub/custom.cfg (id 'cubelinux-<release>'), which is now a SECOND
CUBELinux entry beside the default /etc/grub.d/12_cubelinux (id 'cubelinux'), and only
the default carries cube_boot_record=1. One of them should go.
This commit is contained in:
+25
-7
@@ -88,9 +88,13 @@ done
|
||||
[ "$kept" -gt 0 ] || say "kept : nothing — this release is not installed yet"
|
||||
|
||||
# ── pass 1: the kernel and its module tree ───────────────────────────────────────────────
|
||||
# The GRUB entry install-root.sh writes here names an initramfs that does not exist yet, so the
|
||||
# CUBELinux entry is not bootable until pass 2 completes. That is safe: the default entry is
|
||||
# untouched, so a reboot in between lands on the kernel this machine runs now.
|
||||
# The entry names an initramfs that does not exist yet, so the CUBELinux entry is not bootable
|
||||
# until pass 2 completes — and since 2026-09-23 that entry is the DEFAULT (GRUB_DEFAULT='cubelinux'
|
||||
# in /etc/default/grub, see /etc/grub.d/12_cubelinux). So the window between the two passes is no
|
||||
# longer covered by "the default is some other kernel": this pass has just replaced the file the
|
||||
# default entry names, and the initramfs it names is still the previous install's. Nothing here
|
||||
# reboots, and each pass writes its artefact whole, but the window is real now where it was not
|
||||
# before, and it is named here rather than implied by an old comment.
|
||||
step "kernel + modules"
|
||||
bash "$HERE/install-root.sh" / --root-spec "UUID=$ROOT_UUID" --fs-uuid "$ROOT_UUID" "${STORE_ARGS[@]}"
|
||||
|
||||
@@ -150,10 +154,24 @@ say "default : unchanged ($DEFAULT_AFTER)"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
installed. nothing has been rebooted. to boot CUBELinux once — and only once:
|
||||
installed. nothing has been rebooted. CUBELinux is the DEFAULT entry on this machine
|
||||
(GRUB_DEFAULT='cubelinux'), so a plain reboot boots it — there is nothing to arm:
|
||||
|
||||
grub-reboot '$RELEASE' && reboot
|
||||
reboot
|
||||
|
||||
if it panics, panic=30 reboots the machine back to the default entry by itself. to remove the
|
||||
entry without booting it at all: rm /boot/grub/custom.cfg
|
||||
the way back is the workhorse kernel 6.19.3-cube+, named as GRUB's `fallback` in
|
||||
/boot/grub/grubenv. that covers THIS ENTRY FAILING TO LOAD — a missing kernel or initramfs. it does
|
||||
not cover a kernel that loads and then faults: GRUB has already handed over by then, so panic=30
|
||||
reboots straight back into this same entry, and the fallback never runs. if that happens, choose the
|
||||
workhorse entry at the boot menu, or:
|
||||
|
||||
grub-reboot gnulinux-6.19.3-cube+-advanced-2a7b1834-83ed-4394-a8ee-816b885b5624 && reboot
|
||||
|
||||
to arm that one-shot on purpose, rather than rebooting into CUBELinux — the same command, and the
|
||||
boot after it returns to the default on its own.
|
||||
|
||||
known divergence, not yet fixed: this install maintains /boot/grub/custom.cfg (id
|
||||
'cubelinux-$RELEASE'), which after 2026-09-23 is a SECOND CUBELinux entry beside the default
|
||||
/etc/grub.d/12_cubelinux (id 'cubelinux'). they name the same kernel and differ in the command
|
||||
line — only 12_cubelinux has cube_boot_record=1. one of them should go; see the note for 2026-09-23.
|
||||
EOF
|
||||
|
||||
@@ -30,10 +30,48 @@ echo "running : $RUNNING on $(findmnt -n -o SOURCE / 2>/dev/null || echo '?')"
|
||||
# boots now" — so the boot entry is what it reads. Asking `uname -r` instead is how this preflight
|
||||
# came to refuse an install whose way back had never been in question.
|
||||
GRUB_CFG=/boot/grub/grub.cfg
|
||||
# The installer's own entry lives here, and is sourced at boot rather than at grub-mkconfig time, so
|
||||
# an id in it is invisible to a grep of grub.cfg alone.
|
||||
CUSTOM_CFG=/boot/grub/custom.cfg
|
||||
DEFAULT="$(sed -n 's/^ *set default="\(.*\)"/\1/p' "$GRUB_CFG" 2>/dev/null | tail -1)"
|
||||
# A GRUB entry id carries the release verbatim: `gnulinux-6.19.3-cube+-advanced-<uuid>`.
|
||||
default_boots() { case "$DEFAULT" in *"$1"*) return 0 ;; *) return 1 ;; esac; }
|
||||
|
||||
# What a menuentry actually boots is the kernel on its `linux` line. The id is not a substitute: it
|
||||
# is a name, and the default now names an entry whose id (`cubelinux`) deliberately does NOT carry
|
||||
# the release — so a substring test on the id answers "the default boots something else" about an
|
||||
# entry that boots exactly the release in hand. That is the failure this resolves: a green preflight
|
||||
# over a same-release reinstall of the kernel the default entry boots.
|
||||
entry_kernel() { # entry_kernel <id|title> -> the vmlinuz path that entry loads
|
||||
local id="${1##*>}" f ln
|
||||
for f in "$GRUB_CFG" "$CUSTOM_CFG"; do
|
||||
[ -f "$f" ] || continue
|
||||
ln="$(grep -nE '^[[:space:]]*menuentry' "$f" | grep -F "'$id'" | head -1 | cut -d: -f1)"
|
||||
[ -n "$ln" ] || continue
|
||||
sed -n "${ln},\$p" "$f" \
|
||||
| grep -m1 -E '^[[:space:]]*linux[[:space:]]' \
|
||||
| tr ' \t' '\n\n' \
|
||||
| grep -m1 -- '/vmlinuz-' && return 0
|
||||
done
|
||||
return 1
|
||||
}
|
||||
DEFAULT_KERNEL="$(entry_kernel "$DEFAULT" || true)"
|
||||
DEFAULT_RELEASE=""
|
||||
[ -n "$DEFAULT_KERNEL" ] && DEFAULT_RELEASE="${DEFAULT_KERNEL##*/vmlinuz-}"
|
||||
|
||||
# Resolve by the file when the entry can be read, and fall back to the id's text when it cannot
|
||||
# (a numeric GRUB_DEFAULT, or an id this script cannot follow) — a weaker answer, not a wrong one.
|
||||
default_boots() {
|
||||
if [ -n "$DEFAULT_RELEASE" ]; then
|
||||
[ "$DEFAULT_RELEASE" = "$1" ]
|
||||
return
|
||||
fi
|
||||
case "$DEFAULT" in *"$1"*) return 0 ;; *) return 1 ;; esac
|
||||
}
|
||||
echo "boots : ${DEFAULT:-?} (the default entry, which a plain reboot follows)"
|
||||
if [ -n "$DEFAULT_RELEASE" ]; then
|
||||
echo " it loads ${DEFAULT_KERNEL} (release ${DEFAULT_RELEASE})"
|
||||
else
|
||||
echo " its kernel could not be resolved from the entry; the id's text is used instead"
|
||||
fi
|
||||
echo
|
||||
|
||||
# ── the built kernel exists, and installing it cannot cost the way back ──────────────────
|
||||
|
||||
Reference in New Issue
Block a user