#!/bin/bash # # redeploy_agent_ready_sites.sh — narrow redeploy + AgentReady check of the # three public static sites. # # Redeploy (skipped with --verify-only), the three steps run concurrently: # - setup_personal_website.sh serve recreate the kuhy.duckdns.org container # - setup_kcd2_dice_solver.sh serve recreate the dice.kuhy.duckdns.org one # - systemctl --user restart signal-bot-popes-site.service # None of these uses sudo, pacman, a rebuild or the shared edge: build first in # each site's own repo, then run this to make the new dist/ + Caddyfile live. # # Verify: ~/src/utils/agent_ready/check.sh url against each public URL, all # three at once, one verdict line per site in a fixed order (PASS, FAIL with # the failing check ids, or UNDETERMINED when the checker could not reach the # site or ran out of time). # # Usage: # redeploy_agent_ready_sites.sh Redeploy, then verify. # redeploy_agent_ready_sites.sh --verify-only Verify only; restarts nothing. # redeploy_agent_ready_sites.sh --help Show this help. # # Exit status: 0 when every step and every site passes, 1 otherwise, 2 on a # usage error. set -euo pipefail SCRIPT_DIR="$(dirname "$(readlink -f "$0")")" readonly SCRIPT_DIR readonly CHECKER="${HOME}/src/utils/agent_ready/check.sh" readonly POPES_UNIT="signal-bot-popes-site.service" readonly SITES=( "https://kuhy.duckdns.org" "https://dice.kuhy.duckdns.org" "https://popes.kuhy.duckdns.org" ) # Timing. A live check takes anywhere from under a second to ~22 s (measured), # so each one gets the checker's own 45 s network budget, which it enforces # itself and answers with exit 3 when spent. The whole run must end inside # 60 s, so that budget is cut to whatever is left before RUN_DEADLINE once the # redeploy is done. GRACE covers Python start-up and the post-network scoring # and is also the margin of the outer `timeout`, a backstop for a hung process. readonly RUN_DEADLINE="${AGENT_READY_RUN_DEADLINE:-55}" readonly CHECK_BUDGET_MAX=45 readonly CHECK_BUDGET_MIN=3 readonly GRACE=5 readonly SERVE_TIMEOUT=20 FAILED=0 CHECK_BUDGET=0 WORK_DIR="" usage() { # The header block only: it ends at the first non-comment line. sed -nE '2,/^[^#]/{/^#( |$)/s/^# ?//p}' "$0" exit "${1:-0}" } cleanup() { [[ -z $WORK_DIR ]] || rm -rf "$WORK_DIR" } # in_parallel ...: run ` ` for every arg at once, then print # each one's output in argument order. Runs in the background cannot set # FAILED themselves, so their exit status is collected here. in_parallel() { local fn="$1" arg i=0 pids=() shift for arg in "$@"; do "$fn" "$arg" >"${WORK_DIR}/${i}.out" 2>&1 & pids+=("$!") i=$((i + 1)) done for i in "${!pids[@]}"; do wait "${pids[$i]}" || FAILED=1 cat "${WORK_DIR}/${i}.out" done } # run_step