diff --git a/deploy/onboard-node.sh b/deploy/onboard-node.sh index 0d82ffe..5208c4d 100644 --- a/deploy/onboard-node.sh +++ b/deploy/onboard-node.sh @@ -14,13 +14,15 @@ # MAM_API_URL=http://10.0.0.25:47432 NODE_TOKEN=wd_xxxx ./deploy/onboard-node.sh # # Environment variables: -# MAM_API_URL REQUIRED Primary MAM API base URL -# NODE_TOKEN API bearer token (required if AUTH_ENABLED=true) -# NODE_ROLE Role tag reported to the cluster (default: worker) -# AGENT_PORT Host port for the node agent (default: 7436) -# INSTALL_DIR Where to clone/find the repo (default: /opt/wild-dragon) -# PROFILES Extra compose profiles, space-separated e.g. "worker" -# REPO_URL Override the Forgejo clone URL +# MAM_API_URL REQUIRED Primary MAM API base URL +# NODE_TOKEN API bearer token (required if AUTH_ENABLED=true) +# NODE_ROLE Role tag reported to the cluster (default: worker) +# NODE_IP Override the LAN IP reported back (default: auto-detect) +# AGENT_PORT Host port for the node agent (default: 7436) +# INSTALL_DIR Where to clone/find the repo (default: /opt/wild-dragon) +# PROFILES Extra compose profiles, space-sep e.g. "worker capture" +# BMD_MODEL DeckLink card model name (e.g. "DeckLink Duo 2") +# REPO_URL Override the Forgejo clone URL # ============================================================================= set -euo pipefail @@ -31,8 +33,10 @@ INSTALL_DIR="${INSTALL_DIR:-/opt/wild-dragon}" MAM_API_URL="${MAM_API_URL:-}" NODE_TOKEN="${NODE_TOKEN:-}" NODE_ROLE="${NODE_ROLE:-worker}" +NODE_IP="${NODE_IP:-}" AGENT_PORT="${AGENT_PORT:-7436}" PROFILES="${PROFILES:-}" +BMD_MODEL="${BMD_MODEL:-}" PROJECT_NAME="wild-dragon-worker" # ── Colours ────────────────────────────────────────────────────────────────── @@ -44,16 +48,44 @@ warn() { echo -e "${YEL} ⚠${NC} $*"; } header() { echo -e "\n${BLD}${CYN}── $* ──────────────────────────────────────${NC}"; } die() { echo -e "${RED} ✗ ERROR:${NC} $*" >&2; exit 1; } +# ── Auto-detect LAN IP ─────────────────────────────────────────────────────── +# Node-agent runs in a container; os.networkInterfaces() inside the container +# returns the docker-bridge IP unless we pass NODE_IP through. We resolve the +# host's primary LAN IP here so the cluster page shows the right address. +detect_lan_ip() { + local ip="" + if command -v ip &>/dev/null; then + ip=$(ip -4 route get 1.1.1.1 2>/dev/null \ + | awk '/src/ {for(i=1;i<=NF;i++) if($i=="src"){print $(i+1); exit}}' \ + || true) + fi + if [[ -z "$ip" ]] && command -v hostname &>/dev/null; then + ip=$(hostname -I 2>/dev/null | awk '{print $1}' || true) + fi + echo "$ip" +} + # ── Preflight ──────────────────────────────────────────────────────────────── echo -e "\n${BLD}${CYN}Wild Dragon MAM — Cluster Node Onboarding${NC}\n" [[ -z "$MAM_API_URL" ]] && die "MAM_API_URL is required.\n\n Example:\n export MAM_API_URL=http://10.0.0.25:47432\n export NODE_TOKEN=wd_xxxx\n ./deploy/onboard-node.sh" +if [[ -z "$NODE_IP" ]]; then + NODE_IP="$(detect_lan_ip)" + if [[ -n "$NODE_IP" ]]; then + info "Auto-detected LAN IP: $NODE_IP" + else + warn "Could not auto-detect LAN IP — agent will fall back to interface heuristics." + fi +fi + info "Primary API : $MAM_API_URL" info "Role : $NODE_ROLE" info "Agent port : $AGENT_PORT" info "Install dir : $INSTALL_DIR" -[[ -n "$PROFILES" ]] && info "Profiles : $PROFILES" +[[ -n "$NODE_IP" ]] && info "Node IP : $NODE_IP" +[[ -n "$BMD_MODEL" ]] && info "DeckLink : $BMD_MODEL" +[[ -n "$PROFILES" ]] && info "Profiles : $PROFILES" if [[ -z "$NODE_TOKEN" ]]; then warn "NODE_TOKEN is not set." @@ -68,7 +100,6 @@ if ! command -v docker &>/dev/null; then warn "Docker not found — installing via get.docker.com" curl -fsSL https://get.docker.com | bash systemctl enable --now docker 2>/dev/null || true - # Add current user to docker group (effective on next login) usermod -aG docker "${SUDO_USER:-$USER}" 2>/dev/null || true log "Docker installed" else @@ -104,8 +135,10 @@ info "Writing $ENV_FILE" echo "MAM_API_URL=$MAM_API_URL" echo "NODE_TOKEN=$NODE_TOKEN" echo "NODE_ROLE=$NODE_ROLE" + echo "NODE_IP=$NODE_IP" echo "AGENT_PORT=$AGENT_PORT" echo "HEARTBEAT_MS=30000" + [[ -n "$BMD_MODEL" ]] && echo "BMD_MODEL=$BMD_MODEL" for v in REDIS_URL DATABASE_URL S3_ENDPOINT S3_BUCKET S3_ACCESS_KEY S3_SECRET_KEY S3_REGION; do val="${!v:-}" [[ -n "$val" ]] && echo "$v=$val" @@ -139,6 +172,8 @@ sleep 6 HEALTH_URL="http://localhost:$AGENT_PORT/health" if curl -sf "$HEALTH_URL" > /dev/null 2>&1; then log "Node agent healthy at $HEALTH_URL" + REPORTED_IP=$(curl -sf "$HEALTH_URL" | sed -nE 's/.*"ip":"([^"]+)".*/\1/p') + [[ -n "$REPORTED_IP" ]] && log "Reporting IP: $REPORTED_IP" else warn "Could not reach $HEALTH_URL — check logs:" warn " $COMPOSE logs node-agent" @@ -151,6 +186,7 @@ echo "" echo -e " Node agent ${BLD}:$AGENT_PORT${NC} (heartbeating every 30s)" echo -e " Primary API ${BLD}$MAM_API_URL${NC}" echo -e " Role ${BLD}$NODE_ROLE${NC}" +[[ -n "$NODE_IP" ]] && echo -e " Node IP ${BLD}$NODE_IP${NC}" echo "" echo -e " ${CYN}Useful commands:${NC}" echo -e " Status : $COMPOSE ps"