From cedf36e6326c35fd650f2ec875700849970852d9 Mon Sep 17 00:00:00 2001 From: FlintyLemming Date: Sun, 1 Feb 2026 17:10:54 +0800 Subject: [PATCH] =?UTF-8?q?Beszel=20Agent=20=E6=9B=B4=E6=96=B0=E8=84=9A?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- beszel-agent-updator/update-beszel-agent.sh | 334 ++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100755 beszel-agent-updator/update-beszel-agent.sh diff --git a/beszel-agent-updator/update-beszel-agent.sh b/beszel-agent-updator/update-beszel-agent.sh new file mode 100755 index 0000000..4c8bf50 --- /dev/null +++ b/beszel-agent-updator/update-beszel-agent.sh @@ -0,0 +1,334 @@ +#!/bin/bash +set -e + +# Beszel Agent 更新脚本 +# 支持 Debian/Ubuntu, Arch, RHEL/CentOS/Fedora 等 systemd 系统 + +SERVICE_NAME="beszel-agent.service" +MIRROR_BASE_URL="https://index.mitsea.com/d/Github%20Release%20Mirrors/Beszel" +MIRROR_API_URL="https://index.mitsea.com/api/fs/list" + +# 颜色输出 +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +log_info() { + echo -e "${GREEN}[INFO]${NC} $1" >&2 +} + +log_warn() { + echo -e "${YELLOW}[WARN]${NC} $1" >&2 +} + +log_error() { + echo -e "${RED}[ERROR]${NC} $1" >&2 +} + +# 检查是否以 root 运行 +check_root() { + if [[ $EUID -ne 0 ]]; then + log_error "此脚本需要 root 权限运行" + log_info "请使用 sudo $0" + exit 1 + fi +} + +# 检查依赖 +check_dependencies() { + local missing_deps=() + + for cmd in curl tar systemctl; do + if ! command -v "$cmd" &> /dev/null; then + missing_deps+=("$cmd") + fi + done + + if [[ ${#missing_deps[@]} -gt 0 ]]; then + log_error "缺少依赖: ${missing_deps[*]}" + log_info "请先安装这些依赖" + exit 1 + fi +} + +# 版本号比较函数:返回 0 表示 $1 > $2,返回 1 表示 $1 <= $2 +version_gt() { + local v1="${1#v}" + local v2="${2#v}" + + # 使用 sort -V 进行版本号比较 + if [[ "$(printf '%s\n%s' "$v1" "$v2" | sort -V | tail -n1)" == "$v1" && "$v1" != "$v2" ]]; then + return 0 + else + return 1 + fi +} + +# 从 API 获取最新版本号 +get_latest_version() { + log_info "正在从镜像站获取最新版本信息..." + + local response + response=$(curl -s -X POST "$MIRROR_API_URL" \ + -H 'Content-Type: application/json' \ + -d '{"path": "/Github Release Mirrors/Beszel"}') + + if [[ -z "$response" ]]; then + log_error "无法获取版本信息" + exit 1 + fi + + # 解析版本号列表 + local versions + if command -v jq &> /dev/null; then + versions=$(echo "$response" | jq -r '.data.content[].name' 2>/dev/null) + else + # 使用 grep 和 sed 作为备选方案 + versions=$(echo "$response" | grep -o '"name":"v[^"]*"' | sed 's/"name":"//g; s/"//g') + fi + + if [[ -z "$versions" ]]; then + log_error "无法解析版本列表" + exit 1 + fi + + # 找出最新版本(按版本号排序) + local latest_version + latest_version=$(echo "$versions" | sort -V | tail -n1) + + if [[ -z "$latest_version" ]]; then + log_error "无法确定最新版本" + exit 1 + fi + + echo "$latest_version" +} + +# 从 systemd service 文件获取二进制文件路径 +get_binary_path() { + local service_file="/etc/systemd/system/$SERVICE_NAME" + + if [[ ! -f "$service_file" ]]; then + log_error "找不到 service 文件: $service_file" + exit 1 + fi + + local exec_start + exec_start=$(grep "^ExecStart=" "$service_file" | cut -d'=' -f2-) + + if [[ -z "$exec_start" ]]; then + log_error "无法从 service 文件中获取 ExecStart" + exit 1 + fi + + # 提取二进制文件路径(取第一个参数,即可执行文件路径) + local binary_path + binary_path=$(echo "$exec_start" | awk '{print $1}') + + echo "$binary_path" +} + +# 获取当前版本 +get_current_version() { + local binary_path="$1" + + if [[ ! -f "$binary_path" ]]; then + echo "unknown" + return + fi + + # beszel-agent 不支持 --version,尝试用 strings 从二进制中提取版本号 + # 版本号格式通常是 x.y.z + local version="" + + if command -v strings &> /dev/null; then + version=$(strings "$binary_path" 2>/dev/null | grep -oE '^[0-9]+\.[0-9]+\.[0-9]+$' | head -n1) + fi + + # 如果 strings 不可用或没找到,尝试用 grep + if [[ -z "$version" ]]; then + version=$(grep -aoE '[0-9]+\.[0-9]+\.[0-9]+' "$binary_path" 2>/dev/null | head -n1) + fi + + if [[ -z "$version" ]]; then + echo "unknown" + else + echo "$version" + fi +} + +# 检测系统架构 +detect_arch() { + local arch + arch=$(uname -m) + + case "$arch" in + x86_64|amd64) + echo "amd64" + ;; + aarch64|arm64) + echo "arm64" + ;; + armv7l|armhf) + echo "arm" + ;; + i386|i686) + echo "386" + ;; + *) + log_error "不支持的架构: $arch" + exit 1 + ;; + esac +} + +# 下载并更新 +download_and_update() { + local version="$1" + local binary_path="$2" + local arch="$3" + + # 构建下载 URL(文件名不含版本号) + local filename="beszel-agent_linux_${arch}.tar.gz" + local download_url="${MIRROR_BASE_URL}/${version}/${filename}" + + log_info "下载 URL: $download_url" + + # 创建临时目录 + local tmp_dir + tmp_dir=$(mktemp -d) + trap "rm -rf $tmp_dir" EXIT + + local tar_file="$tmp_dir/$filename" + + # 下载文件 + log_info "正在下载 $filename ..." + if ! curl -L -f -o "$tar_file" "$download_url"; then + log_error "下载失败" + exit 1 + fi + + # 解压 + log_info "正在解压..." + if ! tar -xzf "$tar_file" -C "$tmp_dir"; then + log_error "解压失败" + exit 1 + fi + + # 查找解压后的二进制文件 + local new_binary="$tmp_dir/beszel-agent" + if [[ ! -f "$new_binary" ]]; then + log_error "解压后找不到 beszel-agent 文件" + exit 1 + fi + + # 停止服务 + log_info "正在停止 $SERVICE_NAME ..." + systemctl stop "$SERVICE_NAME" || true + + # 备份旧文件 + local backup_path="${binary_path}.bak" + if [[ -f "$binary_path" ]]; then + log_info "备份旧文件到 $backup_path" + cp "$binary_path" "$backup_path" + fi + + # 替换二进制文件 + log_info "正在更新二进制文件..." + cp "$new_binary" "$binary_path" + chmod +x "$binary_path" + + # 启动服务 + log_info "正在启动 $SERVICE_NAME ..." + systemctl start "$SERVICE_NAME" + + # 检查服务状态 + sleep 2 + if systemctl is-active --quiet "$SERVICE_NAME"; then + log_info "服务启动成功" + else + log_error "服务启动失败,正在回滚..." + if [[ -f "$backup_path" ]]; then + cp "$backup_path" "$binary_path" + systemctl start "$SERVICE_NAME" + fi + exit 1 + fi +} + +# 主函数 +main() { + log_info "===== Beszel Agent 更新脚本 =====" + + check_root + check_dependencies + + # 获取二进制文件路径 + local binary_path + binary_path=$(get_binary_path) + log_info "二进制文件路径: $binary_path" + + # 获取当前版本 + local current_version + current_version=$(get_current_version "$binary_path") + log_info "当前版本: $current_version" + + # 获取最新版本 + local latest_version + latest_version=$(get_latest_version) + log_info "最新版本: $latest_version" + + # 检测架构 + local arch + arch=$(detect_arch) + log_info "系统架构: $arch" + + # 比较版本(简单比较,如果当前版本包含最新版本号则跳过) + local latest_version_num="${latest_version#v}" + if [[ "$current_version" == *"$latest_version_num"* ]]; then + log_info "已经是最新版本,无需更新" + exit 0 + fi + + # 确认更新 + if [[ "$AUTO_CONFIRM" != "true" ]]; then + read -p "是否更新到 $latest_version? [y/N] " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + log_info "取消更新" + exit 0 + fi + fi + + # 执行更新 + download_and_update "$latest_version" "$binary_path" "$arch" + + log_info "===== 更新完成 =====" + log_info "已更新到: $latest_version" +} + +# 解析参数 +while [[ $# -gt 0 ]]; do + case "$1" in + -y|--yes) + AUTO_CONFIRM="true" + shift + ;; + -h|--help) + echo "用法: $0 [选项]" + echo "" + echo "选项:" + echo " -y, --yes 自动确认更新,不询问" + echo " -h, --help 显示帮助信息" + exit 0 + ;; + *) + log_error "未知参数: $1" + echo "使用 -h 或 --help 查看帮助" + exit 1 + ;; + esac +done + +main