Skip to content

Commit dc630ca

Browse files
authored
ci: backport arm64 watchdog drop-test fixes to Intel runner-watchdog (#924)
Ports the three fixes proven by the .227 arm64 drop test (PR #923) onto the Intel node's runner-watchdog: manage the launchd LaunchAgent in the gui/$UID domain, use config.sh remove (not --replace) before a fresh configure, and mint a remove-token to deregister server-side. Drop test on .204 is UNVERIFIED pending SSH access restoration.
1 parent 767afe7 commit dc630ca

1 file changed

Lines changed: 58 additions & 14 deletions

File tree

scripts/ci/runner-watchdog-mac-intel.sh

Lines changed: 58 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,19 @@
1313
# token minted with repo-admin creds, which live here on the bridge, not
1414
# on the Mac node. This watchdog closes that gap.
1515
#
16+
# Sibling of runner-watchdog-mac-arm.sh (PR #923). This is the backport of
17+
# that PR's three drop-test-proven fixes onto the Intel node.
18+
#
1619
# WHAT IT DOES (idempotent, non-destructive):
1720
# 1. Polls the repo's runners API for macpro-intel-204.
1821
# 2. If the runner is absent or "offline" for >= THRESHOLD consecutive
1922
# checks, mints a fresh registration token and re-registers the runner
20-
# over SSH using `config.sh --replace` (no delete; --replace reuses the
21-
# same name), then reloads the launchd service.
23+
# over SSH (see the launchd/config sequence below), then reloads the
24+
# launchd service into the GUI domain.
2225
# 3. Resets the failure counter as soon as the runner is seen online.
2326
#
2427
# REVERT: delete this file + remove its launchd/cron entry on the bridge.
25-
# It never deletes the runner; --replace is the only mutation it makes.
28+
# It never deletes the runner; it re-registers under the same name.
2629
#
2730
set -euo pipefail
2831

@@ -62,20 +65,61 @@ log "status=${status} consecutive_fails=${fails}/${THRESHOLD}"
6265
[ "$fails" -lt "$THRESHOLD" ] && exit 0
6366

6467
log "threshold reached -> re-registering"
65-
TOKEN=$(gh api --method POST "repos/${REPO}/actions/runners/registration-token" --jq .token)
66-
[ -z "$TOKEN" ] && { log "ERROR: empty registration token"; exit 1; }
68+
REG_TOKEN=$(gh api --method POST "repos/${REPO}/actions/runners/registration-token" --jq .token)
69+
[ -z "$REG_TOKEN" ] && { log "ERROR: empty registration token"; exit 1; }
70+
# Removal token deregisters the stale server-side registration + wipes local
71+
# config so a clean re-register succeeds. Best-effort: if GitHub already
72+
# dropped the runner ("absent"), remove is a no-op and we fall back to
73+
# wiping the local config files directly.
74+
RM_TOKEN=$(gh api --method POST "repos/${REPO}/actions/runners/remove-token" --jq .token 2>/dev/null || true)
6775

68-
ssh -i "$NODE_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no "$NODE_SSH" bash -s <<EOF
76+
# The original Intel 5-liner (svc.sh stop -> config.sh --replace -> svc.sh
77+
# start) was never drop-tested and is non-functional for a *deregistered*
78+
# runner, for two reasons proven by the .227 arm64 drop test 2026-07-27
79+
# (PR #923) and expected to hold identically on this Intel node:
80+
# (a) The runner's launchd LaunchAgent lives in the user's *GUI* (Aqua)
81+
# domain. Over a non-GUI SSH session `svc.sh install/uninstall`
82+
# (plain `launchctl load/unload`) fail with "Unload failed: 5:
83+
# Input/output error". The agent must be managed with an explicit
84+
# `launchctl bootout|bootstrap gui/$UID ...` target.
85+
# (b) `config.sh --replace` does NOT bypass the local "already configured"
86+
# guard; a real `config.sh remove` (or wiping .runner/.credentials)
87+
# must precede a fresh `config.sh` configure.
88+
# Sequence: bootout+uninstall service -> unconfigure -> fresh configure ->
89+
# install + bootstrap+kickstart into the GUI domain. Non-destructive: no
90+
# runner is deleted beyond its own re-registration under the same name.
91+
ssh -i "$NODE_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no "$NODE_SSH" \
92+
REG_TOKEN="$REG_TOKEN" RM_TOKEN="$RM_TOKEN" REPO="$REPO" \
93+
RUNNER_NAME="$RUNNER_NAME" RUNNER_LABELS="$RUNNER_LABELS" RUNNER_DIR="$RUNNER_DIR" \
94+
bash -s <<'EOF'
6995
set -e
70-
cd "${RUNNER_DIR}"
71-
./svc.sh stop || true
72-
./config.sh remove --token "${TOKEN}" || true
73-
./config.sh --unattended --replace \
96+
cd "$RUNNER_DIR"
97+
U=$(id -u)
98+
LABEL="actions.runner.$(echo "$REPO" | tr '/' '-').${RUNNER_NAME}"
99+
PLIST="$HOME/Library/LaunchAgents/${LABEL}.plist"
100+
101+
# 1) stop + uninstall the LaunchAgent from the GUI domain
102+
launchctl bootout "gui/${U}/${LABEL}" 2>/dev/null || true
103+
./svc.sh uninstall 2>/dev/null || true
104+
105+
# 2) unconfigure (deregister + wipe local config); fall back to wiping files
106+
if [ -n "$RM_TOKEN" ]; then
107+
./config.sh remove --token "$RM_TOKEN" || rm -f .runner .credentials .credentials_rsaparams
108+
else
109+
rm -f .runner .credentials .credentials_rsaparams
110+
fi
111+
112+
# 3) fresh register under the same name + labels
113+
./config.sh --unattended \
74114
--url "https://github.com/${REPO}" \
75-
--token "${TOKEN}" \
76-
--name "${RUNNER_NAME}" \
77-
--labels "${RUNNER_LABELS}"
78-
./svc.sh start
115+
--token "$REG_TOKEN" \
116+
--name "$RUNNER_NAME" \
117+
--labels "$RUNNER_LABELS"
118+
119+
# 4) (re)install + load the service into the GUI domain
120+
./svc.sh install
121+
launchctl bootstrap "gui/${U}" "$PLIST" 2>/dev/null || true
122+
launchctl kickstart -k "gui/${U}/${LABEL}"
79123
EOF
80124

81125
log "re-registration issued; clearing fail counter"

0 commit comments

Comments
 (0)