215 lines
5.9 KiB
Bash
215 lines
5.9 KiB
Bash
#!/bin/bash
|
||
# 站点管理脚本(自动适配本地/云端)
|
||
#
|
||
# 本地 Mac 运行 → 通过 SSH 操作 txjp 服务器
|
||
# 云服务器运行 → 直接操作本地 Docker
|
||
#
|
||
# 用法:bash sites-manage-cloud.sh <命令> [站点名...]
|
||
# 站点名:ldap www cloud token gitea issue assets oa nginx
|
||
# ai(上述全部)、all(同 ai)
|
||
|
||
set -e
|
||
|
||
# ============================================================
|
||
# 自动检测运行环境
|
||
#
|
||
# 优先级:
|
||
# 1. OA_REMOTE 环境变量 — "local" 强制本地 / "ssh" 强制远程
|
||
# 2. hostname 匹配 — 包含 "Tencent" 则判为云服务器本地
|
||
# 3. 以上都不满足 → SSH 远程模式
|
||
# ============================================================
|
||
THIS_HOST=$(hostname 2>/dev/null || uname -n 2>/dev/null || echo "")
|
||
|
||
if [ "$OA_REMOTE" = "local" ]; then
|
||
IS_LOCAL_SERVER=true
|
||
LABEL="txjp(本地运行 · 手动指定)"
|
||
elif [ "$OA_REMOTE" = "ssh" ]; then
|
||
IS_LOCAL_SERVER=false
|
||
SERVER="txjp"
|
||
LABEL="txjp(SSH 远程 · 手动指定)"
|
||
elif echo "$THIS_HOST" | grep -qi "Tencent"; then
|
||
IS_LOCAL_SERVER=true
|
||
LABEL="txjp(本地运行 · 自动检测)"
|
||
else
|
||
IS_LOCAL_SERVER=false
|
||
SERVER="txjp"
|
||
LABEL="txjp(SSH 远程 · 自动检测)"
|
||
fi
|
||
|
||
# 执行命令:服务器本地直接跑,否则 SSH
|
||
run() {
|
||
if $IS_LOCAL_SERVER; then
|
||
bash -c "$*"
|
||
else
|
||
ssh $SERVER "$*"
|
||
fi
|
||
}
|
||
|
||
BASE="/root/docker"
|
||
|
||
# 站点 → 目录 & 容器名
|
||
declare -A SITE_DIR
|
||
SITE_DIR[ldap]="ldap-ai"
|
||
SITE_DIR[www]="www-ai"
|
||
SITE_DIR[cloud]="cloud-ai"
|
||
SITE_DIR[token]="token-ai"
|
||
SITE_DIR[gitea]="gitea-ai"
|
||
SITE_DIR[issue]="issue-ai"
|
||
SITE_DIR[assets]="assets-ai"
|
||
SITE_DIR[oa]="oa-ai"
|
||
SITE_DIR[nginx]="nginx-proxy-ai"
|
||
SITE_DIR[sso]="sso-ai"
|
||
|
||
declare -A SITE_CONTAINER
|
||
SITE_CONTAINER[ldap]="lldap"
|
||
SITE_CONTAINER[www]="www-ai"
|
||
SITE_CONTAINER[cloud]="cloud-ai"
|
||
SITE_CONTAINER[token]="token-ai"
|
||
SITE_CONTAINER[gitea]="gitea-ai"
|
||
SITE_CONTAINER[issue]="issue-ai"
|
||
SITE_CONTAINER[assets]="assets-ai"
|
||
SITE_CONTAINER[oa]="oa-ai"
|
||
SITE_CONTAINER[nginx]="nginx-ai"
|
||
SITE_CONTAINER[sso]="sso-ai"
|
||
|
||
AI_SITES="ldap www cloud token gitea issue assets oa nginx"
|
||
|
||
GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; RED='\033[0;31m'; NC='\033[0m'
|
||
log() { printf "${GREEN}[✓]${NC} %s\n" "$1"; }
|
||
warn() { printf "${YELLOW}[!]${NC} %s\n" "$1"; }
|
||
err() { printf "${RED}[✗]${NC} %s\n" "$1"; }
|
||
|
||
expand_sites() {
|
||
local result=()
|
||
for s in "$@"; do
|
||
case $s in
|
||
ai|all) for x in $AI_SITES; do result+=("$x"); done ;;
|
||
*) result+=("$s") ;;
|
||
esac
|
||
done
|
||
echo "${result[@]}"
|
||
}
|
||
|
||
# ============================================================
|
||
# 操作
|
||
# ============================================================
|
||
remote_start() {
|
||
local name=$1 dir="${BASE}/${SITE_DIR[$name]}"
|
||
local container="${SITE_CONTAINER[$name]}"
|
||
|
||
if run "docker ps --format '{{.Names}}' | grep -q '^${container}$'" 2>/dev/null; then
|
||
warn "$name 已在运行"
|
||
return
|
||
fi
|
||
log "启动 $name ..."
|
||
run "cd $dir && docker compose up -d" 2>/dev/null && log "$name 已启动" || err "$name 启动失败"
|
||
}
|
||
|
||
remote_stop() {
|
||
local name=$1 dir="${BASE}/${SITE_DIR[$name]}"
|
||
local container="${SITE_CONTAINER[$name]}"
|
||
|
||
if ! run "docker ps --format '{{.Names}}' | grep -q '^${container}$'" 2>/dev/null; then
|
||
warn "$name 未在运行"
|
||
return
|
||
fi
|
||
log "停止 $name ..."
|
||
run "cd $dir && docker compose down" 2>/dev/null && log "$name 已停止" || err "$name 停止失败"
|
||
}
|
||
|
||
remote_status() {
|
||
local targets=("$@")
|
||
echo ""
|
||
printf "${CYAN}=========================================${NC}\n"
|
||
printf "${CYAN} 站点状态 — ${LABEL}${NC}\n"
|
||
printf "${CYAN}=========================================${NC}\n"
|
||
echo ""
|
||
|
||
for name in "${targets[@]}"; do
|
||
local container="${SITE_CONTAINER[$name]}"
|
||
local status
|
||
status=$(run "docker ps --format '{{.Status}}' -f name=^${container}$" 2>/dev/null || echo "")
|
||
if [ -n "$status" ]; then
|
||
printf " ${GREEN}●${NC} %-8s 运行中 (%s)\n" "$name" "$status"
|
||
else
|
||
printf " ${RED}●${NC} %-8s 未运行\n" "$name"
|
||
fi
|
||
done
|
||
echo ""
|
||
}
|
||
|
||
show_help() {
|
||
echo ""
|
||
printf "${CYAN}用法:${NC} bash sites-manage-cloud.sh <命令> [站点名...]\n"
|
||
echo ""
|
||
echo " 当前环境: ${LABEL}"
|
||
echo ""
|
||
echo " 命令:"
|
||
echo " start 启动站点"
|
||
echo " stop 停止站点"
|
||
echo " restart 重启站点"
|
||
echo " status 查看状态"
|
||
echo ""
|
||
echo " 站点名(可指定多个,空格分隔):"
|
||
echo " ldap LLDAP 用户目录"
|
||
echo " www tlyq.ai 官网"
|
||
echo " cloud 云平台登录页"
|
||
echo " token Token 工厂登录页"
|
||
echo " gitea Gitea 代码托管"
|
||
echo " issue 工单系统"
|
||
echo " assets 设备资产管理"
|
||
echo " oa OA 统一门户"
|
||
echo " nginx 反向代理"
|
||
echo " ai 全部 tlyq.ai 站点"
|
||
echo ""
|
||
echo "示例:"
|
||
echo " bash sites-manage-cloud.sh start ai # 启动全部"
|
||
echo " bash sites-manage-cloud.sh restart nginx # 重启 nginx"
|
||
echo " bash sites-manage-cloud.sh stop oa issue # 停 OA + 工单"
|
||
echo " bash sites-manage-cloud.sh status # 查看所有状态"
|
||
echo ""
|
||
}
|
||
|
||
# ============================================================
|
||
# 入口
|
||
# ============================================================
|
||
ACTION=${1:-}
|
||
shift || true
|
||
|
||
if [ -z "$ACTION" ]; then
|
||
show_help
|
||
exit 0
|
||
fi
|
||
|
||
mapfile -t TARGETS < <(expand_sites "$@")
|
||
if [ ${#TARGETS[@]} -eq 0 ]; then
|
||
mapfile -t TARGETS < <(expand_sites ai)
|
||
fi
|
||
|
||
case $ACTION in
|
||
start)
|
||
for s in "${TARGETS[@]}"; do remote_start "$s"; done
|
||
;;
|
||
stop)
|
||
for s in "${TARGETS[@]}"; do remote_stop "$s"; done
|
||
;;
|
||
restart)
|
||
for s in "${TARGETS[@]}"; do remote_stop "$s"; done
|
||
echo ""
|
||
log "等待 2 秒后启动..."
|
||
sleep 2
|
||
for s in "${TARGETS[@]}"; do remote_start "$s"; done
|
||
;;
|
||
status)
|
||
remote_status "${TARGETS[@]}"
|
||
;;
|
||
help|--help|-h)
|
||
show_help
|
||
;;
|
||
*)
|
||
err "未知命令: $ACTION"
|
||
show_help
|
||
exit 1
|
||
;;
|
||
esac
|