Give an installed machine a way to catch up
./install only ever adds. It copies over /, links dotfiles, installs packages -- and has no way to say "remove that file", "disable that unit", "that symlink points nowhere now". So a machine set up months ago keeps whatever this repository has since decided was wrong, and the only thing that ever fixes it is somebody reading a commit message. With a curl installer in the README, that stopped being hypothetical. A migration is one script that performs one repair, exactly once, on the machines that need it. Named by the commit timestamp that authored it, so glob order is chronological without a sequence number two branches could both pick. Marked in ~/.local/state on success and only on success, so a repair that failed stays pending rather than being recorded as done and hidden forever. Ordered, and stopped at the first failure, because a later repair may assume an earlier one landed. A fresh install marks everything without running it, the way Migrations.qml stamps a pre-versioning settings file at its baseline. The first real one removes the dangling ~/.config/forge symlink left behind when the GNOME session was cut: link-dotfiles could link it but never unlink it. Verified both ways -- a no-op on a machine that never had it, an actual repair on one that did. Root work goes through panama-sudo --reason so the password prompt names the repair, and the contract fails any migration reaching for bare sudo.
This commit is contained in:
+22
@@ -73,6 +73,9 @@ ${BOLD}Commands:${RESET}
|
||||
a subset: 'panama test dock' runs the ones matching 'dock'.
|
||||
${GREEN}upgrade${RESET} Re-run ./install from anywhere. Safe: every stage is
|
||||
idempotent and this is the documented upgrade path.
|
||||
${GREEN}migrate${RESET} Apply repairs this machine has not had yet. The half of an
|
||||
upgrade that ./install cannot do, because installing only ever
|
||||
adds. Safe to re-run; nothing is applied twice.
|
||||
${GREEN}apps${RESET} Choose applications to install: pick a category, then tick
|
||||
what you want. The same catalog ./install offers, minus the
|
||||
install.
|
||||
@@ -321,6 +324,24 @@ cmd_upgrade() {
|
||||
exec "$installer" "$@"
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Command: migrate
|
||||
# ----------------------------------------------------------------------------
|
||||
#
|
||||
# What ./install cannot do. The installer only ever adds -- it copies over /,
|
||||
# links dotfiles, installs packages -- so a machine set up months ago keeps
|
||||
# whatever this repository has since decided was wrong. Migrations are the one
|
||||
# mechanism that can remove a file, disable a unit, or repair a symlink on a
|
||||
# machine that already exists. See bin/panama-migrate.
|
||||
cmd_migrate() {
|
||||
local runner="$PANAMA_DIR/bin/panama-migrate"
|
||||
if [[ ! -x "$runner" ]]; then
|
||||
err "The migration runner is missing from $runner"
|
||||
exit 1
|
||||
fi
|
||||
exec "$runner" "$@"
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Command: app
|
||||
# ----------------------------------------------------------------------------
|
||||
@@ -522,6 +543,7 @@ main() {
|
||||
doctor) shift; cmd_doctor "$@" ;;
|
||||
test) shift; cmd_test "$@" ;;
|
||||
upgrade) shift; cmd_upgrade "$@" ;;
|
||||
migrate) shift; cmd_migrate "$@" ;;
|
||||
app) shift; cmd_app "$@" ;;
|
||||
apps) shift; cmd_apps "$@" ;;
|
||||
help|-h|--help|"") usage ;;
|
||||
|
||||
Reference in New Issue
Block a user