mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-11-07 09:47:23 +00:00
产品代码统一为纯文本风格(照参考实现),去掉 emoji:billing/quota/usage 插件、 channels 的提示文案、WebUI 文案,以及 go 测试、docs、packaging 脚本中的 注意/OK/FAIL 等符号化写法。第三方目录(vendor、node_modules、.probe)不动。 另:packaging/upload-release.sh 的仓库名改为真实全名 JianFeeeee/ModelRouter → HeNanMU-EEA/ModelRouter(前者是重定向,POST/PUT 不跟随 会 404)。
124 lines
5.0 KiB
Bash
Executable File
124 lines
5.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
# ============================================================
|
||
# 安装「服务端浏览器栈」依赖(VNC 兜底登录用)
|
||
#
|
||
# 为什么是独立脚本而不是 postinst 自动装:
|
||
# 这些是**系统级包**(Xvfb / x11vnc / websockify / noVNC / chromium),装上
|
||
# 会常驻数百 MB,且 chromium 是安全面较大的组件。很多部署根本用不到 VNC 兜底
|
||
# (大部分平台的登录是 device-poll / callback / paste,纯 HTTP 即可)。默认替
|
||
# 运维的机器装一堆浏览器组件不是发行包该做的事 —— 需要的人显式装。
|
||
#
|
||
# 什么时候需要它:
|
||
# 平台声明 flow="vnc"(登录必须在服务端浏览器里完成:回环回调落不到用户机器、
|
||
# 授权页要求浏览器内交互)。插件会在登录时如实报告缺哪个依赖。
|
||
#
|
||
# 用法:
|
||
# sudo bash packaging/install-browser-stack.sh # 自动识别包管理器
|
||
# sudo bash packaging/install-browser-stack.sh --check # 只检查,不安装
|
||
# ============================================================
|
||
set -euo pipefail
|
||
|
||
CHECK_ONLY=0
|
||
for a in "$@"; do
|
||
case "$a" in
|
||
--check|-c) CHECK_ONLY=1 ;;
|
||
-h|--help) sed -n '2,20p' "$0"; exit 0 ;;
|
||
*) echo "未知参数: $a" >&2; exit 2 ;;
|
||
esac
|
||
done
|
||
|
||
# 需要的外部可执行文件(插件 browserDeps 同一份清单)
|
||
BINS=(Xvfb x11vnc websockify python3)
|
||
# chromium 的二进制名随发行版变化
|
||
CHROMIUM_CANDIDATES=(chromium chromium-browser google-chrome google-chrome-stable)
|
||
NOVNC_DIRS=(/usr/share/novnc /usr/share/webapps/novnc /opt/novnc)
|
||
|
||
missing=()
|
||
for b in "${BINS[@]}"; do
|
||
command -v "$b" >/dev/null 2>&1 || missing+=("$b")
|
||
done
|
||
chromium=""
|
||
for c in "${CHROMIUM_CANDIDATES[@]}"; do
|
||
if command -v "$c" >/dev/null 2>&1; then chromium="$c"; break; fi
|
||
done
|
||
[ -z "$chromium" ] && missing+=("chromium")
|
||
novnc=""
|
||
for d in "${NOVNC_DIRS[@]}"; do
|
||
[ -f "$d/vnc.html" ] && { novnc="$d"; break; }
|
||
done
|
||
[ -z "$novnc" ] && missing+=("novnc")
|
||
# CDP 取凭据需要 python websocket 客户端
|
||
if command -v python3 >/dev/null 2>&1; then
|
||
python3 -c 'import websocket' >/dev/null 2>&1 || missing+=("python3-websocket")
|
||
fi
|
||
|
||
if [ ${#missing[@]} -eq 0 ]; then
|
||
echo "OK 浏览器栈依赖齐全"
|
||
echo " chromium: ${chromium}"
|
||
echo " noVNC: ${novnc}"
|
||
exit 0
|
||
fi
|
||
|
||
echo "缺少依赖: ${missing[*]}"
|
||
if [ "$CHECK_ONLY" = 1 ]; then
|
||
exit 1
|
||
fi
|
||
|
||
# ---------- 识别包管理器 ----------
|
||
if command -v apt-get >/dev/null 2>&1; then
|
||
# Debian/Ubuntu:chromium 在部分版本是 snap 包,apt 装不上;
|
||
# 先试 apt,失败时明确提示替代方案,不静默放弃。
|
||
pkgs=(xvfb x11vnc websockify novnc python3-websocket)
|
||
echo "→ apt-get install ${pkgs[*]} chromium"
|
||
apt-get update -qq || true
|
||
apt-get install -y "${pkgs[@]}" || {
|
||
echo "WARN: 部分包装失败,仍尝试装 chromium" >&2
|
||
}
|
||
apt-get install -y chromium || apt-get install -y chromium-browser || {
|
||
echo "WARN: apt 装不上 chromium(Ubuntu 新版将其作为 snap 分发)。" >&2
|
||
echo " 可选:snap install chromium 或 apt-get install -y chromium-browser" >&2
|
||
}
|
||
elif command -v dnf >/dev/null 2>&1; then
|
||
echo "→ dnf install xorg-x11-server-Xvfb x11vnc python3-websockify novnc chromium python3-websocket-client"
|
||
dnf install -y xorg-x11-server-Xvfb x11vnc python3-websockify novnc chromium python3-websocket-client
|
||
elif command -v yum >/dev/null 2>&1; then
|
||
echo "→ yum install xorg-x11-server-Xvfb x11vnc python3-websockify novnc chromium python3-websocket-client"
|
||
yum install -y xorg-x11-server-Xvfb x11vnc python3-websockify novnc chromium python3-websocket-client
|
||
elif command -v apk >/dev/null 2>&1; then
|
||
echo "→ apk add xvfb x11vnc websockify novnc chromium py3-websocket-client"
|
||
apk add --no-cache xvfb x11vnc websockify novnc chromium py3-websocket-client
|
||
else
|
||
echo "未识别的包管理器。请手动安装:" >&2
|
||
echo " Xvfb, x11vnc, websockify, noVNC, chromium, python3 websocket-client" >&2
|
||
exit 1
|
||
fi
|
||
|
||
# ---------- 复核 ----------
|
||
echo
|
||
echo "复核安装结果:"
|
||
ok=1
|
||
for b in "${BINS[@]}"; do
|
||
if command -v "$b" >/dev/null 2>&1; then echo " OK $b"
|
||
else echo " FAIL $b"; ok=0; fi
|
||
done
|
||
chromium=""
|
||
for c in "${CHROMIUM_CANDIDATES[@]}"; do
|
||
if command -v "$c" >/dev/null 2>&1; then chromium="$c"; break; fi
|
||
done
|
||
[ -n "$chromium" ] && echo " OK $chromium" || { echo " FAIL chromium"; ok=0; }
|
||
novnc=""
|
||
for d in "${NOVNC_DIRS[@]}"; do
|
||
[ -f "$d/vnc.html" ] && { novnc="$d"; break; }
|
||
done
|
||
[ -n "$novnc" ] && echo " OK noVNC ($novnc)" || { echo " FAIL noVNC"; ok=0; }
|
||
python3 -c 'import websocket' >/dev/null 2>&1 && echo " OK python3 websocket-client" || { echo " FAIL python3 websocket-client"; ok=0; }
|
||
|
||
if [ "$ok" = 1 ]; then
|
||
echo
|
||
echo "OK 浏览器栈就绪。重启 llmsproxy 后,flow=vnc 的平台即可用 VNC 兜底登录。"
|
||
else
|
||
echo
|
||
echo "WARN: 仍有缺失项,VNC 兜底在该机器上不可用。插件的 deps/status 端点会一样报告。" >&2
|
||
exit 1
|
||
fi
|