#!/bin/bash # join-pool.sh · 光湖节点池快速加入工具 v1.0 # 铸渊共享节点池 · TCS-0002∞ · ICE-GL-ZY001 # 用法: bash join-pool.sh --token --team awen --operator "Awen" set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${SCRIPT_DIR}/pool-utils.sh" ZHUYUAN_BASE="${ZHUYUAN_BASE:-/opt/zhuyuan}" CONSOLE_URL="${CONSOLE_URL:-https://43.156.237.110:3920}" MODE=""; JOIN_TOKEN=""; TEAM_ID=""; OPERATOR_NAME=""; NON_INTERACTIVE=false; ROLLBACK_NODE=""; RESUME_REG_ID="" while [[ $# -gt 0 ]]; do case "$1" in --token) JOIN_TOKEN="$2"; shift 2;; --team) TEAM_ID="$2"; shift 2;; --operator) OPERATOR_NAME="$2"; shift 2;; --non-interactive) NON_INTERACTIVE=true; shift;; --rollback) MODE="rollback"; ROLLBACK_NODE="$2"; shift 2;; --status) MODE="status"; shift;; --inspect) MODE="inspect"; shift;; --resume) MODE="resume"; RESUME_REG_ID="$2"; shift 2;; --help|-h) echo "光湖节点池加入工具 v1.0"; echo "用法: bash join-pool.sh --token <令牌> --team <团队> --operator <操作人>"; exit 0;; *) echo "未知参数: $1"; exit 1;; esac done [[ -z "$MODE" ]] && MODE="join" # ---- 回滚 ---- if [[ "$MODE" == "rollback" ]]; then check_root; [[ -z "$ROLLBACK_NODE" ]] && { log_err "缺少节点编码"; exit 1; } local t=""; case "${ROLLBACK_NODE:0:2}" in AW) t="awen";; FM) t="feimao";; JZ) t="juzi";; YF) t="yanfan";; YY) t="yeye";; ZZ) t="zhizhi";; esac do_rollback "$ROLLBACK_NODE" "$t"; exit 0 fi # ---- 状态 ---- if [[ "$MODE" == "status" ]]; then echo -e "\n${C_BOLD}节点池状态${C_RESET}\n" local f=0 for conf in "${ZHUYUAN_BASE}"/team/*/.pool-conf.json "${ZHUYUAN_BASE}"/ice/.pool-conf.json; do [[ -f "$conf" ]] || continue; f=1 local nc=$(grep -o '"node_code"[^,]*' "$conf" | head -1 | grep -o '"[^"]*"$' | tr -d '"') local s=$(grep -o '"side"[^,]*' "$conf" | head -1 | grep -o '"[^"]*"$' | tr -d '"') echo " 节点: ${C_BOLD}${nc}${C_RESET} | 侧: ${s} | 配置: $conf" done [[ $f -eq 0 ]] && echo -e " ${C_DIM}未加入节点池${C_RESET}" echo ""; exit 0 fi # ---- 硬件检查 ---- if [[ "$MODE" == "inspect" ]]; then print_header; log_step "1" "1" "硬件信息采集"; echo "" local hw=$(collect_hardware) local cpu=$(echo "$hw" | grep -o '"cpu_cores":[0-9]*' | grep -o '[0-9]*$' || echo "?") local mem=$(echo "$hw" | grep -o '"memory_mb":[0-9]*' | grep -o '[0-9]*$' || echo "?") local disk=$(echo "$hw" | grep -o '"disk_gb":[0-9]*' | grep -o '[0-9]*$' || echo "?") local os=$(echo "$hw" | grep -o '"os":"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "?") echo " CPU: ${cpu}核 | 内存: ${mem}MB ($((mem/1024))GB) | 磁盘: ${disk}GB | 系统: ${os}" [[ -n "$TEAM_ID" ]] && echo " 推荐编码: ${C_BOLD}${C_CYAN}$(generate_node_code "$TEAM_ID")${C_RESET}" echo ""; exit 0 fi # ---- 恢复 ---- if [[ "$MODE" == "resume" ]]; then check_root; await_approval "$RESUME_REG_ID"; exit 0 fi # ========== 主流程: 标准加入 ========== main_join() { print_header; check_root # 步骤1: 确认环境 log_step "1" "7" "确认环境"; echo "" local hw=$(collect_hardware) local hostname=$(echo "$hw" | grep -o '"hostname":"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "?") local pub_ip=$(echo "$hw" | grep -o '"public_ip":"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "?") local cpu=$(echo "$hw" | grep -o '"cpu_cores":[0-9]*' | grep -o '[0-9]*$' || echo "?") local mem=$(echo "$hw" | grep -o '"memory_mb":[0-9]*' | grep -o '[0-9]*$' || echo "?") local disk=$(echo "$hw" | grep -o '"disk_gb":[0-9]*' | grep -o '[0-9]*$' || echo "?") local os=$(echo "$hw" | grep -o '"os":"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"' || echo "?") echo " 主机名: ${C_BOLD}${hostname}${C_RESET} | 公网IP: ${pub_ip}" echo " CPU: ${cpu}核 | 内存: ${mem}MB ($((mem/1024))GB) | 磁盘: ${disk}GB" echo "" detect_existing_zhuanyuan if [[ "$NON_INTERACTIVE" != "true" ]]; then echo -n "这是你要加入节点池的服务器吗?[y/N] "; read confirm [[ "$confirm" != "y" && "$confirm" != "Y" ]] && { log_err "已取消"; exit 1; } fi; log_ok "环境确认完成"; echo "" # 步骤2: 凭证 log_step "2" "7" "输入加入凭证"; echo "" [[ -z "$JOIN_TOKEN" ]] && { echo -n "加入令牌: "; read -rs JOIN_TOKEN; echo ""; } [[ -z "$JOIN_TOKEN" ]] && { log_err "令牌不能为空"; exit 1; } [[ -z "$TEAM_ID" ]] && { echo -n "团队标识: "; read -r TEAM_ID; } [[ -z "$OPERATOR_NAME" ]] && { echo -n "操作人: "; read -r OPERATOR_NAME; } check_already_registered "$TEAM_ID" local node_code=$(generate_node_code "$TEAM_ID") log_ok "团队: ${TEAM_ID} · 节点编码: ${C_BOLD}${node_code}${C_RESET}"; echo "" # 步骤3: 创建目录 log_step "3" "7" "创建目录结构"; echo "" local team_dir="${ZHUYUAN_BASE}/team/${TEAM_ID}" mkdir -p "${team_dir}/logs/pm2" "${team_dir}/apps" "${team_dir}/data" "${team_dir}/nginx" log_ok "${team_dir}/"; [[ ! -d "${ZHUYUAN_BASE}/ice" ]] && { mkdir -p "${ZHUYUAN_BASE}/ice/logs" "${ZHUYUAN_BASE}/ice/apps" "${ZHUYUAN_BASE}/ice/data"; log_ok "${ZHUYUAN_BASE}/ice/ (冰朔侧预留)"; } mkdir -p "${ZHUYUAN_BASE}/.rollback"; echo "" # 步骤4: 注册 log_step "4" "7" "向中枢注册"; echo "" test_connectivity "$CONSOLE_URL" || { log_err "无法连接中枢"; exit 1; }; log_ok "已连接中枢" local join_body="{\"join_token\":\"${JOIN_TOKEN}\",\"node_code\":\"${node_code}\",\"node_name\":\"${OPERATOR_NAME}团队节点\",\"side\":\"team\",\"team_id\":\"${TEAM_ID}\",\"operator_name\":\"${OPERATOR_NAME}\",\"hardware\":{\"cpu_cores\":${cpu},\"memory_mb\":${mem},\"disk_gb\":${disk},\"os\":\"${os}\"},\"network\":{\"public_ip\":\"${pub_ip}\"}}" local resp=$(pool_api_post "/api/pool/join" "$join_body" 15) echo "$resp" | grep -q '"ok":[[:space:]]*true' || { log_err "注册失败: $resp"; exit 1; } local registration_id=$(echo "$resp" | grep -o '"registration_id":"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"') [[ -z "$registration_id" ]] && { log_err "未获取 registration_id"; exit 1; } log_ok "注册请求已提交 · reg_id: ${registration_id}" create_rollback_point "$node_code" > /dev/null; echo "" # 步骤5: 等待审批 await_approval "$registration_id" # 步骤6: 保存配置 log_step "6" "7" "保存配置"; echo "" cat > "${team_dir}/.pool-conf.json" <