guanghulab/scripts/pool/pool-utils.sh
Guanghu Domestic Migration d1e47f4565
Some checks are pending
自动更新代码和重启 / update-and-restart (push) Waiting to run
CI检查 + 自动部署 / check (push) Waiting to run
CI检查 + 自动部署 / deploy (push) Blocked by required conditions
重启聊天服务 / restart (push) Waiting to run
chore: import sanitized domestic snapshot for REPO-002
Source snapshot: ca48d3ddf926d79aa138306164169baf764bb829
2026-07-17 15:54:41 +08:00

77 lines
5.1 KiB
Bash
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 <<HARDWARE_JSON
{"cpu_cores":${cpu_cores:-0},"memory_mb":${mem_mb:-0},"disk_gb":${disk_gb:-0},"os":"$os_name","hostname":"$hostname","public_ip":"$pub_ip","private_ip":"$priv_ip"}
HARDWARE_JSON
}
pool_api_post() { curl -fsSL --max-time "${3:-10}" -X POST -H "Content-Type: application/json" -d "$2" "${POOL_HUB}$1" 2>/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
}