diff --git a/scripts/pool/join-pool.sh b/scripts/pool/join-pool.sh new file mode 100644 index 0000000..4efa980 --- /dev/null +++ b/scripts/pool/join-pool.sh @@ -0,0 +1,150 @@ +#!/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" <