363 lines
8.7 KiB
Bash
363 lines
8.7 KiB
Bash
#!/bin/bash
|
||
# irg.sh - Isometric Room Generator 一键服务管理脚本
|
||
|
||
set -e
|
||
|
||
# 颜色定义
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
# 打印函数
|
||
info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||
success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
||
warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
||
error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||
|
||
# 脚本目录
|
||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
|
||
cd "$SCRIPT_DIR"
|
||
|
||
# 配置变量
|
||
PID_FILE="$SCRIPT_DIR/irg.pid"
|
||
LOG_DIR="/data/Isometquick/logs"
|
||
LOG_FILE="$LOG_DIR/isometquick.log"
|
||
SERVICE_PORT=8003
|
||
|
||
# 创建日志目录
|
||
create_log_dir() {
|
||
if [ ! -d "$LOG_DIR" ]; then
|
||
if sudo mkdir -p "$LOG_DIR" 2>/dev/null && sudo chown $USER:$USER "$LOG_DIR"; then
|
||
info "日志目录创建成功: $LOG_DIR"
|
||
else
|
||
# 如果无法创建/data目录,使用本地目录
|
||
LOG_DIR="$SCRIPT_DIR/logs"
|
||
LOG_FILE="$LOG_DIR/isometquick.log"
|
||
mkdir -p "$LOG_DIR"
|
||
info "使用本地日志目录: $LOG_DIR"
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# 检查服务是否运行
|
||
is_running() {
|
||
if [ -f "$PID_FILE" ]; then
|
||
PID=$(cat "$PID_FILE")
|
||
if ps -p "$PID" > /dev/null 2>&1; then
|
||
return 0
|
||
else
|
||
rm -f "$PID_FILE"
|
||
fi
|
||
fi
|
||
return 1
|
||
}
|
||
|
||
# 清理占用端口的进程
|
||
cleanup_port() {
|
||
info "🧹 清理端口 $SERVICE_PORT..."
|
||
|
||
# 查找占用端口的进程
|
||
PIDS=$(sudo lsof -t -i:$SERVICE_PORT 2>/dev/null || true)
|
||
|
||
if [ -n "$PIDS" ]; then
|
||
info "发现占用端口的进程: $PIDS"
|
||
for PID in $PIDS; do
|
||
info "杀死进程: $PID"
|
||
sudo kill -9 "$PID" 2>/dev/null || true
|
||
done
|
||
sleep 1
|
||
fi
|
||
|
||
# 再次检查
|
||
if sudo lsof -i:$SERVICE_PORT >/dev/null 2>&1; then
|
||
warning "端口 $SERVICE_PORT 仍被占用"
|
||
return 1
|
||
else
|
||
success "端口 $SERVICE_PORT 已清理"
|
||
return 0
|
||
fi
|
||
}
|
||
|
||
# 安装依赖
|
||
install() {
|
||
info "🔧 安装IRG服务依赖..."
|
||
|
||
# 检查Python
|
||
if ! command -v python3 &> /dev/null; then
|
||
error "未找到Python3,请先安装Python 3.8+"
|
||
exit 1
|
||
fi
|
||
|
||
# 创建虚拟环境
|
||
if [ ! -d "venv" ]; then
|
||
info "创建虚拟环境..."
|
||
python3 -m venv venv
|
||
fi
|
||
|
||
# 激活虚拟环境并安装依赖
|
||
. venv/bin/activate
|
||
pip install --upgrade pip -q
|
||
pip install -r requirements.txt -q
|
||
|
||
# 创建输出目录
|
||
if [ ! -d "/data/Isometquick" ]; then
|
||
if sudo mkdir -p /data/Isometquick 2>/dev/null && sudo chown $USER:$USER /data/Isometquick; then
|
||
success "输出目录创建成功: /data/Isometquick"
|
||
else
|
||
mkdir -p ./renders
|
||
success "输出目录: ./renders"
|
||
fi
|
||
fi
|
||
|
||
# 创建日志目录
|
||
create_log_dir
|
||
|
||
success "IRG服务依赖安装完成"
|
||
}
|
||
|
||
# 启动服务
|
||
start() {
|
||
if is_running; then
|
||
PID=$(cat "$PID_FILE")
|
||
warning "IRG服务已在运行 (PID: $PID)"
|
||
return 0
|
||
fi
|
||
|
||
info "🚀 启动IRG服务..."
|
||
|
||
# 创建日志目录
|
||
create_log_dir
|
||
|
||
# 清理占用的端口
|
||
cleanup_port || {
|
||
error "无法清理端口 $SERVICE_PORT,请手动检查"
|
||
exit 1
|
||
}
|
||
|
||
# 确保虚拟环境存在
|
||
if [ ! -d "venv" ]; then
|
||
install
|
||
fi
|
||
|
||
# 启动服务
|
||
nohup bash -c "
|
||
cd '$SCRIPT_DIR'
|
||
. venv/bin/activate
|
||
python start.py
|
||
" > "$LOG_FILE" 2>&1 &
|
||
|
||
echo $! > "$PID_FILE"
|
||
sleep 2
|
||
|
||
if is_running; then
|
||
PID=$(cat "$PID_FILE")
|
||
success "IRG服务启动成功 (PID: $PID)"
|
||
success "API地址: http://localhost:$SERVICE_PORT"
|
||
success "API文档: http://localhost:$SERVICE_PORT/docs"
|
||
success "日志文件: $LOG_FILE"
|
||
else
|
||
error "IRG服务启动失败"
|
||
if [ -f "$LOG_FILE" ]; then
|
||
echo "错误日志:"
|
||
tail -10 "$LOG_FILE"
|
||
fi
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# 停止服务
|
||
stop() {
|
||
if ! is_running; then
|
||
warning "IRG服务未运行"
|
||
return 0
|
||
fi
|
||
|
||
PID=$(cat "$PID_FILE")
|
||
info "🛑 停止IRG服务 (PID: $PID)..."
|
||
|
||
# 优雅停止
|
||
kill -TERM "$PID" 2>/dev/null || true
|
||
|
||
# 等待5秒
|
||
for i in {1..5}; do
|
||
if ! ps -p "$PID" > /dev/null 2>&1; then
|
||
break
|
||
fi
|
||
sleep 1
|
||
done
|
||
|
||
# 强制停止
|
||
if ps -p "$PID" > /dev/null 2>&1; then
|
||
kill -KILL "$PID" 2>/dev/null || true
|
||
fi
|
||
|
||
rm -f "$PID_FILE"
|
||
|
||
# 清理可能残留的端口占用
|
||
cleanup_port
|
||
|
||
success "IRG服务已停止"
|
||
}
|
||
|
||
# 重启服务
|
||
restart() {
|
||
info "🔄 重启IRG服务..."
|
||
stop
|
||
sleep 1
|
||
start
|
||
}
|
||
|
||
# 查看状态
|
||
status() {
|
||
echo "========================================"
|
||
echo "📊 Isometric Room Generator 服务状态"
|
||
echo "========================================"
|
||
|
||
if is_running; then
|
||
PID=$(cat "$PID_FILE")
|
||
MEMORY=$(ps -p "$PID" -o rss= 2>/dev/null | awk '{print int($1/1024)"MB"}' || echo "N/A")
|
||
CPU=$(ps -p "$PID" -o pcpu= 2>/dev/null | awk '{print $1"%"}' || echo "N/A")
|
||
|
||
success "IRG服务正在运行"
|
||
echo " PID: $PID"
|
||
echo " 内存: $MEMORY"
|
||
echo " CPU: $CPU"
|
||
echo " 端口: $SERVICE_PORT"
|
||
echo " 日志: $LOG_FILE"
|
||
|
||
# 检查端口
|
||
if netstat -tlnp 2>/dev/null | grep -q ":$SERVICE_PORT"; then
|
||
success "端口 $SERVICE_PORT 正在监听"
|
||
else
|
||
warning "端口 $SERVICE_PORT 未监听"
|
||
fi
|
||
|
||
# 健康检查
|
||
if command -v curl &> /dev/null; then
|
||
if curl -s "http://localhost:$SERVICE_PORT/health" > /dev/null 2>&1; then
|
||
success "API健康检查通过"
|
||
else
|
||
warning "API健康检查失败"
|
||
fi
|
||
fi
|
||
else
|
||
warning "IRG服务未运行"
|
||
fi
|
||
}
|
||
|
||
# 查看日志
|
||
logs() {
|
||
if [ -f "$LOG_FILE" ]; then
|
||
if [ "$1" = "-f" ]; then
|
||
info "实时查看IRG服务日志 (Ctrl+C退出)..."
|
||
tail -f "$LOG_FILE"
|
||
else
|
||
info "显示最近20行IRG服务日志..."
|
||
tail -20 "$LOG_FILE"
|
||
echo ""
|
||
info "实时查看: $0 logs -f"
|
||
fi
|
||
else
|
||
warning "日志文件不存在: $LOG_FILE"
|
||
fi
|
||
}
|
||
|
||
# 日志管理
|
||
log_rotate() {
|
||
info "🔄 IRG服务日志轮转..."
|
||
|
||
if [ -f "$LOG_FILE" ]; then
|
||
# 获取当前日期
|
||
DATE=$(date +%Y%m%d_%H%M%S)
|
||
BACKUP_FILE="$LOG_DIR/isometquick_$DATE.log"
|
||
|
||
# 备份当前日志
|
||
mv "$LOG_FILE" "$BACKUP_FILE"
|
||
info "日志已备份到: $BACKUP_FILE"
|
||
|
||
# 清理7天前的日志
|
||
find "$LOG_DIR" -name "isometquick_*.log" -mtime +7 -delete 2>/dev/null || true
|
||
success "IRG服务日志轮转完成"
|
||
else
|
||
warning "没有找到日志文件"
|
||
fi
|
||
}
|
||
|
||
# 显示帮助
|
||
help() {
|
||
echo "========================================"
|
||
echo "🏠 Isometric Room Generator 服务管理脚本"
|
||
echo "========================================"
|
||
echo ""
|
||
echo "用法: $0 [命令]"
|
||
echo ""
|
||
echo "命令:"
|
||
echo " install 安装依赖"
|
||
echo " start 启动IRG服务"
|
||
echo " stop 停止IRG服务"
|
||
echo " restart 重启IRG服务"
|
||
echo " status 查看服务状态"
|
||
echo " logs 查看日志"
|
||
echo " logs -f 实时日志"
|
||
echo " rotate 日志轮转"
|
||
echo ""
|
||
echo "示例:"
|
||
echo " $0 start # 启动IRG服务"
|
||
echo " $0 restart # 重启IRG服务"
|
||
echo " $0 status # 查看服务状态"
|
||
echo " $0 logs # 查看日志"
|
||
echo " $0 rotate # 日志轮转"
|
||
echo ""
|
||
echo "首次使用请运行: $0 install"
|
||
echo ""
|
||
}
|
||
|
||
# 主函数
|
||
main() {
|
||
case "${1:-}" in
|
||
"install")
|
||
install
|
||
;;
|
||
"start")
|
||
start
|
||
;;
|
||
"stop")
|
||
stop
|
||
;;
|
||
"restart")
|
||
restart
|
||
;;
|
||
"status")
|
||
status
|
||
;;
|
||
"logs")
|
||
logs "$2"
|
||
;;
|
||
"rotate")
|
||
log_rotate
|
||
;;
|
||
"help"|"-h"|"--help")
|
||
help
|
||
;;
|
||
"")
|
||
# 默认:如果没有参数,显示状态或首次安装启动
|
||
if [ -d "venv" ]; then
|
||
status
|
||
else
|
||
info "首次使用,开始安装IRG服务..."
|
||
install
|
||
start
|
||
fi
|
||
;;
|
||
*)
|
||
error "未知命令: $1"
|
||
help
|
||
exit 1
|
||
;;
|
||
esac
|
||
}
|
||
|
||
# 执行主函数
|
||
main "$@" |