The host delivers its own successor, and versions live side by side
The supervision was already right: a clean exit means the host stood aside, and the launcher's next turn runs what is on disk. Two things made it dead code — nothing told the running host a successor was waiting, and the rollback resolved its known-good version through pacman, which no machine here uses and which two of three operating systems do not have. Keeping a version rather than a path was the clue. Versions now live in directories named for them: - the launcher picks the newest delivered one every time round the loop, or the one a rollback pinned, or the host placed by hand when nothing is delivered; - the running host stands aside between reconciles, never inside one, by exiting cleanly — and returns nil so the launcher does not count it as a crash; - a completed reconcile retires what is older than the predecessor, keeping the predecessor because that is what a rollback starts, and never the running one; - rollback pins the predecessor instead of reinstalling a package: no package manager, no cache anyone may clean, same script on every operating system; - the report says which host version produced it, so 'behind' is answerable. Newest is when it arrived, never how the name sorts: '1.10' orders before '1.9', and ordering by name would start an older host and call it an upgrade. novox/hq ADR 0141. The delivery half — a module carrying the next host — follows; until then nothing delivers a version and every machine takes the fallback, which is what it does today.
This commit is contained in:
@@ -16,16 +16,51 @@ set -u
|
||||
|
||||
STATE_DIR="${MESH_HOST_STATE_DIR:-/var/lib/mesh-host}"
|
||||
LIBEXEC="${MESH_HOST_LIBEXEC:-/usr/lib/nox-mesh-host}"
|
||||
HOST="${MESH_HOST_BIN:-/usr/bin/nox-mesh-host}"
|
||||
# The host that was placed by hand, used only when nothing has been delivered. The first host on a
|
||||
# machine always arrives this way; every one after it is delivered (novox/hq ADR 0141).
|
||||
FALLBACK="${MESH_HOST_BIN:-/usr/bin/nox-mesh-host}"
|
||||
VERSIONS="$LIBEXEC/versions"
|
||||
BINARY="nox-mesh-host"
|
||||
LIMIT="${MESH_HOST_START_LIMIT:-3}"
|
||||
BACKOFF="${MESH_HOST_BACKOFF:-5}"
|
||||
ONCE="${MESH_HOST_RUN_ONCE:-}" # tests run one iteration; nothing else sets this
|
||||
|
||||
ATTEMPTS="$STATE_DIR/start-attempts"
|
||||
HALTED="$STATE_DIR/halted"
|
||||
PINNED="$STATE_DIR/rollback-pinned"
|
||||
|
||||
say() { echo "nox-mesh-host-launch: $*" >&2; }
|
||||
|
||||
# Which host to run: the version a rollback pinned, or the most recently delivered one, or the one
|
||||
# placed by hand when nothing has been delivered (novox/hq ADR 0141).
|
||||
#
|
||||
# **Asked every time round the loop, not once.** Standing aside for a successor is a clean exit, and
|
||||
# the next turn has to run what is on disk NOW — resolving this once would restart the same binary
|
||||
# for ever and the upgrade would never take.
|
||||
#
|
||||
# Newest by when it arrived, never by how its name sorts: a version string is whatever the source was
|
||||
# described as, and those do not sort — "1.10" orders before "1.9". Ordering by name would start an
|
||||
# older host and call it an upgrade.
|
||||
pick_host() {
|
||||
if [ -s "$PINNED" ]; then
|
||||
pinned="$(tr -d '[:space:]' < "$PINNED" 2>/dev/null || true)"
|
||||
if [ -n "$pinned" ] && [ -x "$VERSIONS/$pinned/$BINARY" ]; then
|
||||
echo "$VERSIONS/$pinned/$BINARY"
|
||||
return 0
|
||||
fi
|
||||
say "the pinned version '$pinned' is not delivered; ignoring the pin"
|
||||
fi
|
||||
# A directory with no executable in it is not a version: an interrupted delivery leaves one, and
|
||||
# running "the newest" would then mean running nothing.
|
||||
for candidate in $(ls -1t "$VERSIONS" 2>/dev/null || true); do
|
||||
if [ -x "$VERSIONS/$candidate/$BINARY" ]; then
|
||||
echo "$VERSIONS/$candidate/$BINARY"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo "$FALLBACK"
|
||||
}
|
||||
|
||||
child=
|
||||
stopping=
|
||||
|
||||
@@ -95,6 +130,14 @@ while :; do
|
||||
fi
|
||||
fi
|
||||
|
||||
HOST="$(pick_host)"
|
||||
if [ ! -x "$HOST" ]; then
|
||||
say "no host to run: nothing delivered under $VERSIONS and $FALLBACK is not executable."
|
||||
printf 'no host binary\n' > "$HALTED"
|
||||
exit 0
|
||||
fi
|
||||
say "running $HOST"
|
||||
|
||||
"$HOST" run &
|
||||
child=$!
|
||||
status=0
|
||||
|
||||
Reference in New Issue
Block a user