#!/bin/bash # 核云IDC服务商VPS自动监测重启程序 - 安装脚本 # 该脚本会检查配置并创建systemd服务,持续化运行monitor.py # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # 获取当前脚本所在目录的绝对路径 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # 定义服务名称 SERVICE_NAME="idc-monitor" SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service" CONFIG_FILE="${SCRIPT_DIR}/config.yml" echo "==========================================" echo " 核云IDC VPS监控程序 - 安装向导" echo "==========================================" echo "" # 检查是否以root权限运行 if [ "$EUID" -ne 0 ]; then echo -e "${RED}错误: 请以root权限运行此脚本 (sudo ./install.sh)${NC}" exit 1 fi # 检查Python是否已安装 if ! command -v python3 &> /dev/null; then if command -v python &> /dev/null; then PYTHON_CMD="python" else echo -e "${RED}错误: 未找到Python,请先安装Python 3${NC}" exit 1 fi else PYTHON_CMD="python3" fi echo -e "${GREEN}✅${NC} 检测到Python: ${PYTHON_CMD}" # 检查pip是否存在 if command -v pip3 &> /dev/null; then PIP_CMD="pip3" elif command -v pip &> /dev/null; then PIP_CMD="pip" else echo -e "${YELLOW}警告: 未检测到pip${NC}" read -p "是否现在安装pip?(Y/n): " -n 1 -r echo if [[ $REPLY =~ ^[Nn]$ ]]; then echo -e "${RED}错误: pip不可用,无法继续${NC}" exit 1 else # 安装pip if command -v apt-get &> /dev/null; then apt-get update && apt-get install -y python3-pip elif command -v yum &> /dev/null; then yum install -y python3-pip elif command -v dnf &> /dev/null; then dnf install -y python3-pip else curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py ${PYTHON_CMD} get-pip.py rm -f get-pip.py fi if command -v pip3 &> /dev/null; then PIP_CMD="pip3" elif command -v pip &> /dev/null; then PIP_CMD="pip" else echo -e "${RED}错误: pip安装失败${NC}" exit 1 fi fi fi echo -e "${GREEN}✅${NC} 检测到pip: ${PIP_CMD}" # 检查配置文件是否存在 if [ ! -f "${CONFIG_FILE}" ]; then echo -e "${RED}错误: 配置文件不存在: ${CONFIG_FILE}${NC}" exit 1 fi # 读取现有配置 echo "" echo "正在检查配置文件..." # 使用grep解析YAML配置 ACCOUNT=$(grep "^ACCOUNT:" "${CONFIG_FILE}" | sed 's/ACCOUNT:[[:space:]]*//' | sed 's/[[:space:]]*#.*//' | tr -d "'" | tr -d '"') API_KEY=$(grep "^API_KEY:" "${CONFIG_FILE}" | sed 's/API_KEY:[[:space:]]*//' | sed 's/[[:space:]]*#.*//' | tr -d "'" | tr -d '"') WAY=$(grep "^WAY:" "${CONFIG_FILE}" | sed 's/WAY:[[:space:]]*//' | sed 's/[[:space:]]*#.*//' | tr -d "'" | tr -d '"') DOMAIN=$(grep "^DOMAIN:" "${CONFIG_FILE}" | sed 's/DOMAIN:[[:space:]]*//' | sed 's/[[:space:]]*#.*//' | tr -d "'" | tr -d '"') SPAN=$(grep "^SPAN:" "${CONFIG_FILE}" | sed 's/SPAN:[[:space:]]*//' | sed 's/[[:space:]]*#.*//' | tr -d "'" | tr -d '"') EXCEPTION_IPS=$(grep "^EXCEPTION_IPS:" "${CONFIG_FILE}" | sed 's/EXCEPTION_IPS:[[:space:]]*//' | sed 's/[[:space:]]*#.*//' | tr -d "'" | tr -d '"') NEED_UPDATE=false # 检查ACCOUNT if [ -z "$ACCOUNT" ]; then echo "" echo "==================================================" echo -e -n "${RED}请输入核云IDC账号(手机号或邮箱): ${NC}" read ACCOUNT if [ -z "$ACCOUNT" ]; then echo -e "${RED}错误: 账号不能为空${NC}" exit 1 fi NEED_UPDATE=true fi # 检查API_KEY if [ -z "$API_KEY" ]; then echo "" echo "==================================================" echo -e -n "${RED}请输入核云IDC API密钥: ${NC}" read API_KEY if [ -z "$API_KEY" ]; then echo -e "${RED}错误: API密钥不能为空${NC}" exit 1 fi NEED_UPDATE=true fi # 检查WAY if [ -z "$WAY" ]; then echo "" echo "==================================================" echo -e "${RED}请选择检测方式:${NC}" echo " 1. ping - Ping检测IP地址(默认)" echo " 2. http - HTTP检测域名" echo -e -n "${RED}请输入选项 1/2,直接回车默认为1: ${NC}" read WAY_CHOICE if [ "$WAY_CHOICE" = "2" ]; then WAY="http" else WAY="ping" fi NEED_UPDATE=true fi # 如果WAY为http,检查DOMAIN if [ "$WAY" = "http" ] && [ -z "$DOMAIN" ]; then echo "" echo "==================================================" echo -e "${RED}请输入要检测的域名(多个域名用英文逗号分隔):${NC}" echo "例如: example.com,test.com,demo.com" echo -e -n "${RED}域名: ${NC}" read DOMAIN if [ -z "$DOMAIN" ]; then echo -e "${RED}错误: 域名不能为空${NC}" exit 1 fi NEED_UPDATE=true fi # 检查SPAN if [ -z "$SPAN" ]; then echo "" echo "==================================================" echo -e -n "${RED}请输入监控间隔时间(秒,直接回车默认300秒): ${NC}" read SPAN_INPUT if [ -n "$SPAN_INPUT" ]; then if [[ "$SPAN_INPUT" =~ ^[0-9]+$ ]]; then if [ "$SPAN_INPUT" -lt 60 ]; then echo -e "${RED}警告: 间隔时间过短,建议至少60秒${NC}" fi SPAN=$SPAN_INPUT else echo -e "${RED}警告: 输入无效,使用默认值300秒${NC}" SPAN=300 fi else SPAN=300 fi NEED_UPDATE=true fi # 询问是否设置例外IP echo "" echo "==================================================" echo -e "${RED}是否设置例外IP列表?(这些IP关机时不会自动开机)${NC}" echo -e -n "${RED}请输入例外IP,多个IP用英文逗号分隔,直接回车跳过: ${NC}" read EXCEPTION_INPUT if [ -n "$EXCEPTION_INPUT" ]; then EXCEPTION_IPS="$EXCEPTION_INPUT" NEED_UPDATE=true else if [ -z "$EXCEPTION_IPS" ]; then EXCEPTION_IPS="" fi fi # 保存配置 if [ "$NEED_UPDATE" = true ]; then echo "" echo "==================================================" # 使用Python更新YAML文件 ${PYTHON_CMD} << PYEOF import yaml config_file = "${CONFIG_FILE}" try: with open(config_file, 'r', encoding='utf-8') as f: config = yaml.safe_load(f) except: config = {} config['ACCOUNT'] = "${ACCOUNT}" config['API_KEY'] = "${API_KEY}" config['WAY'] = "${WAY}" if "${WAY}" == "http": config['DOMAIN'] = "${DOMAIN}" config['SPAN'] = ${SPAN} # 处理例外IP exception_ips_str = "${EXCEPTION_IPS}" if exception_ips_str: config['EXCEPTION_IPS'] = [ip.strip() for ip in exception_ips_str.split(',') if ip.strip()] else: config['EXCEPTION_IPS'] = [] # 清除JWT字段(重新生成) if 'JWT' in config: del config['JWT'] with open(config_file, 'w', encoding='utf-8') as f: yaml.dump(config, f, allow_unicode=True, default_flow_style=False) print("\033[32m✅ 配置已保存\033[0m") PYEOF if [ $? -ne 0 ]; then echo -e "${RED}错误: 配置保存失败${NC}" exit 1 fi else echo -e "${GREEN}✅${NC} 配置检查完成,无需更新" fi echo "" echo "当前配置:" echo " 账号: ${ACCOUNT}" echo " 检测方式: ${WAY}" if [ "$WAY" = "http" ]; then echo " 域名: ${DOMAIN}" fi echo " 监控间隔: ${SPAN}秒" if [ -n "$EXCEPTION_IPS" ]; then echo " 例外IP: ${EXCEPTION_IPS}" else echo " 例外IP: 无" fi echo "" # 安装Python依赖 if [ -f "${SCRIPT_DIR}/requirements.txt" ]; then echo "正在安装Python依赖包..." cd ${SCRIPT_DIR} if ${PIP_CMD} install -r requirements.txt; then echo -e "${GREEN}✅${NC} Python依赖包安装成功" else echo -e "${RED}❌${NC} Python依赖包安装失败" exit 1 fi else echo -e "${YELLOW}警告: requirements.txt 文件不存在${NC}" exit 1 fi # 检查monitor.py是否存在 if [ ! -f "${SCRIPT_DIR}/monitor.py" ]; then echo -e "${RED}错误: monitor.py 文件不存在${NC}" exit 1 fi # 创建日志目录 LOG_DIR="${SCRIPT_DIR}/logs" mkdir -p ${LOG_DIR} chmod 755 ${LOG_DIR} echo "" echo "正在创建systemd服务..." # 创建systemd服务文件 cat > ${SERVICE_FILE} << EOF [Unit] Description=Heyun IDC VPS Monitor Service After=network.target Wants=network-online.target [Service] Type=simple User=root WorkingDirectory=${SCRIPT_DIR} ExecStart=${PYTHON_CMD} ${SCRIPT_DIR}/monitor.py Restart=always RestartSec=10 StandardOutput=journal StandardError=journal SyslogIdentifier=${SERVICE_NAME} # 资源限制 LimitNOFILE=65536 # 安全设置 NoNewPrivileges=true ProtectSystem=strict ReadWritePaths=${SCRIPT_DIR} [Install] WantedBy=multi-user.target EOF # 重新加载systemd配置 systemctl daemon-reload # 启用服务(开机自启) systemctl enable ${SERVICE_NAME} # 启动服务 echo "" echo "正在启动服务..." systemctl start ${SERVICE_NAME} # 检查服务状态 sleep 2 if systemctl is-active --quiet ${SERVICE_NAME}; then echo -e "${GREEN}✅${NC} ${SERVICE_NAME} 服务已成功安装并启动" echo -e "${GREEN}✅${NC} 服务状态: 运行中" else echo -e "${RED}❌${NC} ${SERVICE_NAME} 服务启动失败" echo "" echo "请检查日志:" echo " journalctl -u ${SERVICE_NAME} -n 50 --no-pager" exit 1 fi echo "" echo "==========================================" echo -e "${GREEN}安装完成!${NC}" echo "==========================================" echo "" echo "常用命令:" echo -e " ${YELLOW}查看服务状态:${NC} systemctl status ${SERVICE_NAME}" echo -e " ${YELLOW}查看实时日志:${NC} journalctl -u ${SERVICE_NAME} -f" echo -e " ${YELLOW}查看正常日志:${NC} tail -f ${LOG_DIR}/monitor.log" echo -e " ${YELLOW}查看异常日志:${NC} tail -f ${LOG_DIR}/error.log" echo -e " ${YELLOW}停止服务:${NC} systemctl stop ${SERVICE_NAME}" echo -e " ${YELLOW}重启服务:${NC} systemctl restart ${SERVICE_NAME}" echo -e " ${YELLOW}卸载服务:${NC} cd ${SCRIPT_DIR} && ./uninstall.sh" echo "" echo "配置文件位置: ${CONFIG_FILE}" echo "日志文件位置: ${LOG_DIR}" echo ""