feat-chv-to10:往 10 分方向提升(类型/lint 清零、worker 适配抽取、审计落盘、lockfile 生成脚本、前端四态与统一文案、就绪清单 §13)
This commit is contained in:
1 parent
df8c64bd64
commit
2f3ff8b3ec
22 files changed
+1400
-282
No files matched your search
@@ -232,3 +232,94 @@
|
||||
live 状态——server 进程没有 VM 登记表,live 状态编不
|
||||
出来;前端无该字段时不显示 VM 状态,不猜测。VM 控制
|
||||
按钮仍不做(后端无控制端点且安全审计 No-Go)。
|
||||
|
||||
## ADR-13 CHV worker 适配模块(to10 轨)
|
||||
|
||||
- 决策:新建 `cloud/chv/worker_adapter.py`,worker.py 只留
|
||||
薄包装。抽入:断点调用(原顶层函数本体)、审计回调
|
||||
(原 `__init__` 闭包)、孤儿清理(原 `_reconcile_warm_pool`
|
||||
本体)、两条看门狗循环(原 `_chv_*_watchdog` 本体,self
|
||||
依赖全部改成回调参数)、看门狗 VM 名派生(原 `_run_attempt`
|
||||
try/except 块)。worker 方法名、签名、调用点、错误文案
|
||||
全部不变,旧测试继续走 worker 方法;适配器本身另有直接
|
||||
行为测试。适配器只依赖标准库 + chv 叶子模块 +
|
||||
`cloud.logging_config`,不 import `cloud.worker`,无循环;
|
||||
公共 API 全注解(#257 的类型测试扫 `cloud/chv/*.py`,
|
||||
新模块不注解会直接炸该测试——本轨已补齐)。
|
||||
- 明确不抽(硬抽无收益,只会撕通用流程):cancel() 里的
|
||||
`cancel_vm` 分支(与 Docker `kill_container` 分支相邻的
|
||||
通用取消流)、`cleanup_stale_containers` 的 CHV 分支
|
||||
(与 Docker 清理相邻的通用清理流)、网关守卫(Local /
|
||||
Docker / CHV 三分支共用的派发流)、`_executor_name` 的
|
||||
CHV 分支(通用执行器名映射)、`_run_attempt` 的看门狗
|
||||
线程启动(线程管理是 worker 通用逻辑,只抽了 VM 名派生)、
|
||||
VM 死亡写回(通用终局流)。以上六处留在 worker.py,
|
||||
不是遗漏,是评估后有理由的结论。
|
||||
- 附带清理:`inspect` 在 worker.py 的唯一用处随断点函数
|
||||
移走,import 一并删除(留着会触发 F401);worker.py
|
||||
基线已有的 I001(两处 import 排序)与 F821(playwright
|
||||
播种块的 `task`)与本轨无关,不顺手重排整个文件。
|
||||
|
||||
## ADR-14 审计失败落盘兜底(to10 轨)
|
||||
|
||||
- 决策:选“本地审计落盘文件”作为兜底,不选“只记日志 +
|
||||
计数”(已做,仍不够:日志会轮转、计数只剩数字,事后
|
||||
找不回哪次事件丢了)。实现:`executor._emit` 回调失败
|
||||
时,除记宿主 error 日志 + `audit_failure_count` +1 外,
|
||||
再把事件 append 到 `state_dir/chv-audit-spill.jsonl`
|
||||
(每行一 JSON:ts/event/kind/detail/task_id),文件超
|
||||
1MB 时轮转成 `.old` 再写。
|
||||
- 取舍(写清,不当成完整修复):① 落盘本身 best-effort,
|
||||
写失败只记日志,绝不中断任务;② 落盘不是 DB 替代,
|
||||
任务 timeline 查询看不到它,需宿主人工查阅;③ 轮转
|
||||
只留最新两代,更早的丢失事件仍会丢;④ detail 沿用
|
||||
`_emit` 契约(只含 VM 名/路径/URL/kind),绝不含密钥值,
|
||||
落盘文件随 state_dir 的 0700 权限保护。审计完整性本身
|
||||
仍无保证——保证需要 DB 事务级审计写入,那是 worker
|
||||
全局语义的改动,不在本轨硬做。
|
||||
- 不选的另一条路:“审计失败即中断任务”——ADR-9 已否决:
|
||||
审计是可观测性不是门禁,DB 短暂不可用时硬中断会把
|
||||
一次审计失败放大成任务失败,且与 worker 全局 best-effort
|
||||
语义冲突。
|
||||
|
||||
## ADR-15 前端只读 VM 展示四态与可用性统一文案(to10 轨)
|
||||
|
||||
- 决策:`chvVmDisplay(task)` 返回四态而非此前两态文案:
|
||||
dead(字段 present 且 true)、not-reported(CHV 任务但
|
||||
字段 absent,只表示未报告)、unknown(任务详情本身未
|
||||
加载)、not-applicable(非 CHV,不显示行)。旧入口
|
||||
`chvVmStatusText` 保留为 display 的 text 包装(unknown /
|
||||
not-applicable 回空串),已测调用点不变。详情页 VM 行
|
||||
改用 `chvVmDisplay(t).text` 并加 `role="status"` 与
|
||||
`aria-label="VM 状态"`。
|
||||
- 决策:`chvAvailabilityText(availability)` 统一新建任务 /
|
||||
Workers / 环境三处可用性文案。此前三处各写各的,Workers
|
||||
的未知分支恒写“仅全局管理员可见”(加载失败/未加载时
|
||||
也是这句,是文案 bug),本轨统一后按 reason 分三句,
|
||||
known 零在线沿用派发页的完整版(不拦提交、后端是最终
|
||||
权威)。无障碍打磨:可用性区与提交结果区加
|
||||
`aria-live="polite"`(结果区另加 `role="status"`),附件
|
||||
三个 input 加 `aria-label`(此前只有 title),禁用态本身
|
||||
已由 `disabled` 传达,不另造禁用文案。控制按钮仍不做
|
||||
(后端无控制端点且安全审计 No-Go);组件渲染仍不在
|
||||
测试覆盖内(无 testing-library 依赖,不临时加依赖冒充)。
|
||||
|
||||
## ADR-16 to10 轨的类型与 lint 口径(诚实标注)
|
||||
|
||||
- mypy:`--follow-imports=silent cloud/chv/`,只查 chv 本身
|
||||
(不拖入无关文件)。基线该口径 115 错 → 本轨 0 错;
|
||||
默认 follow-imports 口径基线 117 错 → 本轨 2 错,且
|
||||
2 错全在作用域外的 `cloud/marker_tools.py:142`(与 chv
|
||||
无关,不顺手修它),chv 自身在默认口径下也是 0 错。
|
||||
- ruff:作用域 F/E9/W/I(未用变量、语法错、空白、import
|
||||
排序),基线 8 错 → 本轨 0 错;默认全规则基线 208 错
|
||||
(含本仓库未采纳的风格意见,如百分号格式化、
|
||||
best-effort 清理的 try/except-pass),本轨不声称全规则
|
||||
通过。worker.py 不在 lint 作用域内:其基线 I001 两处与
|
||||
F821 一处与本轨无关,未重排;本轨只删了随抽取而变多余
|
||||
的 `inspect` import(否则新增 F401)。
|
||||
- 覆盖率:`coverage --source=cloud/chv` 对 CHV 套件(不含
|
||||
worker/server 全量),基线 85% → 本轨 87%(1826 行,
|
||||
缺 268 → 242);未覆盖大头仍是 executor 深层生命周期
|
||||
分支(需假 VMM 全链路)与 disk 配额分支,不靠删测试
|
||||
或改分母凑数。
|
||||
@@ -459,3 +459,116 @@
|
||||
本 PR 顺序合并 → KVM 宿主 + 防火墙清单 → 镜像构建发布
|
||||
→ §11.5 + 本节真机清单全过 → 默认关闭下单租户/受信项目
|
||||
灰度 → 全量多租户(须另行决策,不在本轨内默认开启)。
|
||||
|
||||
## 13. to10 提升轨 feat-chv-to10(堆叠于 #257 之上)
|
||||
|
||||
本节是准备工作,不是启用结论:代码侧的 to10 项已做,
|
||||
生产就绪与动态安全仍未到 10 分(见 §13.4 外部关卡)。
|
||||
|
||||
### 13.1 合并前 diff 复核清单(以当前 main 头预填)
|
||||
|
||||
- 当前 main 头(本轨核查时):`aebc6238a613066316ec18796b83ea8fc2d8835e`
|
||||
(Merge PR #201)。链上 10 个 PR 在核查时全部
|
||||
OPEN / MERGEABLE(#216 base main,#221→#257 依次堆叠,
|
||||
本 PR base 为 feat-chv-arch-maint-fe)。合并时必须重新
|
||||
核查:main 头若已前进,整条链须逐个 rebase 并重跑测试,
|
||||
绝不直接合并旧基底。
|
||||
- 逐项复核点(合并执行者逐项打勾,任一项不符即停):
|
||||
1. server 任务创建白名单含 `cloud-hypervisor`,环境创建
|
||||
白名单为 local/docker/cloud-hypervisor(不含 cloud),
|
||||
两处白名单差异仍在前端文案里写清。
|
||||
2. worker 断点分支:Local 原路径不变,CHV 经
|
||||
`worker_adapter.call_goal_resume_breakpoint`(薄包装名
|
||||
`_call_goal_resume_breakpoint` 仍在 worker.py,旧测试
|
||||
导入点不变)。
|
||||
3. sandbox re-export:`cloud/chv` 不再 export WarmPool
|
||||
(#257 已移实验模块),`cloud/sandbox.py` 的 CHV
|
||||
re-export 与 `cloud/chv/__init__.py` 一致。
|
||||
4. 前端产物:`cloud/console.html` 与 `dist/index.html`
|
||||
的 sha256 一致(本轨:`269820d1…f389`,353163 字节),
|
||||
产物内含新文案(“无法判断 VM 状态”1 处、
|
||||
“CHV worker 在线数未知”3 处);合并时重建后复核,
|
||||
不直接沿用本轨哈希。
|
||||
5. `package.json` 的 vitest 测试脚本与 lockfile 增量只含
|
||||
vitest 新条目,无旧包版本变动。
|
||||
6. 本轨新增文件:`cloud/chv/worker_adapter.py`、
|
||||
`cloud/tests/test_chv_to10.py`、
|
||||
`chv-guest/generate_lockfile.py`;本轨改动文件:
|
||||
`cloud/worker.py`(薄包装 + 删多余 `inspect` import)、
|
||||
`cloud/chv/executor.py`(审计落盘 + 两函数抽 helper)、
|
||||
`cloud/chv/config.py`、`disk.py`、`hardening.py`、
|
||||
`hostkeys.py`、`ssh_transport.py`、`experimental_pool.py`、
|
||||
`compat215.py`(类型注解 + ruff 整理)、前端 6 文件。
|
||||
7. CI:链上全部 PR 的 `verify` 仍是账单故障秒级失败模式
|
||||
(本轨核查时 #257 等均为 UNSTABLE,非代码失败);
|
||||
CI 变绿前不合并,绝不改 CI 配置绕过。
|
||||
8. 旧链 #199→#205→#207 与 #209–#215 仍全部 OPEN:
|
||||
合并前复核它们与本链的交集(server 白名单、worker
|
||||
断点分支、sandbox re-export),有冲突先解决冲突方,
|
||||
不静默覆盖。
|
||||
|
||||
### 13.2 真机验证清单(用例与验收标准细化)
|
||||
|
||||
以下用例全部待 KVM 宿主,验收标准是“通过才算”,不是
|
||||
“跑过就算”;任一用例未跑即记为未验证,不写进已验。
|
||||
|
||||
- V-1 冷启动:CHV worker 在 KVM 宿主上起 VM → guest
|
||||
SSH 就绪(钉死 known_hosts,provisioned 模式)→ 跑通
|
||||
一个真实任务(host.py 在客机内执行)→ 任务完成且 VM
|
||||
已销毁、任务盘已删。验收:任务状态 completed,宿主
|
||||
state_dir 无该任务残留盘与 seed。
|
||||
- V-2 seed 首启时序:provisioned 模式下客机 cloud-init
|
||||
在 sshd 启动前应用 seed(host key 不再生、客内密钥文件
|
||||
0600)。验收:`sshd -T` 显示 PasswordAuthentication no
|
||||
等加固项,known_hosts 钉死校验通过,非 TOFU 回落。
|
||||
- V-3 快照恢复:任务中途 hibernate(pause + snapshot +
|
||||
shutdown)→ restore 后显式 resume → 断点续跑完成。
|
||||
验收:恢复后 known_hosts 不变(不重预置),快照文件
|
||||
落盘非空且经 `snapshot_not_persisted` 校验。
|
||||
- V-4 网关真实任务:sub2api 网关任务在 CHV 上跑通,
|
||||
密钥只走 seed 客内文件,宿主 `ps` / `/proc/*/cmdline`
|
||||
里看不到密钥值。验收:任务完成 + 宿主进程表抽查无密钥。
|
||||
- V-5 取消与配额真杀:同步 SSH 阻塞中取消任务、配额超限
|
||||
时,看门狗调 `cancel_vm` 真关 VM。验收:VM 进程消失,
|
||||
任务状态 interrupted 且原因写回正确。
|
||||
- V-6 审计落盘:DB 审计回调失败时,`chv-audit-spill.jsonl`
|
||||
里有该事件行、`audit_failure_count` +1、任务不中断。
|
||||
验收:落盘行 event/task_id/detail 与丢失事件一致。
|
||||
- V-7 动态安全负向:客机 root unset 代理后直连(应被
|
||||
tap/防火墙挡住)、跨 VM 探活与 IP 冒用(SSH 钉死应拒)、
|
||||
崩溃注入后残留扫描(私钥/seed/盘应被清理或脏标记拒起)。
|
||||
验收:每一项都有“被挡住”的证据,不是有代码就过。
|
||||
- V-8 负载:4 VM 并发(`CHV_MAX_VMS` 默认值)下容量门
|
||||
计数含重启后残留 socket 扫描,死 socket 不占名额、活
|
||||
VM 不被超发。验收:并发任务全部完成或明确排队拒绝,
|
||||
无静默降级到 Docker/Local。
|
||||
- V-9 供应链清单:`generate_lockfile.py` 在构建宿主上跑
|
||||
出真实 lockfile,`--verify` 通过且 unresolved 为空;
|
||||
再用 `check_lockfile.py` 对 BUILDINFO.versions 复核。
|
||||
验收:lockfile 由构建宿主产出,不是本轨合成数据。
|
||||
|
||||
### 13.3 灰度启用清单
|
||||
|
||||
- 阶段 0(合并后、默认关闭):合并整条链,CHV 仍默认
|
||||
关闭,不进生产任务路由;先跑 §13.2 的 V-1~V-9。
|
||||
- 阶段 1(单租户可信项目):只对明确指定的单租户项目
|
||||
开 CHV(`CHV_REUSE_SINGLE_TENANT_EXPERIMENT` 与
|
||||
`CHV_SINGLE_TENANT_PROJECT` 的声明口径不变,复用
|
||||
实验仍需同时声明,两者缺一即 preflight 拒绝)。
|
||||
- 阶段 2(受限多租户):放开到受邀项目,监控 VM 残留盘、
|
||||
审计落盘、容量门与快照配额三项指标一周无异常。
|
||||
- 阶段 3(全量多租户):仅在阶段 2 指标干净 + 动态安全
|
||||
审计结论由 No-Go 改为有条件启用后,才可讨论;绝不
|
||||
从阶段 0 直跳全量。
|
||||
|
||||
### 13.4 外部关卡(本轨代码做不到,逐项列出)
|
||||
|
||||
1. CI 账单恢复变绿(硬门禁,合并前提)。
|
||||
2. 链上 10 个 PR 按顺序合并 + 本 PR 合并(需先过 §13.1)。
|
||||
3. 用户侧 provision KVM 宿主(裸金属或嵌套虚拟化实例,
|
||||
须见 `/dev/kvm`;生产宿主与本 VM 均无 KVM,无法替代)。
|
||||
4. 客机镜像真实构建与发布(`build.sh` 全量跑通 + V-9)。
|
||||
5. §13.2 真机验证全部通过(含 V-7 动态安全负向)。
|
||||
6. 负载测试(V-8)与安全审计结论更新(No-Go → 有条件启用)。
|
||||
7. 前端 live 点击验证(用户侧 live browser 检查清单见
|
||||
本 PR 描述;回环地址限制下浏览器任务无法代劳)。
|
||||
Reference in new issue
Block a user