redirector.sh: never leave it ambiguous which binary is under test
Two defects, both found by the guards misfiring rather than by reading: 1. BIN preferred target/debug and fell back to release only when debug was absent. `cargo build --release` therefore produced a correct binary while the script kept inspecting a stale debug one, and the build guard refused with a message naming a commit nobody was trying to run. The guard was right that something was stale — it just pointed at the wrong artifact. Disagreement between the two is now an explicit refusal naming both, with OPENFUT_REDIRECTOR_BIN as the deliberate override. The refusal is recorded at load and raised only by `verify` and `start`. `stop` and `status` must work in any build-tree state: rollback can never be blocked by a question about which artifact would have been started. 2. `verify-running` read the stamp file without checking the process still existed. The stamp outlives the process, so after a stop it reported on a corpse — either "identity OK" or a REFUSAL naming a commit, both implying something was running when nothing was. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -22,8 +22,36 @@ PORTFILE="$RUNDIR/redirector.port"
|
||||
# when the branch ref moves) can silently advance past the live process.
|
||||
STAMPFILE="$RUNDIR/redirector.commit"
|
||||
LOGFILE="${OPENFUT_REDIRECTOR_LOG:-$RUNDIR/redirector.log}"
|
||||
BIN="$ROOT/target/debug/openfut-redirector-host"
|
||||
[[ -x "$BIN" ]] || BIN="$ROOT/target/release/openfut-redirector-host"
|
||||
# Which artifact is under test must never be ambiguous. Preferring debug and
|
||||
# falling back to release meant `cargo build --release` could produce a fresh
|
||||
# binary while this kept launching a stale debug one — the guard then compared
|
||||
# the WRONG artifact against HEAD and refused with a message naming a commit
|
||||
# nobody was trying to run. Both present and disagreeing is an error, not a
|
||||
# preference. Set OPENFUT_REDIRECTOR_BIN to choose deliberately.
|
||||
DEBUG_BIN="$ROOT/target/debug/openfut-redirector-host"
|
||||
RELEASE_BIN="$ROOT/target/release/openfut-redirector-host"
|
||||
BIN_ERR=""
|
||||
if [[ -n "${OPENFUT_REDIRECTOR_BIN:-}" ]]; then
|
||||
BIN="$OPENFUT_REDIRECTOR_BIN"
|
||||
[[ -x "$BIN" ]] || { echo "redirector: OPENFUT_REDIRECTOR_BIN is not executable: $BIN" >&2; exit 1; }
|
||||
elif [[ -x "$DEBUG_BIN" && -x "$RELEASE_BIN" ]]; then
|
||||
d="$("$DEBUG_BIN" --identity 2>&1 | sed -nE 's/.*commit=([0-9a-f]+).*/\1/p' | head -1)"
|
||||
r="$("$RELEASE_BIN" --identity 2>&1 | sed -nE 's/.*commit=([0-9a-f]+).*/\1/p' | head -1)"
|
||||
if [[ "$d" != "$r" ]]; then
|
||||
# Recorded, NOT fatal here: `stop` and `status` must keep working no matter
|
||||
# what state the build tree is in. Rolling back can never be blocked by a
|
||||
# question about which artifact would have been started.
|
||||
BIN_ERR="REFUSING — two binaries exist and disagree.
|
||||
debug $DEBUG_BIN commit=$d
|
||||
release $RELEASE_BIN commit=$r
|
||||
Rebuild both, delete one, or set OPENFUT_REDIRECTOR_BIN."
|
||||
fi
|
||||
BIN="$RELEASE_BIN"
|
||||
elif [[ -x "$DEBUG_BIN" ]]; then
|
||||
BIN="$DEBUG_BIN"
|
||||
else
|
||||
BIN="$RELEASE_BIN"
|
||||
fi
|
||||
|
||||
die() { echo "redirector: $*" >&2; exit 1; }
|
||||
pid_alive() { kill -0 "$1" 2>/dev/null; }
|
||||
@@ -48,16 +76,21 @@ list_procs() {
|
||||
return 0
|
||||
}
|
||||
|
||||
# Only the commands that actually run a binary care which one it is.
|
||||
need_bin() { [[ -z "$BIN_ERR" ]] || die "$BIN_ERR"; }
|
||||
|
||||
# The binary prints `commit=<sha>` in its banner; ask it rather than guessing.
|
||||
stamped_commit() { "$BIN" --identity 2>&1 | sed -nE 's/.*commit=([0-9a-f]+).*/\1/p' | head -1; }
|
||||
|
||||
cmd_verify() {
|
||||
need_bin
|
||||
local c; c="$(stamped_commit)"
|
||||
[[ -n "$c" ]] || die "could not read the binary's commit stamp"
|
||||
"$ROOT/scripts/verify-build-identity.sh" "$c"
|
||||
}
|
||||
|
||||
cmd_start() {
|
||||
need_bin
|
||||
[[ -x "$BIN" ]] || die "not built: cargo build -p openfut-redirector-host"
|
||||
: "${OPENFUT_REDIRECTOR_HOST_PORT:?set OPENFUT_REDIRECTOR_HOST_PORT (no default: runs beside Python)}"
|
||||
local strays; strays="$(list_procs)"
|
||||
@@ -115,6 +148,15 @@ cmd_status() {
|
||||
}
|
||||
|
||||
cmd_verify_running() {
|
||||
# The stamp outlives the process it describes. Without this check the command
|
||||
# happily reports on a corpse — either "OK" or a REFUSAL naming a commit,
|
||||
# both implying something is running when nothing is.
|
||||
local pid=""
|
||||
[[ -f "$PIDFILE" ]] && pid="$(cat "$PIDFILE" 2>/dev/null)"
|
||||
if [[ -z "$pid" ]] || ! pid_alive "$pid"; then
|
||||
echo "REFUSING: nothing is running — the stamp describes a process that has exited." >&2
|
||||
return 1
|
||||
fi
|
||||
[[ -f "$STAMPFILE" ]] || die "no running-process stamp — was it started by this script?"
|
||||
local running head
|
||||
running="$(cat "$STAMPFILE")"; head="$(git -C "$ROOT" rev-parse --short=7 HEAD 2>/dev/null)"
|
||||
|
||||
Reference in New Issue
Block a user