feat(chv-guest): seed 附加项供客机用户与静态网络(wake 路径前置)
wake_vm 在 WSL 台架上跑通需要客机身份与网络:镜像本身不建 用户、tap 无 DHCP,缺 users 块的 VM 登不进去、缺 network-config 的 VM 拿不到静态 IP。最小补法(复用 write_seed 机制): - hostkeys.write_seed 新增 user_data_extra(原样追加进 user-data,供 users: 块)与 network_config(写 seed network-config 文件,0600);附加项含 runcmd: 即 ValueError - config _seed_fragment:CHV_SEED_USER_DATA_EXTRA_FILE / CHV_SEED_NETWORK_CONFIG_FILE(只存路径) - executor._seed_extras 在 wake 起 VMM 前读入,缺失即 ChvFailure seed_extra_missing;provision_host_key 透传 - README §7 残留更新:guest-env 集成已做 - 测试:test_chv_gitea_sync 新增 5 项(写盘/禁 runcmd/ 配置映射/wake 带附加项/缺失 fail-closed)
This commit is contained in:
1 parent
e7f699c62b
commit
d7cc482ed5
5 files changed
+184
-11
No files matched your search
+37
-2
@@ -185,10 +185,41 @@ def _guest_env_entry(merged_env: dict) -> list:
|
||||
return lines
|
||||
|
||||
|
||||
def _apply_seed_extras(seed_dir: str, user_data: str,
|
||||
user_data_extra: str | None,
|
||||
network_config: str | None) -> str:
|
||||
"""seed 可选附加项(执行器 wake 路径的客机身份/网络供给):
|
||||
user_data_extra 原样追加进 user-data(调用方用它供
|
||||
`users:` 块——chv 用户 + authorized_keys,镜像本身不
|
||||
建用户);network_config 写成 seed 目录的 network-config
|
||||
文件(NoCloud 静态 IP,tap 无 DHCP 时客机才有地址)。
|
||||
两者皆空即原样返回。user_data_extra 里含 runcmd: 行即
|
||||
ValueError——seed 禁 runcmd 是 2026-11-06 根因禁令,
|
||||
附加项也不得绕过(镜像的 99-chv-sync.cfg 靠它活着)。"""
|
||||
if user_data_extra:
|
||||
for line in user_data_extra.splitlines():
|
||||
if line.strip().startswith("runcmd:"):
|
||||
raise ValueError(
|
||||
"seed 附加 user-data 里不得带 runcmd:")
|
||||
if not user_data.endswith("\n"):
|
||||
user_data += "\n"
|
||||
user_data += user_data_extra
|
||||
if not user_data.endswith("\n"):
|
||||
user_data += "\n"
|
||||
if network_config:
|
||||
net_path = os.path.join(seed_dir, "network-config")
|
||||
with open(net_path, "w") as fh:
|
||||
fh.write(network_config)
|
||||
os.chmod(net_path, 0o600)
|
||||
return user_data
|
||||
|
||||
|
||||
def write_seed(seed_dir: str, vm_name: str, private_key_text: str,
|
||||
public_key_text: str,
|
||||
secret_env: dict | None = None,
|
||||
guest_env: dict | None = None) -> str:
|
||||
guest_env: dict | None = None,
|
||||
user_data_extra: str | None = None,
|
||||
network_config: str | None = None) -> str:
|
||||
"""写 seed 目录:meta-data + user-data(均为 0600),
|
||||
返回 seed 目录路径。调用方负责随 VM 销毁删掉它。
|
||||
|
||||
@@ -198,7 +229,9 @@ def write_seed(seed_dir: str, vm_name: str, private_key_text: str,
|
||||
个条目(secret 优先于同名键,防两行同名);guest_env
|
||||
装 boot 时要用的非密钥同步变量(GITEA_URL 等,见
|
||||
gitea_sync):只走 SSH 前缀到不了 cloud-init 时运行
|
||||
的 chv-sync boot。两者皆空时不写该条目。"""
|
||||
的 chv-sync boot。两者皆空时不写该条目。
|
||||
user_data_extra / network_config 见 _apply_seed_extras
|
||||
(客机用户与静态网络的供给,皆空即不写)。"""
|
||||
os.makedirs(seed_dir, exist_ok=True)
|
||||
meta_path = os.path.join(seed_dir, "meta-data")
|
||||
user_path = os.path.join(seed_dir, "user-data")
|
||||
@@ -221,6 +254,8 @@ def write_seed(seed_dir: str, vm_name: str, private_key_text: str,
|
||||
user_data = head + "\n".join(lines) + "\n" + marker + tail
|
||||
else:
|
||||
user_data = user_data + "\n".join(lines) + "\n"
|
||||
user_data = _apply_seed_extras(seed_dir, user_data,
|
||||
user_data_extra, network_config)
|
||||
with open(user_path, "w") as fh:
|
||||
fh.write(user_data)
|
||||
os.chmod(user_path, 0o600)
|
||||
|
||||
Reference in new issue
Block a user