fix(chv-muse-r12fix3-1): worker 开机时序竞态:Condition + path 触发,不赌重启预算(P6 缺口 ①)

R12 复测 2 钉死:剩下的 226 只点名 /home/chv/workspace——工作区由
cloud-final 的 chv-sync boot 克隆出来,晚于 multi-user.target 约
9 秒,worker 的 5 次启动预算在工作区出现前耗尽(5 台 VM 2 台
failed,手工 reset-failed + start 后立即 active,二进制无辜)。

修法三选一,选 (a)——让服务根本不在工作区出现前启动:
新单元 chv-gitea-worker.path(PathExists=/home/chv/workspace,
工作区一出现即触发启动)+ 服务加
ConditionPathExists=/home/chv/workspace(开机那次启动在命名空间
搭建之前干净跳过,不 226、不耗重启预算)。两者缺一不可:
Condition 本身绝不重试,没有 .path 它就是一次跳过、服务永远不
起;只有 .path 而无 Condition,开机那次启动仍会在命名空间搭建
时 226 撞上限速。WantedBy=multi-user.target 保留(is-enabled 仍
为 enabled),runcmd 只启动 .path 单元(cloud-final 时工作区尚
未 clone,直接 start 服务会 226);.path 进 buildinfo contents
与两处 lockfile 登记,P6 预检由三件扩为四件。

不用 (b) 放宽 StartLimit:放宽只是把竞态窗口拉大,wake 时间在
负载下已翻倍(R12 复测 2),预算仍可能耗尽,仍是时序赌博。
不用 (c) 把工作区创建提前到 tmpfiles-setup 之前:/home/chv 本身
07:23:40 才出现(cloud-init 建 chv 用户),晚于 tmpfiles-setup
(07:23:24);硬约束:绝不盲目补 tmpfiles 行。ExecStartPre 也不
行——命名空间搭建在它之前,救不了 226。

测试:WorkerUnitBootRaceTest 新增 8 项——Condition 在位、
StartLimit 未放宽(修法语义钉)、.path 触发配对(PathExists +
WantedBy、无 Unit= 覆盖)、服务 WantedBy 保留、build.sh 启用
.path + runcmd 只起 .path、绝无工作区 tmpfiles 行、buildinfo 与
lockfile 登记;BuildInfoContentsTest 的 P6 件加 .path;P2/P4 干
跑夹具一并拷入 .path。P6/P2/P4 三模块 174 项全过。
This commit is contained in:
host committed 2026-11-08 09:45:48 +00:00
1 parent 7c517f7fcc
commit e31354dc58
10 files changed
+165 -15

No files matched your search

+10 -4
View File
@@ -216,8 +216,8 @@ 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
# 对齐 Muse P6:privsep worker / 薄客户端 / 单元 / 路径触发器四件缺一即失败。
for p6_file in chv-gitea-worker.py chv-sync-worker-client.py chv-gitea-worker.service chv-gitea-worker.path; do
if [ ! -f "$SCRIPT_DIR/$p6_file" ]; then
echo "缺少 $p6_file(Muse P6 客机文件):$SCRIPT_DIR" >&2
exit 1
@@ -347,7 +347,12 @@ 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 - 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'
# round-12 修复轮第三轮(缺口 ①):runcmd 只启动 .path 单元
#(开机时它已由 enable 激活,这里是兜底),绝不直接 start 服务
#——cloud-final 此时工作区尚未 clone,直接 start 服务会在命名
# 空间搭建时 226;.path 单元在 boot 的 mkdir -p 建出工作区后
# 才触发服务启动。
--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.path || 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
@@ -365,8 +370,9 @@ VC_ARGS=(-a "$OUT/disk.raw"
--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/"
--copy-in "$SCRIPT_DIR/chv-gitea-worker.path:/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'
--run-command 'systemctl enable chv-gitea-worker chv-gitea-worker.path || true'
# round-11 真机修复(层 5):镜像不再设 credential.helper store
#(authd helper 是唯一凭证 helper);P4 的 copy-in 行保留。