diff --git a/src/metric/client-plugins/demo-all-in-one/README.md b/src/metric/client-plugins/demo-all-in-one/README.md index 67808a8..39baf4b 100644 --- a/src/metric/client-plugins/demo-all-in-one/README.md +++ b/src/metric/client-plugins/demo-all-in-one/README.md @@ -46,12 +46,16 @@ node-exporter-installer /path/to/node-exporter-installer 1.1.0 - 压缩版本的安装包 - 一键安装的bash脚本 -## 第四步:部署到FTP服务器 +## 第四步:部署到FTP服务器(详见 FTP 搭建) 把发布的内容上传到FTP服务器,客户端就可以通过一键命令安装: ```bash -curl -fsSL http://your-ftp-server/install.sh | sh - +curl -u user:passwd ftp://server_ip/setup.sh -o setup.sh + +chmod +x setup.sh + +sudo ./setup.sh --server server_ip --user user --password passwd ``` 这样客户就能直接从FTP服务器下载并安装组件了。 \ No newline at end of file diff --git a/src/metric/client-plugins/demo-all-in-one/install-argus-metric.sh b/src/metric/client-plugins/demo-all-in-one/install-argus-metric.sh deleted file mode 100644 index 0e40d9f..0000000 --- a/src/metric/client-plugins/demo-all-in-one/install-argus-metric.sh +++ /dev/null @@ -1,221 +0,0 @@ -#!/bin/bash - -set -e - -# 颜色定义 -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}[SUCCESS]${NC} $1" -} - -log_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# 配置变量 -DEFAULT_VERSION="1.20.0" -BASE_URL="https://releases.yourdomain.com/argus-metric" -TEMP_DIR="/tmp/argus-metric-install-$$" - -# 解析参数 -VERSION="$DEFAULT_VERSION" -ACTION="install" - -while [[ $# -gt 0 ]]; do - case $1 in - --version) - VERSION="$2" - shift 2 - ;; - --uninstall) - ACTION="uninstall" - shift - ;; - --help) - echo "Argus Metric 在线安装脚本" - echo - echo "用法: curl -sfL https://install-argus-metric.yourdomain.com | sh -s -- [选项]" - echo - echo "选项:" - echo " --version VERSION 指定版本 (默认: $DEFAULT_VERSION)" - echo " --uninstall 卸载" - echo " --help 显示帮助" - echo - echo "示例:" - echo " curl -sfL https://install-argus-metric.yourdomain.com | sh -" - echo " curl -sfL https://install-argus-metric.yourdomain.com | sh -s -- --version 1.20.0" - echo " curl -sfL https://install-argus-metric.yourdomain.com | sh -s -- --uninstall" - exit 0 - ;; - *) - log_error "未知参数: $1" - echo "使用 --help 查看帮助信息" - exit 1 - ;; - esac -done - -# 清理函数 -cleanup() { - if [[ -d "$TEMP_DIR" ]]; then - rm -rf "$TEMP_DIR" - fi -} - -trap cleanup EXIT - -# 检查是否为 root 用户 -check_root() { - if [[ $EUID -ne 0 ]]; then - log_error "此脚本需要 root 权限运行" - log_info "请使用: sudo curl -sfL https://install-argus-metric.yourdomain.com | sh -" - exit 1 - fi -} - -# 检查系统要求 -check_system() { - log_info "检查系统要求..." - - # 检查操作系统 - if [[ ! -f /etc/os-release ]]; then - log_error "无法检测操作系统版本" - exit 1 - fi - - source /etc/os-release - log_info "检测到操作系统: $NAME $VERSION" - - # 检查系统架构 - arch=$(uname -m) - log_info "系统架构: $arch" - - # 检查磁盘空间 - available_space=$(df / | awk 'NR==2 {print $4}') - if [[ $available_space -lt 10485760 ]]; then # 10GB in KB - log_warning "可用磁盘空间不足 10GB,当前可用: $(($available_space / 1024 / 1024))GB" - fi -} - -# 下载并安装 -install_argus_metric() { - log_info "开始安装 Argus Metric v$VERSION..." - - # 创建临时目录 - mkdir -p "$TEMP_DIR" - cd "$TEMP_DIR" - - # 下载发布包 - TAR_NAME="argus-metric-$VERSION.tar.gz" - log_info "下载发布包: $TAR_NAME" - if ! curl -sfL "$BASE_URL/$TAR_NAME" -o "$TAR_NAME"; then - log_error "下载发布包失败: $BASE_URL/$TAR_NAME" - exit 1 - fi - - # 解压发布包 - log_info "解压发布包..." - if ! tar -xzf "$TAR_NAME"; then - log_error "解压发布包失败" - exit 1 - fi - - # 进入解压目录 - cd "argus-metric-$VERSION" - - # 执行安装 - log_info "执行安装..." - if [[ -f "install_artifact.sh" ]]; then - chmod +x install_artifact.sh - if ./install_artifact.sh; then - log_success "Argus Metric v$VERSION 安装完成!" - else - log_error "安装失败" - exit 1 - fi - else - log_error "未找到安装脚本 install_artifact.sh" - exit 1 - fi -} - -# 卸载 -uninstall_argus_metric() { - log_info "开始卸载 Argus Metric..." - - # 创建临时目录 - mkdir -p "$TEMP_DIR" - cd "$TEMP_DIR" - - # 下载发布包 - TAR_NAME="argus-metric-$VERSION.tar.gz" - log_info "下载发布包: $TAR_NAME" - if ! curl -sfL "$BASE_URL/$TAR_NAME" -o "$TAR_NAME"; then - log_error "下载发布包失败: $BASE_URL/$TAR_NAME" - exit 1 - fi - - # 解压发布包 - log_info "解压发布包..." - if ! tar -xzf "$TAR_NAME"; then - log_error "解压发布包失败" - exit 1 - fi - - # 进入解压目录 - cd "argus-metric-$VERSION" - - # 执行卸载 - log_info "执行卸载..." - if [[ -f "uninstall_artifact.sh" ]]; then - chmod +x uninstall_artifact.sh - if ./uninstall_artifact.sh; then - log_success "Argus Metric 卸载完成!" - else - log_error "卸载失败" - exit 1 - fi - else - log_error "未找到卸载脚本 uninstall_artifact.sh" - exit 1 - fi -} - -# 主函数 -main() { - echo "==========================================" - echo " Argus Metric 在线安装脚本 v1.0" - echo "==========================================" - echo - - check_root - check_system - - if [[ "$ACTION" == "uninstall" ]]; then - uninstall_argus_metric - else - install_argus_metric - fi - - echo - log_info "操作完成!" -} - -# 脚本入口 -if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then - main "$@" -fi diff --git a/src/metric/client-plugins/demo-all-in-one/install_artifact.sh b/src/metric/client-plugins/demo-all-in-one/install_artifact.sh index d868bb1..9198751 100755 --- a/src/metric/client-plugins/demo-all-in-one/install_artifact.sh +++ b/src/metric/client-plugins/demo-all-in-one/install_artifact.sh @@ -295,7 +295,7 @@ install_system_deps() { local extract_dir="$deps_temp_dir/$extract_name" mkdir -p "$extract_dir" - if tar -xzf "$tar_file" -C "$extract_dir"; then + if tar -xzf "$tar_file" -C "$extract_dir" 2>/dev/null; then log_success " $tar_basename 解压完成" else log_error " $tar_basename 解压失败" @@ -333,9 +333,46 @@ install_system_deps() { cd "$deps_temp_dir" done + # 检查并启动 cron 服务 + start_cron_service + log_success "系统依赖包安装完成" } +# 启动 cron 服务 +start_cron_service() { + log_info "检查并启动 cron 服务..." + + # 检查 cron 是否已经在运行 + if pgrep -x "cron" > /dev/null; then + log_success "cron 服务已在运行" + return 0 + fi + + # 检查 /usr/sbin/cron 是否存在 + if [[ ! -f "/usr/sbin/cron" ]]; then + log_warning "cron 可执行文件不存在,跳过启动" + return 1 + fi + + # 启动 cron 服务 + log_info "启动 cron 服务..." + if /usr/sbin/cron start 2>/dev/null || /usr/sbin/cron 2>/dev/null; then + log_success "cron 服务启动成功" + + sleep 2 + + if pgrep -x "cron" > /dev/null; then + log_success "cron 服务运行正常" + else + log_warning "cron 服务可能未正常启动" + fi + else + log_error "cron 服务启动失败" + return 1 + fi +} + # 安装组件 install_components() { log_info "开始安装组件..." @@ -378,7 +415,7 @@ install_components() { component_temp_dir="$TEMP_DIR/$component" mkdir -p "$component_temp_dir" - if tar -xzf "$tar_file" -C "$component_temp_dir"; then + if tar -xzf "$tar_file" -C "$component_temp_dir" 2>/dev/null; then log_success " $component 解压完成" else log_error " $component 解压失败" @@ -524,8 +561,9 @@ EOF setup_health_check_cron() { log_info "设置健康检查定时任务..." - local script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" - local check_health_script="$script_dir/check_health.sh" + # 直接使用当前安装目录,不依赖current软链接 + # INSTALL_DIR 是 /opt/argus-metric/versions/1.34.0 + local check_health_script="$INSTALL_DIR/check_health.sh" # 检查健康检查脚本是否存在 if [[ ! -f "$check_health_script" ]]; then @@ -542,22 +580,24 @@ setup_health_check_cron() { # 获取当前用户的crontab(如果存在) crontab -l 2>/dev/null > "$temp_cron" || touch "$temp_cron" - # 检查是否已经存在健康检查任务 + # 检查并删除旧的健康检查任务 if grep -q "check_health.sh" "$temp_cron"; then - log_warning "健康检查定时任务已存在,跳过设置" - rm -f "$temp_cron" - return 0 + log_info "发现旧的健康检查定时任务,正在更新..." + # 删除所有包含check_health.sh的行 + grep -v "check_health.sh" "$temp_cron" > "$temp_cron.new" + mv "$temp_cron.new" "$temp_cron" + log_info "旧的健康检查定时任务已删除" fi # 添加新的定时任务(每5分钟执行一次) echo "# Argus-Metrics 健康检查定时任务" >> "$temp_cron" - echo "*/5 * * * * $check_health_script >> $script_dir/.health_cron.log 2>&1" >> "$temp_cron" + echo "*/5 * * * * $check_health_script >> $INSTALL_DIR/.health_cron.log 2>&1" >> "$temp_cron" # 安装新的crontab if crontab "$temp_cron"; then log_success "健康检查定时任务设置成功" log_info " 执行频率: 每5分钟" - log_info " 日志文件: $script_dir/.health_cron.log" + log_info " 日志文件: $INSTALL_DIR/.health_cron.log" log_info " 查看定时任务: crontab -l" log_info " 删除定时任务: crontab -e" else diff --git a/src/metric/client-plugins/demo-all-in-one/publish_artifact.sh b/src/metric/client-plugins/demo-all-in-one/publish_artifact.sh index 16c17f2..710b27a 100755 --- a/src/metric/client-plugins/demo-all-in-one/publish_artifact.sh +++ b/src/metric/client-plugins/demo-all-in-one/publish_artifact.sh @@ -22,7 +22,7 @@ log_error() { # 显示帮助信息 show_help() { - echo "AIOps Artifact 发布脚本" + echo "Argus-Metric Artifact 发布脚本" echo echo "用法: $0 <版本号>" echo @@ -43,7 +43,7 @@ fi VERSION="$1" ARTIFACT_DIR="artifact/$VERSION" -PUBLISH_DIR="publish/$VERSION" +PUBLISH_DIR="/srv/ftp/share" # 检查版本目录是否存在 if [[ ! -d "$ARTIFACT_DIR" ]]; then @@ -53,12 +53,16 @@ fi log_info "开始发布版本: $VERSION" -# 创建发布目录 -log_info "创建发布目录: $PUBLISH_DIR" +# 确保发布目录存在 +log_info "确保发布目录存在: $PUBLISH_DIR" mkdir -p "$PUBLISH_DIR" -# 复制所有 tar.gz 文件到发布目录 -log_info "复制 artifact 文件..." +# 创建临时目录用于打包 +TEMP_PACKAGE_DIR="/tmp/argus-metric-package-$$" +mkdir -p "$TEMP_PACKAGE_DIR" + +# 复制所有 tar.gz 文件到临时目录 +log_info "准备 artifact 文件..." tar_files=$(find "$ARTIFACT_DIR" -name "*.tar.gz" -type f) if [[ -z "$tar_files" ]]; then @@ -68,47 +72,78 @@ fi for file in $tar_files; do filename=$(basename "$file") - log_info " 复制: $filename" - cp "$file" "$PUBLISH_DIR/" + log_info " 准备: $filename" + cp "$file" "$TEMP_PACKAGE_DIR/" done # 复制版本信息文件 if [[ -f "$ARTIFACT_DIR/version.json" ]]; then log_info "复制版本信息文件..." - cp "$ARTIFACT_DIR/version.json" "$PUBLISH_DIR/" + cp "$ARTIFACT_DIR/version.json" "$TEMP_PACKAGE_DIR/" fi -# 复制安装脚本 +# 复制健康检查脚本 +if [[ -f "$ARTIFACT_DIR/check_health.sh" ]]; then + log_info "复制健康检查脚本..." + cp "$ARTIFACT_DIR/check_health.sh" "$TEMP_PACKAGE_DIR/" +elif [[ -f "check_health.sh" ]]; then + log_info "复制健康检查脚本 (从当前目录)..." + cp "check_health.sh" "$TEMP_PACKAGE_DIR/" +else + log_warning "未找到 check_health.sh 文件" +fi + +# 复制安装脚本并重命名为 install.sh if [[ -f "install_artifact.sh" ]]; then log_info "复制安装脚本..." - cp "install_artifact.sh" "$PUBLISH_DIR/" + cp "install_artifact.sh" "$TEMP_PACKAGE_DIR/install.sh" fi if [[ -f "uninstall_artifact.sh" ]]; then log_info "复制卸载脚本..." - cp "uninstall_artifact.sh" "$PUBLISH_DIR/" + cp "uninstall_artifact.sh" "$TEMP_PACKAGE_DIR/uninstall.sh" fi -# 创建tar包 -TAR_NAME="argus-metric-$VERSION.tar.gz" +# 创建tar包,使用新的命名规范 +TAR_NAME="argus-metric_$(echo $VERSION | tr '.' '_').tar.gz" log_info "创建发布包: $TAR_NAME" -cd publish -tar -czf "$TAR_NAME" "$VERSION" -cd .. +cd "$TEMP_PACKAGE_DIR" +tar -czf "$PUBLISH_DIR/$TAR_NAME" * +cd - > /dev/null + +# 清理临时目录 +rm -rf "$TEMP_PACKAGE_DIR" + +# 更新 LATEST_VERSION 文件 +log_info "更新 LATEST_VERSION 文件..." +echo "$VERSION" > "$PUBLISH_DIR/LATEST_VERSION" + +# 复制 setup.sh 到发布目录 +if [[ -f "setup.sh" ]]; then + log_info "复制 setup.sh 到发布目录..." + cp "setup.sh" "$PUBLISH_DIR/" +fi # 显示发布结果 log_success "版本 $VERSION 发布完成!" echo echo "发布目录: $PUBLISH_DIR" -echo "发布包: publish/$TAR_NAME" -echo "包大小: $(du -h "publish/$TAR_NAME" | cut -f1)" +echo "发布包: $PUBLISH_DIR/$TAR_NAME" +echo "包大小: $(du -h "$PUBLISH_DIR/$TAR_NAME" | cut -f1)" +echo "最新版本: $(cat "$PUBLISH_DIR/LATEST_VERSION")" echo -echo "包含文件:" +echo "发布目录中的文件:" ls -la "$PUBLISH_DIR" | while read line; do echo " $line" done echo echo "使用方法:" -echo " 1. 将 publish/$TAR_NAME 部署到 Web 服务器" -echo " 2. 用户可以通过以下命令安装:" -echo " curl -sfL https://yourdomain.com/$TAR_NAME | tar -xz && cd argus-metric-$VERSION && sudo ./install_artifact.sh" +echo " 1. 确保 /srv/ftp/share 目录可通过 FTP 访问" +echo " 2. 用户首先下载安装脚本:" +echo " curl -u ftpuser:admin1234 ftp://10.211.55.4/setup.sh -o setup.sh" +echo " 3. 然后执行安装 (自动获取最新版本):" +echo " sudo sh setup.sh" +echo " 4. 或者指定版本安装:" +echo " sudo sh setup.sh --version $VERSION" +echo " 5. 或者指定不同的FTP服务器:" +echo " sudo sh setup.sh --server 192.168.1.100 --user myuser --password mypass" diff --git a/src/metric/client-plugins/demo-all-in-one/setup.sh b/src/metric/client-plugins/demo-all-in-one/setup.sh new file mode 100644 index 0000000..87128f7 --- /dev/null +++ b/src/metric/client-plugins/demo-all-in-one/setup.sh @@ -0,0 +1,862 @@ +#!/bin/bash + +set -e + +# 颜色定义 +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}[SUCCESS]${NC} $1" +} + +log_warning() { + echo -e "${YELLOW}[WARNING]${NC} $1" +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" +} + +FTP_SERVER="${FTP_SERVER}" +FTP_USER="${FTP_USER}" +FTP_PASS="${FTP_PASS}" +FTP_PORT="${FTP_PORT:-21}" +BASE_URL="" # FTP基础URL (将在check_ftp_params中设置) +LATEST_VERSION_URL="" # 版本文件URL (将在check_ftp_params中设置) +TEMP_DIR="/tmp/argus-metric-install-$$" + +# 安装目录配置 +DEFAULT_INSTALL_DIR="/opt/argus-metric" # 默认安装目录 +INSTALL_DIR="${INSTALL_DIR:-$DEFAULT_INSTALL_DIR}" # 可通过环境变量覆盖 +VERSIONS_DIR="$INSTALL_DIR/versions" # 版本目录 +BACKUPS_DIR="$INSTALL_DIR/backups" # 备份目录 +CURRENT_LINK="$INSTALL_DIR/current" # 当前版本软链接 +LATEST_VERSION_FILE="$INSTALL_DIR/LATEST_VERSION" # 当前版本记录文件 + +# 检查必需的FTP参数 +check_ftp_params() { + local missing_params=() + + if [[ -z "$FTP_SERVER" ]]; then + missing_params+=("FTP_SERVER") + fi + + if [[ -z "$FTP_USER" ]]; then + missing_params+=("FTP_USER") + fi + + if [[ -z "$FTP_PASS" ]]; then + missing_params+=("FTP_PASS") + fi + + if [[ ${#missing_params[@]} -gt 0 ]]; then + log_error "缺少必需的FTP参数: ${missing_params[*]}" + log_error "请通过以下方式之一设置FTP参数:" + log_error " 1. 命令行参数: --server <地址> --user <用户名> --password <密码>" + log_error " 2. 环境变量: FTP_SERVER=<地址> FTP_USER=<用户名> FTP_PASS=<密码>" + log_error "" + log_error "示例:" + log_error " sudo sh setup.sh --server 10.211.55.4 --user ftpuser --password admin1234" + log_error " FTP_SERVER=10.211.55.4 FTP_USER=ftpuser FTP_PASS=admin1234 sudo sh setup.sh" + exit 1 + fi + + # 设置BASE_URL和LATEST_VERSION_URL + BASE_URL="ftp://${FTP_SERVER}:${FTP_PORT}" + LATEST_VERSION_URL="$BASE_URL/LATEST_VERSION" + + log_info "FTP配置:" + log_info " 服务器: $FTP_SERVER:$FTP_PORT" + log_info " 用户: $FTP_USER" +} + +# 获取最新版本号的函数 +get_latest_version() { + log_info "获取最新版本信息..." >&2 + log_info "尝试从URL获取: $LATEST_VERSION_URL" >&2 + + # 先测试FTP连接 + log_info "测试FTP连接..." >&2 + if ! curl -u "${FTP_USER}:${FTP_PASS}" -sfI "$LATEST_VERSION_URL" >/dev/null 2>&1; then + log_error "无法连接到FTP服务器或文件不存在" >&2 + log_error "URL: $LATEST_VERSION_URL" >&2 + log_error "请检查:" >&2 + log_error " 1. FTP服务器是否运行: $FTP_SERVER:$FTP_PORT" >&2 + log_error " 2. 用户名密码是否正确: $FTP_USER" >&2 + log_error " 3. LATEST_VERSION文件是否存在" >&2 + log_error "手动测试命令: curl -u ${FTP_USER}:${FTP_PASS} ftp://${FTP_SERVER}/LATEST_VERSION" >&2 + exit 1 + fi + + # 获取文件内容 + if ! LATEST_VERSION=$(curl -u "${FTP_USER}:${FTP_PASS}" -sfL "$LATEST_VERSION_URL" 2>/dev/null | tr -d '[:space:]'); then + log_error "下载LATEST_VERSION文件失败" >&2 + exit 1 + fi + + log_info "原始获取内容: '$LATEST_VERSION'" >&2 + + if [[ -z "$LATEST_VERSION" ]]; then + log_error "获取到的版本信息为空" >&2 + log_error "可能的原因:" >&2 + log_error " 1. LATEST_VERSION文件为空" >&2 + log_error " 2. 文件内容格式不正确" >&2 + log_error " 3. 网络传输问题" >&2 + log_error "请检查FTP服务器上的 /srv/ftp/share/LATEST_VERSION 文件" >&2 + exit 1 + fi + + log_info "检测到最新版本: $LATEST_VERSION" >&2 + echo "$LATEST_VERSION" +} + +# 解析参数 +ARGUS_VERSION="" # 使用不同的变量名避免与系统VERSION冲突 +ACTION="install" + +while [[ $# -gt 0 ]]; do + case $1 in + --version) + ARGUS_VERSION="$2" + shift 2 + ;; + --server) + FTP_SERVER="$2" + shift 2 + ;; + --user) + FTP_USER="$2" + shift 2 + ;; + --password) + FTP_PASS="$2" + shift 2 + ;; + --port) + FTP_PORT="$2" + shift 2 + ;; + --uninstall) + ACTION="uninstall" + shift + ;; + --install-dir) + INSTALL_DIR="$2" + shift 2 + ;; + --rollback) + ACTION="rollback" + shift + ;; + --backup-list) + ACTION="backup-list" + shift + ;; + --status) + ACTION="status" + shift + ;; + --help) + echo "Argus Metric FTP在线安装脚本" + echo + echo "用法: curl -u <用户名>:<密码> ftp://<服务器>/setup.sh -o setup.sh && sh setup.sh [选项]" + echo + echo "必需参数 (必须通过命令行参数或环境变量设置):" + echo " --server SERVER FTP服务器地址 (必须)" + echo " --user USER FTP用户名 (必须)" + echo " --password PASS FTP密码 (必须)" + echo + echo "可选参数:" + echo " --version VERSION 指定版本 (默认: 自动获取最新版本)" + echo " --port PORT FTP端口 (默认: 21)" + echo " --install-dir DIR 安装目录 (默认: /opt/argus-metric)" + echo " --uninstall 卸载 (自动确认)" + echo " --rollback 回滚到上一个备份版本" + echo " --backup-list 列出所有备份版本" + echo " --status 显示当前安装状态" + echo " --help 显示帮助" + echo + echo "环境变量:" + echo " FTP_SERVER FTP服务器地址 (必须)" + echo " FTP_USER FTP用户名 (必须)" + echo " FTP_PASS FTP密码 (必须)" + echo " FTP_PORT FTP端口 (默认: 21)" + echo + echo "示例:" + echo " # 方式1: 使用命令行参数" + echo " curl -u ftpuser:admin1234 ftp://10.211.55.4/setup.sh -o setup.sh" + echo " sudo sh setup.sh --server 10.211.55.4 --user ftpuser --password admin1234" + echo " " + echo " # 方式2: 使用环境变量" + echo " FTP_SERVER=10.211.55.4 FTP_USER=ftpuser FTP_PASS=admin1234 sudo sh setup.sh" + echo " " + echo " # 指定版本安装" + echo " sudo sh setup.sh --server 10.211.55.4 --user ftpuser --password admin1234 --version 1.30.0" + echo " " + echo " # 卸载" + echo " sudo sh setup.sh --server 10.211.55.4 --user ftpuser --password admin1234 --uninstall" + exit 0 + ;; + *) + log_error "未知参数: $1" + echo "使用 --help 查看帮助信息" + exit 1 + ;; + esac +done + +# 清理函数 +cleanup() { + if [[ -d "$TEMP_DIR" ]]; then + rm -rf "$TEMP_DIR" + fi +} + +trap cleanup EXIT + +# 创建安装目录结构 +create_install_directories() { + log_info "创建安装目录结构..." + + # 创建主要目录 + mkdir -p "$VERSIONS_DIR" + mkdir -p "$BACKUPS_DIR" + + log_success "安装目录结构创建完成: $INSTALL_DIR" +} + +# 获取当前安装的版本 +get_current_version() { + # 优先从LATEST_VERSION文件读取 + if [[ -f "$LATEST_VERSION_FILE" ]]; then + local version_from_file=$(cat "$LATEST_VERSION_FILE" 2>/dev/null | tr -d '[:space:]') + if [[ -n "$version_from_file" ]]; then + # 确保版本号格式一致(不带v前缀) + echo "$version_from_file" + return 0 + fi + fi + + # 如果文件不存在或为空,从软链接读取 + if [[ -L "$CURRENT_LINK" ]]; then + local current_path=$(readlink "$CURRENT_LINK") + # 从版本目录名中提取版本号(现在不带v前缀) + basename "$current_path" + else + echo "" + fi +} + +# 检查是否已安装 +check_installed() { + if [[ -L "$CURRENT_LINK" ]] && [[ -d "$CURRENT_LINK" ]]; then + local current_version=$(get_current_version) + if [[ -n "$current_version" ]]; then + log_info "检测到已安装版本: v$current_version" + return 0 + fi + fi + return 1 +} + +# 更新LATEST_VERSION文件 +update_latest_version_file() { + local version="$1" + log_info "更新LATEST_VERSION文件: $version" + + if echo "$version" > "$LATEST_VERSION_FILE"; then + log_success "LATEST_VERSION文件已更新" + else + log_error "更新LATEST_VERSION文件失败" + return 1 + fi +} + +# 备份当前版本 +backup_current_version() { + local current_version=$(get_current_version) + if [[ -z "$current_version" ]]; then + log_info "没有当前版本需要备份" + return 0 + fi + + local backup_name="$current_version" + local backup_path="$BACKUPS_DIR/$backup_name" + + log_info "备份当前版本 $current_version 到: $backup_path" + + # 如果备份已存在,先删除 + if [[ -d "$backup_path" ]]; then + log_info "备份版本已存在,覆盖: $backup_path" + rm -rf "$backup_path" + fi + + # 复制当前版本目录 + if cp -r "$CURRENT_LINK" "$backup_path"; then + log_success "版本备份完成: $backup_name" + + # 清理旧备份,只保留最近3个 + cleanup_old_backups + else + log_error "版本备份失败" + exit 1 + fi +} + +# 清理旧备份 +cleanup_old_backups() { + log_info "清理旧版本备份..." + + # 获取备份目录列表,按时间排序,保留最近3个 + local backup_count=$(ls -1 "$BACKUPS_DIR" 2>/dev/null | wc -l) + if [[ $backup_count -gt 3 ]]; then + local to_remove=$((backup_count - 3)) + ls -1t "$BACKUPS_DIR" | tail -n $to_remove | while read backup; do + log_info "删除旧备份: $backup" + rm -rf "$BACKUPS_DIR/$backup" + done + fi +} + +# 回滚到备份版本 +rollback_to_backup() { + local backup_name="$1" + local backup_path="$BACKUPS_DIR/$backup_name" + + if [[ ! -d "$backup_path" ]]; then + log_error "备份不存在: $backup_path" + return 1 + fi + + log_info "回滚到备份版本: $backup_name" + + # 停止当前服务 + stop_services + + # 恢复软链接(备份目录应该包含版本内容) + if ln -sfn "$backup_path" "$CURRENT_LINK"; then + log_success "版本回滚完成: $backup_name" + + # 启动服务 + start_services + return 0 + else + log_error "版本回滚失败" + return 1 + fi +} + +# 停止服务 +stop_services() { + log_info "停止当前服务..." + + # 检查服务是否正在运行 + if ! check_services_running; then + log_info "服务未运行,无需停止" + return 0 + fi + + # 尝试使用卸载脚本停止服务 + if [[ -f "$CURRENT_LINK/uninstall.sh" ]]; then + cd "$CURRENT_LINK" + chmod +x uninstall.sh + + # 自动确认停止服务(避免交互式确认) + echo "y" | ./uninstall.sh >/dev/null 2>&1 + local stop_exit_code=$? + + if [[ $stop_exit_code -eq 0 ]]; then + log_success "服务停止完成" + else + log_warning "停止服务时出现警告,尝试手动停止" + manual_stop_services + fi + else + log_warning "未找到卸载脚本,尝试手动停止服务" + manual_stop_services + fi +} + +# 手动停止服务 +manual_stop_services() { + log_info "手动停止服务..." + + # 停止 node_exporter + if pgrep -f "node_exporter" >/dev/null 2>&1; then + pkill -f "node_exporter" && log_info "node_exporter 已停止" + fi + + # 停止 dcgm_exporter + if pgrep -f "dcgm_exporter" >/dev/null 2>&1; then + pkill -f "dcgm_exporter" && log_info "dcgm_exporter 已停止" + fi + + # 等待进程完全停止 + sleep 2 + + # 检查是否还有残留进程 + if pgrep -f "node_exporter\|dcgm_exporter" >/dev/null 2>&1; then + log_warning "仍有服务进程运行,尝试强制停止" + pkill -9 -f "node_exporter\|dcgm_exporter" 2>/dev/null || true + fi + + log_success "手动停止服务完成" +} + +# 启动服务 +start_services() { + log_info "启动服务..." + + if [[ -f "$CURRENT_LINK/install.sh" ]]; then + cd "$CURRENT_LINK" + chmod +x install.sh + + # 检查服务是否已经在运行 + if check_services_running; then + log_info "服务已在运行,跳过启动" + return 0 + fi + + # 启动服务 - 传递正确的安装目录参数 + if ./install.sh "$INSTALL_DIR" 2>/dev/null; then + log_success "服务启动完成" + else + log_error "服务启动失败" + return 1 + fi + else + log_error "未找到安装脚本" + return 1 + fi +} + +# 检查服务是否正在运行 +check_services_running() { + # 检查常见的服务端口是否在监听 + local ports=(9100 9400) # node-exporter 和 dcgm-exporter 的默认端口 + + for port in "${ports[@]}"; do + if netstat -tlnp 2>/dev/null | grep -q ":$port "; then + log_info "检测到服务正在端口 $port 上运行" + return 0 + fi + done + + # 检查相关进程 + if pgrep -f "node_exporter\|dcgm_exporter" >/dev/null 2>&1; then + log_info "检测到相关服务进程正在运行" + return 0 + fi + + return 1 +} + +# 检查是否为 root 用户 +check_root() { + if [[ $EUID -ne 0 ]]; then + log_error "此脚本需要 root 权限运行" + log_info "请使用: sudo sh setup.sh" + exit 1 + fi +} + +# 检查系统要求 +check_system() { + log_info "检查系统要求..." + + # 检查操作系统 + if [[ ! -f /etc/os-release ]]; then + log_error "无法检测操作系统版本" + exit 1 + fi + + # 读取系统信息,使用子shell避免污染当前环境变量 + local OS_INFO=$(source /etc/os-release && echo "$NAME $VERSION_ID") + log_info "检测到操作系统: $OS_INFO" + + # 检查系统架构 + arch=$(uname -m) + log_info "系统架构: $arch" + + # 检查磁盘空间 + available_space=$(df / | awk 'NR==2 {print $4}') + if [[ $available_space -lt 1024 ]]; then + log_warning "可用磁盘空间不足 1GB,当前可用: $(($available_space / 1024 / 1024))GB" + fi +} + +# 下载并安装 +install_argus_metric() { + # 如果没有指定版本,获取最新版本 + if [[ -z "$ARGUS_VERSION" ]]; then + ARGUS_VERSION=$(get_latest_version) + fi + + log_info "开始安装 Argus Metric v$ARGUS_VERSION..." + log_info "安装目录: $INSTALL_DIR" + + # 检查是否已安装 + local is_upgrade=false + if check_installed; then + local current_version=$(get_current_version) + if [[ "$current_version" == "$ARGUS_VERSION" ]]; then + log_info "版本 v$ARGUS_VERSION 已安装,无需重复安装" + return 0 + fi + log_info "检测到版本升级: v$current_version -> v$ARGUS_VERSION" + is_upgrade=true + + # 备份当前版本 + backup_current_version + fi + + # 创建安装目录结构 + create_install_directories + + # 创建临时目录 + mkdir -p "$TEMP_DIR" + cd "$TEMP_DIR" + + # 下载发布包,使用新的命名规范 + TAR_NAME="argus-metric_$(echo $ARGUS_VERSION | tr '.' '_').tar.gz" + log_info "下载发布包: $TAR_NAME" + log_info "从FTP服务器下载: $FTP_SERVER:$FTP_PORT, 用户: $FTP_USER" + + # 构造curl命令并显示(隐藏密码) + CURL_CMD="curl -u \"${FTP_USER}:***\" -sfL \"$BASE_URL/$TAR_NAME\" -o \"$TAR_NAME\"" + log_info "执行命令: $CURL_CMD" + + if ! curl -u "${FTP_USER}:${FTP_PASS}" -sfL "$BASE_URL/$TAR_NAME" -o "$TAR_NAME"; then + log_error "下载发布包失败: $BASE_URL/$TAR_NAME" + log_error "完整命令: curl -u \"${FTP_USER}:${FTP_PASS}\" -sfL \"$BASE_URL/$TAR_NAME\" -o \"$TAR_NAME\"" + log_error "请检查FTP服务器连接、用户名密码是否正确" + exit 1 + fi + + # 解压发布包到当前目录 + log_info "解压发布包..." + if ! tar -xzf "$TAR_NAME"; then + log_error "解压发布包失败" + exit 1 + fi + + # 显示解压后的文件结构 + log_info "解压后的文件结构:" + ls -la "$TEMP_DIR" + + # 准备版本目录 + local version_dir="$VERSIONS_DIR/$ARGUS_VERSION" + log_info "安装到版本目录: $version_dir" + + # 如果升级,先停止服务 + if [[ "$is_upgrade" == true ]]; then + stop_services + fi + + # 创建版本目录 + if [[ -d "$version_dir" ]]; then + log_info "版本目录已存在,备份后更新" + rm -rf "$version_dir" + fi + + # 创建新的版本目录 + mkdir -p "$version_dir" + + # 移动解压的文件到版本目录 + log_info "移动文件到版本目录: $TEMP_DIR/* -> $version_dir/" + + # 检查源目录是否有内容 + if [[ ! "$(ls -A "$TEMP_DIR" 2>/dev/null)" ]]; then + log_error "临时目录为空,无法移动文件" + exit 1 + fi + + # 检查目标目录是否存在 + if [[ ! -d "$version_dir" ]]; then + log_error "目标版本目录不存在: $version_dir" + exit 1 + fi + + # 执行文件移动 + if mv "$TEMP_DIR"/* "$version_dir" 2>/dev/null; then + log_success "文件移动到版本目录完成" + else + log_error "移动文件到版本目录失败" + log_error "源目录内容:" + ls -la "$TEMP_DIR" || true + log_error "目标目录状态:" + ls -la "$version_dir" || true + log_error "权限检查:" + ls -ld "$TEMP_DIR" "$version_dir" || true + exit 1 + fi + + # 执行安装脚本 + log_info "执行安装脚本..." + cd "$version_dir" + if [[ -f "install.sh" ]]; then + chmod +x install.sh + # 传递版本目录作为安装目录给安装脚本 + if ./install.sh "$version_dir"; then + log_success "安装脚本执行完成" + else + log_error "安装脚本执行失败" + # 如果是升级失败,尝试回滚 + if [[ "$is_upgrade" == true ]]; then + log_warning "升级失败,尝试回滚到之前版本..." + local latest_backup=$(ls -1t "$BACKUPS_DIR" 2>/dev/null | head -n 1) + if [[ -n "$latest_backup" ]]; then + rollback_to_backup "$latest_backup" + return 1 + fi + fi + exit 1 + fi + else + log_error "未找到安装脚本 install.sh" + exit 1 + fi + + # 更新软链接指向新版本 + log_info "更新当前版本链接..." + if ln -sfn "$version_dir" "$CURRENT_LINK"; then + log_success "版本链接更新完成: $CURRENT_LINK -> $version_dir" + else + log_error "版本链接更新失败" + exit 1 + fi + + # 更新LATEST_VERSION文件 + update_latest_version_file "$ARGUS_VERSION" + + # 启动服务 + start_services + + log_success "Argus Metric v$ARGUS_VERSION 安装完成!" + + # 显示安装信息 + echo + log_info "安装信息:" + log_info " 版本: $ARGUS_VERSION" + log_info " 安装目录: $INSTALL_DIR" + log_info " 版本目录: $version_dir" + log_info " 当前链接: $CURRENT_LINK" + if [[ "$is_upgrade" == true ]]; then + log_info " 升级类型: 版本升级" + else + log_info " 安装类型: 全新安装" + fi +} + +# 卸载 +uninstall_argus_metric() { + log_info "开始卸载 Argus Metric..." + log_info "安装目录: $INSTALL_DIR" + + # 检查是否已安装 + if ! check_installed; then + log_info "未检测到已安装的 Argus Metric" + return 0 + fi + + local current_version=$(get_current_version) + log_info "检测到当前版本: v$current_version" + + # 停止服务 + stop_services + + # 执行卸载脚本 + log_info "执行卸载脚本..." + if [[ -f "$CURRENT_LINK/uninstall.sh" ]]; then + cd "$CURRENT_LINK" + chmod +x uninstall.sh + + # 自动确认卸载(因为用户已经明确使用了 --uninstall 参数) + log_info "自动确认卸载操作..." + echo "y" | ./uninstall.sh + local uninstall_exit_code=$? + + if [[ $uninstall_exit_code -eq 0 ]]; then + log_success "卸载脚本执行完成" + else + log_error "卸载脚本执行失败 (退出码: $uninstall_exit_code)" + exit 1 + fi + else + log_warning "未找到卸载脚本,执行基本清理" + fi + + # 清理安装目录 + log_info "清理安装目录..." + if [[ -d "$INSTALL_DIR" ]]; then + # 询问是否完全删除安装目录 + log_warning "这将删除整个安装目录: $INSTALL_DIR" + log_warning "包括所有版本、备份和配置文件" + + # 在自动化环境中,直接删除 + if rm -rf "$INSTALL_DIR"; then + log_success "安装目录已完全清理: $INSTALL_DIR" + else + log_error "清理安装目录失败" + exit 1 + fi + else + log_info "安装目录不存在,无需清理" + fi + + log_success "Argus Metric 卸载完成!" +} + +# 显示状态 +show_status() { + echo "==========================================" + echo " Argus Metric 安装状态" + echo "==========================================" + echo + + if check_installed; then + local current_version=$(get_current_version) + log_info "当前版本: $current_version" + log_info "安装目录: $INSTALL_DIR" + log_info "当前链接: $CURRENT_LINK" + log_info "版本目录: $VERSIONS_DIR/$current_version" + log_info "版本文件: $LATEST_VERSION_FILE" + + # 显示LATEST_VERSION文件内容 + if [[ -f "$LATEST_VERSION_FILE" ]]; then + local file_version=$(cat "$LATEST_VERSION_FILE" 2>/dev/null | tr -d '[:space:]') + log_info "版本文件内容: $file_version" + fi + + echo + log_info "目录结构:" + if [[ -d "$INSTALL_DIR" ]]; then + tree -L 2 "$INSTALL_DIR" 2>/dev/null || ls -la "$INSTALL_DIR" + fi + + echo + log_info "可用版本:" + if [[ -d "$VERSIONS_DIR" ]]; then + ls -1 "$VERSIONS_DIR" 2>/dev/null | sed 's/^/ - /' + else + echo " 无" + fi + + echo + log_info "备份版本:" + if [[ -d "$BACKUPS_DIR" ]] && [[ $(ls -1 "$BACKUPS_DIR" 2>/dev/null | wc -l) -gt 0 ]]; then + ls -1t "$BACKUPS_DIR" 2>/dev/null | sed 's/^/ - /' + else + echo " 无" + fi + else + log_warning "Argus Metric 未安装" + log_info "安装目录: $INSTALL_DIR" + fi +} + +# 列出备份 +list_backups() { + echo "==========================================" + echo " Argus Metric 备份列表" + echo "==========================================" + echo + + if [[ -d "$BACKUPS_DIR" ]] && [[ $(ls -1 "$BACKUPS_DIR" 2>/dev/null | wc -l) -gt 0 ]]; then + log_info "可用备份版本:" + ls -1t "$BACKUPS_DIR" 2>/dev/null | while read backup; do + local backup_time=$(stat -c %y "$BACKUPS_DIR/$backup" 2>/dev/null | cut -d' ' -f1-2) + echo " - $backup (创建时间: $backup_time)" + done + else + log_warning "没有可用的备份版本" + fi +} + +# 回滚功能 +rollback_version() { + log_info "开始回滚操作..." + + if ! check_installed; then + log_error "没有检测到已安装的版本,无法回滚" + exit 1 + fi + + # 获取最新的备份 + local latest_backup=$(ls -1t "$BACKUPS_DIR" 2>/dev/null | head -n 1) + if [[ -z "$latest_backup" ]]; then + log_error "没有找到可用的备份版本" + exit 1 + fi + + log_info "将回滚到备份版本: $latest_backup" + + if rollback_to_backup "$latest_backup"; then + log_success "回滚完成!" + + # 显示当前状态 + echo + show_status + else + log_error "回滚失败" + exit 1 + fi +} + +# 主函数 +main() { + echo "==========================================" + echo " Argus Metric 在线安装脚本 v1.0" + echo "==========================================" + echo + + # 对于状态和备份列表操作,不需要FTP参数和root权限 + if [[ "$ACTION" == "status" || "$ACTION" == "backup-list" ]]; then + if [[ "$ACTION" == "status" ]]; then + show_status + elif [[ "$ACTION" == "backup-list" ]]; then + list_backups + fi + return 0 + fi + + check_root + + # 更新目录配置变量(在设置INSTALL_DIR后) + VERSIONS_DIR="$INSTALL_DIR/versions" + BACKUPS_DIR="$INSTALL_DIR/backups" + CURRENT_LINK="$INSTALL_DIR/current" + LATEST_VERSION_FILE="$INSTALL_DIR/LATEST_VERSION" + + # 对于回滚操作,不需要FTP参数 + if [[ "$ACTION" == "rollback" ]]; then + rollback_version + return 0 + fi + + check_ftp_params + check_system + + if [[ "$ACTION" == "uninstall" ]]; then + uninstall_argus_metric + else + install_argus_metric + fi + + echo + log_info "操作完成!" +} + +# 脚本入口 +if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then + main "$@" +fi diff --git a/src/metric/ftp/deps/vsftpd_3.0.5-0ubuntu1.1_amd64.deb b/src/metric/ftp/deps/vsftpd_3.0.5-0ubuntu1.1_amd64.deb new file mode 100644 index 0000000..995a5db Binary files /dev/null and b/src/metric/ftp/deps/vsftpd_3.0.5-0ubuntu1.1_amd64.deb differ diff --git a/src/metric/ftp/vsftpd-config-README.md b/src/metric/ftp/vsftpd-config-README.md new file mode 100644 index 0000000..acd3d0c --- /dev/null +++ b/src/metric/ftp/vsftpd-config-README.md @@ -0,0 +1,111 @@ +# vsftpd 配置 + +配置 vsftpd FTP 服务器。 + +# 安装deps下 vsftpd 的离线安装包 + +sudo dpkg -i vsftpd_3.0.5-0ubuntu1.1_amd64.deb + +# 有依赖问题,修复依赖 + +sudo apt-get install -f + +## 启动服务 + +sudo service vsftpd start + +# 重启服务 + +sudo service vsftpd restart + +# 查看状态 + +sudo service vsftpd status + +## 备份配置文件 + +先备份默认配置,出问题能恢复: + +```bash +sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak +``` + +## 修改配置文件 + +编辑配置: + +```bash +sudo vim /etc/vsftpd.conf +``` + +### 基本配置参数 + +```bash +# 允许本地用户登录 +local_enable=YES + +# 允许写操作(上传/删除/修改) +write_enable=YES + +# 限制用户在自己目录中,不能访问整个系统 +chroot_local_user=YES + +# 防止 chroot 错误(重要!) +allow_writeable_chroot=YES + +# 被动模式配置 +pasv_enable=YES +pasv_min_port=30000 +pasv_max_port=31000 +``` + +## 创建 FTP 目录和用户 + +### 创建共享目录 + +```bash +sudo mkdir -p /srv/ftp/share +sudo chmod 755 /srv/ftp/share +``` + +### 创建专用用户 + +```bash +sudo adduser ftpuser + +# 修改用户主目录 +sudo usermod -d /srv/ftp/share ftpuser +``` + +## 重启服务 + +```bash +sudo service vsftpd restart +``` + +## 防火墙配置 + +### 开放基本端口 + +```bash +sudo ufw allow 21/tcp +``` + +### 开放被动模式端口 + +```bash +sudo ufw allow 30000:31000/tcp +``` + +## 测试连接 + +```bash +# 本地测试 +ftp localhost + +# 远程测试 +ftp 你的服务器IP +``` + +用户名:ftpuser +密码:设置的密码 \ No newline at end of file diff --git a/src/metric/ftp/vsftpd-offline-install.sh b/src/metric/ftp/vsftpd-offline-install.sh new file mode 100755 index 0000000..79f70aa --- /dev/null +++ b/src/metric/ftp/vsftpd-offline-install.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# vsftpd 离线安装脚本 +# 使用方法:./vsftpd-offline-install.sh + +set -e + +echo "开始 vsftpd 离线安装..." + +# 检查是否为 root 用户 +if [ "$EUID" -ne 0 ]; then + echo "请使用 root 权限运行此脚本" + exit 1 +fi + +# 定义离线包目录 +OFFLINE_DIR="./vsftpd-offline" +DEB_DIR="$OFFLINE_DIR/debs" + +# 检查离线包是否存在 +if [ ! -d "$OFFLINE_DIR" ]; then + echo "错误:找不到离线包目录 $OFFLINE_DIR" + echo "请先准备离线包,方法:" + echo "1. 在有网络的机器上运行:" + echo " mkdir -p $DEB_DIR" + echo " cd $DEB_DIR" + echo " apt download vsftpd" + echo " apt download \$(apt-cache depends vsftpd | grep Depends | cut -d: -f2 | tr -d ' ')" + echo "2. 将整个 $OFFLINE_DIR 目录拷贝到目标机器" + exit 1 +fi + +# 安装 deb 包 +echo "安装 vsftpd 及依赖包..." +cd "$DEB_DIR" +dpkg -i *.deb || apt-get install -f -y + +# 检查安装状态 +if systemctl is-active --quiet vsftpd; then + echo "vsftpd 安装成功并已启动" +else + echo "启动 vsftpd 服务..." + systemctl start vsftpd + systemctl enable vsftpd +fi + +echo "vsftpd 离线安装完成!" +echo "配置文件位置: /etc/vsftpd.conf" +echo "服务状态: $(systemctl is-active vsftpd)"