feat(chv): 阶段 1 数据盘与 tenant 标记同 overlay 解耦(copy 也供)

真机根因(2026-11-07,CHV v54 三变体实证):vm.boot 对任何
带 backing file 的 qcow2 都报 Maximum disk nesting depth
exceeded——overlay-only 与 overlay-rawbase 均 500,base 直接
启动(reuse)22.5 秒成功,数据盘与压缩均已排除。overlay 在
本 VMM 上不可用,持久 VM 须能在 copy 模式下跑。
- _provision_task_disk:copy 与 overlay 都供数据盘并写
  tenant.json(只有 reuse 不供不写);_provision_data_disk_path
  同理(reuse 才返回 None)。
- _cleanup_vm_task_disk:保护(持久登记/登记快照)不再只限
  overlay 模式;无登记无快照的 copy 盘仍按旧语义删除。
- provision_data_disk:数据盘改 raw 稀疏盘(os.truncate,
  零外部依赖)——copy 模式本来就不需要 qemu-img,数据盘
  绝不能悄悄加上这个依赖;CHV 按后缀认 Raw。
- 测试:新增 copy 供数据盘+tenant 与 copy 持久盘 stop 保护;
  VmConfig 三盘断言(任务+seed+数据)更新 arch95/fix 两处
  旧“恰好两盘”契约与本轨 qcow2 类型断言。
回归:test_chv_*.py、test_cloud_hypervisor.py 42、test_chv_v3_fixes
38 全过(全量 cloud/tests 在跑)。
不推、不合、不部署;只本地分支。
This commit is contained in:
host committed 2026-11-08 09:45:00 +00:00
1 parent a5f836e9fd
commit f809014bef
5 files changed
+113 -65

No files matched your search

+7 -2
View File
@@ -102,15 +102,20 @@ class Arch95Case(unittest.TestCase):
return FakeResult(0, "", "")
def _strict_api(self, socket_path, method, path, payload=None):
"""严格替身:vm.create 必须带任务盘 + seed 盘、net 无重复。"""
"""严格替身:vm.create 必须带任务盘 + seed 盘 + 数据盘、
net 无重复(阶段 1:数据盘是第三块盘,见
_provision_task_disk 的解耦说明)。"""
if path == "/vm.create":
self.api_payloads.append(payload)
disks = [d.get("path") for d in payload.get("disks", [])]
self.assertEqual(len(disks), 2, "VmConfig 必须恰好两盘")
self.assertEqual(len(disks), 3,
"VmConfig 必须恰好三盘(任务+seed+数据)")
self.assertTrue(disks[0].endswith("disk.raw"),
"第一盘必须是任务盘")
self.assertTrue(disks[1].endswith("seed.iso"),
"第二盘必须是 seed 盘,缺 seed 即假保证")
self.assertTrue(disks[2].endswith("data.raw"),
"第三盘必须是数据盘")
self.assertTrue(payload.get("payload", {}).get("kernel"))
nets = payload.get("net", [])
taps = [n.get("tap") for n in nets]