|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# runner-watchdog-mac-intel.sh |
| 4 | +# |
| 5 | +# Auto-reregister watchdog for the self-hosted macOS Intel CI runner |
| 6 | +# (macpro-intel-204, labels: self-hosted,macOS,X64,c2pool-mac-intel). |
| 7 | +# |
| 8 | +# WHERE THIS RUNS: the CI bridge / workstation -- NOT on the Mac node. |
| 9 | +# The node's launchd service already has KeepAlive(SuccessfulExit=false), |
| 10 | +# which restarts a *crashed runner process*. That alone cannot recover a |
| 11 | +# runner that GitHub has *deregistered* server-side (registration removed |
| 12 | +# or its auth token revoked): re-registration needs a fresh registration |
| 13 | +# token minted with repo-admin creds, which live here on the bridge, not |
| 14 | +# on the Mac node. This watchdog closes that gap. |
| 15 | +# |
| 16 | +# WHAT IT DOES (idempotent, non-destructive): |
| 17 | +# 1. Polls the repo's runners API for macpro-intel-204. |
| 18 | +# 2. If the runner is absent or "offline" for >= THRESHOLD consecutive |
| 19 | +# 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. |
| 22 | +# 3. Resets the failure counter as soon as the runner is seen online. |
| 23 | +# |
| 24 | +# 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. |
| 26 | +# |
| 27 | +set -euo pipefail |
| 28 | + |
| 29 | +REPO="${C2POOL_REPO:-frstrtr/c2pool}" |
| 30 | +RUNNER_NAME="${RUNNER_NAME:-macpro-intel-204}" |
| 31 | +NODE_SSH="${NODE_SSH:-user0@192.168.86.204}" |
| 32 | +NODE_KEY="${NODE_KEY:-$HOME/.ssh/agentmail_deploy}" |
| 33 | +RUNNER_DIR="${RUNNER_DIR:-/Users/user0/actions-runner}" |
| 34 | +RUNNER_LABELS="${RUNNER_LABELS:-self-hosted,macOS,X64,c2pool-mac-intel}" |
| 35 | +SVC_LABEL="actions.runner.frstrtr-c2pool.${RUNNER_NAME}" |
| 36 | + |
| 37 | +# Re-register only after this many consecutive offline observations, so a |
| 38 | +# single transient blip (job restart, brief network drop) does not trigger |
| 39 | +# a churn. With a 5-min poll, 3 == ~15 min sustained offline. |
| 40 | +THRESHOLD="${THRESHOLD:-3}" |
| 41 | +STATE_FILE="${STATE_FILE:-$HOME/.cache/c2pool-runner-watchdog/${RUNNER_NAME}.fails}" |
| 42 | + |
| 43 | +log() { printf '%s [runner-watchdog:%s] %s\n' "$(date -u +%FT%TZ)" "$RUNNER_NAME" "$*"; } |
| 44 | + |
| 45 | +mkdir -p "$(dirname "$STATE_FILE")" |
| 46 | +fails=$(cat "$STATE_FILE" 2>/dev/null || echo 0) |
| 47 | + |
| 48 | +# Status as GitHub sees it: "online" | "offline" | "absent". |
| 49 | +status=$(gh api "repos/${REPO}/actions/runners" \ |
| 50 | + --jq ".runners[] | select(.name==\"${RUNNER_NAME}\") | .status" 2>/dev/null || true) |
| 51 | +[ -z "$status" ] && status="absent" |
| 52 | + |
| 53 | +if [ "$status" = "online" ]; then |
| 54 | + [ "$fails" -ne 0 ] && log "back online; clearing fail counter ($fails -> 0)" |
| 55 | + echo 0 > "$STATE_FILE" |
| 56 | + exit 0 |
| 57 | +fi |
| 58 | + |
| 59 | +fails=$((fails + 1)) |
| 60 | +echo "$fails" > "$STATE_FILE" |
| 61 | +log "status=${status} consecutive_fails=${fails}/${THRESHOLD}" |
| 62 | +[ "$fails" -lt "$THRESHOLD" ] && exit 0 |
| 63 | + |
| 64 | +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; } |
| 67 | + |
| 68 | +ssh -i "$NODE_KEY" -o IdentitiesOnly=yes -o StrictHostKeyChecking=no "$NODE_SSH" bash -s <<EOF |
| 69 | +set -e |
| 70 | +cd "${RUNNER_DIR}" |
| 71 | +./svc.sh stop || true |
| 72 | +./config.sh remove --token "${TOKEN}" || true |
| 73 | +./config.sh --unattended --replace \ |
| 74 | + --url "https://github.com/${REPO}" \ |
| 75 | + --token "${TOKEN}" \ |
| 76 | + --name "${RUNNER_NAME}" \ |
| 77 | + --labels "${RUNNER_LABELS}" |
| 78 | +./svc.sh start |
| 79 | +EOF |
| 80 | + |
| 81 | +log "re-registration issued; clearing fail counter" |
| 82 | +echo 0 > "$STATE_FILE" |
0 commit comments