220 lines
5.9 KiB
Bash
220 lines
5.9 KiB
Bash
#!/bin/bash
|
||
# ==================== Telegram Bot Systemd 服务安装脚本 ====================
|
||
# 用法: sudo bash install_service.sh [install|uninstall|status|logs]
|
||
|
||
set -e
|
||
|
||
# ==================== 配置 ====================
|
||
SERVICE_NAME="oai-team-bot"
|
||
SERVICE_DESC="OpenAI Team Provisioner Bot"
|
||
WORK_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
SCRIPT_NAME="telegram_bot.py"
|
||
USER="${SUDO_USER:-root}"
|
||
|
||
# 颜色输出
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
||
log_success() { echo -e "${GREEN}[OK]${NC} $1"; }
|
||
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
||
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
||
|
||
# ==================== 检查环境 ====================
|
||
check_env() {
|
||
# 检查是否为 root
|
||
if [ "$EUID" -ne 0 ]; then
|
||
log_error "请使用 sudo 运行此脚本"
|
||
exit 1
|
||
fi
|
||
|
||
# 检查工作目录
|
||
if [ ! -f "${WORK_DIR}/${SCRIPT_NAME}" ]; then
|
||
log_error "找不到 ${SCRIPT_NAME},请在项目目录下运行此脚本"
|
||
exit 1
|
||
fi
|
||
|
||
# 检测 uv
|
||
if command -v uv &> /dev/null && [ -f "${WORK_DIR}/pyproject.toml" ]; then
|
||
UV_BIN=$(which uv)
|
||
|
||
# 先执行 uv sync 安装依赖
|
||
log_info "执行 uv sync 安装依赖..."
|
||
cd "${WORK_DIR}"
|
||
sudo -u ${USER} ${UV_BIN} sync
|
||
log_success "依赖安装完成"
|
||
|
||
# 使用 uv run 运行
|
||
EXEC_CMD="${UV_BIN} run python ${SCRIPT_NAME}"
|
||
log_info "使用 uv run 运行"
|
||
elif [ -f "${WORK_DIR}/.venv/bin/python" ]; then
|
||
# 使用 .venv
|
||
EXEC_CMD="${WORK_DIR}/.venv/bin/python ${WORK_DIR}/${SCRIPT_NAME}"
|
||
log_info "使用 .venv 虚拟环境"
|
||
else
|
||
# 使用系统 python
|
||
PYTHON_BIN=$(which python3 || which python)
|
||
if [ -z "$PYTHON_BIN" ]; then
|
||
log_error "找不到 Python 或 uv"
|
||
exit 1
|
||
fi
|
||
EXEC_CMD="${PYTHON_BIN} ${WORK_DIR}/${SCRIPT_NAME}"
|
||
log_warn "使用系统 Python,可能缺少依赖"
|
||
fi
|
||
|
||
log_info "工作目录: ${WORK_DIR}"
|
||
log_info "启动命令: ${EXEC_CMD}"
|
||
log_info "运行用户: ${USER}"
|
||
}
|
||
|
||
# ==================== 安装服务 ====================
|
||
install_service() {
|
||
log_info "正在安装 ${SERVICE_NAME} 服务..."
|
||
|
||
# 获取 uv 路径用于 PATH
|
||
UV_PATH=""
|
||
if command -v uv &> /dev/null; then
|
||
UV_PATH="$(dirname $(which uv)):"
|
||
fi
|
||
|
||
# 创建 systemd service 文件
|
||
cat > /etc/systemd/system/${SERVICE_NAME}.service << EOF
|
||
[Unit]
|
||
Description=${SERVICE_DESC}
|
||
After=network.target network-online.target
|
||
Wants=network-online.target
|
||
|
||
[Service]
|
||
Type=simple
|
||
User=${USER}
|
||
Group=${USER}
|
||
WorkingDirectory=${WORK_DIR}
|
||
ExecStart=${EXEC_CMD}
|
||
Restart=always
|
||
RestartSec=10
|
||
StandardOutput=journal
|
||
StandardError=journal
|
||
|
||
# 环境变量
|
||
Environment="PYTHONUNBUFFERED=1"
|
||
Environment="LOG_LEVEL=INFO"
|
||
Environment="PATH=${UV_PATH}/usr/local/bin:/usr/bin:/bin"
|
||
Environment="HOME=/root"
|
||
|
||
# 安全限制 (root 用户不使用 ProtectSystem)
|
||
NoNewPrivileges=true
|
||
|
||
[Install]
|
||
WantedBy=multi-user.target
|
||
EOF
|
||
|
||
log_success "服务文件已创建: /etc/systemd/system/${SERVICE_NAME}.service"
|
||
|
||
# 重新加载 systemd
|
||
systemctl daemon-reload
|
||
log_success "systemd 配置已重载"
|
||
|
||
# 启用开机自启
|
||
systemctl enable ${SERVICE_NAME}
|
||
log_success "已启用开机自启"
|
||
|
||
# 启动服务
|
||
systemctl start ${SERVICE_NAME}
|
||
log_success "服务已启动"
|
||
|
||
# 显示状态
|
||
echo ""
|
||
systemctl status ${SERVICE_NAME} --no-pager
|
||
|
||
echo ""
|
||
log_success "安装完成!"
|
||
echo ""
|
||
echo "常用命令:"
|
||
echo " 查看状态: sudo systemctl status ${SERVICE_NAME}"
|
||
echo " 查看日志: sudo journalctl -u ${SERVICE_NAME} -f"
|
||
echo " 重启服务: sudo systemctl restart ${SERVICE_NAME}"
|
||
echo " 停止服务: sudo systemctl stop ${SERVICE_NAME}"
|
||
echo " 卸载服务: sudo bash $0 uninstall"
|
||
}
|
||
|
||
# ==================== 卸载服务 ====================
|
||
uninstall_service() {
|
||
log_info "正在卸载 ${SERVICE_NAME} 服务..."
|
||
|
||
# 停止服务
|
||
systemctl stop ${SERVICE_NAME} 2>/dev/null || true
|
||
log_info "服务已停止"
|
||
|
||
# 禁用开机自启
|
||
systemctl disable ${SERVICE_NAME} 2>/dev/null || true
|
||
log_info "已禁用开机自启"
|
||
|
||
# 删除服务文件
|
||
rm -f /etc/systemd/system/${SERVICE_NAME}.service
|
||
log_info "服务文件已删除"
|
||
|
||
# 重新加载 systemd
|
||
systemctl daemon-reload
|
||
log_success "卸载完成!"
|
||
}
|
||
|
||
# ==================== 查看状态 ====================
|
||
show_status() {
|
||
systemctl status ${SERVICE_NAME} --no-pager
|
||
}
|
||
|
||
# ==================== 查看日志 ====================
|
||
show_logs() {
|
||
journalctl -u ${SERVICE_NAME} -f --no-pager -n 50
|
||
}
|
||
|
||
# ==================== 主函数 ====================
|
||
main() {
|
||
case "${1:-install}" in
|
||
install)
|
||
check_env
|
||
install_service
|
||
;;
|
||
uninstall|remove)
|
||
uninstall_service
|
||
;;
|
||
status)
|
||
show_status
|
||
;;
|
||
logs|log)
|
||
show_logs
|
||
;;
|
||
restart)
|
||
systemctl restart ${SERVICE_NAME}
|
||
log_success "服务已重启"
|
||
show_status
|
||
;;
|
||
stop)
|
||
systemctl stop ${SERVICE_NAME}
|
||
log_success "服务已停止"
|
||
;;
|
||
start)
|
||
systemctl start ${SERVICE_NAME}
|
||
log_success "服务已启动"
|
||
show_status
|
||
;;
|
||
*)
|
||
echo "用法: sudo bash $0 [命令]"
|
||
echo ""
|
||
echo "命令:"
|
||
echo " install 安装并启动服务 (默认)"
|
||
echo " uninstall 卸载服务"
|
||
echo " status 查看服务状态"
|
||
echo " logs 查看实时日志"
|
||
echo " restart 重启服务"
|
||
echo " start 启动服务"
|
||
echo " stop 停止服务"
|
||
;;
|
||
esac
|
||
}
|
||
|
||
main "$@"
|