From eb495892e19fbd275780f0c9187d051ea6536f7d Mon Sep 17 00:00:00 2001 From: host Date: Sat, 7 Nov 2026 19:41:00 +0000 Subject: [PATCH] =?UTF-8?q?fix(chv):=20=E9=98=B6=E6=AE=B5=203=20live=20?= =?UTF-8?q?=E6=A0=B9=E5=9B=A0=E2=80=94=E2=80=94=E6=B5=8F=E8=A7=88=E5=99=A8?= =?UTF-8?q?=20socket=20=E4=B8=8E=E6=95=B0=E6=8D=AE=E7=9B=98=20profile=20?= =?UTF-8?q?=E7=9A=84=E4=B8=A4=E5=A4=84=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - /run/chv 0755 root:root 时 chv-browser 建 browser.sock 报 PermissionError、服务无限 crash-loop(P2 遗留,阶段 2 从未验 过 browser.sock):tmpfiles 改 0775 root:chv-browser。 - /home/chv 默认 0750,chv-browser 穿不过家目录,ismount 判假、 profile 静默回落本机盘:chv-data-mount 挂载成功后 chmod 0751 /home/chv(只放行穿过,不放行列表)。 - 驱动:等 cloud-init done + 四服务 active 再验浏览器。 - 回归 97 项全过(新增 2 项接线断言)。 --- chv-guest/build.sh | 9 ++++++++- chv-guest/chv-data-mount.sh | 6 ++++++ cloud/tests/test_chv_opt_stage3.py | 14 ++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/chv-guest/build.sh b/chv-guest/build.sh index c5ba5fe..143523e 100755 --- a/chv-guest/build.sh +++ b/chv-guest/build.sh @@ -334,7 +334,14 @@ VC_ARGS=(-a "$OUT/disk.raw" # 启动再按 pid 认领(登记落盘 /run/chv/execd-tasks.json)。 --run-command 'printf "[Unit]\nDescription=CHV guest exec daemon (stage 2: shell/files/codex hosting)\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/python3 /usr/local/bin/chv-execd\nRestart=always\nRestartSec=2\nKillMode=process\n\n[Install]\nWantedBy=multi-user.target\n" > /etc/systemd/system/chv-execd.service' --run-command 'printf "[Unit]\nDescription=CHV Gitea sync daemon (stage 2: resident pull/push loop)\nAfter=network.target\n\n[Service]\nType=simple\nUser=chv\nGroup=chv\nRuntimeDirectory=chv-syncd\nRuntimeDirectoryMode=0755\nExecStart=/usr/bin/python3 /usr/local/bin/chv-syncd\nRestart=always\nRestartSec=2\n\n[Install]\nWantedBy=multi-user.target\n" > /etc/systemd/system/chv-syncd.service' - --run-command 'printf "d /run/chv 0755 root root -\nd /run/chv/shots 0755 chv-browser chv-browser -\nd /run/chv/tasks 0755 root root -\n" > /etc/tmpfiles.d/chv.conf && systemctl enable chv-broker chv-browser chv-daemon chv-execd chv-syncd || true') + # 阶段 3 live 实证(2026-11-08,构建 #8 驱动):chv-browser 以 + # chv-browser 身份跑,要在 /run/chv 里建 browser.sock;0755 + # root:root 时 bind 报 PermissionError、服务无限 crash-loop, + # 阶段 2 从未验过 browser.sock 故一直没暴露。改 0775 + # root:chv-browser(组在镜像构建时已建,tmpfiles-setup 启动时 + # 能解析——与 syncd 那行因 chv 用户尚不存在被跳过不同); + # socket 本身仍由服务 chmod 0600,broker 以 root 连,不受影响。 + --run-command 'printf "d /run/chv 0775 root chv-browser -\nd /run/chv/shots 0755 chv-browser chv-browser -\nd /run/chv/tasks 0755 root root -\n" > /etc/tmpfiles.d/chv.conf && systemctl enable chv-broker chv-browser chv-daemon chv-execd chv-syncd || true') # P1 交接(Muse P1 的 vsock_notify.py):文件在仓库里存在时拷入 # 镜像(P1 分支才有,本分支尚无);不存在时只警告、不失败—— # 合并后自动生效,P2 不改该脚本内容。 diff --git a/chv-guest/chv-data-mount.sh b/chv-guest/chv-data-mount.sh index 6282808..0ca666a 100755 --- a/chv-guest/chv-data-mount.sh +++ b/chv-guest/chv-data-mount.sh @@ -52,5 +52,11 @@ chown chv:chv "$MOUNT" || true mkdir -p "$MOUNT/.chv-browser-profile" || true chown chv-browser:chv-browser "$MOUNT/.chv-browser-profile" 2>/dev/null || true chmod 0700 "$MOUNT/.chv-browser-profile" 2>/dev/null || true +# 阶段 3 live 实证(2026-11-08,构建 #8 驱动):/home/chv 默认 +# 0750 chv:chv,chv-browser 穿不过家目录去够数据盘 profile—— +# ismount 判假、profile 静默回落本机盘(服务本身不报错)。 +# 放到 0751:只放行穿过(+x),不放行列表(无 r), +# chv-browser 能进已知子目录,看不见家目录内容。 +chmod 0751 /home/chv 2>/dev/null || true log "mounted $DEV -> $MOUNT" exit 0 diff --git a/cloud/tests/test_chv_opt_stage3.py b/cloud/tests/test_chv_opt_stage3.py index 58bf69e..9af1b6b 100644 --- a/cloud/tests/test_chv_opt_stage3.py +++ b/cloud/tests/test_chv_opt_stage3.py @@ -352,6 +352,20 @@ class BuildWiringTest(unittest.TestCase): self.assertIn("After=network.target cloud-final.service", block) + def test_tmpfiles_lets_browser_bind_its_socket(self): + # 阶段 3 live 根因:/run/chv 0755 root:root 时 chv-browser + # 建 browser.sock 报 PermissionError、服务无限 crash-loop。 + text = (ROOT / "chv-guest" / "build.sh").read_text() + self.assertIn("d /run/chv 0775 root chv-browser -", text) + self.assertNotIn("d /run/chv 0755 root root -", text) + + def test_data_mount_lets_browser_traverse_home(self): + # 阶段 3 live 根因 #2:/home/chv 默认 0750,chv-browser + # 穿不过家目录,ismount 判假、profile 静默回落本机盘。 + text = (ROOT / "chv-guest" / "chv-data-mount.sh").read_text() + self.assertIn("chmod 0751 /home/chv", text) + self.assertIn(".chv-browser-profile", text) + def test_dry_run_contains_stage3_browser_wiring(self): with tempfile.TemporaryDirectory() as tmp: repo = os.path.join(tmp, "repo")