218 lines
8.6 KiB
Bash
Executable File
218 lines
8.6 KiB
Bash
Executable File
#!/bin/bash
|
|
#═══════════════════════════════════════════════════════════════════════════════
|
|
# install_z1_agent.sh — Palladium Z1 主机端 collect.py 一键部署脚本
|
|
#═══════════════════════════════════════════════════════════════════════════════
|
|
# 用法:
|
|
# sudo ./install_z1_agent.sh --url http://MONITOR_HOST:5100/api/collect --host scmp03
|
|
# sudo ./install_z1_agent.sh --uninstall
|
|
#
|
|
# 关键点:
|
|
# - 默认 30 分钟一次 (cron */30)
|
|
# - 自动检测 env.csh / env.sh (如不存在则提示用户提供 --env)
|
|
# - 幂等: 重复运行会先卸载旧的
|
|
# - 保险模式: 不会覆盖用户已有 crontab, 也不会 rm 任何文件
|
|
#═══════════════════════════════════════════════════════════════════════════════
|
|
|
|
set -euo pipefail
|
|
|
|
# ─── Defaults ────────────────────────────────────────────────────────────────
|
|
INSTALL_DIR="/opt/palladium-monitor"
|
|
LOG_DIR="/var/log"
|
|
LOG_FILE="$LOG_DIR/palladium-collect.log"
|
|
CRON_TAG="palladium-monitor-collect" # crontab 注释标记, 便于后续识别
|
|
DEFAULT_TIMEOUT=300
|
|
DEFAULT_RETRIES=3
|
|
DEFAULT_RETRY_DELAY=5
|
|
|
|
# ─── CLI ─────────────────────────────────────────────────────────────────────
|
|
usage() {
|
|
cat <<EOF
|
|
Palladium Z1 监控客户端安装脚本
|
|
|
|
用法:
|
|
$0 --url URL [--host NAME] [--env ENV_SCRIPT] [--interval MINUTES] [--uninstall]
|
|
|
|
必选 (首次安装):
|
|
--url URL 监控服务器 API 地址 (例如 http://10.0.0.10:5100/api/collect)
|
|
|
|
可选:
|
|
--host NAME 本机标签 (默认: hostname)
|
|
--env ENV_SCRIPT VXE env.csh / env.sh 绝对路径
|
|
--interval MINUTES 采集间隔分钟数 (默认: 30)
|
|
--timeout SECONDS test_server 超时 (默认: 300)
|
|
--retries N 推送失败重试次数 (默认: 3)
|
|
--uninstall 卸载 (保留日志和安装目录, 仅移除 crontab 和脚本)
|
|
|
|
示例:
|
|
$0 --url http://10.0.0.10:5100/api/collect --host scmp03 \\
|
|
--env /edatools/vxe/VXE23.03.001/bin/env.csh --interval 30
|
|
EOF
|
|
}
|
|
|
|
UNINSTALL=0
|
|
URL=""
|
|
HOST="$(hostname -s 2>/dev/null || hostname)"
|
|
ENV_SCRIPT=""
|
|
INTERVAL=30
|
|
TIMEOUT=$DEFAULT_TIMEOUT
|
|
RETRIES=$DEFAULT_RETRIES
|
|
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--url) URL="$2"; shift 2 ;;
|
|
--host) HOST="$2"; shift 2 ;;
|
|
--env) ENV_SCRIPT="$2"; shift 2 ;;
|
|
--interval) INTERVAL="$2"; shift 2 ;;
|
|
--timeout) TIMEOUT="$2"; shift 2 ;;
|
|
--retries) RETRIES="$2"; shift 2 ;;
|
|
--uninstall) UNINSTALL=1; shift ;;
|
|
-h|--help) usage; exit 0 ;;
|
|
*) echo "未知参数: $1" >&2; usage; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
# ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
log_info() { echo "[INFO] $*"; }
|
|
log_warn() { echo "[WARN] $*" >&2; }
|
|
log_error() { echo "[ERROR] $*" >&2; }
|
|
|
|
require_root() {
|
|
if [[ $EUID -ne 0 ]]; then
|
|
log_error "请用 root 运行: sudo $0 $*"
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# 备份当前 crontab
|
|
backup_crontab() {
|
|
local bak="/tmp/crontab.backup.$(date +%Y%m%d_%H%M%S)"
|
|
if crontab -l >/dev/null 2>&1; then
|
|
crontab -l > "$bak"
|
|
log_info "已备份现有 crontab → $bak"
|
|
else
|
|
: > "$bak"
|
|
log_info "当前用户无 crontab, 备份为空文件 $bak"
|
|
fi
|
|
}
|
|
|
|
# 移除已存在的同标记行 (幂等)
|
|
remove_existing_cron() {
|
|
if crontab -l 2>/dev/null | grep -q "$CRON_TAG"; then
|
|
log_info "检测到旧任务, 先移除 (幂等)"
|
|
crontab -l | grep -v "$CRON_TAG" | grep -v "^#" | crontab -
|
|
fi
|
|
}
|
|
|
|
# ─── Uninstall ────────────────────────────────────────────────────────────────
|
|
do_uninstall() {
|
|
require_root
|
|
log_info "卸载: 移除 crontab 任务 (标签: $CRON_TAG)"
|
|
remove_existing_cron
|
|
if [[ -f "$INSTALL_DIR/collect.py" ]]; then
|
|
log_info "移除脚本: $INSTALL_DIR/collect.py"
|
|
rm -f "$INSTALL_DIR/collect.py"
|
|
fi
|
|
log_info "卸载完成. 日志保留在 $LOG_FILE (如不再需要请手动清理)"
|
|
exit 0
|
|
}
|
|
|
|
[[ "$UNINSTALL" -eq 1 ]] && do_uninstall
|
|
|
|
# ─── Install ──────────────────────────────────────────────────────────────────
|
|
require_root
|
|
|
|
if [[ -z "$URL" ]]; then
|
|
log_error "--url 是必选参数"
|
|
usage
|
|
exit 1
|
|
fi
|
|
|
|
# 校验 URL 格式 (基本)
|
|
if ! [[ "$URL" =~ ^https?://[^:]+:[0-9]+/.* ]]; then
|
|
log_warn "URL 格式异常: $URL (期望 http://host:port/path)"
|
|
read -r -p "仍要继续? [y/N] " ans
|
|
[[ "$ans" =~ ^[Yy]$ ]] || { log_info "已取消"; exit 1; }
|
|
fi
|
|
|
|
# 校验 env 脚本 (如果指定)
|
|
if [[ -n "$ENV_SCRIPT" ]]; then
|
|
if [[ ! -f "$ENV_SCRIPT" ]]; then
|
|
log_error "env 脚本不存在: $ENV_SCRIPT"
|
|
exit 1
|
|
fi
|
|
log_info "env 脚本校验通过: $ENV_SCRIPT"
|
|
fi
|
|
|
|
# 创建安装目录
|
|
log_info "创建安装目录: $INSTALL_DIR"
|
|
mkdir -p "$INSTALL_DIR"
|
|
|
|
# 复制 collect.py
|
|
SCRIPT_SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/collect.py"
|
|
if [[ ! -f "$SCRIPT_SRC" ]]; then
|
|
log_error "未找到 collect.py, 请把脚本和本安装器放在同一目录"
|
|
exit 1
|
|
fi
|
|
install -m 0755 "$SCRIPT_SRC" "$INSTALL_DIR/collect.py"
|
|
log_info "已安装: $INSTALL_DIR/collect.py"
|
|
|
|
# 确保 requests 可用
|
|
if ! python3 -c "import requests" 2>/dev/null; then
|
|
log_warn "python3 'requests' 未安装, 尝试安装..."
|
|
if command -v pip3 >/dev/null; then
|
|
pip3 install requests
|
|
elif command -v pip >/dev/null; then
|
|
pip install requests
|
|
else
|
|
log_error "找不到 pip/pip3, 请手动安装 requests 后重试"
|
|
exit 1
|
|
fi
|
|
fi
|
|
log_info "Python 'requests' 模块可用"
|
|
|
|
# 准备日志
|
|
touch "$LOG_FILE" 2>/dev/null || { log_error "无法写入 $LOG_FILE"; exit 1; }
|
|
chmod 0644 "$LOG_FILE"
|
|
|
|
# 安装 crontab
|
|
log_info "安装 crontab — 每 $INTERVAL 分钟, 标签: $CRON_TAG"
|
|
backup_crontab
|
|
remove_existing_cron
|
|
|
|
# 构造 cron 行
|
|
CRON_LINE="*/${INTERVAL} * * * * /usr/bin/python3 ${INSTALL_DIR}/collect.py --url ${URL} --host ${HOST}"
|
|
if [[ -n "$ENV_SCRIPT" ]]; then
|
|
CRON_LINE="${CRON_LINE} --env ${ENV_SCRIPT}"
|
|
fi
|
|
CRON_LINE="${CRON_LINE} --timeout ${TIMEOUT} --retries ${RETRIES} --log ${LOG_FILE} >> ${LOG_FILE}.cron 2>&1 # ${CRON_TAG}"
|
|
|
|
# 写入新 crontab (保留旧任务)
|
|
{ crontab -l 2>/dev/null; echo "$CRON_LINE"; } | crontab -
|
|
log_info "crontab 已更新"
|
|
|
|
# ─── 验证安装 ────────────────────────────────────────────────────────────────
|
|
log_info "── 当前 crontab 中本任务相关行 ──"
|
|
crontab -l | grep "$CRON_TAG" || log_warn "未找到新行, 请检查"
|
|
|
|
log_info "── 立即跑一次 dry-run 验证脚本可执行 ──"
|
|
"$INSTALL_DIR/collect.py" \
|
|
--url "$URL" --host "$HOST" \
|
|
${ENV_SCRIPT:+--env "$ENV_SCRIPT"} \
|
|
--timeout 30 --retries 1 --retry-delay 1 \
|
|
--dry-run 2>&1 | tail -20 || log_warn "dry-run 失败 (test_server 可能在 VXE 工具链环境外, 这是正常的)"
|
|
|
|
cat <<EOF
|
|
|
|
════════════════════════════════════════════════════════════════════════════
|
|
✅ 安装完成
|
|
|
|
脚本: $INSTALL_DIR/collect.py
|
|
日志: $LOG_FILE (主日志)
|
|
${LOG_FILE}.cron (cron 自己的输出)
|
|
Crontab: 每 $INTERVAL 分钟一次
|
|
监控服务器: $URL
|
|
主机标签: $HOST
|
|
卸载: sudo $0 --uninstall
|
|
════════════════════════════════════════════════════════════════════════════
|
|
EOF
|