diff options
| author | Danilo M. <danix@danix.xyz> | 2026-09-26 10:03:08 +0200 |
|---|---|---|
| committer | Danilo M. <danix@danix.xyz> | 2026-09-26 10:03:08 +0200 |
| commit | 83b30e4076356e7a2a104e7f67f727c792699107 (patch) | |
| tree | 5a198620a5995da48843e526e2ca29dfc2f1bfe6 | |
| parent | 2addd8bd31e146e91cc2489840da7b4ae1325eed (diff) | |
| download | dist-upgrade-83b30e4076356e7a2a104e7f67f727c792699107.tar.gz dist-upgrade-83b30e4076356e7a2a104e7f67f727c792699107.zip | |
Handle slackpkg exit 20 and 50, auto-restart on self-upgrade
slackpkg's cleanup() exits 20 when no packages match (benign, e.g. an
install-new with nothing to do) and 50 when it upgraded itself and wants
the operation restarted. Treating every nonzero as fatal aborted the run
on the very common 20.
Add handle_rc(): 0 and 20 continue, real errors abort with the exit code,
and 50 re-execs the script once with the original arguments, guarded by
DIST_UPGRADE_RESTARTS so a repeated 50 aborts instead of looping. All
steps now go through it.
| -rw-r--r-- | README.md | 4 | ||||
| -rwxr-xr-x | dist-upgrade | 49 |
2 files changed, 47 insertions, 6 deletions
@@ -35,6 +35,10 @@ Environment: - the module set against the pre-upgrade snapshot (notices modules lost). 4. Reports whether a reboot is recommended. +If slackpkg upgrades itself mid-run (exit status 50) the script re-executes +once from the top to finish the operation, exactly as slackpkg's own message +asks. A second occurrence aborts with a message instead of looping. + Unattended mode runs the package commands with `-batch=on -default_answer=y`. `clean-system` is the exception: unattended it only lists packages that are not part of the official Slackware set and removes nothing, so third-party or diff --git a/dist-upgrade b/dist-upgrade index 578410f..39b40a8 100755 --- a/dist-upgrade +++ b/dist-upgrade @@ -22,6 +22,8 @@ MKINITRD_GEN=/usr/share/mkinitrd/mkinitrd_command_generator.sh INTERACTIVE=0 TMPDIR_SNAP="" +ORIG_ARGS=("$@") +RESTARTS=${DIST_UPGRADE_RESTARTS:-0} die() { printf 'dist-upgrade: %s\n' "$*" >&2; exit 1; } warn() { printf 'WARNING: %s\n' "$*" >&2; } @@ -105,6 +107,35 @@ run_slackpkg() { fi } +# slackpkg (via cleanup() in core-functions.sh) exits 20 when nothing matches, +# and 50 when it upgraded itself and wants the operation restarted. +handle_rc() { + local cmd=$1 rc=$2 + case "$rc" in + 0) return 0 ;; + 20) info "slackpkg $cmd: nothing to do." ;; + 50) + if [ "$RESTARTS" -ge 1 ]; then + warn "slackpkg upgraded itself again mid-run; re-run dist-upgrade to continue." + exit 1 + fi + info "slackpkg upgraded itself mid-run; restarting dist-upgrade to continue." + RESTARTS=$((RESTARTS + 1)) + export DIST_UPGRADE_RESTARTS=$RESTARTS + [ -n "$TMPDIR_SNAP" ] && rm -rf "$TMPDIR_SNAP" + exec "$0" "${ORIG_ARGS[@]}" + ;; + *) die "slackpkg $cmd failed (exit $rc)" ;; + esac +} + +run_step() { + local cmd=$1 + shift + run_slackpkg "$cmd" "$@" + handle_rc "$cmd" $? +} + snapshot_initrd() { if [ ! -e "$INITRD" ] && [ ! -L "$INITRD" ]; then info "snapshot: no initrd at $INITRD, skipping initrd checks." @@ -199,6 +230,11 @@ lib/modules/6.18.50/modules.dep' expected="ext4 " [ "$got" = "$expected" ] || die "self-test: mkinitrd -f parse failed: '$got'" + ( handle_rc test 0 ) >/dev/null 2>&1 || die "self-test: rc 0 should pass" + ( handle_rc test 20 ) >/dev/null 2>&1 || die "self-test: rc 20 should pass" + if ( RESTARTS=1; handle_rc test 50 ) >/dev/null 2>&1; then die "self-test: rc 50 should abort once restarted"; fi + if ( handle_rc test 1 ) >/dev/null 2>&1; then die "self-test: rc 1 should abort"; fi + d=$(mktemp -d) || die "self-test: mktemp failed" mkdir -p "$d/lib/modules/6.18.50/kernel/fs/ext4" "$d/lib/modules/6.18.50/kernel/drivers/usb/host" : > "$d/lib/modules/6.18.50/kernel/fs/ext4/ext4.ko" @@ -234,16 +270,17 @@ trap 'rm -rf "$TMPDIR_SNAP"' EXIT snapshot_initrd -run_slackpkg update || die "slackpkg update failed" -run_slackpkg install-new || die "slackpkg install-new failed" -run_slackpkg upgrade-all || die "slackpkg upgrade-all failed" +run_step update +run_step install-new +run_step upgrade-all if [ "$INTERACTIVE" -eq 1 ]; then - run_slackpkg clean-system || die "slackpkg clean-system failed" + run_step clean-system else info "clean-system: listing packages not in the official tree only, removing nothing (use -i to review)." - slackpkg -batch=on -default_answer=n clean-system || die "slackpkg clean-system failed" + slackpkg -batch=on -default_answer=n clean-system + handle_rc clean-system $? fi -run_slackpkg new-config || die "slackpkg new-config failed" +run_step new-config check_initrd |
