Skip to content

feat(console): 设置页「待重启」提示——暴露“配置已保存但未重启” - #80

Open
Windsander wants to merge 1 commit into
mainfrom
feat/console-pending-restart
Open

Windsander wants to merge 1 commit into
mainfrom
feat/console-pending-restart

Conversation

@Windsander

Copy link
Copy Markdown
Owner

问题

控制台设置页保存配置后,只弹一次 toast,没有任何持久提示。用户看到字段「已开启」、而「运行状态」仍是「未启用」,容易误以为「配置无法生效」。

真实案例config.json 在 22:12 保存 network.enabled=true / joinService.enabled=true,而 serve 进程 21:30 就已启动;/admin/api/settings 仍返回 network.enabled=false / join.enabled=false。字段显示已开启、运行状态显示未启用,二者长期不一致,且没有任何解释。

根因

  • 守护(mebular serve)只在启动时读取一次 config.jsoncreateMebular),运行期没有热加载
  • 设置页编辑字段读的是磁盘 config.jsonstate.rawConfig),而「实际运行状态」读的是启动快照
  • 保存后磁盘已变、启动快照未变,因此二者会持续不一致,直到重启 serve。

修复

后端 packages/mcp/src/admin.mjsbuildSettings):

  • 新增 pendingRestart:按 curated 白名单(与 serve.mjsCONFIG_PATCH_SPECS 对齐)对比当前磁盘 config.json本次启动快照,列出不一致的重启类配置项,元素形如 { path, file, running }(JSON 安全值,未设置为 null)。
  • 归一化「未设置」为默认值(空数组 = 未设置 = null,如 sync.namespaces / listen),避免默认值被误报。
  • 环境变量优先(MEBULAR_PUSH_ON_WRITE / MEBULAR_NETWORK_ENABLED / MEBULAR_SEMANTIC_ENABLED)时,磁盘值重启也不会被采纳——这类路径不计入 pendingRestart,改列到 pendingRestartEnvOverrides,不报错。
  • mcp.* 以启动快照为基准,--port 0 的实际端口由系统分配,不代表磁盘值未生效,避免误报。
  • 新增 restart 元信息:serviceHeartbeat(读取 <home>/service.heartbeat)与 serviceManaged(launchd/systemd/计划任务注入的 MEBULAR_SERVICE_KIND/MEBULAR_SERVICE_SHA),供前端选择重启命令文案。

前端 packages/console/console.js + index.html + console.css

  • 设置弹窗内持久「待重启」提示:列出变更项(中文标签 + 已配置 / 实际),给出可复制重启命令(托管服务 → mebular service restart;普通启动 → nohup mebular serve … &),并附根因说明:「守护只在启动时读取配置;保存后当前实例仍按上次启动的配置工作,重启后生效。」;环境变量优先时以环境变量为准。
  • 设置入口徽标 + 「关于本机 · 运行状态」区标注「待重启 N 项」。
  • 保存 toast 保留。

回归

  • packages/console/scripts/verify-console.mjs(E1):新增 pendingRestart 断言——保存后命中刚改的 network.enabled / joinService.enabled / sync.antiEntropy.intervalMs,元素含 file/running;独立 home 重启用例断言「全新为空 → 保存后命中 → 重启后清空」。
  • packages/console/scripts/verify-console-ui.mjs:页面内 fetch + CSRF(document.cookiemebular_csrf)POST /admin/api/configsync.antiEntropy.intervalMs,刷新后断言出现「待重启」且含该项与入口徽标;改回/删除后确认 pendingRestart 清空。
  • 顺带把 E1 的只读降级用例改用临时端口(seedHome 默认 7331),避免与本机已在运行的真实实例抢 7331 导致误失败。

证据(全绿)

npm test                        → Test Suites: 119 passed, Tests: 845 passed
npm run lint                    → exit 0
npm run check:cleanliness       → 0 错误 / 0 警告
npm run check:docs              → 7/7 PASS
node packages/console/scripts/verify-console.mjs     → ✓ 控制台 E1 验证通过
node packages/console/scripts/verify-console-ui.mjs  → ✓ 控制台 UI 冒烟通过(17 项)

影响面

  • 只读 API 新增字段(pendingRestart / pendingRestartEnvOverrides / restart),向后兼容,不改动既有字段语义与写端点行为。
  • 不触碰 packages/fleet、CI workflow、根 package.json;未新增依赖/脚本。
  • pendingRestart 仅覆盖 serve.mjs curated 白名单(可经控制台保存的重启类配置);身份/存储/加密等手工编辑项不在内。

守护(mebular serve)只在启动时读取一次 config.json,运行期没有热加载;
设置页保存后磁盘已变,但当前实例仍按上次启动的快照工作,用户误以为
「配置无法生效」。真实案例:config 22:12 保存 network/join=true,进程
21:30 启动,settings 仍为 false/false。

- admin.mjs:buildSettings 新增 pendingRestart,按 curated 白名单(对齐
  serve.mjs CONFIG_PATCH_SPECS)对比当前磁盘 config.json 与启动快照,元素
  形如 { path, file, running };空数组=未设置归一为 null;受环境变量优先
  的路径跳过并列入 pendingRestartEnvOverrides(不报错)。新增 restart
  元信息(serviceHeartbeat / serviceManaged)供 UI 选择重启命令。
- console.js:设置弹窗内持久「待重启」提示(中文标签 + 已配置/实际 +
  可复制重启命令 + 根因说明 + 环境变量优先说明);设置入口徽标与「运行
  状态」区标注「待重启 N 项」;保留保存 toast。
- verify-console.mjs(E1):新增 pendingRestart 断言(含刚改键、元素
  形状、重启后清空);顺带让只读降级用例改用临时端口,避免与本机真实
  实例抢 7331。
- verify-console-ui.mjs:页面内 fetch+CSRF 改 sync.antiEntropy.intervalMs,
  断言出现「待重启」及该项,改回后确认清空。

证据:npm test / npm run lint / check:cleanliness / check:docs /
verify-console / verify-console-ui 全绿。

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant