diff --git a/scripts/pool/pool-utils.sh b/scripts/pool/pool-utils.sh new file mode 100644 index 0000000..e873e2c --- /dev/null +++ b/scripts/pool/pool-utils.sh @@ -0,0 +1,77 @@ +#!/bin/bash +# pool-utils.sh · 光湖节点池共用函数库 v1.0 +# 铸渊共享节点池 · TCS-0002∞ + +C_RESET='\033[0m'; C_GREEN='\033[0;32m'; C_RED='\033[0;31m'; C_YELLOW='\033[0;33m'; C_BLUE='\033[0;34m'; C_CYAN='\033[0;36m'; C_BOLD='\033[1m'; C_DIM='\033[2m' +ICON_OK="✅"; ICON_ERR="❌"; ICON_WARN="⚠️"; ICON_WAIT="⏳"; ICON_INFO="ℹ️" +POOL_HUB="${POOL_HUB:-https://43.156.237.110:3920}"; POLL_INTERVAL="${POLL_INTERVAL:-15}"; POLL_TIMEOUT="${POLL_TIMEOUT:-300}"; ZHUYUAN_BASE="/opt/zhuyuan" + +log_step() { echo -e "${C_BOLD}${C_CYAN}[第${1}/${2}]${C_RESET} ${3}"; } +log_ok() { echo -e " ${ICON_OK} ${C_GREEN}${1}${C_RESET}"; } +log_err() { echo -e " ${ICON_ERR} ${C_RED}${1}${C_RESET}"; } +log_warn() { echo -e " ${ICON_WARN} ${C_YELLOW}${1}${C_RESET}"; } +log_info() { echo -e " ${ICON_INFO} ${1}"; } +log_wait() { echo -e " ${ICON_WAIT} ${C_YELLOW}${1}${C_RESET}"; } + +print_header() { + echo ""; echo -e "${C_BOLD}${C_CYAN}════════════════════════════════════════════════════════${C_RESET}" + echo -e "${C_BOLD}${C_CYAN} 光湖 · 快速节点加入工具 v1.0${C_RESET}" + echo -e "${C_BOLD}${C_CYAN} 铸渊共享节点池 · TCS-0002∞${C_RESET}" + echo -e "${C_BOLD}${C_CYAN}════════════════════════════════════════════════════════${C_RESET}"; echo "" +} + +collect_hardware() { + local cpu_cores mem_mb disk_gb os_name hostname pub_ip priv_ip + if [[ "$(uname)" == "Darwin" ]]; then cpu_cores=$(sysctl -n hw.ncpu 2>/dev/null || echo 0); else cpu_cores=$(nproc 2>/dev/null || grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 0); fi + if [[ "$(uname)" == "Darwin" ]]; then mem_mb=$(( $(sysctl -n hw.memsize 2>/dev/null || echo 0) / 1024 / 1024 )); else mem_mb=$(free -m 2>/dev/null | awk '/^Mem:/{print $2}' || echo 0); fi + disk_gb=$(df -BG / 2>/dev/null | awk 'NR==2{print $2}' | sed 's/G//' || echo 0) + if [[ -f /etc/os-release ]]; then os_name=$(grep ^PRETTY_NAME /etc/os-release 2>/dev/null | cut -d'"' -f2 || echo "Linux"); else os_name="$(uname -s)"; fi + hostname=$(hostname 2>/dev/null || echo "unknown") + pub_ip=$(curl -fsSL --max-time 5 ifconfig.me 2>/dev/null || echo "unknown") + if [[ "$(uname)" == "Darwin" ]]; then priv_ip=$(ifconfig en0 2>/dev/null | awk '/inet /{print $2}' | head -1 || echo "unknown"); else priv_ip=$(hostname -I 2>/dev/null | awk '{print $1}' || echo "unknown"); fi + cat </dev/null; } +pool_api_get() { curl -fsSL --max-time "${2:-10}" "${POOL_HUB}$1" 2>/dev/null; } + +generate_node_code() { + local team_id="$1" region="" + local pub_ip=$(curl -fsSL --max-time 3 ifconfig.me 2>/dev/null || echo "") + if echo "$pub_ip" | grep -qE '^(43\.|119\.|124\.|106\.)'; then region="gz"; elif echo "$pub_ip" | grep -qE '^(43\.15|43\.13)'; then region="sg"; else region="gz"; fi + local owner=""; case "$team_id" in awen) owner="AW";; feimao) owner="FM";; juzi) owner="JZ";; yanfan) owner="YF";; yeye) owner="YY";; zhizhi) owner="ZZ";; *) owner=$(echo "$team_id" | tr '[:lower:]' '[:upper:]' | head -c2);; esac + echo "${owner}-$(echo "$region" | tr '[:lower:]' '[:upper:]')-01" +} + +check_root() { if [[ "$(id -u)" != "0" ]]; then log_err "此脚本需要 root 权限"; echo "请使用: sudo bash $0"; exit 1; fi; } + +check_already_registered() { + local conf_file="${ZHUYUAN_BASE}/team/${1}/.pool-conf.json" + if [[ -f "$conf_file" ]]; then log_err "此服务器已经注册过节点池"; echo "已注册: $(grep -o '"node_code"[^,]*' "$conf_file" | head -1)"; exit 1; fi +} + +detect_existing_zhuanyuan() { + if [[ -d "${ZHUYUAN_BASE}" ]] && [[ "$(ls -A ${ZHUYUAN_BASE} 2>/dev/null)" != "" ]]; then + log_warn "检测到已有 /opt/zhuyuan 目录"; ls -la "${ZHUYUAN_BASE}/" 2>/dev/null | head -10 + echo -n "输入 CONFIRM 确认继续: "; read confirm; [[ "$confirm" != "CONFIRM" ]] && { log_err "操作已取消"; exit 1; } + fi +} + +create_rollback_point() { local d="${ZHUYUAN_BASE}/.rollback"; mkdir -p "$d"; local f="${d}/join-${1}-$(date +%Y%m%d-%H%M%S).json"; echo "{\"node_code\":\"$1\",\"action\":\"join\",\"timestamp\":\"$(date -Iseconds)\"}" > "$f"; echo "$f"; } + +do_rollback() { + local conf_file="${ZHUYUAN_BASE}/team/${2}/.pool-conf.json" + [[ -f "$conf_file" ]] && { rm -f "$conf_file"; log_ok "已删除配置"; } + pool_api_post "/api/pool/node/${1}" '{"action":"rollback"}' 5 > /dev/null 2>&1 + log_ok "回滚完成"; echo "数据保留在 /opt/zhuyuan/team/${2}/" +} + +test_connectivity() { + curl -fsSL --max-time 5 "${1}/api/pool/status" > /dev/null 2>&1 && return 0 + local host=$(echo "$1" | sed -E 's|https?://||' | cut -d: -f1) + local port=$(echo "$1" | sed -E 's|https?://||' | cut -d: -f2); port="${port:-443}" + timeout 5 bash -c "echo > /dev/tcp/${host}/${port}" 2>/dev/null && return 0 + return 1 +} \ No newline at end of file