mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-10-21 23:01:37 +02:00
feat: make a restart part of the one-click update, and recover the page by itself
The console now knows what it is running: the status endpoint compares the binary identity captured at startup (size + nanosecond mtime) with the file on disk, so an update, a rollback or a CLI run that swapped the binary without a restart is reported as needsRestart (with the build time) - a state that used to live only in one job's result and vanished with the process. That state grows a persistent banner and POST /api/system/update/restart (409 when there is nothing to activate or a job owns the tree, 400 without a hook), so a forgotten tick is one click instead of a shell login. The restart tick defaults to on exactly where it is safe: launchd/systemd leave markers in the environment (XPC_SERVICE_NAME, INVOCATION_ID/JOURNAL_STREAM) and the box follows them; an operator's own choice is never second-guessed afterwards. While the process is down the console becomes a recovery view that probes the status endpoint every 2 seconds: 200 means the old process still answers, a dead socket means it is on its way out, and a 401 - only a new process can fail to know the session - reloads the page back to #system-update. A job poll that dies during a requested restart is the restart in flight, not a failure to toast. Also fixed: updateT now asks i18next not to escape interpolated values, because the console escapes at render time - the apply confirm dialog has been showing branch names with / ever since they contained a slash, and the new banner showed dates the same way. Tests: 7 new console contract tests (36 total: banner, tick default, restart confirm/refusal, watchdog 200-vs-401, timeout copy, the in-flight poll death) plus handler tests for the stamp and the endpoint, all mutation-probed; docs describe the pending-restart state and the self-recovery.
This commit is contained in:
1 parent
cbd8073beb
commit
e80668b2e9
14 files changed
+837
-30
No files matched your search
@@ -86,6 +86,12 @@ kept. For a fork this is the only path that does not overwrite you with somebody
|
||||
source is modified locally or the branch has diverged it refuses and says why instead of forcing.
|
||||
See [the developer guide](developer-guide.md) for the full semantics.
|
||||
|
||||
When a supervisor is detected (systemd/launchd startup markers in the environment), the "exit after
|
||||
updating" tick is pre-ticked: the process stands down after a successful update, the supervisor brings
|
||||
the new binary back, and the page reloads itself once the service answers (sessions live in memory, so
|
||||
one fresh login follows). Forgot the tick, or swapped the binary from the CLI? The console carries a
|
||||
persistent banner with **Restart now** - no shell login needed.
|
||||
|
||||
The source is chosen either in the `update` section of `config.yaml` (`remote` or `remote_url`, plus
|
||||
an optional `branch`) or right on the console page: the official repository, your own fork, or
|
||||
somebody else's second-development repository are all just this one setting; unset, it follows the
|
||||
|
||||
@@ -48,7 +48,7 @@ disagree about why an update was refused.
|
||||
|
||||
| entry | how it is used |
|
||||
|---|---|
|
||||
| console | System settings -> One-click update (`#system-update`, the old deep link still works). Opening this section reads the local tree only and does not go online; **Check** is what performs the fetch; **Update** starts a job the page polls; the page also carries the "exit after updating" option and a rollback button |
|
||||
| console | System settings -> One-click update (`#system-update`, the old deep link still works). Opening this section reads the local tree only and does not go online; **Check** is what performs the fetch; **Update** starts a job the page polls; the "exit after updating" tick is pre-ticked when a supervisor is detected (launchd/systemd startup markers), and while the process is down the page watches for its return and reloads itself (sessions live in memory, so a fresh login follows); a rollback button sits below |
|
||||
| REST | `GET /api/system/update` (state on disk, no network), `POST /api/system/update/check` (fetch, then report the gap), `POST /api/system/update/apply` (`202` with `job_id`, polled through `GET /api/system/update/job`), `POST /api/system/update/rollback` |
|
||||
| CLI | `./cyberstrike-ai -check-update`, `./cyberstrike-ai -update`, `./cyberstrike-ai -update-rollback`. The install root is the directory holding `--config`, or the current directory when `--config` was not given |
|
||||
|
||||
@@ -134,8 +134,23 @@ modified locally (`local_source_edits`).
|
||||
The process only stands down (graceful `Shutdown`, then exit 0) when the request explicitly says
|
||||
`restart: true` **and** a restart hook was wired at startup. Whether it actually comes back is up to a
|
||||
supervisor (systemd, `run.sh`), and the page says exactly that rather than promising a boot that may
|
||||
not happen. Otherwise the API only reports `needsRestart` and the old binary keeps running. Asking for
|
||||
a restart with no hook wired is a `400`, instead of stopping the service and claiming it restarted.
|
||||
not happen. Asking for a restart with no hook wired is a `400`, instead of stopping the service and
|
||||
claiming it restarted.
|
||||
|
||||
**A pending binary is a durable state, and it can be activated later.** The status endpoint compares
|
||||
the binary identity captured at startup (size + nanosecond mtime) with what is on disk now: after an
|
||||
update, a rollback or a CLI run swapped the file without a restart, `needsRestart` is true,
|
||||
`binaryBuiltAt` says when it was built, and the console grows a persistent banner with **Restart now**
|
||||
(`POST /api/system/update/restart`; `409 nothing_pending` when there is nothing to activate, `409`
|
||||
while a job runs, `400` without a hook). The `supervised` field comes from environment markers
|
||||
(launchd's `XPC_SERVICE_NAME`, systemd's `INVOCATION_ID`/`JOURNAL_STREAM`) and only decides the tick's
|
||||
default.
|
||||
|
||||
**And the page recovers by itself.** While the process is down the console becomes a recovery view
|
||||
that probes the status endpoint every 2 seconds: a 200 means the old process is still answering (keep
|
||||
waiting), a dead connection means it is on its way out, and a 401 from a process that no longer knows
|
||||
the session is the proof the restart happened - the page then `location.replace`s itself back to
|
||||
`#system-update`. Leaving the console stops the watching instead of yanking the user back.
|
||||
|
||||
## Adding a Business Module
|
||||
|
||||
|
||||
@@ -186,6 +186,10 @@ knowledge_base/ data/ config.yaml` 等运维者内容先暂存再放回,结果
|
||||
跑 fork 时这是唯一不会"用别人的代码覆盖自己"的路径;本地源码有改动或分支已分叉时它会拒绝并说明原因,
|
||||
而不是硬来。细节见 [开发者指南](developer-guide.md) 的「一键更新」一节。
|
||||
|
||||
检测到 systemd/launchd(环境里有对应启动标记)时,"更新完成后退出进程"默认勾选:更新成功后进程退出、
|
||||
由守护拉起新二进制,页面会在服务回来时自动刷新(会话在内存里,需要重新登录一次)。忘勾、或在命令行
|
||||
换过二进制时,控制台顶部有常驻横幅和「立即重启服务」补上这一步——不必再登录服务器手动重启。
|
||||
|
||||
更新源可以在 `config.yaml` 的 `update` 段指定(`remote` 或 `remote_url`,可带 `branch`),也可以直接在
|
||||
控制台「一键更新」页填写保存:想跟随官方仓库、自己的二开或别人的二开,改的都是这一处;不配置时跟随
|
||||
本目录自己跟踪的远端。**用 Release 包解压安装、目录里没有 git 的**,配好地址后在同一页点「预览并接入」:
|
||||
|
||||
@@ -54,7 +54,7 @@ go run ./cmd/server --config config.yaml
|
||||
|
||||
| 入口 | 怎么用 |
|
||||
|---|---|
|
||||
| 控制台 | 「系统设置 → 一键更新」(`#system-update` 老深链仍可用)。打开这一区只读本机状态、不联网;点「检查更新」才去 fetch;「一键更新」发起任务并轮询进度;页面另有"更新完成后退出进程"勾选与回滚按钮 |
|
||||
| 控制台 | 「系统设置 → 一键更新」(`#system-update` 老深链仍可用)。打开这一区只读本机状态、不联网;点「检查更新」才去 fetch;「一键更新」发起任务并轮询进度;"更新完成后退出进程"在检测到守护进程(launchd/systemd 的启动标记)时默认勾选,重启期间页面守着重连、新进程一应答就自动刷新(会话在内存里,刷新后需重新登录);另有回滚按钮 |
|
||||
| REST | `GET /api/system/update`(磁盘现状,不联网)、`POST /api/system/update/check`(fetch 后报告差集)、`POST /api/system/update/apply`(`202` 返回 `job_id`,用 `GET /api/system/update/job` 轮询)、`POST /api/system/update/rollback` |
|
||||
| CLI | `./cyberstrike-ai -check-update`、`./cyberstrike-ai -update`、`./cyberstrike-ai -update-rollback`。安装目录 = `--config` 所在目录,未给 `--config` 时是当前目录 |
|
||||
|
||||
@@ -125,7 +125,17 @@ update:
|
||||
|
||||
进程只有在请求显式带 `restart: true`、且启动时装配了重启钩子时才会优雅退出(`Shutdown` 后退出码 0)。
|
||||
能不能被拉起来取决于外部守护(systemd、`run.sh`),页面如实这么写,而不是承诺一次可能不发生的启动;
|
||||
没装配钩子时要求重启是 `400`,而不是先停掉服务再自称重启了。未重启时接口只报告 `needsRestart`,旧二进制继续跑。
|
||||
没装配钩子时要求重启是 `400`,而不是先停掉服务再自称重启了。
|
||||
|
||||
**待生效状态是持久的、可补重启。** 状态接口对比"启动时记下的二进制身份(大小 + 纳秒 mtime)"与磁盘
|
||||
现值:更新、回滚或 CLI 换过二进制而没重启时,`needsRestart` 为真、`binaryBuiltAt` 给出构建时间,
|
||||
控制台顶部出现常驻横幅与「立即重启服务」(`POST /api/system/update/restart`;没有待生效版本时
|
||||
`409 nothing_pending`、有任务在跑 `409`、没钩子 `400`)。`supervised` 字段来自环境标记(launchd 的
|
||||
`XPC_SERVICE_NAME`、systemd 的 `INVOCATION_ID`/`JOURNAL_STREAM`),只用来决定勾选框的默认值。
|
||||
|
||||
**重启后页面自己回来。** 重启期间控制台换成自恢复视图,每 2 秒探一次状态接口:旧进程还在应答(200)
|
||||
就继续等;连不上说明正在退出;新进程接客但对旧会话只回 401——这就是"重启已完成"的判据,页面随即
|
||||
`location.replace` 回 `#system-update` 整页刷新。离开控制台则静默停表,不把已经走开的用户拽回来。
|
||||
|
||||
## 数据库
|
||||
|
||||
|
||||
Reference in new issue
Block a user