mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-10-19 05:57:39 +02:00
docs: explain update locking and interrupted rollback recovery
This commit is contained in:
1 parent
98de085912
commit
a63070dbd7
4 files changed
+24
-8
No files matched your search
@@ -99,7 +99,7 @@ mirror are all just this one setting; empty means the official repository. An in
|
||||
from a Release archive (no `.git`) can be connected from the same page (no configuration needed - the
|
||||
default official repository applies): the preview lists the files the target would replace and the
|
||||
operator content that is kept, replaced files are backed up under
|
||||
`.update-backup/<timestamp>/overwritten/`, and confirming turns the directory into a normal
|
||||
`.update-backup/<unique-backup>/overwritten/`, and confirming turns the directory into a normal
|
||||
installation with one-click updates.
|
||||
|
||||
`upgrade.sh` still works and is now a thin shell over that implementation, with two paths decided by
|
||||
@@ -136,7 +136,7 @@ quick upgrades without compatibility risk; in production still back up first. Py
|
||||
The one-click update leaves its own rollback point: `./cyberstrike-ai -update-rollback`, or the button
|
||||
on the page, goes back to the commit before that update and puts `cyberstrike-ai.prev` back. It runs
|
||||
only while HEAD is still the commit that update wrote, so work done afterwards is not discarded.
|
||||
Content that was put aside also survives under `.update-backup/<timestamp>/`.
|
||||
Content that was put aside also survives under `.update-backup/<unique-backup>/`.
|
||||
|
||||
Beyond that, roll back together:
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ An installation that started as an unpacked Release archive has no `.git`; it ca
|
||||
the same page (the default official repository works without any configuration): the preview fetches in a throwaway repository and first lists
|
||||
**the local files the target would replace** and **the operator content that will be kept**; on
|
||||
confirm the directory becomes a git work tree (`git init`, origin added, the target branch checked
|
||||
out), every replaced file is kept under `.update-backup/<timestamp>/overwritten/`, operator content
|
||||
out), every replaced file is kept under `.update-backup/<unique-backup>/overwritten/`, operator content
|
||||
is stashed and restored as usual, and the binary is rebuilt. From then on it is a normal
|
||||
installation with one-click update and rollback - but note there is no git history before the
|
||||
connection, so the connection itself has no earlier commit to roll back to; the first real update
|
||||
@@ -119,11 +119,15 @@ else -> 400). Other failures (`merge_failed`, `build_failed`, `swap_failed`) car
|
||||
compiler's own output; a failed build leaves the previous binary in place while the source has already
|
||||
moved and the state file is written, so it stays rollback-able.
|
||||
|
||||
Check, update, adoption, rollback and restart share an operating-system file lock in the install
|
||||
directory (`.update-lock`). Wait for the other operation when `update_busy` is reported. The system
|
||||
releases the lock when its process exits; do not delete the lock file to bypass it.
|
||||
|
||||
### How operator content survives
|
||||
|
||||
`roles/ skills/ tools/ agents/ knowledge_base/ data/ log/ venv/ config.yaml .env` belong to the
|
||||
**operator** (`update.Protected` is the judge). Before the merge, only those of those paths the
|
||||
update actually writes to are copied into `.update-backup/<timestamp>/` and removed from the tree -
|
||||
update actually writes to are copied into `.update-backup/<unique-backup>/` and removed from the tree -
|
||||
your extra directories that upstream never touched are not disturbed - and they are put back
|
||||
afterwards, which is what "update the code, keep my work" means. The result names every file in
|
||||
`keptContent` instead of quietly dropping it: where both you and upstream changed the same file, the
|
||||
@@ -141,6 +145,11 @@ not the one the record pairs with that commit (`binary_changed`), **HEAD has mov
|
||||
(`moved_since_update` - a rollback undoes the update, not the work done after it), or source is
|
||||
modified locally (`local_source_edits`).
|
||||
|
||||
Rollback writes `.update-rollback-pending.json` before changing source or binaries. Run rollback
|
||||
again after an interruption to finish recovery; the console reports `rollbackPending` and pauses new
|
||||
updates. Keep the recovery record, backup directory and `.prev` file. If recorded binary hashes do not
|
||||
match the files on disk, recovery refuses to overwrite them.
|
||||
|
||||
### The two restart cases
|
||||
|
||||
The process only stands down (graceful `Shutdown`, then exit 0) when the request explicitly says
|
||||
|
||||
@@ -196,7 +196,7 @@ SQLite 热备份时最好先停止服务,或至少复制 `*.db`、`*.db-wal`
|
||||
更新源是 `config.yaml` `update` 段里的**一个仓库地址**(`repo`),也可以直接在控制台「一键更新」页填写保存:
|
||||
想跟随官方仓库、自己的二开、别人的二开或镜像,改的都是这一处;不写就是官方仓库。**用 Release 包解压安装、
|
||||
目录里没有 git 的**,在同一页点「预览并接入」(不配置也能用默认的官方仓库):预览先列出会被目标版本替换的
|
||||
文件与会保留的运维者内容,被替换的都会备份在 `.update-backup/<时间戳>/overwritten/`,确认后目录成为可一键
|
||||
文件与会保留的运维者内容,被替换的都会备份在 `.update-backup/<唯一备份目录>/overwritten/`,确认后目录成为可一键
|
||||
更新的正常安装。
|
||||
|
||||
`upgrade.sh` 仍然可用,它现在只是这条实现的薄壳,并按安装形态分两条路:
|
||||
@@ -227,7 +227,7 @@ Python 依赖方面:`venv/` 由 `run.sh` 自动创建和管理,保留它就
|
||||
|
||||
一键更新自带回滚点:`./cyberstrike-ai -update-rollback` 或页面上的回滚按钮,会撤到那次更新前的提交并把
|
||||
`cyberstrike-ai.prev` 换回原位;它只在"HEAD 仍是那次更新写下的提交"时才执行,之后的工作不会被顺手抹掉。
|
||||
被暂存过的内容也留在 `.update-backup/<时间戳>/` 里。
|
||||
被暂存过的内容也留在 `.update-backup/<唯一备份目录>/` 里。
|
||||
|
||||
除此之外,回滚时同时恢复:
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ update:
|
||||
一开始用 Release 包解压安装、目录里没有 `.git` 的,可在同一页执行「预览并接入」(不配置也能用默认的官方仓库):
|
||||
预览在临时仓库里 fetch,先列出**会被目标版本替换的本机文件**与**会保留的运维者内容**;确认后目录接入
|
||||
成为 git 工作树(`git init` + 添加 origin + 落地目标分支),被替换的文件全部留底在
|
||||
`.update-backup/<时间戳>/overwritten/`,运维者内容照旧先暂存再放回,随后重编译二进制。
|
||||
`.update-backup/<唯一备份目录>/overwritten/`,运维者内容照旧先暂存再放回,随后重编译二进制。
|
||||
接入后它就是正常安装,一键更新与回滚都可用了;注意接入前没有 git 历史,因此「接入」本身没有可回滚的
|
||||
上一提交,第一个回滚点由接入后的第一次更新写下。
|
||||
|
||||
@@ -114,11 +114,14 @@ update:
|
||||
`no_binary` → 409,其余 → 400)。其他失败(`merge_failed`、`build_failed`、`swap_failed`)带着 git/go 的原始输出;
|
||||
编译失败时二进制保持原版本,而源码已移动、状态文件已写好,因此仍然可以回滚。
|
||||
|
||||
检查、更新、接入、回滚和重启共用安装目录的系统文件锁(`.update-lock`)。遇到
|
||||
`update_busy` 时等待另一操作完成;进程退出后锁由系统释放,不要删除锁文件来绕过互斥。
|
||||
|
||||
### 运维者的内容如何被保留
|
||||
|
||||
`roles/ skills/ tools/ agents/ knowledge_base/ data/ log/ venv/ config.yaml .env` 是**运维者的内容**,
|
||||
判定在 `update.Protected`。合并前,只有本次更新**确实会写到**的那些路径被复制到
|
||||
`.update-backup/<时间戳>/` 并从工作树移开(你多出来的、上游没动的目录连碰都不碰),合并后再原样放回,
|
||||
`.update-backup/<唯一备份目录>/` 并从工作树移开(你多出来的、上游没动的目录连碰都不碰),合并后再原样放回,
|
||||
于是"更新代码、留下我的工作"成立。结果里的 `keptContent` 逐个点名被保留的文件——绝不静默丢弃:
|
||||
当上游与你在同一个文件上都有改动,落地的是你的版本,而这件事写在结果里。
|
||||
**回滚遵循同一条规则**:`reset --hard` 会把受保护文件上现存的本地改动先暂存、重置后放回(更新前改的
|
||||
@@ -134,6 +137,10 @@ update:
|
||||
**HEAD 自那次更新之后又动过**(`moved_since_update`:回滚只该撤到更新前,不该顺手抹掉之后的工作)、
|
||||
以及存在本地源码改动(`local_source_edits`)。
|
||||
|
||||
回滚开始前会写入 `.update-rollback-pending.json`。中断后再次执行回滚会继续恢复;页面的
|
||||
`rollbackPending` 提示会暂停新更新。保留恢复记录、备份目录和 `.prev`,不要手动删除它们。
|
||||
如果记录中的二进制哈希无法与现场对应,会拒绝覆盖并保留现场。
|
||||
|
||||
### 重启的两种情形
|
||||
|
||||
进程只有在请求显式带 `restart: true`、且启动时装配了重启钩子时才会优雅退出(`Shutdown` 后退出码 0)。
|
||||
|
||||
Reference in new issue
Block a user