Files
Nexus/web/agent/install.sh
T

152 lines
4.9 KiB
Bash
Raw Normal View History

#!/bin/bash
# ================================================================
# Nexus Agent Install Script
2026-05-22 08:19:56 +08:00
# Usage: curl -fsSL https://YOUR_NEXUS_DOMAIN/agent/install.sh | bash -s -- --url https://YOUR_NEXUS_DOMAIN --key API_KEY --id SERVER_ID
#
# Network model:
# - Heartbeat: child → central HTTPS (443 outbound), no inbound 8601 required
# - Scripts / push: central → child SSH (22)
# - Agent HTTP listens on 127.0.0.1 only (local); not exposed on public 8601
# ================================================================
set -e
CENTRAL_URL=""
WEB_URL=""
API_KEY=""
SERVER_ID=""
AGENT_PORT="8601"
INSTALL_DIR="/opt/nexus-agent"
VENV_DIR="${INSTALL_DIR}/.venv"
while [[ $# -gt 0 ]]; do
case $1 in
--url) CENTRAL_URL="$2"; shift 2 ;;
--web-url) WEB_URL="$2"; shift 2 ;;
--key) API_KEY="$2"; shift 2 ;;
--id) SERVER_ID="$2"; shift 2 ;;
--port) AGENT_PORT="$2"; shift 2 ;;
*) shift ;;
esac
done
[ -z "$CENTRAL_URL" ] && echo "ERROR: --url is required" && exit 1
[ -z "$SERVER_ID" ] && echo "ERROR: --id is required (server ID from Nexus dashboard)" && exit 1
[ -z "$API_KEY" ] && echo "ERROR: --key is required (API key from Nexus settings)" && exit 1
echo ""
echo "=========================================="
echo " Nexus Agent Install"
echo "=========================================="
echo " Server: $CENTRAL_URL"
echo " ID: $SERVER_ID"
echo " Port: ${AGENT_PORT} (localhost only)"
echo "=========================================="
echo ""
# 1. Resolve Python 3.10+ (prefer system 3.12 on BT panels; skip 3.7 pyenv)
echo "[1/5] Resolve Python 3.10+..."
PYTHON=""
for candidate in python3.12 python3.11 python3.10 /usr/bin/python3.12 /usr/bin/python3.11 /usr/bin/python3.10 python3; do
if command -v "$candidate" >/dev/null 2>&1; then
ver=$("$candidate" -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null || true)
major=${ver%%.*}
minor=${ver#*.}
if [ -n "$major" ] && [ "$major" -eq 3 ] && [ "${minor:-0}" -ge 10 ] 2>/dev/null; then
PYTHON="$candidate"
break
fi
fi
done
if [ -z "$PYTHON" ]; then
echo "ERROR: Python 3.10+ required (found only older pyenv/BT Python?). Install system python3.12."
exit 1
fi
echo " Using: $PYTHON ($($PYTHON --version 2>&1))"
# 2. Create dir + venv
echo "[2/5] Create venv..."
mkdir -p "$INSTALL_DIR"
if [ ! -d "$VENV_DIR" ]; then
"$PYTHON" -m venv "$VENV_DIR"
fi
# shellcheck disable=SC1091
source "$VENV_DIR/bin/activate"
pip install -q --upgrade pip
pip install -q fastapi==0.115.6 uvicorn==0.34.0 httpx==0.28.1 psutil python-multipart==0.0.19
# 3. Download agent.py
echo "[3/5] Download agent.py..."
[ -z "$WEB_URL" ] && WEB_URL="${CENTRAL_URL}"
curl -fsSL "${WEB_URL}/agent/agent.py" -o "$INSTALL_DIR/agent.py" || {
echo "ERROR: Cannot download from $WEB_URL/agent/agent.py"
exit 1
}
# 4. Config
echo "[4/5] Write config..."
CENTRAL_HOST=$(echo "${CENTRAL_URL}" | sed 's~https\?://~~' | cut -d'/' -f1 | cut -d':' -f1)
cat > "$INSTALL_DIR/config.json" << EOF
{
"server_id": ${SERVER_ID},
"central": { "url": "${CENTRAL_URL}", "api_key": "${API_KEY}" },
"api_key": "${API_KEY}",
"heartbeat_interval": 60,
"allowed_ips": ["${CENTRAL_HOST}"],
"log_file": "/var/log/nexus-agent.log",
"log_level": "INFO",
"server": { "host": "127.0.0.1", "port": ${AGENT_PORT} }
}
EOF
echo " IP allowlist (Agent HTTP): ${CENTRAL_HOST}"
echo " Note: inbound TCP ${AGENT_PORT} is NOT required (heartbeat uses HTTPS outbound)."
# 5. systemd + start (bind localhost only)
echo "[5/5] Setup systemd + start..."
cat > /etc/systemd/system/nexus-agent.service << EOF
[Unit]
Description=Nexus Agent
After=network.target
[Service]
Type=simple
User=root
WorkingDirectory=${INSTALL_DIR}
Environment=PATH=${VENV_DIR}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ExecStart=${VENV_DIR}/bin/python -m uvicorn agent:app --host 127.0.0.1 --port ${AGENT_PORT} --log-level info
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable nexus-agent
systemctl start nexus-agent
sleep 2
STATUS="running"
systemctl is-active --quiet nexus-agent || STATUS="FAILED"
HOSTNAME=$(hostname 2>/dev/null || echo "unknown")
IP=$(hostname -I 2>/dev/null | awk '{print $1}' || echo "unknown")
echo ""
echo "=========================================="
echo " Done! Status: ${STATUS}"
echo "=========================================="
echo ""
echo " Heartbeat: ${CENTRAL_URL}/api/agent/heartbeat (HTTPS outbound)"
echo " Agent HTTP: 127.0.0.1:${AGENT_PORT} (local only, no public firewall rule needed)"
echo " Scripts: via SSH port 22 from Nexus center"
echo " Server ID: ${SERVER_ID}"
echo ""
echo " Commands:"
echo " systemctl status nexus-agent"
echo " journalctl -u nexus-agent -f"
echo " systemctl restart nexus-agent"
echo ""