VPSHUB/app/install.sh

364 lines
10 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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
# 核云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 ""