#!/usr/bin/env bash # # health-check.sh — Probe the Zopu execution plane. # # Checks (TCP/process-level; no assumed HTTP health routes): # 1. zopu-daemon systemd unit is active # 2. zopu-agent systemd unit is active # 3. RivetKit engine TCP port (RIVET_ENDPOINT, default 6420) accepts connections # 4. Flue agent TCP port (PORT, default 3583) accepts connections # 5. Docker daemon is reachable # # Flue does not expose a health endpoint by design. RivetKit's health route # is internal to the registry runtime. We use TCP connection checks only. # # Usage: # health-check.sh # print results # health-check.sh --quiet # suppress output, exit 0 only if all healthy # # Exit codes: 0 = all healthy, 1 = one or more unhealthy set -euo pipefail QUIET=false [[ "${1:-}" == "--quiet" ]] && QUIET=true GREEN='\033[0;32m' RED='\033[0;31m' NC='\033[0m' pass() { $QUIET || echo -e " ${GREEN}PASS${NC} $*"; } fail() { echo -e " ${RED}FAIL${NC} $*" >&2; FAILURES=$((FAILURES + 1)); } FAILURES=0 # --------------------------------------------------------------------------- # Load environment # --------------------------------------------------------------------------- ENV_FILE="${ENV_FILE:-/opt/zopu/.env}" if [[ -f "$ENV_FILE" ]]; then # shellcheck source=/dev/null set -a . "$ENV_FILE" set +a fi RIVET_PORT="6420" if [[ -n "${RIVET_ENDPOINT:-}" ]]; then RIVET_PORT=$(echo "$RIVET_ENDPOINT" | sed -n 's|.*://[^:]*:\([0-9]*\).*|\1|p') [[ -z "$RIVET_PORT" ]] && RIVET_PORT="6420" fi AGENT_PORT="${PORT:-3583}" # --------------------------------------------------------------------------- # TCP probe helper: works on Debian (nc from netcat-openbsd) and macOS. # Falls back to bash /dev/tcp if nc is unavailable. # --------------------------------------------------------------------------- tcp_probe() { local host="$1" port="$2" if command -v nc &>/dev/null; then nc -z -w 5 "$host" "$port" 2>/dev/null else timeout 5 bash -c "echo > /dev/tcp/${host}/${port}" 2>/dev/null fi } # --------------------------------------------------------------------------- # 1. Daemon systemd unit # --------------------------------------------------------------------------- if systemctl is-active --quiet zopu-daemon 2>/dev/null; then pass "zopu-daemon service is active" else fail "zopu-daemon service is not active" fi # --------------------------------------------------------------------------- # 2. Agent systemd unit # --------------------------------------------------------------------------- if systemctl is-active --quiet zopu-agent 2>/dev/null; then pass "zopu-agent service is active" else fail "zopu-agent service is not active" fi # --------------------------------------------------------------------------- # 3. RivetKit engine TCP port # --------------------------------------------------------------------------- if tcp_probe localhost "$RIVET_PORT"; then pass "RivetKit engine port ${RIVET_PORT} is accepting connections" else fail "RivetKit engine port ${RIVET_PORT} is not accepting connections" fi # --------------------------------------------------------------------------- # 4. Flue agent TCP port # --------------------------------------------------------------------------- if tcp_probe localhost "$AGENT_PORT"; then pass "Flue agent port ${AGENT_PORT} is accepting connections" else fail "Flue agent port ${AGENT_PORT} is not accepting connections" fi # --------------------------------------------------------------------------- # 5. Docker daemon # --------------------------------------------------------------------------- if docker info &>/dev/null; then pass "Docker daemon is reachable" else fail "Docker daemon is not reachable" fi # --------------------------------------------------------------------------- # Summary # --------------------------------------------------------------------------- $QUIET || echo "" if [[ "$FAILURES" -eq 0 ]]; then $QUIET || echo -e "${GREEN}All checks passed.${NC}" exit 0 else echo -e "${RED}${FAILURES} check(s) failed.${NC}" >&2 exit 1 fi