#!/bin/sh # Put the host back on the last version that worked. # # novox/hq ADR 0005. This runs when nox-mesh-host will not start, so it shares no code with it # and calls none of it: a binary that cannot start cannot be its own recovery. POSIX sh, no # bashisms, nothing that has to be installed. # # It is deliberately dull. Everything it does is one of: read a file, run the package manager, # ask the service manager to try again. set -eu STATE_DIR="${MESH_HOST_STATE_DIR:-/var/lib/mesh-host}" PKG_CACHE="${MESH_HOST_PKG_CACHE:-/var/cache/pacman/pkg}" PACKAGE="${MESH_HOST_PACKAGE:-nox-mesh-host}" KNOWN_GOOD="$STATE_DIR/known-good" ATTEMPTED="$STATE_DIR/rollback-attempted" say() { echo "nox-mesh-host-rollback: $*" >&2; } # Roll back once. A second failure is a different diagnosis: the previously working binary also # does not run, so the binary is not the problem — the machine is. Rolling back again would flap # between two versions forever and bury the actual cause under a loop. if [ -e "$ATTEMPTED" ]; then say "already rolled back once, to $(cat "$ATTEMPTED" 2>/dev/null || echo unknown)." say "the previous version also failed to start, so this is the machine and not the binary." say "not rolling back again. this node needs a person." exit 0 fi # A machine whose host never completed a reconcile has no version to go back to. That is a real # state rather than a fault: the node was never working, so the failure belongs to the # installation. Guessing a version here is how a recovery becomes a second fault. if [ ! -s "$KNOWN_GOOD" ]; then say "no known-good version recorded — this host has never completed a reconcile." say "there is nothing to roll back to. this is an installation failure, not an upgrade one." exit 0 fi VERSION="$(tr -d '[:space:]' < "$KNOWN_GOOD")" if [ -z "$VERSION" ]; then say "known-good is empty. refusing to guess." exit 0 fi PKG="$(ls "$PKG_CACHE"/"$PACKAGE"-"$VERSION"-*.pkg.tar.* 2>/dev/null | head -n 1 || true)" if [ -z "$PKG" ]; then say "known-good is $VERSION and no package for it is in $PKG_CACHE." say "the cache was cleaned, or that version was never installed from here." say "cannot roll back. this node needs a person." exit 1 fi say "rolling back to $VERSION ($PKG)" printf '%s\n' "$VERSION" > "$ATTEMPTED" if ! pacman -U --noconfirm "$PKG"; then say "the package manager refused to install $PKG." exit 1 fi # Deliberately does NOT start anything. The launcher called this and will exec the host next, # so starting it here would run two. novox/hq ADR 0005 moved that responsibility; this script # installs a version and says so, and nothing else. say "rolled back to $VERSION. the launcher will start it."