master
sh 83 lines 3.07 KB
Raw
1 #!/usr/bin/env bash
2 # Keep the Coverity Scan session warm during a triage run.
3 #
4 # DESIGN — the script EXITS NON-ZERO the moment a ping fails. That fires the
5 # orchestrator's background-task completion notification, so the agent learns
6 # *immediately* that the cookie went bad and can ask the user to recapture it.
7 # DO NOT silently retry — silent retries hide the failure and waste a triage
8 # session's worth of work.
9 #
10 # The Coverity session cookie expires after a few minutes of inactivity AND
11 # requires the user's browser tab on https://scan.coverity.com to be open.
12 # Closing the browser tab kills the session immediately; pings stop working.
13 #
14 # Usage (from an orchestrator agent):
15 # Bash tool with run_in_background=true,
16 # command="bash .agents/skills/coverity-audit/scripts/keepalive.sh"
17 #
18 # Stop the background task at the end of the triage session.
19 #
20 # Environment overrides:
21 # PING_INTERVAL seconds between pings (default 300 = 5 min)
22
23 set -euo pipefail
24
25 # shellcheck source=./_lib.sh
26 # shellcheck disable=SC1091
27 source "$(dirname "$0")/_lib.sh"
28 cov_load_env
29
30 PING_INTERVAL="${PING_INTERVAL:-300}"
31
32 # Pick a cheap, authenticated endpoint. /reports/table.json with the configured
33 # Outstanding view is ideal — it returns proper JSON when authenticated and
34 # HTML (Cloudflare challenge or login redirect) when not.
35 if [[ -z "${COVERITY_VIEW_OUTSTANDING:-}" ]]; then
36 echo -e "${COV_RED}[ERROR]${COV_NC} COVERITY_VIEW_OUTSTANDING is not set in .env -- keepalive needs a viewId to ping. See SKILL.md." >&2
37 exit 1
38 fi
39 if [[ ! "${COVERITY_VIEW_OUTSTANDING}" =~ ^[1-9][0-9]*$ ]]; then
40 echo -e "${COV_RED}[ERROR]${COV_NC} COVERITY_VIEW_OUTSTANDING must be a positive integer (got: '${COVERITY_VIEW_OUTSTANDING}')" >&2
41 exit 1
42 fi
43
44 PING_URL="${COVERITY_HOST}/reports/table.json?projectId=${COVERITY_PROJECT_ID}&viewId=${COVERITY_VIEW_OUTSTANDING}"
45
46 ping_once() {
47 local body rc
48 # Capture both body and HTTP code in one go.
49 body="$(curl -sS --max-time 30 \
50 -H "accept: application/json, text/plain, */*" \
51 -H "user-agent: ${COVERITY_USER_AGENT}" \
52 -H "referer: ${COVERITY_HOST}/" \
53 -b "${COVERITY_COOKIE}" \
54 "${PING_URL}" 2>/dev/null)" || {
55 rc=$?
56 echo "[$(date -Iseconds)] FAIL curl rc=${rc}" >&2
57 return 1
58 }
59
60 if [[ -z "${body}" ]]; then
61 echo "[$(date -Iseconds)] FAIL empty response -- session likely expired" >&2
62 return 1
63 fi
64
65 # Validate the JSON shape -- a Cloudflare challenge or login redirect
66 # returns HTML; we want the structured response.
67 if ! printf '%s' "${body}" | jq -e '.resultSet.results' >/dev/null 2>&1; then
68 echo "[$(date -Iseconds)] FAIL response shape invalid (first 80 chars: '${body:0:80}') -- session likely expired or browser tab closed" >&2
69 return 1
70 fi
71
72 echo "[$(date -Iseconds)] OK" >&2
73 return 0
74 }
75
76 # First ping immediately -- if we're already dead, fail fast.
77 ping_once || exit 1
78 echo "[$(date -Iseconds)] keepalive running (interval=${PING_INTERVAL}s)" >&2
79
80 while true; do
81 sleep "${PING_INTERVAL}"
82 ping_once || exit 1
83 done