中控更新改为先同步 git pull 再重启,并修复前端已是最新时一直显示更新中。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-10-04 07:56:06 +08:00
parent 04c750f2dd
commit ea24149a55
4 changed files with 122 additions and 80 deletions
+40 -8
View File
@@ -64,22 +64,38 @@
el.className = "update-status" + (cls ? " " + cls : "");
}
async function waitRecover(versionUrl, beforeSha, statusEl, label) {
async function waitRecover(versionUrl, beforeSha, statusEl, label, opts) {
const options = opts || {};
const expectSha = options.expectSha || "";
const alreadyLatest = !!options.alreadyLatest;
let sawDown = false;
const maxTries = 45;
let stableOnline = 0;
const maxTries = 30;
for (let i = 0; i < maxTries; i++) {
await sleep(2000);
await sleep(1500);
const res = await fetchJson(versionUrl);
const v = res.data || {};
const online = res.httpOk && (v.ok !== false) && (v.online !== false);
if (!online) {
sawDown = true;
setStatus(statusEl, "已受理 → 等待上线… (" + (i + 1) + "/" + maxTries + ")", "pending");
stableOnline = 0;
setStatus(statusEl, "重启中 → 等待上线… (" + (i + 1) + "/" + maxTries + ")", "pending");
continue;
}
const afterSha = v.sha || "";
const afterShort = v.short_sha || (afterSha ? afterSha.slice(0, 7) : "");
const beforeShort = beforeSha ? String(beforeSha).slice(0, 7) : "";
if (expectSha && afterSha && afterSha === expectSha) {
setStatus(
statusEl,
(label || "更新完成") +
(beforeSha && beforeSha !== afterSha
? ": " + (beforeShort || "?") + " → " + (afterShort || "?")
: " " + (afterShort || "")),
"ok"
);
return v;
}
if (afterSha && beforeSha && afterSha !== beforeSha) {
setStatus(statusEl, (label || "更新完成") + ": " + (beforeShort || "?") + " → " + (afterShort || "?"), "ok");
return v;
@@ -94,9 +110,21 @@
);
return v;
}
setStatus(statusEl, "更新中… (" + (i + 1) + "/" + maxTries + ")", "pending");
stableOnline += 1;
// 重启很快时可能看不到掉线:连续在线数次且版本符合预期/未变 → 视为完成
if (stableOnline >= 4) {
if (alreadyLatest || (afterSha && beforeSha && afterSha === beforeSha)) {
setStatus(statusEl, "完成(已是最新 " + (afterShort || "") + ",进程已重启)", "ok");
return v;
}
if (expectSha && afterSha === expectSha) {
setStatus(statusEl, (label || "更新完成") + " " + (afterShort || ""), "ok");
return v;
}
}
setStatus(statusEl, "等待重启生效… (" + (i + 1) + "/" + maxTries + ")", "pending");
}
setStatus(statusEl, "超时未确认上线,请稍后刷新版本或查看 logs/hub_update.log", "err");
setStatus(statusEl, "超时未确认,请点「刷新版本」或查看 logs/hub_update.log", "err");
return null;
}
@@ -147,13 +175,17 @@
btn.disabled = false;
return;
}
setStatus(statusEl, "已受理 → 等待上线…", "pending");
setStatus(statusEl, data.msg || "已拉取,等待重启…", "pending");
try {
await waitRecover(
"/api/settings/update/hub/version",
beforeSha || data.before_sha || "",
statusEl,
"中控更新完成"
"中控更新完成",
{
expectSha: data.after_sha || "",
alreadyLatest: !data.changed,
}
);
await refreshHubVersion();
} finally {