mirror of
https://gitcode.com/JianFeeeee/ModelRouter.git
synced 2026-11-07 09:47:23 +00:00
fix(lua): 持久化的出站主机授权在重启后不生效(LoadDir 缺折叠)
生产实测暴露的内核缺陷:**重启后所有已批准出站主机全被拒**。
根因链:
1. `LoadKernelPermissions` 把 `.kernel-perms.json` 里的 `jp.Hosts` 装进
`ps.extraHosts`,但它明确注释「折叠由调用方负责」——**启动路径上没人负责**。
2. `SetOutboundHosts` 早已跑过(core.New 里,在 LoadDir **之前**),
于是 allowlist 只含 source 主机,插件声明的整套 host 全被拒。
3. 症状是经典的「重启丢掉运维的决定」:运维一打开插件页重新保存就恢复。
**它还静默打坏了定时任务**:`refresh_models` 在启动后 5s 补跑
(first_due_now),正好落在这个窗口里,于是每个平台的刷新都报
「host "zcode.z.ai" is not an allowed outbound destination」——看起来像
"白名单缺 host",实际是授权根本没被折叠。我按这个假象查了一圈(去核对
.kernel-perms.json 里 zcode.z.ai 明明在),才定位到折叠这一步缺失。
修法:LoadDir 末尾补 `rebuildOutboundAllowlistLocked()`。
判据:`TestPersistedHostGrantsSurviveRestart` —— 造一份持久化授权、模拟
启动顺序(SetOutboundHosts → LoadDir),断言已批准的 host 可用、
source 主机未丢、未批准的仍被拒。
**变异验证**:撤掉修复 → 判据变红(两条"被拒");加回 → 变绿。
回归:internal/{lua,core,provider,gateway} 全绿。
This commit is contained in:
@ -634,6 +634,24 @@ func (ps *Plugins) LoadDir() error {
|
||||
}
|
||||
}
|
||||
ps.rebuild()
|
||||
// Persisted host grants must be folded into the allowlist HERE, not only in
|
||||
// the WebUI grant path.
|
||||
//
|
||||
// Why (live defect): LoadKernelPermissions above loads `jp.Hosts` into
|
||||
// ps.extraHosts but deliberately does NOT fold it — its comment says "the
|
||||
// caller owns that fold". On the boot path nobody did. SetOutboundHosts had
|
||||
// already run (core.New, before LoadDir), so the allowlist held the source
|
||||
// hosts and nothing else, and every approved extra host (the plugin's whole
|
||||
// declared set: zcode.z.ai, copilot.tencent.com, …) was refused after a
|
||||
// restart with "host ... is not an allowed outbound destination".
|
||||
//
|
||||
// Symptom is the classic "restart loses the operator's decision": it clears
|
||||
// the moment an operator opens the plugin page and re-saves the grants. It
|
||||
// also broke the scheduled work — refresh_models fires 5s after boot, inside
|
||||
// that window, and reported the grant as missing for every platform.
|
||||
ps.mu.Lock()
|
||||
ps.rebuildOutboundAllowlistLocked()
|
||||
ps.mu.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user