feat: CHV 审核修复(P0+P1,堆叠于 #230)
P0:seed 磁盘 CIDATA ISO 挂进 VmConfig 第二块只读盘; restore provisioned 下复用钉死 known_hosts、缺失 fail-fast 绝不 keyscan;preflight 拦截 CHV_DISK_MODE=reuse(显式 实验二次确认 + 审计放行);SSH 目标选客机 IP 方案(显式 host > net 静态 ip > 显式转发宣称回环,三者皆无 fail-fast)。 P1:网关 extra_env 经 SSH env 前缀注入、worker 守卫收窄到 Local/CHV;取消/清理/看门狗接 CHV 通用路径;WarmPool acquire 内 resume;容量门持久化计数;磁盘配额总量+余量 与已存在磁盘校验重拷;API 按 Content-Length 验完整性; 快照 file:// 验落盘再 shutdown;execute 死端口归类 vm_not_running。 P2 全部排除未做(用户范围收窄令,留待以后一轨)。 测试:原 84 + 新增 29 = 113 项,mock,无真 VM。
This commit is contained in:
1 parent
22b83f118a
commit
9771ed9e8c
13 files changed
+1231
-128
No files matched your search
+37
-4
@@ -44,16 +44,49 @@ def host_key_paths(state_dir, vm_name):
|
||||
}
|
||||
|
||||
|
||||
def known_hosts_line(port, public_key_text):
|
||||
def known_hosts_line(port, public_key_text, host="127.0.0.1"):
|
||||
"""公钥文件内容转 known_hosts 行:只取前两列(类型+数据)。
|
||||
|
||||
公钥文件形如 'ssh-ed25519 AAAA... [comment]',known_hosts
|
||||
行形如 '[127.0.0.1]:<port> ssh-ed25519 AAAA...'。非法
|
||||
内容 ValueError,绝不把陌生行原样写进文件。"""
|
||||
行形如 '[<host>]:<port> ssh-ed25519 AAAA...'(host 缺省
|
||||
回环,仅作兼容;客机 IP 方案下 host 应为解析出的客机 IP)。
|
||||
非法内容 ValueError,绝不把陌生行原样写进文件。"""
|
||||
parts = (public_key_text or "").strip().split()
|
||||
if len(parts) < 2 or not parts[0].startswith("ssh-"):
|
||||
raise ValueError("host 公钥格式非法")
|
||||
return "[127.0.0.1]:%s %s %s" % (port, parts[0], parts[1])
|
||||
return "[%s]:%s %s %s" % (host, port, parts[0], parts[1])
|
||||
|
||||
|
||||
def seed_disk_path(state_dir, vm_name):
|
||||
"""该 VM 的 NoCloud seed 磁盘镜像路径(CIDATA 卷标 ISO)。"""
|
||||
return os.path.join(state_dir, vm_name, "seed.iso")
|
||||
|
||||
|
||||
def build_seed_disk(seed_dir, seed_disk, runner=None):
|
||||
"""把 seed 目录做成 CIDATA 卷标 ISO(feat-chv-fix,P0-1 的
|
||||
注入载体):genisoimage -volid CIDATA -joliet -rock。
|
||||
|
||||
runner 不给时用 subprocess;测试可注入假 runner(假
|
||||
runner 负责把 seed_disk 文件写出来)。工具失败、返回码
|
||||
非 0、或产物不存在/为空时一律 RuntimeError,调用方
|
||||
(wake_vm provisioned 路径)fail-fast,绝不带着“seed
|
||||
目录已写但未挂进 VmConfig”的 VM 继续启动。seed 目录
|
||||
本身只是中间物,不再被当成注入通道。"""
|
||||
cmd = ["genisoimage", "-output", seed_disk, "-volid", "CIDATA",
|
||||
"-joliet", "-rock", seed_dir]
|
||||
if runner is not None:
|
||||
result = runner(cmd)
|
||||
rc = getattr(result, "returncode", 0)
|
||||
if rc not in (0, None):
|
||||
raise RuntimeError("genisoimage 失败:returncode=%s" % rc)
|
||||
else:
|
||||
import subprocess
|
||||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||
if result.returncode != 0:
|
||||
raise RuntimeError("genisoimage 失败:%s" % result.stderr)
|
||||
if not os.path.isfile(seed_disk) or os.path.getsize(seed_disk) == 0:
|
||||
raise RuntimeError("seed 磁盘未生成:%s" % seed_disk)
|
||||
return seed_disk
|
||||
|
||||
|
||||
def build_seed_user_data(private_key_text, public_key_text):
|
||||
|
||||
Reference in new issue
Block a user