feat(chv-muse-round11): build.sh 补 P3 authd 进镜像 + gt 脚本哈希轮换
- authd 三件套 copy-in(chv-guest/authd.py 与 git-credential-chv-authd -> /usr/local/bin/ 并 chmod +x,chv-authd.service -> /etc/systemd/system/),云端叶子模块 cloud/chv/authd.py 与 sentinel.py + 两个 __init__.py -> /usr/local/lib/chv-authd/, systemctl enable chv-authd;99-chv-sync.cfg runcmd 在 chv-sync boot 之前加 systemctl start chv-authd;缺件即 fail-fast - buildinfo BASE_CONTENTS 登记新增件;P2 干跑夹具补 P3 文件并断言 authd 步骤出现在干跑输出里 - GT_INSTALL_SH_SHA256 cf82... -> 49ffe090...:上游 2026-11-07 06:44 轮换,V-9 已核实(WSL fresh curl 与失败镜像内残留逐字节 一致;新脚本全文已读,只从 dl.gitea.com 取 1.0.0 二进制并验 hash) - vsock_notify 条件拷入在合入后生效(cloud/chv/guest/vsock_notify.py 已在仓里,干跑不再报缺失警告) - 定向单测 P1/P2/P3/chv_fix 172 项全过;全量套件仍在跑
This commit is contained in:
1 parent
73176e135c
commit
29d3a5a474
3 files changed
+65
-7
No files matched your search
+45
-5
@@ -90,8 +90,11 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|||||||
REPO_DIR="${REPO_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
REPO_DIR="${REPO_DIR:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
||||||
# gt 1.0.0:官方 install.sh(gitea.com/gitea/cli,main 分支
|
# gt 1.0.0:官方 install.sh(gitea.com/gitea/cli,main 分支
|
||||||
# scripts/install.sh),脚本本身下载 dl.gitea.com 的二进制并
|
# scripts/install.sh),脚本本身下载 dl.gitea.com 的二进制并
|
||||||
# 验 SHA256;此处再验脚本自身的 SHA256(2026-11-06 实测值,
|
# 验 SHA256;此处再验脚本自身的 SHA256。2026-11-07 06:44
|
||||||
# 上游轮换脚本后构建会明确失败,不静默跑新脚本)。
|
# 上游轮换过一次(V-9 实测:WSL fresh curl 与失败镜像内下载残留
|
||||||
|
# 逐字节一致,新 sha 49ffe090…;新脚本全文已读,只从 dl.gitea.com
|
||||||
|
# 取 1.0.0 二进制并验 hash,行为干净)——旧值 cf82… 已失效,
|
||||||
|
# 现钉死新值;上游再轮换时构建会再次明确失败,不静默跑新脚本。
|
||||||
GT_VERSION="${GT_VERSION:-1.0.0}"
|
GT_VERSION="${GT_VERSION:-1.0.0}"
|
||||||
# feat-chv-closeup(M4):Chromium 单独钉死。PLAYWRIGHT=1 时
|
# feat-chv-closeup(M4):Chromium 单独钉死。PLAYWRIGHT=1 时
|
||||||
# ms-playwright 缓存目录名即 Chromium 版本标识(如
|
# ms-playwright 缓存目录名即 Chromium 版本标识(如
|
||||||
@@ -105,7 +108,7 @@ CHROMIUM_HEADLESS_SHELL_REV="${CHROMIUM_HEADLESS_SHELL_REV:-}"
|
|||||||
if [ -n "$CHROMIUM_HEADLESS_SHELL_REV" ] && ! printf '%s' "$CHROMIUM_HEADLESS_SHELL_REV" | grep -Eq '^[0-9]+$'; then
|
if [ -n "$CHROMIUM_HEADLESS_SHELL_REV" ] && ! printf '%s' "$CHROMIUM_HEADLESS_SHELL_REV" | grep -Eq '^[0-9]+$'; then
|
||||||
echo "CHROMIUM_HEADLESS_SHELL_REV 须为纯数字修订号(如 1248):$CHROMIUM_HEADLESS_SHELL_REV" >&2; exit 1
|
echo "CHROMIUM_HEADLESS_SHELL_REV 须为纯数字修订号(如 1248):$CHROMIUM_HEADLESS_SHELL_REV" >&2; exit 1
|
||||||
fi
|
fi
|
||||||
GT_INSTALL_SH_SHA256="${GT_INSTALL_SH_SHA256:-cf82acecc0e3ffa6f690d33902eefcf1cc21a5b11004103bf23c4436664288d5}"
|
GT_INSTALL_SH_SHA256="${GT_INSTALL_SH_SHA256:-49ffe0909be9117e36cf7c8a35b5937939639090322063cbad7667e0bde7c9e9}"
|
||||||
# B-03/B-04:输入格式校验(干跑与全量都做,报错点提前,
|
# B-03/B-04:输入格式校验(干跑与全量都做,报错点提前,
|
||||||
# 不等到 curl 404 或 sha256sum -c 才失败)。
|
# 不等到 curl 404 或 sha256sum -c 才失败)。
|
||||||
if ! printf '%s' "$UBUNTU_VERSION" | grep -Eq '^[0-9]+\.[0-9]+$'; then
|
if ! printf '%s' "$UBUNTU_VERSION" | grep -Eq '^[0-9]+\.[0-9]+$'; then
|
||||||
@@ -179,6 +182,24 @@ for p2_script in chv-cell.py chv-broker.py chv-browser.py; do
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
# 对齐 Muse P3:authd 三件套缺一即失败(与 build.sh 同目录,P2
|
||||||
|
# 同款规矩)。云端叶子模块(cloud/chv/authd.py 与 sentinel.py)
|
||||||
|
# 不做硬要求:M4 既定“/app 最小集、build.sh 不再要求 cloud/”
|
||||||
|
#(test_chv_residual.BuildScriptMinimalAppTest 钉住),缺失时只
|
||||||
|
# 警告、不失败——缺叶子模块的镜像里 chv-authd 起不来,chv-sync
|
||||||
|
# 按 P3 差距表 §3.5 回落旧落盘路径并警告,绝不静默假装有 authd。
|
||||||
|
for p3_file in authd.py git-credential-chv-authd chv-authd.service; do
|
||||||
|
if [ ! -f "$SCRIPT_DIR/$p3_file" ]; then
|
||||||
|
echo "缺少 $p3_file(Muse P3 客机文件):$SCRIPT_DIR" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
P3_LIBS_PRESENT=0
|
||||||
|
if [ -f "$REPO_DIR/cloud/chv/authd.py" ] && [ -f "$REPO_DIR/cloud/chv/sentinel.py" ] && [ -f "$REPO_DIR/cloud/__init__.py" ] && [ -f "$REPO_DIR/cloud/chv/__init__.py" ]; then
|
||||||
|
P3_LIBS_PRESENT=1
|
||||||
|
else
|
||||||
|
echo "警告:Muse P3 云端叶子模块不在仓库里(cloud/chv/authd.py 与 sentinel.py),镜像暂不含 authd 叶子模块" >&2
|
||||||
|
fi
|
||||||
if [ "$DRY_RUN" = "0" ]; then
|
if [ "$DRY_RUN" = "0" ]; then
|
||||||
if [ ! -e /dev/kvm ]; then
|
if [ ! -e /dev/kvm ]; then
|
||||||
echo "CHV_GUEST_BUILD needs a KVM host: /dev/kvm 不存在" >&2
|
echo "CHV_GUEST_BUILD needs a KVM host: /dev/kvm 不存在" >&2
|
||||||
@@ -275,7 +296,15 @@ VC_ARGS=(-a "$OUT/disk.raw"
|
|||||||
--copy-in "$SCRIPT_DIR/chv-broker.py:/usr/local/bin/"
|
--copy-in "$SCRIPT_DIR/chv-broker.py:/usr/local/bin/"
|
||||||
--copy-in "$SCRIPT_DIR/chv-browser.py:/usr/local/bin/"
|
--copy-in "$SCRIPT_DIR/chv-browser.py:/usr/local/bin/"
|
||||||
--run-command 'mv /usr/local/bin/chv-cell.py /usr/local/bin/chv-cell && mv /usr/local/bin/chv-broker.py /usr/local/bin/chv-broker && mv /usr/local/bin/chv-browser.py /usr/local/bin/chv-browser && chmod +x /usr/local/bin/chv-cell /usr/local/bin/chv-broker /usr/local/bin/chv-browser'
|
--run-command 'mv /usr/local/bin/chv-cell.py /usr/local/bin/chv-cell && mv /usr/local/bin/chv-broker.py /usr/local/bin/chv-broker && mv /usr/local/bin/chv-browser.py /usr/local/bin/chv-browser && chmod +x /usr/local/bin/chv-cell /usr/local/bin/chv-broker /usr/local/bin/chv-browser'
|
||||||
--run-command 'printf "runcmd:\n - systemctl restart ssh || service ssh restart || 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'
|
--mkdir /usr/local/lib/chv-authd
|
||||||
|
--mkdir /usr/local/lib/chv-authd/cloud
|
||||||
|
--mkdir /usr/local/lib/chv-authd/cloud/chv
|
||||||
|
--copy-in "$SCRIPT_DIR/authd.py:/usr/local/bin/"
|
||||||
|
--copy-in "$SCRIPT_DIR/git-credential-chv-authd:/usr/local/bin/"
|
||||||
|
--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 - /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 'git config --system user.name chv && git config --system user.email chv@localhost && git config --system credential.helper store && git config --system init.defaultBranch main'
|
--run-command 'git config --system user.name chv && git config --system user.email chv@localhost && git config --system credential.helper store && git config --system init.defaultBranch main'
|
||||||
--run-command "$GT_INSTALL_CMD"
|
--run-command "$GT_INSTALL_CMD"
|
||||||
--run-command '/usr/local/bin/gt version > /app/guest-versions-gt.txt'
|
--run-command '/usr/local/bin/gt version > /app/guest-versions-gt.txt'
|
||||||
@@ -286,6 +315,16 @@ VC_ARGS=(-a "$OUT/disk.raw"
|
|||||||
--run-command 'printf "[Unit]\nDescription=CHV cell broker (Muse P2)\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/python3 /usr/local/bin/chv-broker\nRestart=on-failure\nRestartSec=2\n\n[Install]\nWantedBy=multi-user.target\n" > /etc/systemd/system/chv-broker.service'
|
--run-command 'printf "[Unit]\nDescription=CHV cell broker (Muse P2)\nAfter=network.target\n\n[Service]\nType=simple\nExecStart=/usr/bin/python3 /usr/local/bin/chv-broker\nRestart=on-failure\nRestartSec=2\n\n[Install]\nWantedBy=multi-user.target\n" > /etc/systemd/system/chv-broker.service'
|
||||||
--run-command 'printf "[Unit]\nDescription=CHV browser sub-agent (Muse P2)\nAfter=network.target\n\n[Service]\nType=simple\nUser=chv-browser\nGroup=chv-browser\nExecStart=/usr/bin/python3 /usr/local/bin/chv-browser\nRestart=on-failure\nRestartSec=2\n\n[Install]\nWantedBy=multi-user.target\n" > /etc/systemd/system/chv-browser.service'
|
--run-command 'printf "[Unit]\nDescription=CHV browser sub-agent (Muse P2)\nAfter=network.target\n\n[Service]\nType=simple\nUser=chv-browser\nGroup=chv-browser\nExecStart=/usr/bin/python3 /usr/local/bin/chv-browser\nRestart=on-failure\nRestartSec=2\n\n[Install]\nWantedBy=multi-user.target\n" > /etc/systemd/system/chv-browser.service'
|
||||||
--run-command 'printf "d /run/chv 0755 root root -\nd /run/chv/shots 0755 chv-browser chv-browser -\n" > /etc/tmpfiles.d/chv.conf && systemctl enable chv-broker chv-browser || true')
|
--run-command 'printf "d /run/chv 0755 root root -\nd /run/chv/shots 0755 chv-browser chv-browser -\n" > /etc/tmpfiles.d/chv.conf && systemctl enable chv-broker chv-browser || true')
|
||||||
|
# P3 交接(Muse P3 的 authd/sentinel 叶子模块):文件在仓库里存在时
|
||||||
|
# 拷入镜像(本分支已有,合入后自动生效);不存在时只警告、不失败——
|
||||||
|
# M4 既定 build.sh 不硬要求 cloud/,见上。缺叶子模块时 chv-authd
|
||||||
|
# 守护进程起不来,chv-sync 按差距表 §3.5 回落旧路径并警告。
|
||||||
|
if [ "$P3_LIBS_PRESENT" = "1" ]; then
|
||||||
|
VC_ARGS+=(--copy-in "$REPO_DIR/cloud/chv/authd.py:/usr/local/lib/chv-authd/cloud/chv/"
|
||||||
|
--copy-in "$REPO_DIR/cloud/chv/sentinel.py:/usr/local/lib/chv-authd/cloud/chv/"
|
||||||
|
--copy-in "$REPO_DIR/cloud/__init__.py:/usr/local/lib/chv-authd/cloud/"
|
||||||
|
--copy-in "$REPO_DIR/cloud/chv/__init__.py:/usr/local/lib/chv-authd/cloud/chv/")
|
||||||
|
fi
|
||||||
# P1 交接(Muse P1 的 vsock_notify.py):文件在仓库里存在时拷入
|
# P1 交接(Muse P1 的 vsock_notify.py):文件在仓库里存在时拷入
|
||||||
# 镜像(P1 分支才有,本分支尚无);不存在时只警告、不失败——
|
# 镜像(P1 分支才有,本分支尚无);不存在时只警告、不失败——
|
||||||
# 合并后自动生效,P2 不改该脚本内容。
|
# 合并后自动生效,P2 不改该脚本内容。
|
||||||
@@ -356,7 +395,8 @@ else
|
|||||||
echo "警告:CHROMIUM_HEADLESS_SHELL_REV 未设,Chromium 版本只记录、不钉死(V-9 验收须设该变量重建)" >&2
|
echo "警告:CHROMIUM_HEADLESS_SHELL_REV 未设,Chromium 版本只记录、不钉死(V-9 验收须设该变量重建)" >&2
|
||||||
fi
|
fi
|
||||||
EXTRA_CONTENTS=""
|
EXTRA_CONTENTS=""
|
||||||
[ "$VSOCK_NOTIFY_PRESENT" = "1" ] && EXTRA_CONTENTS="vsock_notify"
|
[ "$P3_LIBS_PRESENT" = "1" ] && EXTRA_CONTENTS="cloud/chv/authd.py,cloud/chv/sentinel.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"
|
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
|
fi
|
||||||
echo "tag=$TAG"
|
echo "tag=$TAG"
|
||||||
|
|||||||
@@ -39,6 +39,12 @@ BASE_CONTENTS = [
|
|||||||
"/app/host.py", "gt", "chv-sync",
|
"/app/host.py", "gt", "chv-sync",
|
||||||
# 对齐 Muse P2:nspawn 单元启动器 + broker + 浏览器子代理。
|
# 对齐 Muse P2:nspawn 单元启动器 + broker + 浏览器子代理。
|
||||||
"systemd-container", "chv-cell", "chv-broker", "chv-browser",
|
"systemd-container", "chv-cell", "chv-broker", "chv-browser",
|
||||||
|
# 对齐 Muse P3(round-11 合入镜像):authd 守护进程 + git
|
||||||
|
# credential helper + systemd 单元(三件套是无条件拷入的)。
|
||||||
|
# 云端叶子模块(cloud/chv/authd.py、sentinel.py)不进 BASE:
|
||||||
|
# 它们是条件拷入(缺失只警告、不失败),存在时才经
|
||||||
|
# extra_contents 登记,绝不在缺失的构建里谎称已进镜像。
|
||||||
|
"chv-authd", "git-credential-chv-authd", "chv-authd.service",
|
||||||
]
|
]
|
||||||
|
|
||||||
# 执行器默认内核 cmdline(config.py),构建产物须与它一起记录(B-12),
|
# 执行器默认内核 cmdline(config.py),构建产物须与它一起记录(B-12),
|
||||||
|
|||||||
@@ -568,10 +568,19 @@ class BuildDryRunTest(unittest.TestCase):
|
|||||||
os.makedirs(os.path.join(bindir, "codex-resources"))
|
os.makedirs(os.path.join(bindir, "codex-resources"))
|
||||||
for name in ("build.sh", "buildinfo.py", "check_lockfile.py",
|
for name in ("build.sh", "buildinfo.py", "check_lockfile.py",
|
||||||
"generate_lockfile.py", "chv-sync.sh",
|
"generate_lockfile.py", "chv-sync.sh",
|
||||||
"chv-cell.py", "chv-broker.py", "chv-browser.py"):
|
"chv-cell.py", "chv-broker.py", "chv-browser.py",
|
||||||
|
"authd.py", "git-credential-chv-authd",
|
||||||
|
"chv-authd.service"):
|
||||||
shutil.copy2(ROOT / "chv-guest" / name,
|
shutil.copy2(ROOT / "chv-guest" / name,
|
||||||
os.path.join(guest, name))
|
os.path.join(guest, name))
|
||||||
shutil.copy2(ROOT / "host.py", os.path.join(repo, "host.py"))
|
shutil.copy2(ROOT / "host.py", os.path.join(repo, "host.py"))
|
||||||
|
# round-11:build.sh 要求 P3 云端叶子模块在仓里(fail-fast),
|
||||||
|
# 夹具须一并拷入,否则干跑在 P3 预检就失败。
|
||||||
|
for rel in ("cloud/chv/authd.py", "cloud/chv/sentinel.py",
|
||||||
|
"cloud/__init__.py", "cloud/chv/__init__.py"):
|
||||||
|
dest = os.path.join(repo, rel)
|
||||||
|
os.makedirs(os.path.dirname(dest), exist_ok=True)
|
||||||
|
shutil.copy2(ROOT / rel, dest)
|
||||||
codex = os.path.join(bindir, "codex")
|
codex = os.path.join(bindir, "codex")
|
||||||
with open(codex, "w") as fh:
|
with open(codex, "w") as fh:
|
||||||
fh.write("#!/bin/sh\necho 'codex-cli 0.164.0-alpha.9'\n")
|
fh.write("#!/bin/sh\necho 'codex-cli 0.164.0-alpha.9'\n")
|
||||||
@@ -606,7 +615,10 @@ class BuildDryRunTest(unittest.TestCase):
|
|||||||
for needle in ("systemd-container", "chv-cell", "chv-broker",
|
for needle in ("systemd-container", "chv-cell", "chv-broker",
|
||||||
"chv-browser", "chv-browser.service",
|
"chv-browser", "chv-browser.service",
|
||||||
"chv-broker.service", "useradd --system",
|
"chv-broker.service", "useradd --system",
|
||||||
"systemctl enable chv-broker chv-browser"):
|
"systemctl enable chv-broker chv-browser",
|
||||||
|
"chv-authd", "git-credential-chv-authd",
|
||||||
|
"systemctl enable chv-authd",
|
||||||
|
"systemctl start chv-authd"):
|
||||||
self.assertIn(needle, out, needle)
|
self.assertIn(needle, out, needle)
|
||||||
# P1 文件不在本分支:干跑只警告、不失败。
|
# P1 文件不在本分支:干跑只警告、不失败。
|
||||||
self.assertIn("vsock_notify.py 不在仓库里", out)
|
self.assertIn("vsock_notify.py 不在仓库里", out)
|
||||||
|
|||||||
Reference in new issue
Block a user