#!/bin/bash # deploy/hal-host-agent.sh — [0.4.1] HAL 서버 자신에 Node Agent(+HawkEye) 를 설치·등록·승인한다(개발 지시 v0.4.1 요구 2). # bootstrap-hal.sh 가 HAL 설치 직후 부르며(부트스트랩을 "미완료" 로 남기지 않는다), 0.4.0 이하로 설치된 기존 HAL 서버에서는 직접 실행한다: # cd /srv/ariweb/hal/current && bash deploy/hal-host-agent.sh [--hal-data /srv/ariweb/hal/data] [--hal-local http://127.0.0.1:8900] [--name <서버 이름>] [--agent-dir /srv/ariweb/agent] [--by bootstrap] # 왜 loopback 인가: HAL 서버의 Agent 는 HAL 에 http://127.0.0.1:8900 으로 붙는다 — DNS 레코드·공개 인증서(사설 CA 포함)와 무관하게 부트스트랩이 끝난다. 요청은 HMAC 서명이라 평문 loopback 으로 충분하다. # 설치 범위: Node Agent + HawkEye(Agent 안의 기능)만. Web·Mail·Backup·Portal 은 설치하지 않는다 — 기능 단위 서버로 따로 배포한다. # 멱등: 이미 이 서버에 Agent 가 있으면(agent.json) 재등록하지 않고 승인 상태만 확인한다. 토큰은 스크립트 안에서만 쓰고 출력하지 않는다. set -euo pipefail HAL_DATA="${ARIWEB_HAL_DATA:-/srv/ariweb/hal/data}"; HAL_LOCAL="http://127.0.0.1:8900"; NAME=""; AGENT_DIR="/srv/ariweb/agent"; BY="bootstrap" while [ $# -gt 0 ]; do case "$1" in --hal-data) HAL_DATA="$2"; shift 2;; --hal-local) HAL_LOCAL="$2"; shift 2;; --name) NAME="$2"; shift 2;; --agent-dir) AGENT_DIR="$2"; shift 2;; --by) BY="$2"; shift 2;; *) echo "알 수 없는 옵션 $1" >&2; exit 1;; esac; done HERE="$(cd "$(dirname "$0")/.." && pwd)"; cd "$HERE" # HAL 코드 트리(current) [ -n "$NAME" ] || NAME="$(hostname -f 2>/dev/null || hostname)" NODE_BIN="$(command -v node || true)"; [ -n "$NODE_BIN" ] || { echo "node 가 필요합니다" >&2; exit 1; } export ARIWEB_HAL_DATA="$HAL_DATA" json() { $NODE_BIN -e "let s='';process.stdin.on('data',c=>s+=c).on('end',()=>{const j=JSON.parse(s);const v=j[process.argv[1]];console.log(v==null?'':(typeof v==='object'?JSON.stringify(v):v))})" "$1"; } echo "== HAL 서버 Node Agent: HAL $HAL_LOCAL 확인" curl -fsS -m 5 "$HAL_LOCAL/api/health" >/dev/null || { echo "HAL 이 $HAL_LOCAL 에서 응답하지 않습니다(ariweb-hal 유닛·포트 확인)" >&2; exit 1; } if [ -f "$AGENT_DIR/data/agent.json" ]; then SRV="$(cat "$AGENT_DIR/data/agent.json" | json serverId)"; AG="$(cat "$AGENT_DIR/data/agent.json" | json id)" echo "== 이미 이 서버에 Agent 가 있습니다(Agent $AG, 서버 ${SRV:-?}) — 재등록하지 않습니다" [ -n "$SRV" ] || { echo "agent.json 에 서버 id 가 없어 승인을 진행할 수 없습니다" >&2; exit 1; } else echo "== 1/3 관리 서버 등록: $NAME (역할 control, 프로필 hal)" SRV="$($NODE_BIN --no-warnings hal/index.mjs server-create --name "$NAME" --role control --profile hal --by "$BY" | json id)"; [ -n "$SRV" ] || { echo "서버 생성 실패" >&2; exit 1; } echo "== 2/3 일회용 등록 토큰 → Agent 설치(loopback, 토큰은 표시하지 않음)" TOKEN="$($NODE_BIN --no-warnings hal/index.mjs server-token --server "$SRV" --by "$BY" --json | json token)"; [ -n "$TOKEN" ] || { echo "토큰 발급 실패" >&2; exit 1; } bash deploy/agent-install.sh --hal "$HAL_LOCAL" --token "$TOKEN" --role control --label "$NAME" --app-dir "$AGENT_DIR" fi echo "== 3/3 승인(부트스트랩 닫기)" OUT="$($NODE_BIN --no-warnings hal/index.mjs server-approve --server "$SRV" --by "$BY")"; echo " $OUT" [ "$(echo "$OUT" | json bootstrapComplete)" = "true" ] && echo "== 부트스트랩 완료 — 기능 단위 서버 배포 대기: $(echo "$OUT" | json pendingModules)" || { echo "부트스트랩이 아직 닫히지 않았습니다(HAL 실행 버전 기록 전?) — HAL 로그를 확인하세요" >&2; exit 1; }