mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-11-07 09:47:23 +00:00
用户指出「vnc 无头浏览器兜底登陆你根本没有实现」。核对后确认:进程层代码存在,
但**只接在一个我编的假平台上**(loopbackish,已随夹具移出),四个真实平台全标
flow="manual" 并给一句"请你自己去某处搞定"。且代码写着「运行 deploy 脚本一键
安装」,而那个安装机制根本不存在(deploy.sh 里零浏览器栈内容)。
## 实现
- **依赖预检** browserDeps():探测 Xvfb/x11vnc/websockify/noVNC/chromium/
python3-websocket,如实报告缺什么、装哪个包、干什么用。
- **就绪探针** waitPort + X socket 等待:不再 sleep 2 拍脑袋(view_url 先于
服务可用会让 iframe 白屏)。
- **CDP 取凭据**:浏览器带 --remote-debugging-port,登录完成后经 CDP 读
localStorage/sessionStorage/cookie 或平台声明的 collect_expr。人只负责在 VNC
窗口里交互,机器负责把结果取出来 —— VNC 不该只是"看屏幕"。
实测:在真 HTTP 页面上 `localStorage.getItem('access_token')` → REAL-TOKEN-XYZ,
`document.cookie` → session=COOKIE-VAL,全部正确。
- **新端点**:channels/deps/status、browser/collect、browser/stop、browser/status。
- **安装入口** packaging/install-browser-stack.sh:识别 apt/dnf/yum/apk,
--check 只检查;装进发行包(/usr/share/llmsproxy/)。插件 install_hint 指向它。
默认不自动装:系统级包、数百 MB、chromium 安全面大,多数部署用不到 VNC。
## 过程中修掉三个真 bug(都是测试逼出来的)
1. **Xvfb 从未被启动**:steps 数组里有 Xvfb,但循环明确 `if st[1] ~= "Xvfb"`
跳过它(想先等 socket)→ 等一个永远不会出现的 socket。
2. **display 号按 seq 取模**:`90 + (seq % 10)`。Xvfb 锁文件在强杀后残留,
重启后 seq 从头 → 又选同一个号 → `Fatal: Server is already active`,
而报错只显示"Xvfb 未就绪"。改为**探测空闲**号(锁+socket+端口)。
3. **io.open 判 socket 存在**(两处):X socket 是 socket 文件,io.open 返回 nil
→ 探测误判"空闲"、等待循环永远等不到。改用 `[ -e ]`。
4. **孤儿进程**:spawn 往局部 pids 表追加,只在函数末尾回写 b.pids →
中途失败时 reapBrowser 读到空表,已起的 Xvfb 不被杀(实测留下 4 个孤儿)。
改为即时回写。
## 判据
- TestChannelsVncStackEndToEnd:注入 flow=vnc 平台 → 真起浏览器栈(view_url 含
vnc.html + CDP 端口)→ 回收。缺依赖则 SKIP 并说明。
- TestChannelsVncNoOrphanOnFailure:回收后 running=false、无孤儿。
- TestChannelsBrowserStackDeps:依赖清单三个字段齐全、缺件必须给安装提示。
- TestChannelsBrowserEndpointsRequireSession:无会话时三个端点如实报错/幂等。
- 全量 core 回归后确认:生产插件目录未被写入、无孤儿进程。
内核对照 v2.0.2:diff 为空(本次零内核改动)。
68 lines
2.1 KiB
YAML
68 lines
2.1 KiB
YAML
# nfpm config for the llmsproxy core gateway binary.
|
||
# The version placeholder below is substituted by packaging/core-dist.sh (nfpm v2
|
||
# here does not honour {{ .Env.VERSION }} template rendering), so do not edit it
|
||
# by hand.
|
||
name: llmsproxy
|
||
arch: amd64
|
||
platform: linux
|
||
version: __VERSION__
|
||
epoch: "1"
|
||
section: net
|
||
priority: optional
|
||
maintainer: JianFeeeee <dev@modelrouter.local>
|
||
description: |
|
||
Unified OpenAI-compatible multi-source LLM gateway.
|
||
Routes requests across multiple upstream LLM providers with Lua adapters,
|
||
model scheduling, quota windows, an elastic Lua worker pool, and a Web UI.
|
||
vendor: ModelRouter
|
||
homepage: https://gitcode.com/JianFeeeee/ModelRouter
|
||
license: MIT
|
||
contents:
|
||
# binary
|
||
- src: ./cmd/build/llmsproxy
|
||
dst: /usr/bin/llmsproxy
|
||
file_info:
|
||
mode: 0755
|
||
# systemd unit (memory tuning baked in)
|
||
- src: ./packaging/llmsproxy.service
|
||
dst: /etc/systemd/system/llmsproxy.service
|
||
file_info:
|
||
mode: 0644
|
||
# example config (seeded to /etc/llmsproxy on first install by postinst).
|
||
# Must be the tracked sanitised template: ./config.yaml is the operator's own
|
||
# gitignored config and shipping it would leak real credentials — it shipped a
|
||
# working admin key (sk-gw-local-0001) to every install for a while.
|
||
- src: ./packaging/config.example.yaml
|
||
dst: /usr/share/llmsproxy/config.example.yaml
|
||
file_info:
|
||
mode: 0644
|
||
# built-in Lua adapters (deployed to /etc/llmsproxy/adapters)
|
||
- src: ./internal/lua/adapters/*.lua
|
||
dst: /usr/share/llmsproxy/adapters/
|
||
file_info:
|
||
mode: 0644
|
||
# 服务端浏览器栈依赖安装脚本(VNC 兜底登录用;需 root,运维显式执行)
|
||
- src: ./packaging/install-browser-stack.sh
|
||
dst: /usr/share/llmsproxy/install-browser-stack.sh
|
||
file_info:
|
||
mode: 0755
|
||
# README pointer
|
||
- src: ./README.md
|
||
dst: /usr/share/doc/llmsproxy/README.md
|
||
file_info:
|
||
mode: 0644
|
||
|
||
scripts:
|
||
postinstall: ./packaging/postinst.sh
|
||
preremove: ./packaging/prerm.sh
|
||
|
||
rpm:
|
||
group: Applications/Internet
|
||
summary: Unified OpenAI-compatible multi-source LLM gateway
|
||
compression: gzip
|
||
|
||
deb:
|
||
compression: gzip
|
||
fields:
|
||
Recommends: ca-certificates
|