merge next-scripts: items 15/16/17/23 (install-agent mirror/reuse/self-check, openrc respawn)
CI / go-test (push) Waiting to run
CI / postgres-durable-first (push) Waiting to run
CI / codegen (push) Waiting to run
CI / govulncheck (push) Waiting to run
CI / race (push) Waiting to run
CI / fuzz-smoke (push) Waiting to run
CI / golangci (push) Waiting to run
CI / frontend (push) Waiting to run
Release 3X-UI / build (386) (push) Waiting to run
Release 3X-UI / build (amd64) (push) Waiting to run
Release 3X-UI / build (arm64) (push) Waiting to run
Release 3X-UI / build (armv5) (push) Waiting to run
Release 3X-UI / build (armv6) (push) Waiting to run
Release 3X-UI / build (armv7) (push) Waiting to run
Release 3X-UI / build (s390x) (push) Waiting to run
Release 3X-UI / Build for Windows (amd64) (push) Waiting to run
Release 3X-UI / Publish rolling dev release (push) Blocked by required conditions
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CI / go-test (push) Waiting to run
CI / postgres-durable-first (push) Waiting to run
CI / codegen (push) Waiting to run
CI / govulncheck (push) Waiting to run
CI / race (push) Waiting to run
CI / fuzz-smoke (push) Waiting to run
CI / golangci (push) Waiting to run
CI / frontend (push) Waiting to run
Release 3X-UI / build (386) (push) Waiting to run
Release 3X-UI / build (amd64) (push) Waiting to run
Release 3X-UI / build (arm64) (push) Waiting to run
Release 3X-UI / build (armv5) (push) Waiting to run
Release 3X-UI / build (armv6) (push) Waiting to run
Release 3X-UI / build (armv7) (push) Waiting to run
Release 3X-UI / build (s390x) (push) Waiting to run
Release 3X-UI / Build for Windows (amd64) (push) Waiting to run
Release 3X-UI / Publish rolling dev release (push) Blocked by required conditions
CodeQL Advanced / Analyze (go) (push) Waiting to run
CodeQL Advanced / Analyze (actions) (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
This commit is contained in:
+74
-10
@@ -3,6 +3,10 @@
|
|||||||
# 用法: bash install-agent.sh --master http://MASTER_IP:2053 --token YOUR_AGENT_TOKEN [--name my-node]
|
# 用法: bash install-agent.sh --master http://MASTER_IP:2053 --token YOUR_AGENT_TOKEN [--name my-node]
|
||||||
# 要求: Debian/Ubuntu/Alpine/CentOS (amd64/arm64), root 运行
|
# 要求: Debian/Ubuntu/Alpine/CentOS (amd64/arm64), root 运行
|
||||||
#
|
#
|
||||||
|
# 无参沿用(第 16 条):已装过 agent 的机器重跑本脚本升级时,可省略全部参数——
|
||||||
|
# 脚本会从本机 /etc/x-ui/agent.json 沿用 master_url/token/node_name;显式传入的
|
||||||
|
# 参数逐字段覆盖沿用值。日志只打明沿用的节点名与主控地址,绝不打印 token。
|
||||||
|
#
|
||||||
# 测试用环境变量(一般无需设置):
|
# 测试用环境变量(一般无需设置):
|
||||||
# XUI_ROOT 安装路径前缀(假根目录验证用),默认空 = 真实路径
|
# XUI_ROOT 安装路径前缀(假根目录验证用),默认空 = 真实路径
|
||||||
# XUI_INIT_SYSTEM 强制 init 系统: systemd | openrc | none,默认 auto 探测
|
# XUI_INIT_SYSTEM 强制 init 系统: systemd | openrc | none,默认 auto 探测
|
||||||
@@ -22,8 +26,10 @@ warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
|
|||||||
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
|
error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; }
|
||||||
|
|
||||||
[[ $EUID -ne 0 ]] && error "请用 root 运行"
|
[[ $EUID -ne 0 ]] && error "请用 root 运行"
|
||||||
|
command -v curl >/dev/null 2>&1 || error "缺少 curl,请先安装 curl 后重跑"
|
||||||
|
command -v unzip >/dev/null 2>&1 || error "缺少 unzip,请先安装 unzip 后重跑"
|
||||||
|
|
||||||
MASTER=""; TOKEN=""; NAME="agent-node"
|
MASTER=""; TOKEN=""; NAME=""
|
||||||
while [[ $# -gt 0 ]]; do
|
while [[ $# -gt 0 ]]; do
|
||||||
case $1 in
|
case $1 in
|
||||||
--master) MASTER="$2"; shift 2;;
|
--master) MASTER="$2"; shift 2;;
|
||||||
@@ -33,8 +39,31 @@ while [[ $# -gt 0 ]]; do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
[[ -z "$MASTER" ]] && error "缺少 --master 参数"
|
# 无参沿用(第 16 条):参数缺项时,从本机已有 agent.json 逐字段补默认值,
|
||||||
|
# 显式参数优先。agent.json 由本脚本以固定格式写出,这里用 sed 提取字段,
|
||||||
|
# 不依赖 jq。文件不存在或解析不出可用字段、且必填值仍缺 → 下方校验明确报错。
|
||||||
|
AGENT_JSON_PATH="${XUI_ROOT:-}/etc/x-ui/agent.json"
|
||||||
|
json_get() { # $1=文件 $2=键名 → 打印值(取不到则空)
|
||||||
|
sed -n "s/.*\"$2\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" "$1" 2>/dev/null | head -n 1
|
||||||
|
}
|
||||||
|
if [[ -f "$AGENT_JSON_PATH" ]]; then
|
||||||
|
INHERITED=()
|
||||||
|
f_master=$(json_get "$AGENT_JSON_PATH" master_url)
|
||||||
|
f_token=$(json_get "$AGENT_JSON_PATH" token)
|
||||||
|
f_name=$(json_get "$AGENT_JSON_PATH" node_name)
|
||||||
|
if [[ -z "$MASTER" && -n "$f_master" ]]; then MASTER="$f_master"; INHERITED+=("主控地址"); fi
|
||||||
|
if [[ -z "$TOKEN" && -n "$f_token" ]]; then TOKEN="$f_token"; INHERITED+=("token"); fi
|
||||||
|
if [[ -z "$NAME" && -n "$f_name" ]]; then NAME="$f_name"; INHERITED+=("节点名"); fi
|
||||||
|
if [[ ${#INHERITED[@]} -gt 0 ]]; then
|
||||||
|
info "沿用本机已有配置 ${AGENT_JSON_PATH}(${INHERITED[*]}):节点名=${NAME},主控=${MASTER}(token 已沿用,不显示)"
|
||||||
|
elif [[ -z "$MASTER" || -z "$TOKEN" ]]; then
|
||||||
|
warn "发现已有配置 ${AGENT_JSON_PATH},但未能解析出可用字段"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -z "$MASTER" ]] && error "缺少 --master 参数(本机亦无可沿用的 agent.json)"
|
||||||
[[ -z "$TOKEN" ]] && error "缺少 --token 参数 (从主控面板 API 获取)"
|
[[ -z "$TOKEN" ]] && error "缺少 --token 参数 (从主控面板 API 获取)"
|
||||||
|
[[ -z "$NAME" ]] && NAME="agent-node"
|
||||||
|
|
||||||
ARCH=$(uname -m)
|
ARCH=$(uname -m)
|
||||||
case "$ARCH" in
|
case "$ARCH" in
|
||||||
@@ -43,8 +72,10 @@ case "$ARCH" in
|
|||||||
*) error "不支持的架构: $ARCH (仅支持 amd64/arm64)";;
|
*) error "不支持的架构: $ARCH (仅支持 amd64/arm64)";;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
# 二进制下载地址(本仓 Gitea Releases,tag 沿用 v3.7.0-agent.1)
|
# 发行下载基址(本仓 Gitea Releases,发行 tag V1.0.0):agent 二进制、xray、geo
|
||||||
XUI_URL="${XUI_URL:-https://git.881218.xyz/rogue/3x-ui-agent/releases/download/v3.7.0-agent.1/x-ui-linux-${BIN_ARCH}}"
|
# 全部走自建镜像,不再依赖 GitHub CDN(部分节点极慢甚至僵死,见第 15 条)。
|
||||||
|
RELEASE_BASE="https://git.881218.xyz/rogue/3x-ui-agent/releases/download/V1.0.0"
|
||||||
|
XUI_URL="${XUI_URL:-${RELEASE_BASE}/x-ui-linux-${BIN_ARCH}}"
|
||||||
XRAY_VER="26.6.27"
|
XRAY_VER="26.6.27"
|
||||||
|
|
||||||
ROOT="${XUI_ROOT:-}"
|
ROOT="${XUI_ROOT:-}"
|
||||||
@@ -58,7 +89,8 @@ mkdir -p "${XUI_HOME}/bin" "${CONF_DIR}"
|
|||||||
info "下载 agent 二进制..."
|
info "下载 agent 二进制..."
|
||||||
# 先下到 .new 再改名覆盖:改名是原子替换,正在运行的旧 agent 进程不受影响,
|
# 先下到 .new 再改名覆盖:改名是原子替换,正在运行的旧 agent 进程不受影响,
|
||||||
# 也不会因目标文件正被执行而报 Text file busy;全程只写 xui-agent,不碰主控的 x-ui。
|
# 也不会因目标文件正被执行而报 Text file busy;全程只写 xui-agent,不碰主控的 x-ui。
|
||||||
curl -fL -o "${AGENT_BIN}.new" "$XUI_URL" || error "agent 下载失败"
|
curl -fL -o "${AGENT_BIN}.new" "$XUI_URL" || error "agent 下载失败: $XUI_URL"
|
||||||
|
[[ -s "${AGENT_BIN}.new" ]] || error "agent 下载得到空文件: $XUI_URL"
|
||||||
chmod +x "${AGENT_BIN}.new"
|
chmod +x "${AGENT_BIN}.new"
|
||||||
mv -f "${AGENT_BIN}.new" "${AGENT_BIN}"
|
mv -f "${AGENT_BIN}.new" "${AGENT_BIN}"
|
||||||
|
|
||||||
@@ -68,15 +100,41 @@ case "$BIN_ARCH" in
|
|||||||
amd64) XRAY_ZIP="Xray-linux-64.zip";;
|
amd64) XRAY_ZIP="Xray-linux-64.zip";;
|
||||||
arm64) XRAY_ZIP="Xray-linux-arm64-v8a.zip";;
|
arm64) XRAY_ZIP="Xray-linux-arm64-v8a.zip";;
|
||||||
esac
|
esac
|
||||||
curl -fL -o "$XRAY_ZIP" "https://github.com/XTLS/Xray-core/releases/download/v${XRAY_VER}/${XRAY_ZIP}" || error "xray 下载失败"
|
# 每一步都显式判失败并报错退出(第 17 条):历史教训——下载/解压失败曾被
|
||||||
unzip -o -q "$XRAY_ZIP" xray && mv xray "xray-linux-${BIN_ARCH}" && chmod +x "xray-linux-${BIN_ARCH}"
|
# && 链条吞掉,脚本带病走完报成功,结果 bin 里没有 xray、入站全断而面板显在线。
|
||||||
|
curl -fL -o "$XRAY_ZIP" "${RELEASE_BASE}/${XRAY_ZIP}" || error "xray 下载失败: ${RELEASE_BASE}/${XRAY_ZIP}"
|
||||||
|
[[ -s "$XRAY_ZIP" ]] || error "xray 下载得到空文件: ${RELEASE_BASE}/${XRAY_ZIP}"
|
||||||
|
unzip -o -q "$XRAY_ZIP" xray || error "xray 解压失败: $XRAY_ZIP"
|
||||||
|
mv xray "xray-linux-${BIN_ARCH}" || error "xray 落位失败(解压产物缺失)"
|
||||||
|
chmod +x "xray-linux-${BIN_ARCH}"
|
||||||
rm -f "$XRAY_ZIP"
|
rm -f "$XRAY_ZIP"
|
||||||
|
|
||||||
info "下载 geo 文件..."
|
info "下载 geo 文件..."
|
||||||
curl -fL -o geoip.dat "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geoip.dat" || error "geoip 下载失败"
|
curl -fL -o geoip.dat "${RELEASE_BASE}/geoip.dat" || error "geoip 下载失败: ${RELEASE_BASE}/geoip.dat"
|
||||||
curl -fL -o geosite.dat "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat" || error "geosite 下载失败"
|
[[ -s geoip.dat ]] || error "geoip 下载得到空文件: ${RELEASE_BASE}/geoip.dat"
|
||||||
|
curl -fL -o geosite.dat "${RELEASE_BASE}/geosite.dat" || error "geosite 下载失败: ${RELEASE_BASE}/geosite.dat"
|
||||||
|
[[ -s geosite.dat ]] || error "geosite 下载得到空文件: ${RELEASE_BASE}/geosite.dat"
|
||||||
cd - >/dev/null
|
cd - >/dev/null
|
||||||
|
|
||||||
|
# 安装收尾自检(第 17 条):文件在不等于能用——xray 本体须存在、可执行、
|
||||||
|
# version 能真实跑通;geo 须存在且非空;agent 本体须可执行。任一不过即
|
||||||
|
# 报错退出并指出缺什么,不许带病进入写配置/起服务阶段。
|
||||||
|
self_check() {
|
||||||
|
local xray_bin="${XUI_HOME}/bin/xray-linux-${BIN_ARCH}"
|
||||||
|
[[ -f "$xray_bin" ]] || error "自检失败:缺少 xray 本体 ${xray_bin}"
|
||||||
|
[[ -x "$xray_bin" ]] || error "自检失败:xray 本体不可执行 ${xray_bin}"
|
||||||
|
local ver_out
|
||||||
|
if ! ver_out=$("$xray_bin" version 2>/dev/null); then
|
||||||
|
error "自检失败:xray 本体无法运行(${xray_bin} version 退出非零)"
|
||||||
|
fi
|
||||||
|
[[ -n "$ver_out" ]] || error "自检失败:xray version 无输出(${xray_bin})"
|
||||||
|
info "自检通过:$(printf '%s' "$ver_out" | head -n 1)"
|
||||||
|
[[ -s "${XUI_HOME}/bin/geoip.dat" ]] || error "自检失败:geoip.dat 缺失或为空(${XUI_HOME}/bin/geoip.dat)"
|
||||||
|
[[ -s "${XUI_HOME}/bin/geosite.dat" ]] || error "自检失败:geosite.dat 缺失或为空(${XUI_HOME}/bin/geosite.dat)"
|
||||||
|
[[ -x "$AGENT_BIN" ]] || error "自检失败:agent 二进制不可执行 ${AGENT_BIN}"
|
||||||
|
}
|
||||||
|
self_check
|
||||||
|
|
||||||
info "写入 agent 配置..."
|
info "写入 agent 配置..."
|
||||||
cat > "${CONF_DIR}/agent.json" <<EOF
|
cat > "${CONF_DIR}/agent.json" <<EOF
|
||||||
{
|
{
|
||||||
@@ -204,7 +262,13 @@ name="x-ui-agent"
|
|||||||
description="3x-ui lightweight node agent"
|
description="3x-ui lightweight node agent"
|
||||||
command="/usr/local/x-ui/xui-agent"
|
command="/usr/local/x-ui/xui-agent"
|
||||||
command_args="agent"
|
command_args="agent"
|
||||||
command_background="yes"
|
# supervise-daemon 守护(第 23 条):进程崩溃后按 respawn 参数自动拉起,
|
||||||
|
# 对齐 systemd 支的 Restart=on-failure + RestartSec=5;旧版 command_background
|
||||||
|
# 只负责后台化、崩溃不重启。respawn_max=0 = 不限次(同 systemd 的持续重试)。
|
||||||
|
supervisor="supervise-daemon"
|
||||||
|
respawn_delay=5
|
||||||
|
respawn_max=0
|
||||||
|
respawn_period=0
|
||||||
pidfile="/run/x-ui-agent.pid"
|
pidfile="/run/x-ui-agent.pid"
|
||||||
output_log="/var/log/x-ui-agent.log"
|
output_log="/var/log/x-ui-agent.log"
|
||||||
error_log="/var/log/x-ui-agent.log"
|
error_log="/var/log/x-ui-agent.log"
|
||||||
|
|||||||
Reference in New Issue
Block a user