fix(chv-muse-r12fix2-2): chv-sync 回落显性化:警告 + 每回落一行审计(P6-2)

R12 复测:worker 226 期间 chv-sync 全程静默走直接路径回落,pull/
push/status 表面 rc=0,privsep/safety 一行没跑——回落只有一句 stderr
警告,无事后可数的痕。本提交让一次回落留两处痕:stderr 警告保留
“worker 不在”标记(措辞加“未走 worker,privsep 未生效”,供驱动
识别)+ 追加一行 JSON 审计到
$USER_HOME/.chv-sync-fallback-audit.log(CHV_SYNC_FALLBACK_LOG 可改
位置;事件/动作/仓/时间戳,delegated_to_worker=false、
privsep_active=false)。审计写失败只记 stderr,绝不中断同步(与
worker _audit 同款口径)。gap 文档诚实边界第 4 条同步更新。

取舍:不改 fail-closed,仍是 fail-open。理由:旧镜像(无 worker)
须仍能同步,改 fail-closed 会把所有旧镜像的同步当场 brick,且无
镜像外恢复手段;本轮项 1 已让新镜像的 worker 开机即起,回落只在
worker 真挂 / 旧镜像时发生,不再是常态路径。旧镜像退役后改为无
worker 即 fail-closed(原定方向不变,见 chv-sync.sh 头注)。

测试:ChvSyncDelegationTest 新增——回落审计一行 JSON(字段全)、
两次回落两行、审计落盘失败不中断同步;走 worker 时不留回落审计
(反向对照)。
This commit is contained in:
host committed 2026-11-08 06:01:54 +00:00
1 parent 35d9c3ff3f
commit 7c517f7fcc
3 files changed
+77 -9

No files matched your search

+29 -5
View File
@@ -35,8 +35,17 @@ WORKSPACE="${CHV_WORKSPACE:-/home/chv/workspace}"
USER_HOME="${CHV_USER_HOME:-/home/chv}"
SYNC_USER="${CHV_USER:-chv}"
# privsep worker(feat-chv-muse-p6):socket 在时 pull/push/status
# 改走 worker(类型化请求),不在时走旧的直接路径 + 警告(过渡兼容,
# 旧镜像退役后改为无 worker 即 fail-closed)。
# 改走 worker(类型化请求),不在时走旧的直接路径(过渡兼容)。
# round-12 修复轮第二轮(项 2):回落仍是 fail-open,不改
# fail-closed——旧镜像(无 worker)须仍能同步,改 fail-closed 会把
# 所有旧镜像的同步当场 brick,且无镜像外恢复手段;本轮项 1 已让新
# 镜像的 worker 开机即起,回落只在 worker 真挂 / 旧镜像时发生,不
# 再是常态路径。但回落不再静默:每次回落都在 stderr 警告(保留
# “worker 不在”标记供驱动识别)+ 追加一行 JSON 审计
# ($USER_HOME/.chv-sync-fallback-audit.log,可用
# CHV_SYNC_FALLBACK_LOG 改位置;写失败只记 stderr,绝不中断同步,
# 与 worker 的 _audit 同款口径)。事后 grep 该审计文件即能数出回落
# 次数、动作与仓。旧镜像退役后改为无 worker 即 fail-closed。
WORKER_SOCK="${CHV_GITEA_WORKER_SOCK:-/run/chv-gitea/worker.sock}"
WORKER_CLIENT="${CHV_GITEA_WORKER_CLIENT:-/usr/local/bin/chv-sync-worker-client}"
@@ -52,6 +61,21 @@ try_worker() {
"$WORKER_CLIENT" "$action" "$@"
}
# 回落显性化(round-12 修复轮第二轮,项 2):一次回落留两处痕——
# stderr 警告 + 一行 JSON 审计(事件/动作/仓/时间戳,明确记
# delegated_to_worker=false、privsep_active=false)。审计写失败
# 只记 stderr,绝不中断同步。
fallback_warn() {
local action="$1" repo="${2:-}"
echo "chv-sync: worker 不在,走旧的直接路径(过渡兼容):未走 worker,privsep 未生效" >&2
local log="${CHV_SYNC_FALLBACK_LOG:-$USER_HOME/.chv-sync-fallback-audit.log}"
local ts
ts="$(date -u +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo unknown)"
repo="${repo//\"/}"
printf '%s\n' "{\"event\":\"chv_sync_worker_fallback\",\"action\":\"$action\",\"repo\":\"$repo\",\"delegated_to_worker\":false,\"privsep_active\":false,\"ts\":\"$ts\"}" >> "$log" 2>/dev/null \
|| echo "chv-sync: 回落审计落盘失败:$log" >&2
}
# 解析仓目录:显式给则用它;否则取 WORKSPACE 下唯一的 git 仓库。
resolve_repo() {
if [ -n "${1:-}" ]; then
@@ -128,7 +152,7 @@ cmd_pull() {
local rc=0
try_worker pull "${1:-}" || rc=$?
[ "$rc" != "42" ] && exit "$rc"
echo "chv-sync: worker 不在,走旧的直接路径(过渡兼容)" >&2
fallback_warn pull "${1:-}"
local dir
dir="$(resolve_repo "${1:-}")"
[ -z "$(git -C "$dir" status --porcelain)" ] \
@@ -142,7 +166,7 @@ cmd_push() {
local rc=0
try_worker push "${1:-}" || rc=$?
[ "$rc" != "42" ] && exit "$rc"
echo "chv-sync: worker 不在,走旧的直接路径(过渡兼容)" >&2
fallback_warn push "${1:-}"
local dir
dir="$(resolve_repo "${1:-}")"
if git -C "$dir" rev-parse --abbrev-ref --symbolic-full-name '@{u}' >/dev/null 2>&1; then
@@ -159,7 +183,7 @@ cmd_status() {
local rc=0
try_worker status "${1:-}" || rc=$?
[ "$rc" != "42" ] && exit "$rc"
echo "chv-sync: worker 不在,走旧的直接路径(过渡兼容)" >&2
fallback_warn status "${1:-}"
local dir
dir="$(resolve_repo "${1:-}")"
git -C "$dir" status -sb