Files
scripts-public/beszel-agent-updator/update-beszel-agent.sh
2026-02-01 17:10:54 +08:00

335 lines
8.1 KiB
Bash
Executable File
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
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