#!/bin/sh # BackupX Agent 一键安装脚本(由 Master 动态渲染) # Magic: BACKUPX_AGENT_INSTALL_V1 —— 若 `head -3 脚本` 看不到此行,说明反向代理/CDN 改写了响应 # 模式: {{.Mode}} | 架构: {{.Arch}} | 版本: {{.AgentVersion}} set -eu # 自举到 bash(文件执行模式下生效;管道模式 $0 不是文件,exec 会静默失败,继续用 sh)。 # 动机:部分 Debian/Ubuntu 用户通过 `curl | sudo sh` 触发时,dash 对本脚本报语法错误; # 若目标机装有 bash,优先切换到 bash 获得更一致的行为。 if [ -z "${BASH_VERSION:-}" ] && command -v bash >/dev/null 2>&1 && [ -f "$0" ]; then exec bash "$0" "$@" fi MASTER_URL="{{.MasterURL}}" AGENT_TOKEN="{{.AgentToken}}" AGENT_VERSION="{{.AgentVersion}}" DOWNLOAD_BASE="{{.DownloadBase}}" INSTALL_PREFIX="{{.InstallPrefix}}" ARCH="{{.Arch}}" # 1. 前置检查 [ "$(id -u)" -eq 0 ] || { echo "请使用 root 或 sudo 执行" >&2; exit 1; } command -v curl >/dev/null || command -v wget >/dev/null \ || { echo "需要 curl 或 wget" >&2; exit 1; } {{if eq .Mode "systemd"}}command -v systemctl >/dev/null || { echo "不支持非 systemd 系统" >&2; exit 1; } {{end}}{{if eq .Mode "docker"}}command -v docker >/dev/null || { echo "需要先安装 docker" >&2; exit 1; } {{end}} # 2. 架构检测 if [ "$ARCH" = "auto" ]; then case "$(uname -m)" in x86_64|amd64) ARCH=amd64 ;; aarch64|arm64) ARCH=arm64 ;; *) echo "不支持的架构: $(uname -m)" >&2; exit 1 ;; esac fi {{if ne .Mode "docker"}} # 3. 下载二进制(systemd / foreground 模式) ARCHIVE="backupx-${AGENT_VERSION}-linux-${ARCH}.tar.gz" URL="${DOWNLOAD_BASE}/${AGENT_VERSION}/${ARCHIVE}" TMPDIR="$(mktemp -d)"; trap 'rm -rf "$TMPDIR"' EXIT echo "[1/4] 下载 ${URL}" if command -v curl >/dev/null; then curl -fsSL "$URL" -o "$TMPDIR/pkg.tar.gz" else wget -qO "$TMPDIR/pkg.tar.gz" "$URL" fi tar xzf "$TMPDIR/pkg.tar.gz" -C "$TMPDIR" # 4. 安装二进制 + 数据目录 echo "[2/4] 安装到 ${INSTALL_PREFIX}" install -d -m 0755 "$INSTALL_PREFIX" install -d -m 0700 /var/lib/backupx-agent /var/lib/backupx-agent/tmp install -m 0755 "$TMPDIR/backupx-${AGENT_VERSION}-linux-${ARCH}/backupx" "$INSTALL_PREFIX/backupx" {{end}} {{if eq .Mode "systemd"}} # 5. systemd unit echo "[3/4] 配置 systemd" cat > /etc/systemd/system/backupx-agent.service </dev/null \ | grep -q '"status":"online"'; then echo "✓ 节点已上线" exit 0 fi done echo "⚠ 30s 内未收到上线心跳,请检查防火墙或 journalctl -u backupx-agent" echo "提示:systemd 服务名是 backupx-agent,可执行 systemctl status backupx-agent 查看状态。" exit 2 {{end}} {{if eq .Mode "foreground"}} # 5. 前台运行 echo "[3/3] 前台启动 agent(Ctrl+C 退出)" export BACKUPX_AGENT_MASTER="${MASTER_URL}" export BACKUPX_AGENT_TOKEN="${AGENT_TOKEN}" exec "${INSTALL_PREFIX}/backupx" agent --temp-dir /var/lib/backupx-agent/tmp {{end}} {{if eq .Mode "docker"}} # Docker 模式:直接用镜像启动容器 echo "[1/2] 拉取镜像 awuqing/backupx:${AGENT_VERSION}" docker pull "awuqing/backupx:${AGENT_VERSION}" echo "[2/2] 启动容器 backupx-agent" docker rm -f backupx-agent >/dev/null 2>&1 || true docker run -d --name backupx-agent --restart=unless-stopped \ -e "BACKUPX_AGENT_MASTER=${MASTER_URL}" \ -e "BACKUPX_AGENT_TOKEN=${AGENT_TOKEN}" \ -e "BACKUPX_AGENT_TEMP_DIR=/var/lib/backupx-agent/tmp" \ -v /var/lib/backupx-agent:/var/lib/backupx-agent \ "awuqing/backupx:${AGENT_VERSION}" agent echo "✓ 容器已启动,等待节点上线" for i in $(seq 1 15); do sleep 2 if curl -fsSL -H "X-Agent-Token: ${AGENT_TOKEN}" "${MASTER_URL}/api/v1/agent/self" 2>/dev/null \ | grep -q '"status":"online"'; then echo "✓ 节点已上线" exit 0 fi done echo "⚠ 30s 内未收到上线心跳,请检查容器状态、网络与 Master URL。" echo "排查命令:docker ps -a --filter name=backupx-agent" echo "排查命令:docker logs --tail=100 backupx-agent" exit 2 {{end}}