feat(chv-muse-p1): 常驻 VM + WarmPool 扶正 + 气球 + vsock,对齐 Muse
每用户一台常驻 VM(暂停态,resume 到 SSH 5 秒内为待验证目标), 池空/失败回落冷启动;CHV 配置加 virtio-balloon + free-page-reporting 与 vsock notify 最小实现(SSH 仍是命令通道与就绪判定)。 新模块 resident_pool.py / vsock.py + 客内 vsock_notify.py; _config 增加 CHV_RESIDENT_IDLE_MINUTES / CHV_BALLOON / CHV_VSOCK; worker_adapter 接常驻孤儿清理 facade;ADR-17 差距表见 docs/chv-muse-p1-gap.md。 恢复收尾(分离后回归,见 gap.md §4):VmDeathTest 死亡模拟改杀 实际跑命令的 VM;两处冷路径旧测试显式关常驻;_balloon_vsock_payload 与 listen_notify 拆到 50 行内;resident_pool.py:208 mypy 修掉。 executor.py out 未注解与 marker_tools.py:142 是基线旧错,未动。 测试:全量 cloud 套件 1934 OK(skipped=8);mypy 在改动文件上 干净(仅基线旧错 4 处)。真机验证待第三棒让出 WSL 测试机。
This commit is contained in:
1 parent
06c3e172fe
commit
78098c5594
13 files changed
+2527
-36
No files matched your search
@@ -57,6 +57,60 @@
|
||||
- 重启条件:将来要重新接线,必须先实现任务盘重供给并补
|
||||
“任务盘来源”不变量测试,否则不得把 wired 改成 True。
|
||||
|
||||
## ADR-17 常驻 VM 池取代 WarmPool 接线(feat-chv-muse-p1)
|
||||
|
||||
- 决策:不再接线 WarmPool,改走新建的生产模块
|
||||
`cloud/chv/resident_pool.py`(ResidentPool):每用户一台
|
||||
常驻 VM,任务到时 resume 已暂停的 VM,跑完 pause,不
|
||||
销毁;池空或任何一步失败都回落冷启动。WarmPool 实验模块
|
||||
一字不动,`wired_to_dispatch` 仍恒 False,ADR-5 的定案
|
||||
(预热盘是干净快照盘、不是任务盘)仍然成立、只是不再
|
||||
是接线障碍——常驻 VM 的盘本来就是每用户持久工作区盘,
|
||||
不是每任务新盘。
|
||||
- 隔离单元变了:常驻路径下隔离单元从“每任务”变成“每用户”
|
||||
——同一用户的任务共享同一台常驻 VM 与同一块工作区盘,
|
||||
每任务新盘的不变量在常驻路径上不再成立。冷启动路径
|
||||
(每任务新盘)保留作回落与隔离严格场景。当前是单租户,
|
||||
这个取舍可接受;多租户重审前不得把常驻路径当多租户隔离。
|
||||
任务 dict 目前无 user_id,全落到 "default" 键;user_id
|
||||
出现时按键隔离,release 绝不把用过的 VM 放回给另一用户。
|
||||
- 接线:`_run_with_vm` 先常驻 acquire,命中走常驻路径
|
||||
(finally 里 release=pause),失败/未启用走原冷启动路径
|
||||
(finally shutdown 不变,冷启动本体逐字移到 `_run_cold`);
|
||||
dispatch/run/goal/goal_resume/断点续跑都走 `_run_with_vm`,
|
||||
签名不动。常驻默认开,`CHV_RESIDENT_ENABLED=0` 可关;
|
||||
开关用 getattr/env 惰性读,`__init__` 不动。池空时惰性
|
||||
provision 一次(wake + pause)再取,仍无则冷启动——首个
|
||||
任务自举常驻 VM,不依赖 worker 启动时预热。
|
||||
- 常驻执行细节:`_run_guest`/`_run_guest_goal` 一律走常驻伪
|
||||
任务 `{"id": "resident-<用户>"}` 传参(SSH known_hosts、
|
||||
api-socket、密钥投递记录、VMM 登记都按常驻 VM 名算),
|
||||
返回后把 `task_id` 改回真实任务 id;中途死亡判据同样按
|
||||
常驻伪任务查登记进程。带密钥 extra_env 的任务不走常驻
|
||||
(seed 是建池时定的,密钥只能冷启动随 seed 投递),直接
|
||||
冷启动。同一用户同一时间只跑一个常驻任务,并发第二个
|
||||
任务回落冷启动。
|
||||
- Registry:`state_dir/resident-pool.json`,文件 IO 与损坏
|
||||
语义复用 orphans(原子写、损坏 quarantine、单条目非法
|
||||
只丢该条);重启后读到的条目一律 orphan 不复用、只清理。
|
||||
空闲回收:paused 超 `CHV_RESIDENT_IDLE_MINUTES`(默认 0=
|
||||
不自动关机)时 hibernate(pause + snapshot + shutdown)
|
||||
并删条目,快照文件留作恢复物,restore 是后续工作。
|
||||
- 依赖方向(ADR-12 的禁令全部保留):executor 仍绝不 import
|
||||
orphans/experimental_pool(常驻池用方法内 import 拿
|
||||
ResidentPool);resident_pool → orphans(只借 registry
|
||||
文件 IO,与 experimental_pool 同款方向);worker 启动/
|
||||
关闭调 `worker_adapter.reconcile_resident_pool` facade,
|
||||
它只读 resident-pool.json 做清理,不构造 ResidentPool。
|
||||
`reconcile_warm_pool` 不动。
|
||||
- 诚实边界(未验证,不宣称):resume 耗时、到 SSH 5 秒内、
|
||||
气球压内存——无真机验证(第三棒占着 WSL 测试机),一律
|
||||
记入真机待验证清单;resume 失败时 `wait_guest_ready` 的
|
||||
失败路径会 stop_vm(含删工作区盘),该路径的工作区以
|
||||
Gitea 同步为准;pause 失败时条目留在 running(不删不销
|
||||
毁),worker 关闭时 reconcile 清理,在此之前该用户只走
|
||||
冷启动。
|
||||
|
||||
## ADR-6 Docker goal 解析分叉:共享正典 + 同步守卫(本轨定案)
|
||||
|
||||
- 决策:Local/CHV 共用 parse_goal_result 正典;Docker goal_task
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
# 对齐 Muse P1 差距表:常驻 VM + WarmPool + 气球 + vsock
|
||||
|
||||
依据:`~/workspace/research_notes/meta-muse-ai-architecture-20261101-0755/report.md`
|
||||
(官方以 Meta security.muse.ai 2026-09-08 为准;第三方拆解只作参考,
|
||||
逆向细节不得写成官方架构)。Muse 模型一句话:每用户一台常驻 Secure VM,
|
||||
闲置靠气球压内存,宿主–客机走 vsock 通知通道。
|
||||
|
||||
本轨范围只限 P1:常驻 VM、WarmPool 扶正、内存气球、vsock 通道。
|
||||
不碰 P2(客机 nspawn 单元、浏览器子代理独立)、不碰 P3(authd 替身凭证、
|
||||
Sentinel 式出口审批)。分支 `feat-chv-muse-p1`(从 `feat-chv-cover100`
|
||||
分出,基线 HEAD `06c3e17`)。
|
||||
|
||||
## 1. 现状 vs Muse
|
||||
|
||||
| 项 | 现状(实测/代码为准) | Muse 目标 | 本轨做法 |
|
||||
|---|---|---|---|
|
||||
| VM 生命周期 | 1 任务 = 1 VM,用完销毁;冷启动到 SSH 实测 11 秒 | 每用户一台常驻 Secure VM(hatchling),任务来了直接用 | 新增常驻服务:每用户一台常驻 VM(暂停态),任务到时 resume;池空回落冷启动(11 秒路径不动) |
|
||||
| 派发查池 | `_run_with_vm` 绝不查池,`warm_pool_wired_to_dispatch` 恒 False;worker 派发前查池未接线 | 常驻 VM 就是派发目标,无冷启动 | `_run_with_vm` 接常驻路径:先 acquire 常驻 VM(resume + 等 SSH 就绪),无可用时回落 `wake_vm` |
|
||||
| 预热池状态 | `experimental_pool.WarmPool` 纯实验,生产禁 import(ADR-12);ADR-5 定案:预热盘是干净快照盘、不是任务盘,接线须先实现任务盘重供给 | —(Muse 无此概念:常驻 VM 的盘就是用户工作区盘) | WarmPool 实验模块不动(仍禁生产 import);新建生产模块 `resident_pool.py`。常驻 VM 的盘是**每用户持久工作区盘**,不是每任务新盘 |
|
||||
| 内存 | 固定 2G,无气球 | 气球 + 空闲页上报,闲置 8G 压到约 2G 工作集 | CHV 配置加 virtio-balloon + free-page-reporting(默认开,可关) |
|
||||
| 宿主–客机通道 | 只 SSH;executor 文档明确“只选 SSH,不做 vsock 第二套”(旧决策) | vsock 通知通道(另有 Unix socket + SO_PEERCRED 的单元内 IPC,属 P2/P3 层) | vsock 只做最小 notify(就绪/心跳上报),与 SSH 并存;SSH 仍是命令通道与就绪判定,host key 钉死不动 |
|
||||
| 池持久化/孤儿 | WarmPool registry `state_dir/warm-pool.json` 已有(原子写、损坏 quarantine、重启后条目一律 orphan 不复用) | — | 常驻池复用同款 registry 语义,另建 `resident-pool.json`;worker 启动/关闭走 `orphans` facade 清理,不自动复用上一世条目 |
|
||||
|
||||
## 2. 改了什么(本轨交付物)
|
||||
|
||||
- `cloud/chv/resident_pool.py`(新):常驻池。状态机 cold → provisioning →
|
||||
paused → running → paused;`acquire(user)` resume + SSH 就绪,
|
||||
`release(user)` pause 不销毁;空闲回收策略(pause 后常驻,超闲置阈值
|
||||
关机+快照,阈值可配,默认不开自动关机);registry 原子落盘、损坏
|
||||
quarantine、重启后不复用。
|
||||
- `cloud/chv/executor.py`:`_run_with_vm` 接常驻路径(默认开,可配关;
|
||||
常驻失败一律回落冷启动,绝不因池坏而丢任务);`_create` payload 加
|
||||
balloon/vsock 设备。
|
||||
- `cloud/chv/config.py`:`CHV_RESIDENT_IDLE_MINUTES`、`CHV_BALLOON`、
|
||||
`CHV_VSOCK`(开关 + CID),非法值 ValueError,不静默 fallback。
|
||||
- `cloud/chv/worker_adapter.py`:常驻池 reconcile facade(接 `orphans`)。
|
||||
- `cloud/chv/vsock.py`(新,宿主侧):vsock notify 客户端/监听最小实现。
|
||||
- `cloud/chv/guest/vsock_notify.py`(新,客内脚本):连宿主 CID 2 发
|
||||
ready/心跳。**只写脚本文件,不改 `chv-guest/build.sh`**——镜像集成
|
||||
是 P2 的范围,本轨只留接入说明。
|
||||
- `cloud/tests/test_chv_muse_p1_*.py`(新):常驻池、气球/vsock 配置与
|
||||
payload、回落语义的单测;全量 cloud 套件全过。
|
||||
- `docs/chv-architecture.md`:ADR-5/ADR-12 补充新决策(常驻路径取代
|
||||
WarmPool 接线问题),旧定案不删、只追加。
|
||||
|
||||
## 3. 诚实边界(本轮不宣称的东西)
|
||||
|
||||
1. **隔离单元变了**:常驻路径下隔离单元从“每任务”变成“每用户”——同一
|
||||
用户的任务共享同一台常驻 VM 与同一块工作区盘,每任务新盘的不变量在
|
||||
常驻路径上不再成立。冷启动路径(每任务新盘)保留作回落与隔离严格场景。
|
||||
当前是单租户,这个取舍可接受;多租户重审前不得把常驻路径当多租户隔离。
|
||||
2. **性能数字全是待验证目标,不是结果**:resume 1–2 秒、到 SSH 5 秒内、
|
||||
气球压内存——本轮无真机验证(第三棒 V-1~V-9 占着 WSL 测试机),一律
|
||||
记入“真机待验证清单”,不在代码/文档里写成已测得。
|
||||
3. **气球 API 形态须核对**:CHV 54 的 balloon/vsock payload 字段以
|
||||
Cloud Hypervisor 官方文档/二进制为准;本机无 /dev/kvm,无法本地起
|
||||
VM 校验,只做配置层 + payload 单测。
|
||||
4. **vsock 端到端未通**:本轮只做到宿主侧 + 客内脚本;客内脚本进镜像、
|
||||
真机收发验证都待 P2 集成后、测试机空闲时再做。SSH 不动,vsock 坏了
|
||||
不影响任务。
|
||||
5. **WarmPool 实验模块不动**:不把它翻成生产模块,不改
|
||||
`wired_to_dispatch`;常驻是新模块、新路径,旧实验代码与测试原样保留。
|
||||
|
||||
## 4. 恢复收尾(分离后在本分支修掉的回归)
|
||||
|
||||
分离时 chv 子集 3 失败 + 1 错误,全量另有 2 失败,均已修
|
||||
掉、未删测试、未改断言:
|
||||
|
||||
- **VmDeathTest 两处**:根因不是生产判定错——探针实证,
|
||||
常驻 VM 真死时 `_run_on_resident` 两态都正确判
|
||||
interrupted;错的是旧测试的死亡模拟:它杀
|
||||
`ex._vms["chv-abc123"]`,P1 常驻路由下该 VM 从未 wake、
|
||||
登记里只有 `chv-resident-default`,模拟是空操作。修
|
||||
法:模拟器改杀 dispatch 时已登记的 VM(即实际跑命令
|
||||
的那台),断言不动。
|
||||
- **test_cloud_hypervisor 两处冷路径测试**
|
||||
(`test_dispatch_wakes_runs_shuts_down`、
|
||||
`test_dispatch_missing_dependency_does_not_call_runner`):
|
||||
P1 把常驻改成默认开后,它们测的冷启动序列不再是默认
|
||||
路径;修法:两测试显式 `CHV_RESIDENT_ENABLED=0`,
|
||||
继续钉冷启动行为,断言不动。常驻 dispatch 由 P1 新测
|
||||
试覆盖。附带说明:建池 wake 失败后的清理 shutdown 是
|
||||
既定行为(P1 回落测试钉住),不是回归。
|
||||
- **超 50 行**:`_balloon_vsock_payload`(54)拆出
|
||||
`_resolve_vsock_socket`;`vsock.listen_notify`(55)
|
||||
拆出 `_bind_notify_listener`;行为不动。
|
||||
- **mypy**:`resident_pool.py:208` 加 None 守卫后干净;
|
||||
`executor.py` 的 `out` 未注解错与 `marker_tools.py:142`
|
||||
是基线 06c3e17 已有(`git show` 核对,P1 diff 零行碰
|
||||
`out`),如实记录、未动。
|
||||
Reference in new issue
Block a user