fix(deploy): 故障通知脚本的安装原来在 if 分支里(--skip-web 就不装)+ 判据 ③ 只验"在不在"
pi 读代码抓到的两处,实测确认: 1. `redeploy-gateway.sh` 的 `install … service-failure-notify.mjs` 夹在 `if [ "$SYNC_WEB" = 1 ] && [ -d …/dist/assets ]` 里(在 `[ OK ] 前端产物比源码新` 之后、`else` 之前)⇒ **`--skip-web`、或 `dist/assets` 不存在时运行时脚本根本不装**。 它跟前端产物没有任何关系,只是恰好被写进了同一支。后果:改了仓库里的通知脚本、 用 `--skip-web` 部署 ⇒ **生产还是旧的那份**。 已移出 if/else(并加 `install -d` / 安装失败的判失败 + exit 2)。 2. 判据 ③ 原先只判 `<isFile> && 有执行位`,不判**是哪一份** ⇒ 上一条的后果全绿。 现在比内容(与仓库 `deploy/service-failure-notify.mjs` 逐字节), 读不到仓库那份时**报"比不了"并判红**,不许当成"一致"。 —— 判据 ② 对 unit 本来就是比内容的,③ 该同形。 自检新增一条:★通知脚本内容与仓库不一致 ⇒ 必须红。 (探针第一版按**文件名**判两侧,而两条路径的文件名相同 (`deploy/service-failure-notify.mjs` vs `/opt/agentmail/bin/service-failure-notify.mjs`) ⇒ 两边返回同一个串、探针自己没分辨力。改成按哪一侧区分。) 现状实测:仓库与装机两份 sha256 相同(496 行),所以这是**盲区而非事故** —— pi 的措辞准确。自检 28 条全过;实跑 ③ 报"内容与仓库一致"。
This commit is contained in:
@ -816,6 +816,26 @@ export function checkLayout(inject = {}) {
|
||||
scriptOk = st.isFile() && (st.mode & 0o111) !== 0;
|
||||
if (!scriptOk) note = `${script} 缺执行位`;
|
||||
} catch { note = `${script} 不存在`; }
|
||||
// ★ 只判"在不在、有没有执行位"是不够的(pi 评审 2026-09-14):
|
||||
// **"仓库里改过、装的那份还是旧的"会是绿灯**,而判据 ② 对 unit 就是比内容的
|
||||
// ⇒ ③ 该同形。动作要紧:这个脚本是故障通知的落点,单元里引用的是 /opt 那份。
|
||||
if (scriptOk) {
|
||||
try {
|
||||
const repoCopy = join(REPO, 'deploy', 'service-failure-notify.mjs');
|
||||
const a = String(readFile(repoCopy, 'utf8'));
|
||||
const b = String(readFile(script, 'utf8'));
|
||||
if (a !== b) {
|
||||
scriptOk = false;
|
||||
note = `${script} 内容与仓库 deploy/service-failure-notify.mjs 不一致(重新部署即可对齐)`;
|
||||
} else {
|
||||
note = `${script}(内容与仓库一致)`;
|
||||
}
|
||||
} catch (e) {
|
||||
// 读不到仓库那份 ⇒ **比不了就说比不了**,不许当成"一致"
|
||||
scriptOk = false;
|
||||
note = `比不了内容:读不到 ${join(REPO, 'deploy', 'service-failure-notify.mjs')}(${e.code ?? e.message})`;
|
||||
}
|
||||
}
|
||||
push('故障通知脚本装在 /opt/agentmail/bin/ 且可执行', scriptOk, note);
|
||||
|
||||
// ④ 自有服务的 cwd / ExecStart 不得落在源码目录
|
||||
@ -1016,6 +1036,24 @@ export function layoutSelfCheck() {
|
||||
{ name: '★依赖树一致 ⇒ 绿,且说出比了几个包', ok: sameDeps?.ok === true && /2 个包/.test(sameDeps?.note ?? '') },
|
||||
{ name: '★依赖树版本变了 ⇒ 必须红', ok: diffDeps?.ok === false && /不一致/.test(diffDeps?.note ?? '') },
|
||||
{ name: '★一侧没有依赖树 ⇒ 必须红(不许当"未比"放过)', ok: missingDeps?.ok === false },
|
||||
// ③ 从"只判在不在"改成"比内容"之后,必须证明它真能发现内容不同(否则又是一条假绿)。
|
||||
// 探针:把仓库那份读成别的内容 ⇒ ③ 必须红。
|
||||
{
|
||||
name: '★通知脚本内容与仓库不一致 ⇒ 必须红',
|
||||
ok: byName(
|
||||
checkLayout({
|
||||
...fake({ '/etc/systemd/system': [], '/repo/systemd': [], '/opt/agentmail/bin/service-failure-notify.mjs': 'installed' }),
|
||||
// ⚠️ 两条路径的文件名**相同**(仓库 `deploy/service-failure-notify.mjs`
|
||||
// vs 装机 `/opt/agentmail/bin/service-failure-notify.mjs`),
|
||||
// 第一版探针按文件名判、两边返回同一个串 ⇒ 探针自己没分辨力、自检红。
|
||||
// 必须按**哪一侧**区分。
|
||||
readFile: p => (p.includes('/deploy/service-failure-notify.mjs')
|
||||
? 'REPO-COPY'
|
||||
: (p.endsWith('service-failure-notify.mjs') ? 'INSTALLED-COPY' : (() => { throw new Error('ENOENT'); })()))
|
||||
}),
|
||||
'故障通知脚本'
|
||||
)?.ok === false
|
||||
},
|
||||
{ name: '标准目录:.bak 里引用源码目录也必须判红', ok: unitRefCheck(badBak)?.ok === false },
|
||||
{ name: '标准目录:干净样本必须判绿', ok: unitRefCheck(good)?.ok === true },
|
||||
// 二进制那条两侧都要真:嵌了源码路径必须红,trimpath 的必须绿。
|
||||
|
||||
@ -100,13 +100,29 @@ if [ -d "$REPO/client/electron/src" ] && [ -d "$REPO/client/electron/dist" ]; th
|
||||
fi
|
||||
echo " [ OK ] 前端产物比源码新"
|
||||
fi
|
||||
install -d /opt/agentmail/bin
|
||||
install -m 0755 "$REPO/deploy/service-failure-notify.mjs" /opt/agentmail/bin/service-failure-notify.mjs
|
||||
else
|
||||
say "1. 跳过前端同步"
|
||||
[ "$SYNC_WEB" = 0 ] && ok "--skip-web" || warn "client/electron/dist 不存在,先跑 cd client/electron && npm run build"
|
||||
fi
|
||||
|
||||
# 运行时脚本必须装在安装根下 —— 单元/drop-in 里引用的是
|
||||
# /opt/agentmail/bin/service-failure-notify.mjs,不是仓库路径。
|
||||
# 漏了这一步,故障通知会在"仓库被挪走/改名"时静默失效(2026-09-14 修的就是这个)。
|
||||
#
|
||||
# ★ 这一段**必须在 if/else 之外**(pi 评审 2026-09-14 抓到,实测确认):
|
||||
# 它原先夹在 `if SYNC_WEB…` 分支里(在 `echo " [ OK ] 前端产物比源码新"` 之后、
|
||||
# `else` 之前),于是 `--skip-web`、或 `client/electron/dist/assets` 不存在时,
|
||||
# **运行时脚本根本不装** —— 而它跟前端产物没有任何关系,只是恰好被写进了同一支。
|
||||
# 后果是"改了仓库里的通知脚本、用 --skip-web 部署 ⇒ 生产还是旧的那份",
|
||||
# 而判据 ③ 只判"在不在、有没有执行位",不判**是哪一份** ⇒ 全绿。
|
||||
# (已把 ③ 一并改成比内容。)
|
||||
install -d /opt/agentmail/bin || { bad "建不了 /opt/agentmail/bin"; exit 2; }
|
||||
if ! install -m 0755 "$REPO/deploy/service-failure-notify.mjs" /opt/agentmail/bin/service-failure-notify.mjs; then
|
||||
bad "装不了故障通知脚本"
|
||||
exit 2
|
||||
fi
|
||||
ok "故障通知脚本已装到 /opt/agentmail/bin/"
|
||||
|
||||
# ---------------------------------------------------------------- 2 静态检查与测试
|
||||
say "2. 构建前检查"
|
||||
if [ "$DRY_RUN" = 1 ]; then
|
||||
|
||||
Reference in New Issue
Block a user