150 lines
7.9 KiB
Bash
150 lines
7.9 KiB
Bash
#!/bin/bash
|
|
# join-pool.sh · 光湖节点池快速加入工具 v1.0
|
|
# 铸渊共享节点池 · TCS-0002∞ · ICE-GL-ZY001
|
|
# 用法: bash join-pool.sh --token <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" <<POOL
|
|
{"node_code":"${node_code}","side":"team","team_id":"${TEAM_ID}","pool_token":"${POOL_TOKEN}","report_endpoint":"${CONSOLE_URL}/api/pool/report","joined_at":"$(date -Iseconds)","operator_name":"${OPERATOR_NAME}","script_version":"1.0.0"}
|
|
POOL
|
|
chmod 600 "${team_dir}/.pool-conf.json"; log_ok "配置已保存"; echo ""
|
|
|
|
# 步骤7: 验证
|
|
log_step "7" "7" "验证连接"; echo ""
|
|
local hb="{\"node_code\":\"${node_code}\",\"cpu_load\":0,\"mem_total_mb\":${mem},\"mem_avail_mb\":${mem},\"spec\":{\"cpu\":${cpu},\"mem_gb\":$((mem/1024))},\"pool_token\":\"${POOL_TOKEN}\"}"
|
|
pool_api_post "/api/pool/report" "$hb" 10 | grep -q '"ok":true' && log_ok "心跳上报成功" || log_warn "心跳上报失败"
|
|
echo ""; echo -e "${C_GREEN}${C_BOLD} ✅ 节点加入完成!${C_RESET}"; echo " 节点编码: ${node_code} | 团队: ${TEAM_ID}"
|
|
echo " 路径: ${team_dir}/"; echo " 回滚: bash join-pool.sh --rollback ${node_code}"
|
|
echo ""
|
|
}
|
|
|
|
await_approval() {
|
|
local elapsed=0 poll_c=0
|
|
log_step "5" "7" "等待审批"
|
|
while [[ $elapsed -lt $POLL_TIMEOUT ]]; do
|
|
poll_c=$((poll_c+1))
|
|
local s=$(pool_api_get "/api/pool/join-status/${1}" 10)
|
|
if echo "$s" | grep -q '"status":[[:space:]]*"approved"'; then
|
|
POOL_TOKEN=$(echo "$s" | grep -o '"pool_token":"[^"]*"' | grep -o '"[^"]*"$' | tr -d '"')
|
|
echo ""; echo -e " ✅ ${C_GREEN}冰朔已批准!${C_RESET}"; echo ""; return 0
|
|
fi
|
|
echo "$s" | grep -q '"status":[[:space:]]*"rejected"' && { log_err "注册被拒绝"; exit 1; }
|
|
log_wait "等待冰朔审批... (${elapsed}秒)"; sleep "$POLL_INTERVAL"; elapsed=$((elapsed+POLL_INTERVAL))
|
|
done
|
|
log_warn "等待超时"; echo "恢复码: ${1}"; exit 1
|
|
}
|
|
|
|
main_join; unset JOIN_TOKEN POOL_TOKEN |