From 33ca6c75ed8dcc81dac4a67e587612c14c1c2a62 Mon Sep 17 00:00:00 2001 From: host Date: Sun, 8 Nov 2026 04:25:33 +0000 Subject: [PATCH] =?UTF-8?q?fix(chv-muse-r12fix-2):=20P6=20worker=20?= =?UTF-8?q?=E6=8E=A5=E8=BF=9B=E9=95=9C=E5=83=8F=EF=BC=88build.sh=20+=20BUI?= =?UTF-8?q?LDINFO=20+=20lockfile=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit R12 真机:chv-gitea-worker / chv-sync-worker-client / privsep.py / safety.py / chv-gitea-worker.service 5 文件全不在 镜像内,build.sh 从未有 P6 拷入行,全链路无法跑。按 gap 文档 §2 接入说明落地:worker 三件硬校验 + 拷入 /usr/local/bin/ 与 /etc/systemd/system/(mv 去后缀 + chmod +x + systemctl enable);privsep/safety 叶子模块条件拷入 /usr/local/lib/chv-gitea/(与 P3 同款口径,缺失只警告); 叶子树 __init__ 用 stub(绝不拷真实 cloud/chv/__init__.py, round-11 层 1 教训),stub 需 errors.py 故一并拷入;runcmd 在 chv-sync boot 前加 systemctl start chv-gitea-worker。 BUILDINFO contents 列入 worker 三件(无条件)与 privsep/ safety(条件,extra_contents);两处 lockfile 登记补齐 P6 五项,另补 P4 三件自 P4 起缺失的登记。 --- chv-guest/build.sh | 44 ++++++++++++++++++++++++++++++++- chv-guest/buildinfo.py | 3 +++ chv-guest/check_lockfile.py | 11 +++++++++ chv-guest/generate_lockfile.py | 11 +++++++++ cloud/tests/test_chv_muse_p2.py | 13 ++++++++-- cloud/tests/test_chv_muse_p4.py | 14 +++++++++-- cloud/tests/test_chv_muse_p6.py | 34 +++++++++++++++++++++++++ 7 files changed, 125 insertions(+), 5 deletions(-) diff --git a/chv-guest/build.sh b/chv-guest/build.sh index c0b878c..b44285b 100755 --- a/chv-guest/build.sh +++ b/chv-guest/build.sh @@ -216,6 +216,22 @@ if [ ! -f "$SCRIPT_DIR/chv-memory.py" ]; then echo "缺少 chv-memory.py(客内记忆文件脚本):$SCRIPT_DIR" >&2 exit 1 fi +# 对齐 Muse P6:privsep worker / 薄客户端 / 单元三件缺一即失败。 +for p6_file in chv-gitea-worker.py chv-sync-worker-client.py chv-gitea-worker.service; do + if [ ! -f "$SCRIPT_DIR/$p6_file" ]; then + echo "缺少 $p6_file(Muse P6 客机文件):$SCRIPT_DIR" >&2 + exit 1 + fi +done +# P6 云端叶子模块(privsep.py / safety.py)只警告、不失败—— +# 与 P3 同款口径(M4 既定 build.sh 不硬要求 cloud/);缺失时 +# worker 起不来、git 直连回落路径也不走 worker。 +P6_LIBS_PRESENT=0 +if [ -f "$REPO_DIR/cloud/chv/privsep.py" ] && [ -f "$REPO_DIR/cloud/chv/safety.py" ]; then + P6_LIBS_PRESENT=1 +else + echo "警告:Muse P6 云端叶子模块不在仓库里(cloud/chv/privsep.py 与 safety.py),镜像暂不含 worker 叶子模块" >&2 +fi if [ "$DRY_RUN" = "0" ]; then if [ ! -e /dev/kvm ]; then @@ -321,7 +337,7 @@ VC_ARGS=(-a "$OUT/disk.raw" --copy-in "$SCRIPT_DIR/chv-authd.service:/etc/systemd/system/" --run-command 'mv /usr/local/bin/authd.py /usr/local/bin/chv-authd && chmod +x /usr/local/bin/chv-authd /usr/local/bin/git-credential-chv-authd' --run-command 'systemctl enable chv-authd || true' - --run-command 'printf "runcmd:\n - systemctl restart ssh || service ssh restart || true\n - systemctl start chv-authd || true\n - test -f /etc/chv/guest-env && chown chv:chv /etc/chv/guest-env || true\n - /usr/local/bin/chv-sync boot >>/var/log/chv-sync.log 2>&1 || true\n" > /etc/cloud/cloud.cfg.d/99-chv-sync.cfg' + --run-command 'printf "runcmd:\n - systemctl restart ssh || service ssh restart || true\n - systemctl start chv-authd || true\n - test -f /etc/chv/guest-env && chown chv:chv /etc/chv/guest-env || true\n - systemctl start chv-gitea-worker || true\n - /usr/local/bin/chv-sync boot >>/var/log/chv-sync.log 2>&1 || true\n" > /etc/cloud/cloud.cfg.d/99-chv-sync.cfg' --copy-in "$SCRIPT_DIR/chv-cdp-broker.py:/usr/local/bin/" --copy-in "$SCRIPT_DIR/chv_browser_guard.py:/usr/local/bin/" # round-12 修复轮(项 0):c3bf9fd 认领——browser-blocklist.txt @@ -332,6 +348,15 @@ VC_ARGS=(-a "$OUT/disk.raw" --run-command 'mv /usr/local/bin/chv-cdp-broker.py /usr/local/bin/chv-cdp-broker && chmod +x /usr/local/bin/chv-cdp-broker && chmod 0644 /usr/local/bin/chv_browser_guard.py /usr/local/share/chv/browser-blocklist.txt' --copy-in "$SCRIPT_DIR/chv-memory.py:/usr/local/bin/" --run-command 'mv /usr/local/bin/chv-memory.py /usr/local/bin/chv-memory && chmod +x /usr/local/bin/chv-memory' + # 对齐 Muse P6:privsep worker(gap 文档 §2 接入说明)。 + --mkdir /usr/local/lib/chv-gitea + --mkdir /usr/local/lib/chv-gitea/cloud + --mkdir /usr/local/lib/chv-gitea/cloud/chv + --copy-in "$SCRIPT_DIR/chv-gitea-worker.py:/usr/local/bin/" + --copy-in "$SCRIPT_DIR/chv-sync-worker-client.py:/usr/local/bin/" + --copy-in "$SCRIPT_DIR/chv-gitea-worker.service:/etc/systemd/system/" + --run-command 'mv /usr/local/bin/chv-gitea-worker.py /usr/local/bin/chv-gitea-worker && mv /usr/local/bin/chv-sync-worker-client.py /usr/local/bin/chv-sync-worker-client && chmod +x /usr/local/bin/chv-gitea-worker /usr/local/bin/chv-sync-worker-client' + --run-command 'systemctl enable chv-gitea-worker || true' # round-11 真机修复(层 5):镜像不再设 credential.helper store #(authd helper 是唯一凭证 helper);P4 的 copy-in 行保留。 @@ -371,6 +396,22 @@ if [ "$P3_LIBS_PRESENT" = "1" ]; then --copy-in "$SCRIPT_DIR/authd_init_stub.py:/usr/local/lib/chv-authd/cloud/chv/" --run-command 'mv /usr/local/lib/chv-authd/cloud/chv/authd_init_stub.py /usr/local/lib/chv-authd/cloud/chv/__init__.py') fi +# P6 交接(Muse P6 的 worker 叶子模块):文件在仓库里存在时 +# 拷入 /usr/local/lib/chv-gitea/ 叶子树;不存在时只警告、不失败—— +# 与 P3 同款口径(M4 既定 build.sh 不硬要求 cloud/)。 +# 注意:叶子树的 cloud/chv/__init__.py 用 stub(authd_init_stub.py), +# 绝不拷真实的 cloud/chv/__init__.py(它 import executor/orphans, +# 会让 worker 在 import 时 ModuleNotFoundError;round-11 层 1 同款 +# 教训)。stub 要从 cloud.chv.errors import ChvFailure,故 +# errors.py 也一并拷进本树。 +if [ "$P6_LIBS_PRESENT" = "1" ]; then + VC_ARGS+=(--copy-in "$REPO_DIR/cloud/chv/privsep.py:/usr/local/lib/chv-gitea/cloud/chv/" + --copy-in "$REPO_DIR/cloud/chv/safety.py:/usr/local/lib/chv-gitea/cloud/chv/" + --copy-in "$REPO_DIR/cloud/chv/errors.py:/usr/local/lib/chv-gitea/cloud/chv/" + --copy-in "$REPO_DIR/cloud/__init__.py:/usr/local/lib/chv-gitea/cloud/" + --copy-in "$SCRIPT_DIR/authd_init_stub.py:/usr/local/lib/chv-gitea/cloud/chv/" + --run-command 'mv /usr/local/lib/chv-gitea/cloud/chv/authd_init_stub.py /usr/local/lib/chv-gitea/cloud/chv/__init__.py') +fi # P1 交接(Muse P1 的 vsock_notify.py):文件在仓库里存在时拷入 # 镜像并建 vsock-notify.service(自动启动,round-11 真机修复: # 此前只拷文件、不建服务,vsock 通道从未自动启动;服务形状按 @@ -446,6 +487,7 @@ else fi EXTRA_CONTENTS="" [ "$P3_LIBS_PRESENT" = "1" ] && EXTRA_CONTENTS="cloud/chv/authd.py,cloud/chv/sentinel.py,cloud/chv/errors.py,cloud/chv/__init__.py" + [ "$P6_LIBS_PRESENT" = "1" ] && EXTRA_CONTENTS="${EXTRA_CONTENTS:+$EXTRA_CONTENTS,}cloud/chv/privsep.py,cloud/chv/safety.py" [ "$VSOCK_NOTIFY_PRESENT" = "1" ] && EXTRA_CONTENTS="${EXTRA_CONTENTS:+$EXTRA_CONTENTS,}vsock_notify" python3 "$SCRIPT_DIR/buildinfo.py" "$OUT" "$TAG" "$UBUNTU_VERSION" "$CODEX_VERSION" "$REPO_COMMIT" "$UBUNTU_IMAGE_SHA256" "${PLAYWRIGHT:-1}" "${CHROMIUM_HEADLESS_SHELL_REV:-}" "$EXTRA_CONTENTS" fi diff --git a/chv-guest/buildinfo.py b/chv-guest/buildinfo.py index 40c2b3c..f6ed314 100644 --- a/chv-guest/buildinfo.py +++ b/chv-guest/buildinfo.py @@ -48,6 +48,9 @@ BASE_CONTENTS = [ # 对齐 Muse P4:单元外 CDP broker + 浏览器安全共享模块 + # 静态拦截名单。 "chv-cdp-broker", "chv-browser-guard", "browser-blocklist", + # 对齐 Muse P6:privsep worker + 薄客户端 + 单元(无条件拷入)。 + "chv-gitea-worker", "chv-sync-worker-client", + "chv-gitea-worker.service", ] diff --git a/chv-guest/check_lockfile.py b/chv-guest/check_lockfile.py index 71bd249..5d907e0 100644 --- a/chv-guest/check_lockfile.py +++ b/chv-guest/check_lockfile.py @@ -44,6 +44,17 @@ DECLARED_SOURCES = { "cloud/chv/errors.py": "repo_commit", "cloud/chv/__init__.py": "repo_commit", "vsock_notify": "repo_commit", + # 对齐 Muse P4:CDP broker 三件在 contents 里,登记自 P4 起 + # 一直缺失;本轮补上,否则新镜像的 lockfile 仍 unresolved。 + "chv-cdp-broker": "repo_commit", + "chv-browser-guard": "repo_commit", + "browser-blocklist": "repo_commit", + # 对齐 Muse P6:worker 三件 + 叶子模块(privsep/safety)。 + "chv-gitea-worker": "repo_commit", + "chv-sync-worker-client": "repo_commit", + "chv-gitea-worker.service": "repo_commit", + "cloud/chv/privsep.py": "repo_commit", + "cloud/chv/safety.py": "repo_commit", } diff --git a/chv-guest/generate_lockfile.py b/chv-guest/generate_lockfile.py index 091bb80..7424074 100644 --- a/chv-guest/generate_lockfile.py +++ b/chv-guest/generate_lockfile.py @@ -66,6 +66,17 @@ DECLARED_SOURCES = { "cloud/chv/errors.py": "repo_commit", "cloud/chv/__init__.py": "repo_commit", "vsock_notify": "repo_commit", + # 对齐 Muse P4:CDP broker 三件在 contents 里,登记自 P4 起 + # 一直缺失;本轮补上,否则新镜像的 lockfile 仍 unresolved。 + "chv-cdp-broker": "repo_commit", + "chv-browser-guard": "repo_commit", + "browser-blocklist": "repo_commit", + # 对齐 Muse P6:worker 三件 + 叶子模块(privsep/safety)。 + "chv-gitea-worker": "repo_commit", + "chv-sync-worker-client": "repo_commit", + "chv-gitea-worker.service": "repo_commit", + "cloud/chv/privsep.py": "repo_commit", + "cloud/chv/safety.py": "repo_commit", } diff --git a/cloud/tests/test_chv_muse_p2.py b/cloud/tests/test_chv_muse_p2.py index b6617b0..6f34da0 100644 --- a/cloud/tests/test_chv_muse_p2.py +++ b/cloud/tests/test_chv_muse_p2.py @@ -629,7 +629,11 @@ class BuildDryRunTest(unittest.TestCase): # round-12 P4:build.sh 缺一即 fail-fast,夹具 # 须一并拷入(合入时补:R11 夹具本无此四件)。 "chv-cdp-broker.py", "chv_browser_guard.py", - "browser-blocklist.txt", "chv-memory.py"): + "browser-blocklist.txt", "chv-memory.py", + # round-12 修复轮(项 2,P6):worker 三件亦 + # 是 build.sh 硬校验,夹具须一并拷入。 + "chv-gitea-worker.py", "chv-sync-worker-client.py", + "chv-gitea-worker.service"): shutil.copy2(ROOT / "chv-guest" / name, os.path.join(guest, name)) shutil.copy2(ROOT / "host.py", os.path.join(repo, "host.py")) @@ -700,7 +704,12 @@ class BuildDryRunTest(unittest.TestCase): # round-11 真机修复(层 1):叶子树含 # errors.py + stub __init__,不拷真实的 # cloud/chv/__init__.py。 - "errors.py", "authd_init_stub.py"): + "errors.py", "authd_init_stub.py", + # round-12 修复轮(项 2,P6):worker + # 三件进镜像,干跑输出须含拷入与 enable。 + "chv-gitea-worker", + "chv-gitea-worker.service", + "systemctl enable chv-gitea-worker"): self.assertIn(needle, out, needle) # P1 文件不在本分支:干跑只警告、不失败。 self.assertIn("vsock_notify.py 不在仓库里", out) diff --git a/cloud/tests/test_chv_muse_p4.py b/cloud/tests/test_chv_muse_p4.py index 39fe3ab..5a88d09 100644 --- a/cloud/tests/test_chv_muse_p4.py +++ b/cloud/tests/test_chv_muse_p4.py @@ -802,7 +802,12 @@ class BuildDryRunTest(unittest.TestCase): # 合入 round-11 时补:build.sh 的 P3 预检硬要求 # authd_init_stub.py 在仓(缺一即 exit 1)。 "chv-authd.service", "authd_init_stub.py", - "chv-memory.py"): + "chv-memory.py", + # round-12 修复轮(项 2,P6):worker 三件亦 + # 是 build.sh 硬校验,夹具须一并拷入。 + "chv-gitea-worker.py", + "chv-sync-worker-client.py", + "chv-gitea-worker.service"): shutil.copy2(ROOT / "chv-guest" / name, os.path.join(guest, name)) shutil.copy2(ROOT / "host.py", os.path.join(repo, "host.py")) @@ -852,7 +857,12 @@ class BuildDryRunTest(unittest.TestCase): "chv-cdp-broker.service", "systemctl enable chv-broker chv-browser " "chv-cdp-broker", - "ask-queue"): + "ask-queue", + # round-12 修复轮(项 2,P6):worker + # 三件进镜像,干跑输出须含拷入与 enable。 + "chv-gitea-worker", + "chv-gitea-worker.service", + "systemctl enable chv-gitea-worker"): self.assertIn(needle, out, needle) # P1 文件不在本分支:干跑只警告、不失败。 self.assertIn("vsock_notify.py 不在仓库里", out) diff --git a/cloud/tests/test_chv_muse_p6.py b/cloud/tests/test_chv_muse_p6.py index a5a4805..678e2b0 100644 --- a/cloud/tests/test_chv_muse_p6.py +++ b/cloud/tests/test_chv_muse_p6.py @@ -756,5 +756,39 @@ class ExecutorAuditHookTest(unittest.TestCase): safety_mod.DEFAULT_AUDIT_LOGGER = old +class BuildInfoContentsTest(unittest.TestCase): + """round-12 修复轮(项 2,P6):worker 三件须进 BUILDINFO + contents(无条件拷入,与 P2/P4 同款钉法)。""" + + def test_contents_include_p6_items(self): + root = Path(__file__).resolve().parents[2] + path = root / "chv-guest" / "buildinfo.py" + spec = importlib.util.spec_from_file_location( + "chv_guest_p6_buildinfo", str(path)) + module = importlib.util.module_from_spec(spec) + spec.loader.exec_module(module) + with tempfile.TemporaryDirectory() as tmp: + out = os.path.join(tmp, "out") + os.makedirs(out) + for name, content in (("disk.raw", b"D"), + ("vmlinux", b"K")): + with open(os.path.join(out, name), "wb") as fh: + fh.write(content) + for name, lines in ( + ("guest-versions-dpkg.txt", ["git 9.9.9-9ubuntu9"]), + ("guest-versions-pip.txt", ["playwright==9.9.9"]), + ("guest-versions-gt.txt", ["gt version 1.0.0"]), + ("guest-versions-chromium.txt", + ["chromium_headless_shell-1248"])): + with open(os.path.join(out, name), "w") as fh: + fh.write("\n".join(lines) + "\n") + info = module.build( + out, "chv-guest-24.04-0.164.0-alpha.9-abc1234", "24.04", + "0.164.0-alpha.9", "abc1234", "0" * 64, True, "1248") + for item in ("chv-gitea-worker", "chv-sync-worker-client", + "chv-gitea-worker.service"): + self.assertIn(item, info["contents"]) + + if __name__ == "__main__": unittest.main()