aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rwxr-xr-xdist-upgrade49
2 files changed, 47 insertions, 6 deletions
diff --git a/README.md b/README.md
index 44c54bd..941808c 100644
--- a/README.md
+++ b/README.md
@@ -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