@lark-apaas/openclaw-scripts-diagnose-cli 0.1.15-alpha.11 → 0.1.15-alpha.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +180 -77
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -52,7 +52,7 @@ node_assert = __toESM(node_assert);
|
|
|
52
52
|
* it terse and parseable.
|
|
53
53
|
*/
|
|
54
54
|
function getVersion() {
|
|
55
|
-
return "0.1.15-alpha.
|
|
55
|
+
return "0.1.15-alpha.13";
|
|
56
56
|
}
|
|
57
57
|
//#endregion
|
|
58
58
|
//#region src/rule-engine/base.ts
|
|
@@ -1792,7 +1792,6 @@ let ToolsAllowAlsoAllowConflictRule = class ToolsAllowAlsoAllowConflictRule exte
|
|
|
1792
1792
|
validate(ctx) {
|
|
1793
1793
|
const conflicts = [];
|
|
1794
1794
|
visitAllScopes(ctx.config, (scope, label) => {
|
|
1795
|
-
console.error(`[tools_allow_also_allow_conflict] scope=${label} hasConflict=${hasConflict(scope)} allow=${JSON.stringify(scope.allow)?.slice(0, 40)} alsoAllow=${JSON.stringify(scope.alsoAllow)?.slice(0, 40)}`);
|
|
1796
1795
|
if (hasConflict(scope)) conflicts.push(label);
|
|
1797
1796
|
});
|
|
1798
1797
|
if (conflicts.length === 0) return { pass: true };
|
|
@@ -2635,6 +2634,12 @@ const SECRETS_FILE_PATH = "/home/gem/workspace/.force/openclaw/miaoda-openclaw-s
|
|
|
2635
2634
|
/** Absolute path to the openclaw config JSON. */
|
|
2636
2635
|
const CONFIG_PATH = `${WORKSPACE_DIR}/openclaw.json`;
|
|
2637
2636
|
/**
|
|
2637
|
+
* upgrade-lark 场景专属修复状态的信号文件目录。
|
|
2638
|
+
* fixStatus 有值时在此目录下创建同名文件(如 /tmp/event/PORT_FIX_READY),
|
|
2639
|
+
* 文件内容为完整的 UpgradeLarkResult JSON,供外部进程轮询感知升级结果。
|
|
2640
|
+
*/
|
|
2641
|
+
const FIX_EVENT_DIR = "/tmp/event";
|
|
2642
|
+
/**
|
|
2638
2643
|
* upgrade-lark 每次运行的日志文件路径,含时间戳便于按时间排序定位。
|
|
2639
2644
|
* checkOnly=true 时文件名含 "-check" 后缀,便于与正式安装日志区分。
|
|
2640
2645
|
*/
|
|
@@ -3314,6 +3319,13 @@ function execCaptureErr(cmd) {
|
|
|
3314
3319
|
throw new Error(stderrStr ? `${base}\nstderr: ${stderrStr}` : base);
|
|
3315
3320
|
}
|
|
3316
3321
|
}
|
|
3322
|
+
/**
|
|
3323
|
+
* Synchronous sleep using Atomics.wait on a shared buffer.
|
|
3324
|
+
* Works on the main thread (unlike setTimeout which requires an event loop tick).
|
|
3325
|
+
*/
|
|
3326
|
+
function sleepSync(ms) {
|
|
3327
|
+
Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
|
|
3328
|
+
}
|
|
3317
3329
|
/** POSIX single-quote shell escape. Paths with embedded quotes are rare but
|
|
3318
3330
|
* the token-file path conventions in sandboxes don't guarantee cleanliness. */
|
|
3319
3331
|
function shellQuote(s) {
|
|
@@ -7366,14 +7378,6 @@ function getResetTask(taskId) {
|
|
|
7366
7378
|
progress: "等待中..."
|
|
7367
7379
|
};
|
|
7368
7380
|
}
|
|
7369
|
-
/**
|
|
7370
|
-
* Synchronous sleep using Atomics.wait on a shared buffer.
|
|
7371
|
-
*/
|
|
7372
|
-
function sleepSync(ms) {
|
|
7373
|
-
const buf = new SharedArrayBuffer(4);
|
|
7374
|
-
const arr = new Int32Array(buf);
|
|
7375
|
-
Atomics.wait(arr, 0, 0, ms);
|
|
7376
|
-
}
|
|
7377
7381
|
//#endregion
|
|
7378
7382
|
//#region src/oss/resolveOssFileMap.ts
|
|
7379
7383
|
/**
|
|
@@ -10693,7 +10697,7 @@ async function reportCliRun(opts) {
|
|
|
10693
10697
|
//#region src/help.ts
|
|
10694
10698
|
const BIN = "mclaw-diagnose";
|
|
10695
10699
|
function versionBanner() {
|
|
10696
|
-
return `v0.1.15-alpha.
|
|
10700
|
+
return `v0.1.15-alpha.13`;
|
|
10697
10701
|
}
|
|
10698
10702
|
const COMMANDS = [
|
|
10699
10703
|
{
|
|
@@ -11289,14 +11293,16 @@ function reportDoctorRunToSlardar(opts) {
|
|
|
11289
11293
|
* ## extraCategories(字符串维度)
|
|
11290
11294
|
* - scene:调用方标识(如 PageUpgradeLark)
|
|
11291
11295
|
* - check_only:是否为 --check 仅诊断模式
|
|
11292
|
-
* -
|
|
11293
|
-
* - skip_reason
|
|
11294
|
-
* -
|
|
11295
|
-
* -
|
|
11296
|
-
* -
|
|
11297
|
-
* -
|
|
11298
|
-
* -
|
|
11299
|
-
* -
|
|
11296
|
+
* - status:与 UpgradeLarkResult.status 一致(success / skipped / failed)
|
|
11297
|
+
* - skip_reason:跳过原因(对应 UpgradeLarkResult.skipReason)
|
|
11298
|
+
* - upgrade_needed:仅 --check 模式,是否检测到需要升级(对应 UpgradeLarkResult.upgradeNeeded)
|
|
11299
|
+
* - exit_code:npx 子进程退出码(对应 UpgradeLarkResult.exitCode,跳过安装时为空)
|
|
11300
|
+
* - rollback_ok:回滚是否成功(对应 UpgradeLarkResult.rollbackOk,未触发回滚时为空)
|
|
11301
|
+
* - validation_error:安装后校验失败信息(对应 UpgradeLarkResult.validationError)
|
|
11302
|
+
* - error:命令级错误信息(对应 UpgradeLarkResult.error)
|
|
11303
|
+
* - port_check_ok:端口存活检测结果(对应 UpgradeLarkResult.portCheckOk,未执行时为空)
|
|
11304
|
+
* - result:执行结果一行摘要(派生字段,见 buildUpgradeLarkResultSummary)
|
|
11305
|
+
* - log_file:日志文件绝对路径(对应 UpgradeLarkResult.logFile)
|
|
11300
11306
|
*
|
|
11301
11307
|
* ## extraMetrics(数值指标,单位毫秒)
|
|
11302
11308
|
* 未执行的阶段上报 -1 作为哨兵值,便于与"运行了 0ms"区分。
|
|
@@ -11309,21 +11315,23 @@ function reportDoctorRunToSlardar(opts) {
|
|
|
11309
11315
|
* 注:[7/7] 重启耗时写入日志但未单独上报,包含在 durationMs 总耗时中。
|
|
11310
11316
|
*/
|
|
11311
11317
|
function reportUpgradeLarkToSlardar(opts) {
|
|
11312
|
-
console.error(`[slardar] upgrade_lark_run scene=${opts.scene ?? ""} checkOnly=${opts.checkOnly}
|
|
11318
|
+
console.error(`[slardar] upgrade_lark_run scene=${opts.scene ?? ""} checkOnly=${opts.checkOnly} status=${opts.resultStatus} exitCode=${opts.exitCode ?? ""} rollbackOk=${opts.rollbackOk ?? ""}`);
|
|
11313
11319
|
const t = opts.timing ?? {};
|
|
11314
11320
|
reportTask({
|
|
11315
11321
|
eventName: "upgrade_lark_run",
|
|
11316
11322
|
durationMs: opts.durationMs,
|
|
11317
|
-
status: opts.
|
|
11323
|
+
status: opts.resultStatus === "failed" || opts.upgradeNeeded ? "failed" : "success",
|
|
11318
11324
|
extraCategories: {
|
|
11319
11325
|
scene: opts.scene ?? "",
|
|
11320
11326
|
check_only: String(opts.checkOnly),
|
|
11321
|
-
|
|
11327
|
+
status: opts.resultStatus,
|
|
11322
11328
|
skip_reason: opts.skipReason ?? "",
|
|
11329
|
+
upgrade_needed: String(opts.upgradeNeeded ?? ""),
|
|
11323
11330
|
exit_code: String(opts.exitCode ?? ""),
|
|
11324
|
-
rollback_ok:
|
|
11331
|
+
rollback_ok: String(opts.rollbackOk ?? ""),
|
|
11325
11332
|
validation_error: opts.validationError ?? "",
|
|
11326
|
-
|
|
11333
|
+
error: opts.error ?? "",
|
|
11334
|
+
port_check_ok: String(opts.portCheckOk ?? ""),
|
|
11327
11335
|
result: opts.resultSummary,
|
|
11328
11336
|
log_file: opts.logFile
|
|
11329
11337
|
},
|
|
@@ -11333,7 +11341,8 @@ function reportUpgradeLarkToSlardar(opts) {
|
|
|
11333
11341
|
backup_ms: t.backupMs ?? -1,
|
|
11334
11342
|
npx_install_ms: t.npxInstallMs ?? -1,
|
|
11335
11343
|
post_probe_ms: t.postProbeMs ?? -1,
|
|
11336
|
-
doctor_fix_ms: t.doctorFixMs ?? -1
|
|
11344
|
+
doctor_fix_ms: t.doctorFixMs ?? -1,
|
|
11345
|
+
port_check_ms: t.portCheckMs ?? -1
|
|
11337
11346
|
}
|
|
11338
11347
|
});
|
|
11339
11348
|
}
|
|
@@ -11341,18 +11350,18 @@ function reportUpgradeLarkToSlardar(opts) {
|
|
|
11341
11350
|
* 将 upgrade-lark 运行结果归纳为一行摘要字符串,用于 Slardar result 字段。
|
|
11342
11351
|
*
|
|
11343
11352
|
* 格式:
|
|
11344
|
-
* "check: upgrade needed"
|
|
11345
|
-
* "check: no upgrade needed"
|
|
11353
|
+
* "check: upgrade needed" / "check: no upgrade needed"
|
|
11346
11354
|
* "skipped: <skipReason>"
|
|
11347
11355
|
* "success: upgrade installed"
|
|
11348
|
-
* "
|
|
11349
|
-
* "failed: <error>"
|
|
11356
|
+
* "failed: <error> (rolled back)" / "failed: <error> (rollback FAILED)"
|
|
11350
11357
|
*/
|
|
11351
|
-
function buildUpgradeLarkResultSummary(
|
|
11352
|
-
if (
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
11358
|
+
function buildUpgradeLarkResultSummary(result, checkOnly) {
|
|
11359
|
+
if (result.status === "skipped") {
|
|
11360
|
+
if (checkOnly) return result.upgradeNeeded ? "check: upgrade needed" : "check: no upgrade needed";
|
|
11361
|
+
return `skipped: ${result.skipReason ?? "pre-check gate"}`;
|
|
11362
|
+
}
|
|
11363
|
+
if (result.status === "success") return "success: upgrade installed";
|
|
11364
|
+
return `failed: ${result.error ?? result.validationError ?? "unknown error"}${result.rollbackOk === false ? " (rollback FAILED)" : result.rollbackOk ? " (rolled back)" : ""}`;
|
|
11356
11365
|
}
|
|
11357
11366
|
//#endregion
|
|
11358
11367
|
//#region src/upgrade-lark.ts
|
|
@@ -11492,6 +11501,82 @@ function probeChannels(label, log, timeoutMs) {
|
|
|
11492
11501
|
};
|
|
11493
11502
|
}
|
|
11494
11503
|
}
|
|
11504
|
+
/**
|
|
11505
|
+
* 根据 scene、最终状态和端口检测结果,计算场景专属修复状态。
|
|
11506
|
+
* scene 不在已知场景列表时返回 undefined。
|
|
11507
|
+
*/
|
|
11508
|
+
function computeFixStatus(scene, status, portCheckOk = void 0) {
|
|
11509
|
+
if (scene === "FromPreviewFailed") return status === "success" && portCheckOk !== false ? "PORT_FIX_READY" : "PORT_FIX_FAILED";
|
|
11510
|
+
if (scene === "FromChannelFailed") return status === "success" ? "CHANNEL_FIX_READY" : "CHANNEL_FIX_FAILED";
|
|
11511
|
+
}
|
|
11512
|
+
/**
|
|
11513
|
+
* 轮询端口检测脚本,确认 openclaw-gateway 在重启后监听指定端口。
|
|
11514
|
+
*
|
|
11515
|
+
* 逻辑:
|
|
11516
|
+
* 1. 先等待 initialWaitMs(让服务有时间完成重启)
|
|
11517
|
+
* 2. 循环执行 `bash ${BUILTIN_PATH}/tool/port_check.sh <port>`,至多 maxAttempts 次:
|
|
11518
|
+
* - 输出为空 → 服务尚未就绪,等 intervalMs 后重试
|
|
11519
|
+
* - 输出含端口号 → 端口存活,返回 ok=true
|
|
11520
|
+
* - 输出非空但不含端口号 → 端口异常,立即返回 ok=false
|
|
11521
|
+
* 3. 超过 maxAttempts 仍无响应 → 返回 ok=false
|
|
11522
|
+
*
|
|
11523
|
+
* 注意:${BUILTIN_PATH} 是沙箱 shell 环境变量,通过 `bash -c` 让 shell 自行展开,
|
|
11524
|
+
* Node 侧不读取、不拼接该路径。
|
|
11525
|
+
*/
|
|
11526
|
+
function pollPortCheck(opts) {
|
|
11527
|
+
const { port, initialWaitMs, intervalMs, maxAttempts, log } = opts;
|
|
11528
|
+
const portStr = String(port);
|
|
11529
|
+
const cmd = "bash ${BUILTIN_PATH}/tool/port_check.sh " + portStr;
|
|
11530
|
+
log(` waiting ${initialWaitMs / 1e3}s before first port-check poll...`);
|
|
11531
|
+
if (initialWaitMs > 0) sleepSync(initialWaitMs);
|
|
11532
|
+
for (let i = 1; i <= maxAttempts; i++) {
|
|
11533
|
+
const r = (0, node_child_process.spawnSync)("bash", ["-c", cmd], {
|
|
11534
|
+
encoding: "utf-8",
|
|
11535
|
+
stdio: [
|
|
11536
|
+
"ignore",
|
|
11537
|
+
"pipe",
|
|
11538
|
+
"pipe"
|
|
11539
|
+
],
|
|
11540
|
+
timeout: 1e4
|
|
11541
|
+
});
|
|
11542
|
+
const output = (r.stdout ?? "").trim();
|
|
11543
|
+
const errout = (r.stderr ?? "").trim();
|
|
11544
|
+
log(` port-check [${i}/${maxAttempts}]: exit=${r.status ?? "null"} output=${JSON.stringify(output)}${errout ? ` stderr=${JSON.stringify(errout)}` : ""}`);
|
|
11545
|
+
if (!output) {
|
|
11546
|
+
sleepSync(intervalMs);
|
|
11547
|
+
continue;
|
|
11548
|
+
}
|
|
11549
|
+
if (output.includes(portStr)) {
|
|
11550
|
+
log(` port-check: SUCCESS — port ${port} confirmed in output`);
|
|
11551
|
+
return {
|
|
11552
|
+
ok: true,
|
|
11553
|
+
output
|
|
11554
|
+
};
|
|
11555
|
+
}
|
|
11556
|
+
log(` port-check: FAILED — output non-empty but port ${port} not found`);
|
|
11557
|
+
return {
|
|
11558
|
+
ok: false,
|
|
11559
|
+
output
|
|
11560
|
+
};
|
|
11561
|
+
}
|
|
11562
|
+
log(` port-check: FAILED — no response after ${maxAttempts} attempts`);
|
|
11563
|
+
return { ok: false };
|
|
11564
|
+
}
|
|
11565
|
+
/**
|
|
11566
|
+
* 将 fixStatus 信号文件写入 /tmp/event/<fixStatus>,内容为完整的 UpgradeLarkResult JSON。
|
|
11567
|
+
* 外部进程(如服务端诊断流程)通过轮询此文件感知升级结果。
|
|
11568
|
+
* 写入失败只记录日志,不影响主流程返回值。
|
|
11569
|
+
*/
|
|
11570
|
+
function writeFixStatusEvent(fixStatus, result, log) {
|
|
11571
|
+
const filePath = `${FIX_EVENT_DIR}/${fixStatus}`;
|
|
11572
|
+
try {
|
|
11573
|
+
node_fs.default.mkdirSync(FIX_EVENT_DIR, { recursive: true });
|
|
11574
|
+
node_fs.default.writeFileSync(filePath, JSON.stringify(result, null, 2));
|
|
11575
|
+
log(`[fix-event] written: ${filePath}`);
|
|
11576
|
+
} catch (e) {
|
|
11577
|
+
log(`[fix-event] write failed: ${filePath} — ${e.message}`);
|
|
11578
|
+
}
|
|
11579
|
+
}
|
|
11495
11580
|
function runUpgradeLark(opts) {
|
|
11496
11581
|
const cwd = opts.cwd ?? "/home/gem/workspace/agent";
|
|
11497
11582
|
const configPath = opts.configPath ?? CONFIG_PATH;
|
|
@@ -11511,6 +11596,10 @@ function runUpgradeLark(opts) {
|
|
|
11511
11596
|
log(` configPath : ${configPath}`);
|
|
11512
11597
|
log(`${"=".repeat(60)}`);
|
|
11513
11598
|
const timing = {};
|
|
11599
|
+
const finalReturn = (r) => {
|
|
11600
|
+
if (r.fixStatus !== void 0) writeFixStatusEvent(r.fixStatus, r, log);
|
|
11601
|
+
return r;
|
|
11602
|
+
};
|
|
11514
11603
|
log("");
|
|
11515
11604
|
log("── [Pre-check A] channels probe(升级前)────────────────");
|
|
11516
11605
|
const t_preProbeStart = Date.now();
|
|
@@ -11549,14 +11638,14 @@ function runUpgradeLark(opts) {
|
|
|
11549
11638
|
log(`${"=".repeat(60)}`);
|
|
11550
11639
|
log("upgrade-lark skipped (pre-check gate)");
|
|
11551
11640
|
log(`${"=".repeat(60)}`);
|
|
11552
|
-
return {
|
|
11553
|
-
|
|
11554
|
-
skipped: true,
|
|
11641
|
+
return finalReturn({
|
|
11642
|
+
status: "skipped",
|
|
11555
11643
|
skipReason: reason,
|
|
11556
11644
|
upgradeNeeded: false,
|
|
11557
11645
|
timing,
|
|
11558
|
-
logFile
|
|
11559
|
-
|
|
11646
|
+
logFile,
|
|
11647
|
+
fixStatus: computeFixStatus(opts.scene, "skipped")
|
|
11648
|
+
});
|
|
11560
11649
|
}
|
|
11561
11650
|
if (beforeChannels.anyAccountWorking) {
|
|
11562
11651
|
const reason = "channels are working — upgrade not needed (issue detected but system is functional)";
|
|
@@ -11564,14 +11653,14 @@ function runUpgradeLark(opts) {
|
|
|
11564
11653
|
log(`${"=".repeat(60)}`);
|
|
11565
11654
|
log("upgrade-lark skipped (pre-check gate)");
|
|
11566
11655
|
log(`${"=".repeat(60)}`);
|
|
11567
|
-
return {
|
|
11568
|
-
|
|
11569
|
-
skipped: true,
|
|
11656
|
+
return finalReturn({
|
|
11657
|
+
status: "skipped",
|
|
11570
11658
|
skipReason: reason,
|
|
11571
11659
|
upgradeNeeded: false,
|
|
11572
11660
|
timing,
|
|
11573
|
-
logFile
|
|
11574
|
-
|
|
11661
|
+
logFile,
|
|
11662
|
+
fixStatus: computeFixStatus(opts.scene, "skipped")
|
|
11663
|
+
});
|
|
11575
11664
|
}
|
|
11576
11665
|
log(` PROCEED: requiresLarkUpgrade=true (version=${versionIncompatible}, feishuConfig=${feishuConfigInvalid}) AND channels not working → running upgrade`);
|
|
11577
11666
|
if (opts.checkOnly) {
|
|
@@ -11579,14 +11668,13 @@ function runUpgradeLark(opts) {
|
|
|
11579
11668
|
log(`${"=".repeat(60)}`);
|
|
11580
11669
|
log("upgrade-lark check complete");
|
|
11581
11670
|
log(`${"=".repeat(60)}`);
|
|
11582
|
-
return {
|
|
11583
|
-
|
|
11584
|
-
skipped: true,
|
|
11671
|
+
return finalReturn({
|
|
11672
|
+
status: "skipped",
|
|
11585
11673
|
skipReason: "check",
|
|
11586
11674
|
upgradeNeeded: true,
|
|
11587
11675
|
timing,
|
|
11588
11676
|
logFile
|
|
11589
|
-
};
|
|
11677
|
+
});
|
|
11590
11678
|
}
|
|
11591
11679
|
log("");
|
|
11592
11680
|
log("── [1/6] 文件备份 ────────────────────────────────────────");
|
|
@@ -11596,12 +11684,13 @@ function runUpgradeLark(opts) {
|
|
|
11596
11684
|
timing.backupMs = Date.now() - t_backupStart;
|
|
11597
11685
|
if (!backup.ok) {
|
|
11598
11686
|
log(`ERROR: ${backup.error}`);
|
|
11599
|
-
return {
|
|
11600
|
-
|
|
11687
|
+
return finalReturn({
|
|
11688
|
+
status: "failed",
|
|
11601
11689
|
error: backup.error,
|
|
11602
11690
|
timing,
|
|
11603
|
-
logFile
|
|
11604
|
-
|
|
11691
|
+
logFile,
|
|
11692
|
+
fixStatus: computeFixStatus(opts.scene, "failed")
|
|
11693
|
+
});
|
|
11605
11694
|
}
|
|
11606
11695
|
log("backup: ok");
|
|
11607
11696
|
logVersionSnapshot("before-versions", snapshotVersions(cwd, log), log);
|
|
@@ -11642,15 +11731,15 @@ function runUpgradeLark(opts) {
|
|
|
11642
11731
|
if (statusCheckDelayMs > 0) {
|
|
11643
11732
|
log("");
|
|
11644
11733
|
log(`── 等待 ${statusCheckDelayMs / 1e3}s(让 openclaw 服务完成重启) ─────────────`);
|
|
11645
|
-
|
|
11734
|
+
sleepSync(statusCheckDelayMs);
|
|
11646
11735
|
log("wait done");
|
|
11647
11736
|
}
|
|
11648
11737
|
const doRollback = (reason) => {
|
|
11649
11738
|
log(`ERROR: ${reason}`);
|
|
11650
11739
|
const rollbackOk = restoreFiles(fsOpts);
|
|
11651
11740
|
log(`rollback: ${rollbackOk ? "ok" : "FAILED"}`);
|
|
11652
|
-
return {
|
|
11653
|
-
|
|
11741
|
+
return finalReturn({
|
|
11742
|
+
status: "failed",
|
|
11654
11743
|
error: reason,
|
|
11655
11744
|
validationError: reason,
|
|
11656
11745
|
stdout: npxStdout,
|
|
@@ -11658,8 +11747,9 @@ function runUpgradeLark(opts) {
|
|
|
11658
11747
|
exitCode: npxExitCode,
|
|
11659
11748
|
rollbackOk,
|
|
11660
11749
|
timing,
|
|
11661
|
-
logFile
|
|
11662
|
-
|
|
11750
|
+
logFile,
|
|
11751
|
+
fixStatus: computeFixStatus(opts.scene, "failed")
|
|
11752
|
+
});
|
|
11663
11753
|
};
|
|
11664
11754
|
log("");
|
|
11665
11755
|
log("── [4/5] 安装后诊断校验 ─────────────────────────────────");
|
|
@@ -11711,8 +11801,9 @@ function runUpgradeLark(opts) {
|
|
|
11711
11801
|
if (fixResult.stderr?.trim()) log(`doctor(fix) stderr:\n${fixResult.stderr.trim()}`);
|
|
11712
11802
|
log(`doctor(fix) exit: ${fixResult.status ?? "null"}${fixResult.error ? ` error: ${fixResult.error.message}` : ""}`);
|
|
11713
11803
|
log("");
|
|
11714
|
-
log("── [7/
|
|
11804
|
+
log("── [7/8] 重启 openclaw 服务 ──────────────────────────────");
|
|
11715
11805
|
const restartScript = "/opt/force/bin/openclaw_scripts/restart.sh";
|
|
11806
|
+
let restartExecuted = false;
|
|
11716
11807
|
if (opts.skipRestart) log(" skipped: --skip-restart");
|
|
11717
11808
|
else if (node_fs.default.existsSync(restartScript)) {
|
|
11718
11809
|
const t_restart = Date.now();
|
|
@@ -11729,19 +11820,39 @@ function runUpgradeLark(opts) {
|
|
|
11729
11820
|
if (restartResult.stdout?.trim()) log(` restart stdout:\n${restartResult.stdout.trim()}`);
|
|
11730
11821
|
if (restartResult.stderr?.trim()) log(` restart stderr:\n${restartResult.stderr.trim()}`);
|
|
11731
11822
|
log(` restart.sh exit: ${restartResult.status ?? "null"} (${restartMs}ms)${restartResult.error ? ` error: ${restartResult.error.message}` : ""}`);
|
|
11823
|
+
restartExecuted = true;
|
|
11732
11824
|
} else log(` skipped: ${restartScript} not found`);
|
|
11733
11825
|
log("");
|
|
11826
|
+
log("── [8/8] 端口存活检测 ────────────────────────────────────");
|
|
11827
|
+
let portCheckOk;
|
|
11828
|
+
if (!restartExecuted) log(" skipped: restart was not executed");
|
|
11829
|
+
else {
|
|
11830
|
+
const t_portCheck = Date.now();
|
|
11831
|
+
const pcResult = pollPortCheck({
|
|
11832
|
+
port: 18789,
|
|
11833
|
+
initialWaitMs: opts.portCheckInitialWaitMs ?? 3e3,
|
|
11834
|
+
intervalMs: opts.portCheckIntervalMs ?? 1e3,
|
|
11835
|
+
maxAttempts: opts.portCheckMaxAttempts ?? 30,
|
|
11836
|
+
log
|
|
11837
|
+
});
|
|
11838
|
+
timing.portCheckMs = Date.now() - t_portCheck;
|
|
11839
|
+
portCheckOk = pcResult.ok;
|
|
11840
|
+
log(` port-check result: ${portCheckOk ? "ok" : "FAILED"} (${timing.portCheckMs}ms)`);
|
|
11841
|
+
}
|
|
11842
|
+
log("");
|
|
11734
11843
|
log(`${"=".repeat(60)}`);
|
|
11735
11844
|
log("upgrade-lark completed successfully");
|
|
11736
11845
|
log(`${"=".repeat(60)}`);
|
|
11737
|
-
return {
|
|
11738
|
-
|
|
11846
|
+
return finalReturn({
|
|
11847
|
+
status: "success",
|
|
11739
11848
|
stdout: npxStdout,
|
|
11740
11849
|
stderr: npxStderr,
|
|
11741
11850
|
exitCode: npxExitCode,
|
|
11851
|
+
portCheckOk,
|
|
11742
11852
|
timing,
|
|
11743
|
-
logFile
|
|
11744
|
-
|
|
11853
|
+
logFile,
|
|
11854
|
+
fixStatus: computeFixStatus(opts.scene, "success", portCheckOk)
|
|
11855
|
+
});
|
|
11745
11856
|
}
|
|
11746
11857
|
//#endregion
|
|
11747
11858
|
//#region src/index.ts
|
|
@@ -12248,24 +12359,16 @@ async function main() {
|
|
|
12248
12359
|
scene,
|
|
12249
12360
|
checkOnly,
|
|
12250
12361
|
durationMs: upgradeDurationMs,
|
|
12251
|
-
|
|
12252
|
-
|
|
12362
|
+
resultStatus: result.status,
|
|
12363
|
+
upgradeNeeded: result.upgradeNeeded,
|
|
12253
12364
|
skipReason: result.skipReason,
|
|
12254
12365
|
logFile: result.logFile,
|
|
12255
|
-
resultSummary: buildUpgradeLarkResultSummary(
|
|
12256
|
-
ok: result.ok,
|
|
12257
|
-
checkOnly,
|
|
12258
|
-
skipped: result.skipped,
|
|
12259
|
-
skipReason: result.skipReason,
|
|
12260
|
-
upgradeNeeded: result.upgradeNeeded,
|
|
12261
|
-
error: result.error,
|
|
12262
|
-
validationError: result.validationError,
|
|
12263
|
-
rollbackOk: result.rollbackOk
|
|
12264
|
-
}),
|
|
12366
|
+
resultSummary: buildUpgradeLarkResultSummary(result, checkOnly),
|
|
12265
12367
|
exitCode: result.exitCode,
|
|
12266
12368
|
rollbackOk: result.rollbackOk,
|
|
12267
12369
|
validationError: result.validationError,
|
|
12268
12370
|
error: result.error,
|
|
12371
|
+
portCheckOk: result.portCheckOk,
|
|
12269
12372
|
timing: result.timing
|
|
12270
12373
|
});
|
|
12271
12374
|
try {
|
|
@@ -12277,14 +12380,14 @@ async function main() {
|
|
|
12277
12380
|
durationMs: upgradeDurationMs,
|
|
12278
12381
|
caller: rc.caller,
|
|
12279
12382
|
traceId: rc.traceId,
|
|
12280
|
-
success: result.
|
|
12383
|
+
success: result.status !== "failed",
|
|
12281
12384
|
result,
|
|
12282
|
-
error: result.
|
|
12385
|
+
error: result.status === "failed" ? { message: result.error ?? "upgrade-lark failed" } : void 0
|
|
12283
12386
|
});
|
|
12284
12387
|
} catch (e) {
|
|
12285
12388
|
console.error(`[telemetry] reportCliRun failed: ${e.message}`);
|
|
12286
12389
|
}
|
|
12287
|
-
if (
|
|
12390
|
+
if (result.status === "failed" || checkOnly && result.upgradeNeeded) {
|
|
12288
12391
|
node_process.default.exitCode = 1;
|
|
12289
12392
|
return;
|
|
12290
12393
|
}
|
package/package.json
CHANGED