feat: CHV gap fill — worker breakpoint wiring, pool reconcile, per-VM host keys, egress validation, guest build script

Stack: #216 -> #221 -> this. Worker breakpoint branch now calls any
executor providing goal_resume_breakpoint_task (Local keeps its
original path, gateway tasks still loud-fail); WarmPool
reconcile_orphans is called on CHV worker startup and close with
audit-on-failure; per-VM SSH host keys are provisioned before VMM
start via cloud-init NoCloud seed (keyscan kept only as weak
fallback, CHV_HOST_KEY_MODE=provisioned|keyscan); CHV_NET_JSON is
validated in preflight and explicit direct egress is audited;
chv-guest/build.sh is now real steps with --dry-run and fails fast
without /dev/kvm. Tests: new test_chv_gaps.py (18), cloud full
1514 OK (skipped=4). No real VM verification: no KVM host.
This commit is contained in:
host committed 2026-10-31 01:30:52 +00:00
1 parent fde7bf4c3e
commit 22b83f118a
8 files changed
+922 -59

No files matched your search

+35 -11
View File
@@ -1,11 +1,12 @@
# Cloud Hypervisor 客机镜像(chv-guest)——内容清单与版本化构建说明
> 本目录只有清单与构建脚本骨架,镜像本身不在本轨内实际构建
> 发布。原因写在前面,不藏着:当前没有带 /dev/kvm 的宿主
> 可以构建并实测 VM 镜像(生产主机是 CVM、无嵌套虚拟化;
> 本 VM 容器内同样无 /dev/kvm)。构建与实测见
> `docs/chv-production-readiness.md` 的“需镜像构建 / 需 KVM
> 宿主实测”项,绝不在本轨声称镜像已建成、已发布、已跑通。
> 本目录有清单与真实构建步骤(build.sh,补缺口轨已实做),
> 但镜像本身不在本轨内实际构建发布。原因写在前面,不藏着:
> 当前没有带 /dev/kvm 的宿主可以构建并实测 VM 镜像(生产
> 主机是 CVM、无嵌套虚拟化;本 VM 容器内同样无 /dev/kvm)。
> 构建与实测见 `docs/chv-production-readiness.md` 的“需镜像
> 构建 / 需 KVM 宿主实测”项,绝不在本轨声称镜像已建成、
> 已发布、已跑通。
## 1. 镜像定位
@@ -53,12 +54,35 @@ chv-guest-<ubuntu 版本>-<codex 版本>-<仓库 commit 短 hash>
- `BUILDINFO.json`:`{ubuntu, codex_version, repo_commit, built_at,
contents: [清单逐项版本]}`
## 4. 构建脚本骨架
## 4. 构建脚本(补缺口轨:已从骨架改成真实步骤)
见 `build.sh`:只做参数校验、产物路径与版本 tag 计算、以及
“需要 KVM 宿主 / virt-customize 才能执行的步骤”占位。脚本在
无 KVM 的机器上运行时应在第一步就明确退出(`CHV_GUEST_BUILD
needs a KVM host`),绝不假装构建成功。
见 `build.sh`:参数校验 → 下载 Ubuntu 云镜像 → qemu-img
转 raw → virt-customize 装 §2 清单、拷入 codex 成套二进制
与仓库代码到 /app、写 host key 不重生成配置 →
virt-get-kernel 取内核 → 生成并校验 BUILDINFO.json。
`./build.sh --dry-run out/` 只打印命令、不执行、不要求
KVM;全量模式在无 /dev/kvm 的机器上第一步就明确退出
(`CHV_GUEST_BUILD needs a KVM host`),绝不假装构建成功。
本轨未在真机上跑过全量模式,镜像未建成、未发布,仍属
“需 KVM 宿主实测”项。
## 6. Host key 首启注入硬性要求(补缺口轨新增)
执行器的 per-VM 预置方案(见 `cloud/chv/hostkeys.py`)能
跑通的前提是客机镜像必须满足以下全部,否则预置在真机
上跑不通,执行器会 fail-fast,不回落成弱方案:
- 装 cloud-init 且支持 NoCloud seed(seed 磁盘/目录由
执行器在 VM 启动前生成,含 meta-data 与 user-data);
- 首启时先应用 seed 再启动 sshd,seed 里的 user-data
把该 VM 的 host key 对写进 /etc/ssh/ 并重启 sshd;
- 镜像里已钉死 `ssh_deletekeys: false` 与
`ssh_genkeytypes: []`(build.sh 已写),首启不得无条件
重新生成 host key——重生成会使预置的 known_hosts 立即
失效,SSH 钉死直接拒绝,这是设计,不是 bug;
- sshd 只允许 key 登录,禁止密码登录;
- seed 磁盘/目录是 per-VM 敏感物,执行器在 VM 关闭/
回收时删除,镜像构建方不得把任何一把 host key 固化
进镜像(所有 VM 同 key 是安全事故)。
## 5. 与执行器的对接