bb17615f41
SLICE-03 (devops-engineer): ported from coreci/scripts/proxmox/: api.sh (verbatim), ct-exists.sh, lxc-clone.sh (4GB/16GB, hostname=praxis), lxc-config.sh (praxis env vars, praxis-firstboot.sh snippet), lxc-start.sh, stage-snippet.sh (G-101 FIX: bakes GITEA_TOKEN into snippet via sed), timing.sh (verbatim), rollback.sh (proxy code removed) SLICE-04 (devops-engineer): health-check.sh adapted for /health:8789 (G-104 FIX: timeout bumped 300s→600s for Docker build margin) REQ-DEPLOY-03, 04, 05, 07, 08 covered. ---ci--- project: praxis phase: 1 milestone: v0.2 status: execute slice: 03-04 wave: 2 ---/ci---
70 lines
2.5 KiB
Bash
Executable File
70 lines
2.5 KiB
Bash
Executable File
#!/bin/sh
|
|
# Praxis — Poll a deployed LXC container's /health endpoint.
|
|
#
|
|
# Adapted from coreci/scripts/proxmox/health-check.sh.
|
|
# Coreci polls /healthz:18080; praxis polls /health:8789.
|
|
#
|
|
# If PRAXIS_HEALTH_URL is set, use it directly. Otherwise, query
|
|
# the Proxmox /interfaces endpoint for the CT's bridge IP and
|
|
# construct http://<ip>:<port>/health.
|
|
#
|
|
# Env: PROXMOX_API_URL, PROXMOX_API_TOKEN, PROXMOX_NODE,
|
|
# PRAXIS_HEALTH_URL (optional override), PRAXIS_PORT (default 8789),
|
|
# PRAXIS_HEALTH_TIMEOUT (default 600 — first-boot Docker build +
|
|
# compose up may take up to 5 min; G-104 FIX bumped from 300s to
|
|
# give margin vs the 5-min worst-case build time per RESEARCH.md Q7)
|
|
# Args: $1 = VMID
|
|
# Exit: 0 if healthy within timeout, 1 otherwise
|
|
|
|
set -eu
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
# shellcheck source=api.sh disable=SC1091
|
|
. "${SCRIPT_DIR}/api.sh"
|
|
|
|
pve_env PROXMOX_API_URL PROXMOX_API_TOKEN PROXMOX_NODE
|
|
|
|
vmid="${1:?usage: health-check.sh <vmid>}"
|
|
http_port="${PRAXIS_PORT:-8789}"
|
|
timeout_s="${PRAXIS_HEALTH_TIMEOUT:-600}"
|
|
|
|
# Resolve health URL
|
|
if [ -n "${PRAXIS_HEALTH_URL:-}" ]; then
|
|
health_url="${PRAXIS_HEALTH_URL}"
|
|
else
|
|
# Query the CT's network interfaces for the bridge IP.
|
|
node="${PROXMOX_NODE}"
|
|
ifaces=$(pve_get "/nodes/${node}/lxc/${vmid}/interfaces" 2>/dev/null || true)
|
|
if [ -z "$ifaces" ] || [ "$ifaces" = "null" ]; then
|
|
echo "health-check: cannot resolve bridge IP for VMID ${vmid} (set PRAXIS_HEALTH_URL)" >&2
|
|
exit 1
|
|
fi
|
|
# Pick the first non-loopback IPv4 address. Emit only the IP fields
|
|
# (not hwaddr — it precedes .inet/.ip in PVE's response and head -1
|
|
# would pick the MAC — a bug fixed in coreci v3.6 P18 review).
|
|
ip=$(printf '%s' "$ifaces" | jq -r \
|
|
'.[] | select(.name != "lo") | (.inet? // .ip? // empty)' 2>/dev/null | grep -v '^$' | head -1)
|
|
if [ -z "$ip" ] || [ "$ip" = "null" ]; then
|
|
echo "health-check: no bridge IP found for VMID ${vmid} (set PRAXIS_HEALTH_URL)" >&2
|
|
exit 1
|
|
fi
|
|
health_url="http://${ip}:${http_port}/health"
|
|
fi
|
|
|
|
echo "health-check: polling ${health_url} for up to ${timeout_s}s..." >&2
|
|
ok=0
|
|
# shellcheck disable=SC2034
|
|
for i in $(seq 1 "$timeout_s"); do
|
|
if curl -fsS --connect-timeout 2 "$health_url" >/dev/null 2>&1; then
|
|
ok=1
|
|
break
|
|
fi
|
|
sleep 1
|
|
done
|
|
|
|
if [ "$ok" -ne 1 ]; then
|
|
echo "health-check: praxis did not become healthy within ${timeout_s}s at ${health_url}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo "health-check: praxis healthy at ${health_url}" >&2 |