maestro/scripts/gateway.sh
2026-06-03 05:08:00 +00:00

163 lines
4.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Launch AAO in gateway mode (OpenAI-compatible LLM gateway, no UI).
#
# This is a sibling of scripts/server.sh (worker mode). Both can run
# concurrently on the same host because:
# - PID file: .gateway.pid (worker uses .server.pid)
# - Log file: logs/gateway.log (worker uses logs/server.log)
# - Listen port: $GATEWAY_PORT (default 4000)、worker は $PORT (default 9876)
# - DB: 同じ data/aao.db を SQLite WAL mode で共有
# (gateway は gateway_virtual_keys + gateway_key_usage の 2 table のみ touch)
#
# Usage:
# scripts/gateway.sh start
# scripts/gateway.sh stop
# scripts/gateway.sh restart
# scripts/gateway.sh status
# scripts/gateway.sh logs
#
# Env override:
# GATEWAY_PORT=4000 # gateway.listen_port を上書き (config.yaml より優先)
# AAO_CONFIG=/etc/aao/config-gateway.yaml # 専用 config を使う場合
# AAO_GATEWAY_NO_DB=1 # ステートレス起動 (virtual_keys は config 経由のみ、budget/rate-limit 無効)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
PID_FILE="$PROJECT_DIR/.gateway.pid"
LOG_FILE="$PROJECT_DIR/logs/gateway.log"
GATEWAY_PORT="${GATEWAY_PORT:-4000}"
cd "$PROJECT_DIR"
usage() {
echo "Usage: $0 {start|stop|restart|status|logs}"
echo
echo "Env:"
echo " GATEWAY_PORT=$GATEWAY_PORT"
echo " AAO_CONFIG=${AAO_CONFIG:-<repo config.yaml>}"
echo " AAO_GATEWAY_NO_DB=${AAO_GATEWAY_NO_DB:-<unset, DB enabled>}"
exit 1
}
is_running() {
if [[ -f "$PID_FILE" ]]; then
local pid
pid=$(cat "$PID_FILE")
if kill -0 "$pid" 2>/dev/null; then
return 0
fi
rm -f "$PID_FILE"
fi
return 1
}
do_start() {
if is_running; then
echo "Gateway already running (PID $(cat "$PID_FILE"))"
return 0
fi
mkdir -p "$(dirname "$LOG_FILE")"
echo "Checking runtime dependencies..."
"$SCRIPT_DIR/prepare.sh"
echo "Building..."
npm run build --silent 2>&1 | tail -1
echo "Starting gateway on port $GATEWAY_PORT..."
# AAO_MODE=gateway は src/main.ts の switch を gateway/bootstrap に向ける
# GATEWAY_PORT は src/gateway/config.ts が config.yaml の listen_port を
# env で上書きするためのキー (実装側で env > config の precedence)。
AAO_MODE=gateway \
GATEWAY_PORT="$GATEWAY_PORT" \
${AAO_CONFIG:+AAO_CONFIG="$AAO_CONFIG"} \
${AAO_GATEWAY_NO_DB:+AAO_GATEWAY_NO_DB="$AAO_GATEWAY_NO_DB"} \
nohup node dist/main.js >> "$LOG_FILE" 2>&1 &
local pid=$!
echo "$pid" > "$PID_FILE"
# Wait briefly and verify it started
sleep 2
if kill -0 "$pid" 2>/dev/null; then
echo "Gateway started (PID $pid, log: $LOG_FILE)"
echo " Health: curl http://localhost:$GATEWAY_PORT/health/liveness"
echo " Metrics: curl http://localhost:$GATEWAY_PORT/metrics"
else
rm -f "$PID_FILE"
echo "Gateway failed to start. Last 20 log lines:"
tail -20 "$LOG_FILE"
return 1
fi
}
do_stop() {
if ! is_running; then
echo "Gateway not running"
# Also kill any stray process on the port
local stray
stray=$(lsof -ti:"$GATEWAY_PORT" 2>/dev/null || true)
if [[ -n "$stray" ]]; then
echo "Found stray process on port $GATEWAY_PORT (PID $stray), killing..."
kill "$stray" 2>/dev/null || true
fi
return 0
fi
local pid
pid=$(cat "$PID_FILE")
echo "Stopping gateway (PID $pid)..."
# SIGTERM で graceful shutdown (gateway.shutdown_graceful_sec で SSE drain)
kill "$pid" 2>/dev/null || true
# Wait for graceful shutdown — gateway drain may take up to ~30s by default
for i in {1..60}; do
if ! kill -0 "$pid" 2>/dev/null; then
rm -f "$PID_FILE"
echo "Gateway stopped (graceful)"
return 0
fi
sleep 0.5
done
# Force kill
echo "Graceful shutdown timed out; force killing..."
kill -9 "$pid" 2>/dev/null || true
rm -f "$PID_FILE"
echo "Gateway stopped (forced)"
}
do_status() {
if is_running; then
local pid
pid=$(cat "$PID_FILE")
echo "Gateway running (PID $pid, port $GATEWAY_PORT)"
# Probe liveness for confirmation
if curl -sS -o /dev/null -w "%{http_code}" "http://localhost:$GATEWAY_PORT/health/liveness" 2>/dev/null | grep -q 200; then
echo " Liveness: OK"
else
echo " Liveness: NOT OK (process up but endpoint not responding)"
fi
else
echo "Gateway not running"
fi
}
do_logs() {
if [[ -f "$LOG_FILE" ]]; then
tail -f "$LOG_FILE"
else
echo "No log file found at $LOG_FILE"
fi
}
case "${1:-}" in
start) do_start ;;
stop) do_stop ;;
restart) do_stop; do_start ;;
status) do_status ;;
logs) do_logs ;;
*) usage ;;
esac