Files
codex-app-server/chv-guest/buildinfo.py
T
host dcb0824f78 fix(chv-guest): 浏览器装系统路径(B-22)
Round 7 构建本身成功,但 BUILDINFO.versions.chromium 为空:
virt-customize 的客机 shell 里 HOME=/,Playwright 默认缓存
~/.cache/ms-playwright 落到根目录 /.cache(实测浏览器在
/.cache/ms-playwright/chromium_headless_shell-1248),而
build.sh 读的是 /root/.cache/ms-playwright(不存在),ls 读回
空文件;buildinfo.py 当时不校验 chromium 非空,静默放过,
事后 check_lockfile / generate --verify 兜底报未覆盖(exit 1)。
改:安装与读回都走 PLAYWRIGHT_BROWSERS_PATH=
/usr/local/share/ms-playwright(agent 运行时也须设同一变量,
否则 chv 用户在家目录找不到浏览器);buildinfo.py 加
playwright_browsers_path 字段,并校验 playwright=1 时
versions.chromium 非空;README 同步。
2026-11-06 10:55:02 +00:00

145 lines
5.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""生成 CHV 客机镜像的 BUILDINFO.json(build.sh 调用)。
从 build.sh 抽出(B-02),使其可独立单元测试。输入全部是
已落盘的构建产物与读回文件,不编造版本号:versions 来自
客机读回的 dpkg-query / pip freeze(Playwright=1 时另有
ms-playwright 缓存目录名作 chromium 标识);artifacts 的
sha256/size 是对产物文件实测的;image_sha256 即 disk.raw
的 sha256,供 generate_lockfile.py 沿用。
用法:
python3 buildinfo.py OUT_DIR TAG UBUNTU CODEX_VERSION \\
REPO_COMMIT UBUNTU_IMAGE_SHA256 PLAYWRIGHT(0|1)
"""
import hashlib
import json
import os
import re
import sys
import time
# 轻量口径(2026-11-06 用户定):Ubuntu Minimal 底座,只装
# codex + Python + SSH + cloud-init + 薄 agent + git + gt +
# 最小中文字体;已裁剪 pandoc/texlive/python-docx 等文档工具
# 与 qemu-guest-agent。chv-sync 是仓库内脚本,版本随 repo_commit。
BASE_CONTENTS = [
"git", "openssh-server", "openssh-client", "cloud-init",
"python3", "python3-pip", "curl", "ca-certificates",
"xz-utils", "fonts-wqy-microhei", "fontconfig", "codex",
"codex-code-mode-host", "codex-resources/bwrap",
"/app/host.py", "gt", "chv-sync",
]
# 执行器默认内核 cmdline(config.py),构建产物须与它一起记录(B-12),
# 否则换宿主/换执行器配置时无法复现。
KERNEL_CMDLINE = "console=hvc0 root=/dev/vda1 rw"
# 浏览器装在系统路径(B-22),不是某用户的 ~/.cache:构建时
# PLAYWRIGHT_BROWSERS_PATH 指这里,agent 运行时也须设同一变量。
PLAYWRIGHT_BROWSERS_PATH = "/usr/local/share/ms-playwright"
def _read_lines(path):
try:
with open(path) as fh:
return [line.strip() for line in fh if line.strip()]
except OSError:
return []
def _sha256_size(path):
digest = hashlib.sha256()
size = 0
with open(path, "rb") as fh:
for chunk in iter(lambda: fh.read(1 << 20), b""):
digest.update(chunk)
size += len(chunk)
return digest.hexdigest(), size
def build(outdir, tag, ubuntu, codex_version, repo_commit,
ubuntu_image_sha256, playwright):
disk_path = os.path.join(outdir, "disk.raw")
vmlinux_path = os.path.join(outdir, "vmlinux")
disk_sha, disk_size = _sha256_size(disk_path)
vmlinux_sha, vmlinux_size = _sha256_size(vmlinux_path)
contents = list(BASE_CONTENTS)
versions = {
"dpkg": _read_lines(
os.path.join(outdir, "guest-versions-dpkg.txt")),
"pip": _read_lines(
os.path.join(outdir, "guest-versions-pip.txt")),
"gt": _read_lines(
os.path.join(outdir, "guest-versions-gt.txt")),
}
gt_version = ""
for line in versions["gt"]:
m = re.search(r"(\d+\.\d+\.\d+)", line)
if m:
gt_version = m.group(1)
break
if playwright:
contents += ["playwright", "chromium-headless-shell"]
versions["chromium"] = _read_lines(
os.path.join(outdir, "guest-versions-chromium.txt"))
info = {
"tag": tag,
"ubuntu": ubuntu,
"codex_version": codex_version,
"repo_commit": repo_commit,
"gt_version": gt_version,
"built_at": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
"contents": contents,
"versions": versions,
"ubuntu_image_sha256": ubuntu_image_sha256,
"ubuntu_image_sha256_set": True,
"kernel_cmdline": KERNEL_CMDLINE,
"playwright": bool(playwright),
"playwright_browsers_path": PLAYWRIGHT_BROWSERS_PATH
if playwright else "",
"image_sha256": disk_sha,
"artifacts": {
"disk.raw": {"sha256": disk_sha, "size": disk_size},
"vmlinux": {"sha256": vmlinux_sha, "size": vmlinux_size},
},
}
path = os.path.join(outdir, "BUILDINFO.json")
with open(path, "w") as fh:
json.dump(info, fh, indent=2)
fh.write("\n")
return info
def main(argv):
if len(argv) != 8:
print("用法:buildinfo.py OUT TAG UBUNTU CODEX_VERSION "
"REPO_COMMIT UBUNTU_IMAGE_SHA256 PLAYWRIGHT",
file=sys.stderr)
return 2
_, outdir, tag, ubuntu, codex_version, repo_commit, \
ubuntu_image_sha256, playwright = argv
info = build(outdir, tag, ubuntu, codex_version, repo_commit,
ubuntu_image_sha256, playwright == "1")
if not info["versions"]["dpkg"]:
print("BUILDINFO versions.dpkg 为空", file=sys.stderr)
return 1
if not info["versions"]["pip"]:
print("BUILDINFO versions.pip 为空", file=sys.stderr)
return 1
if not info["gt_version"]:
print("BUILDINFO gt_version 为空(gt 未装好)", file=sys.stderr)
return 1
if playwright == "1" and not info["versions"].get("chromium"):
print("BUILDINFO versions.chromium 为空(浏览器未装好或"
"读回路径不对)", file=sys.stderr)
return 1
if info["tag"] != tag:
print("BUILDINFO tag 不一致", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
raise SystemExit(main(sys.argv))