@dsh-sup/dsh-core-linux-x64 0.1.6-BETA.5 → 0.1.6-BETA.7
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/core.cjs +404 -341
- package/package.json +1 -1
package/core.cjs
CHANGED
|
@@ -60,11 +60,7 @@ var require_exec = __commonJS({
|
|
|
60
60
|
function runAsync(bin, args, opts) {
|
|
61
61
|
const o = opts || {};
|
|
62
62
|
return new Promise((resolve) => {
|
|
63
|
-
|
|
64
|
-
if (!err) {
|
|
65
|
-
resolve({ ok: true, code: "0", stdout: String(stdout == null ? "" : stdout), stderr: String(stderr == null ? "" : stderr), timedOut: false, error: null });
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
63
|
+
const fail = (err) => {
|
|
68
64
|
if (o.logger && o.logger.warn) {
|
|
69
65
|
try {
|
|
70
66
|
o.logger.warn("[exec] (async) " + bin + " " + (args || []).join(" ").slice(0, 80) + " failed: " + (err && err.message || err));
|
|
@@ -75,12 +71,25 @@ var require_exec = __commonJS({
|
|
|
75
71
|
resolve({
|
|
76
72
|
ok: false,
|
|
77
73
|
code: err.status != null ? String(err.status) : null,
|
|
78
|
-
stdout: String(
|
|
79
|
-
stderr: String(
|
|
74
|
+
stdout: String(err.stdout || ""),
|
|
75
|
+
stderr: String(err.stderr || ""),
|
|
80
76
|
timedOut,
|
|
81
77
|
error: err && err.message ? String(err.message) : String(err)
|
|
82
78
|
});
|
|
83
|
-
}
|
|
79
|
+
};
|
|
80
|
+
try {
|
|
81
|
+
execFile(bin, args, Object.assign({}, options(o), { encoding: "utf8" }), (err, stdout, stderr) => {
|
|
82
|
+
if (!err) {
|
|
83
|
+
resolve({ ok: true, code: "0", stdout: String(stdout == null ? "" : stdout), stderr: String(stderr == null ? "" : stderr), timedOut: false, error: null });
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
err.stdout = stdout;
|
|
87
|
+
err.stderr = stderr;
|
|
88
|
+
fail(err);
|
|
89
|
+
});
|
|
90
|
+
} catch (e) {
|
|
91
|
+
fail(e);
|
|
92
|
+
}
|
|
84
93
|
});
|
|
85
94
|
}
|
|
86
95
|
function runOutAsync(bin, args, opts) {
|
|
@@ -503,15 +512,21 @@ var require_probe = __commonJS({
|
|
|
503
512
|
}
|
|
504
513
|
return null;
|
|
505
514
|
}
|
|
506
|
-
function
|
|
507
|
-
if (!Number.isInteger(pid) || pid <= 0) return
|
|
515
|
+
function probeAlive(pid) {
|
|
516
|
+
if (!Number.isInteger(pid) || pid <= 0) return "dead";
|
|
508
517
|
try {
|
|
509
518
|
process.kill(pid, 0);
|
|
510
|
-
return
|
|
519
|
+
return "alive";
|
|
511
520
|
} catch (e) {
|
|
512
|
-
|
|
521
|
+
const code = e && e.code;
|
|
522
|
+
if (code === "EPERM") return "alive";
|
|
523
|
+
if (code === "ESRCH") return "dead";
|
|
524
|
+
return "unknown";
|
|
513
525
|
}
|
|
514
526
|
}
|
|
527
|
+
function isAlive(pid) {
|
|
528
|
+
return probeAlive(pid) === "alive";
|
|
529
|
+
}
|
|
515
530
|
function isZombie(pid) {
|
|
516
531
|
if (!Number.isInteger(pid) || pid <= 0 || isWindows) return false;
|
|
517
532
|
if (isLinux) {
|
|
@@ -611,6 +626,7 @@ var require_probe = __commonJS({
|
|
|
611
626
|
readCmdline: readCmdline2,
|
|
612
627
|
pgrepList,
|
|
613
628
|
isAlive,
|
|
629
|
+
probeAlive,
|
|
614
630
|
isZombie
|
|
615
631
|
};
|
|
616
632
|
}
|
|
@@ -637,6 +653,7 @@ var require_pidlookup = __commonJS({
|
|
|
637
653
|
readCmdline: readCmdline2,
|
|
638
654
|
pgrepList,
|
|
639
655
|
isAlive,
|
|
656
|
+
probeAlive,
|
|
640
657
|
isZombie
|
|
641
658
|
} = require_probe();
|
|
642
659
|
var isLinux = process.platform === "linux";
|
|
@@ -659,6 +676,7 @@ var require_pidlookup = __commonJS({
|
|
|
659
676
|
module2.exports = {
|
|
660
677
|
findListeningPid,
|
|
661
678
|
isAlive,
|
|
679
|
+
probeAlive,
|
|
662
680
|
isZombie,
|
|
663
681
|
readCmdline: readCmdline2,
|
|
664
682
|
normCmdline,
|
|
@@ -929,7 +947,7 @@ var require_version = __commonJS({
|
|
|
929
947
|
var fs2 = require("node:fs");
|
|
930
948
|
var path2 = require("node:path");
|
|
931
949
|
function guardVersion() {
|
|
932
|
-
if (true) return String("0.1.6-BETA.
|
|
950
|
+
if (true) return String("0.1.6-BETA.7");
|
|
933
951
|
try {
|
|
934
952
|
return JSON.parse(fs2.readFileSync(path2.join(__dirname, "..", "..", "package.json"), "utf8")).version || "unknown";
|
|
935
953
|
} catch {
|
|
@@ -949,6 +967,8 @@ var require_main_record = __commonJS({
|
|
|
949
967
|
const reg = () => typeof g.getManagedObjects === "function" ? g.getManagedObjects() : null;
|
|
950
968
|
const logger = () => typeof g.getLogger === "function" ? g.getLogger() : null;
|
|
951
969
|
let fallback = null;
|
|
970
|
+
const DEFAULTS = { restartCount: 0, backoffLevel: 0, backoffUntil: null, crashWindowStart: null, crashWindowRestarts: 0 };
|
|
971
|
+
const buffered = /* @__PURE__ */ new Map();
|
|
952
972
|
function entryOf() {
|
|
953
973
|
const m = reg();
|
|
954
974
|
if (!m || typeof m.get !== "function") return null;
|
|
@@ -964,8 +984,8 @@ var require_main_record = __commonJS({
|
|
|
964
984
|
kind: "dsh",
|
|
965
985
|
id: "main",
|
|
966
986
|
name: "\u4E3B\u5B9E\u4F8B",
|
|
987
|
+
// 不带 guardian(B2-2/B2-3):目录 entry 形态已无该键,守护开关权威在 dsh-main.json。
|
|
967
988
|
desired: "running",
|
|
968
|
-
guardian: true,
|
|
969
989
|
ownership: { ports: [], rootPath: null, unit: null, daemonScript: null, processMode: "spawn", meta: null },
|
|
970
990
|
phase: "stopped",
|
|
971
991
|
lastObserved: null,
|
|
@@ -994,11 +1014,26 @@ var require_main_record = __commonJS({
|
|
|
994
1014
|
}
|
|
995
1015
|
}
|
|
996
1016
|
function storeOf() {
|
|
997
|
-
|
|
1017
|
+
const e = entryOf();
|
|
1018
|
+
if (!e) return fallbackEntryOf();
|
|
1019
|
+
if (buffered.size) flushBuffered(e);
|
|
1020
|
+
return e;
|
|
1021
|
+
}
|
|
1022
|
+
function flushBuffered(e) {
|
|
1023
|
+
let changed = false;
|
|
1024
|
+
for (const [k, v] of buffered) {
|
|
1025
|
+
if (k in DEFAULTS && e[k] === DEFAULTS[k] && e[k] !== v) {
|
|
1026
|
+
e[k] = v;
|
|
1027
|
+
changed = true;
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
buffered.clear();
|
|
1031
|
+
if (changed) persistCrashField();
|
|
998
1032
|
}
|
|
999
1033
|
function fieldOf(name, v, write) {
|
|
1000
1034
|
const e = storeOf();
|
|
1001
1035
|
if (write) {
|
|
1036
|
+
if (e === fallback && name in DEFAULTS) buffered.set(name, v);
|
|
1002
1037
|
if (e[name] !== v) {
|
|
1003
1038
|
e[name] = v;
|
|
1004
1039
|
persistCrashField();
|
|
@@ -1172,7 +1207,7 @@ var require_main_store = __commonJS({
|
|
|
1172
1207
|
if (!live) live = readDshMainFile();
|
|
1173
1208
|
if (corrupt && !(typeof m.remoteToken === "string" && m.remoteToken)) {
|
|
1174
1209
|
const l = logger();
|
|
1175
|
-
if (l && l.warn) l.warn("
|
|
1210
|
+
if (l && l.warn) l.warn("writeDshMain: \u6587\u4EF6\u635F\u574F\u6001\uFF0C\u62D2\u7EDD\u4EE5\u9ED8\u8BA4\u503C\u8986\u76D6\u5199\u56DE");
|
|
1176
1211
|
return;
|
|
1177
1212
|
}
|
|
1178
1213
|
corrupt = false;
|
|
@@ -1192,7 +1227,7 @@ var require_main_store = __commonJS({
|
|
|
1192
1227
|
writeAtomic(f, body, { mode: 384 });
|
|
1193
1228
|
} catch (e) {
|
|
1194
1229
|
const l = logger();
|
|
1195
|
-
if (l && l.warn) l.warn("
|
|
1230
|
+
if (l && l.warn) l.warn("writeDshMain: " + (e && e.message || e));
|
|
1196
1231
|
}
|
|
1197
1232
|
}
|
|
1198
1233
|
return { dshMainFile, registryFileName, readDshMain, readDshMainFile, writeDshMain };
|
|
@@ -1280,8 +1315,8 @@ var require_fields = __commonJS({
|
|
|
1280
1315
|
try {
|
|
1281
1316
|
if (m && typeof m.setPhase === "function" && record.entryOf() === e) {
|
|
1282
1317
|
if (e.phase !== ph) m.setPhase("main", ph);
|
|
1283
|
-
} else
|
|
1284
|
-
|
|
1318
|
+
} else {
|
|
1319
|
+
record.fieldOf("phase", ph, true);
|
|
1285
1320
|
}
|
|
1286
1321
|
} catch (e2) {
|
|
1287
1322
|
const l = logger();
|
|
@@ -1308,8 +1343,8 @@ var require_fields = __commonJS({
|
|
|
1308
1343
|
try {
|
|
1309
1344
|
if (m && typeof m.update === "function" && record.entryOf() === e) {
|
|
1310
1345
|
if (e.desired !== want) m.update("main", { desired: want });
|
|
1311
|
-
} else
|
|
1312
|
-
|
|
1346
|
+
} else {
|
|
1347
|
+
record.fieldOf("desired", want, true);
|
|
1313
1348
|
}
|
|
1314
1349
|
} catch (e2) {
|
|
1315
1350
|
const l = logger();
|
|
@@ -1511,6 +1546,7 @@ var require_desired = __commonJS({
|
|
|
1511
1546
|
const intents = () => typeof g.getIntents === "function" ? g.getIntents() : null;
|
|
1512
1547
|
const events = () => typeof g.getEvents === "function" ? g.getEvents() : null;
|
|
1513
1548
|
const configPath = () => typeof g.getConfigPath === "function" ? g.getConfigPath() : null;
|
|
1549
|
+
const configAliases = () => typeof g.getConfigAliases === "function" ? g.getConfigAliases() || [] : [];
|
|
1514
1550
|
const logger = () => typeof g.getLogger === "function" ? g.getLogger() : null;
|
|
1515
1551
|
const setCrashHalted = typeof g.setCrashHalted === "function" ? g.setCrashHalted : () => {
|
|
1516
1552
|
};
|
|
@@ -1592,7 +1628,9 @@ var require_desired = __commonJS({
|
|
|
1592
1628
|
}
|
|
1593
1629
|
}
|
|
1594
1630
|
Object.assign(cur, patch);
|
|
1595
|
-
|
|
1631
|
+
for (const [from, to] of configAliases()) {
|
|
1632
|
+
if (cur[from] !== void 0 && cur[to] !== void 0) delete cur[from];
|
|
1633
|
+
}
|
|
1596
1634
|
writeAtomic(p, JSON.stringify(cur, null, 2), { mode: 384 });
|
|
1597
1635
|
return true;
|
|
1598
1636
|
} catch (e) {
|
|
@@ -1741,6 +1779,7 @@ var require_collaborator = __commonJS({
|
|
|
1741
1779
|
getIntents: g.getIntents,
|
|
1742
1780
|
getEvents: g.getEvents,
|
|
1743
1781
|
getConfigPath: g.getConfigPath,
|
|
1782
|
+
getConfigAliases: g.getConfigAliases,
|
|
1744
1783
|
getLogger: logger,
|
|
1745
1784
|
setCrashHalted: g.setCrashHalted,
|
|
1746
1785
|
setManualRestart: g.setManualRestart,
|
|
@@ -2022,13 +2061,11 @@ var require_specs = __commonJS({
|
|
|
2022
2061
|
const daemons = () => typeof g.getDaemons === "function" ? g.getDaemons() : null;
|
|
2023
2062
|
const logger = () => typeof g.getLogger === "function" ? g.getLogger() : null;
|
|
2024
2063
|
function mainSpec() {
|
|
2025
|
-
const m = state().readMainMeta();
|
|
2026
2064
|
return {
|
|
2027
2065
|
kind: "dsh",
|
|
2028
2066
|
id: "main",
|
|
2029
2067
|
name: "\u4E3B\u5B9E\u4F8B",
|
|
2030
2068
|
desired: state().desired() === "stopped" ? "stopped" : "running",
|
|
2031
|
-
guardian: m.guardian === true,
|
|
2032
2069
|
ownership: {
|
|
2033
2070
|
ports: [{ role: "dsh-main", port: Number(config().targetPort || 3080) }],
|
|
2034
2071
|
rootPath: path2.join(os2.homedir(), ".dsh"),
|
|
@@ -2048,8 +2085,6 @@ var require_specs = __commonJS({
|
|
|
2048
2085
|
kind: "sandbox-instance",
|
|
2049
2086
|
id: inst.id,
|
|
2050
2087
|
name: String(inst.name || inst.id),
|
|
2051
|
-
desired: inst.state && inst.state.desired === "stopped" ? "stopped" : "running",
|
|
2052
|
-
guardian: inst.guardian === true,
|
|
2053
2088
|
ownership: {
|
|
2054
2089
|
ports: [{ role: "inst", port: Number(inst.port) }],
|
|
2055
2090
|
rootPath,
|
|
@@ -2063,7 +2098,7 @@ var require_specs = __commonJS({
|
|
|
2063
2098
|
if (!m || !spec) return;
|
|
2064
2099
|
try {
|
|
2065
2100
|
const existing = m.get(spec.id);
|
|
2066
|
-
if (existing) m.update(spec.id, { desired: spec.desired,
|
|
2101
|
+
if (existing) m.update(spec.id, { desired: spec.desired, name: spec.name, ownership: spec.ownership });
|
|
2067
2102
|
else m.register(spec);
|
|
2068
2103
|
} catch (e) {
|
|
2069
2104
|
const l = logger();
|
|
@@ -2985,10 +3020,6 @@ var require_facades = __commonJS({
|
|
|
2985
3020
|
_makeRouterFacade() {
|
|
2986
3021
|
const client = createCtlClient({ getConfig: () => this.config });
|
|
2987
3022
|
return createRouterCtlFacade({ getRouterPort: client.routerCtlPort, ctlCall: client.ctlCall });
|
|
2988
|
-
},
|
|
2989
|
-
_makeCtlFacade(port) {
|
|
2990
|
-
const client = createCtlClient({ getConfig: () => this.config });
|
|
2991
|
-
return createCtlFacade({ port, ctlCall: client.ctlCall });
|
|
2992
3023
|
}
|
|
2993
3024
|
};
|
|
2994
3025
|
module2.exports = { createCtlFacade, createRouterCtlFacade, methods };
|
|
@@ -3172,6 +3203,14 @@ var require_store2 = __commonJS({
|
|
|
3172
3203
|
}
|
|
3173
3204
|
return out;
|
|
3174
3205
|
}
|
|
3206
|
+
function fileStamp(file) {
|
|
3207
|
+
try {
|
|
3208
|
+
const st = fs2.statSync(file);
|
|
3209
|
+
return st.mtimeMs + ":" + st.size;
|
|
3210
|
+
} catch {
|
|
3211
|
+
return "0";
|
|
3212
|
+
}
|
|
3213
|
+
}
|
|
3175
3214
|
function saveRecords(file, records) {
|
|
3176
3215
|
try {
|
|
3177
3216
|
fs2.mkdirSync(path2.dirname(file), { recursive: true });
|
|
@@ -3197,7 +3236,7 @@ var require_store2 = __commonJS({
|
|
|
3197
3236
|
}
|
|
3198
3237
|
return out;
|
|
3199
3238
|
}
|
|
3200
|
-
module2.exports = { loadRecords, saveRecords, extraRecords };
|
|
3239
|
+
module2.exports = { loadRecords, saveRecords, extraRecords, fileStamp };
|
|
3201
3240
|
}
|
|
3202
3241
|
});
|
|
3203
3242
|
|
|
@@ -3440,6 +3479,7 @@ var require_alloc = __commonJS({
|
|
|
3440
3479
|
}
|
|
3441
3480
|
r._allocLock = true;
|
|
3442
3481
|
this._xrel = await this._acquireXLock();
|
|
3482
|
+
r._syncFromDisk();
|
|
3443
3483
|
}
|
|
3444
3484
|
_releaseAlloc() {
|
|
3445
3485
|
this._registry._allocLock = false;
|
|
@@ -3694,6 +3734,14 @@ var require_pool = __commonJS({
|
|
|
3694
3734
|
_load() {
|
|
3695
3735
|
this._records = /* @__PURE__ */ new Map();
|
|
3696
3736
|
for (const r of store.loadRecords(this._file)) this._records.set(r.port, r);
|
|
3737
|
+
this._diskStamp = store.fileStamp(this._file);
|
|
3738
|
+
}
|
|
3739
|
+
/** 跨进程对时(B2-5):ports.json 是多进程(守卫 + lan-daemon)共享事实源,各方全量
|
|
3740
|
+
* read-modify-write,陈旧内存快照会在 _save 时把他人新增整段覆盖丢失、或让分配器抢注
|
|
3741
|
+
* 他进程已登记的端口。指纹(mtime+size)变化即重载——所有写口与冲突判读口的入口。
|
|
3742
|
+
* 不动 _allocLock(复位会击穿本进程在飞分配的互斥)。 */
|
|
3743
|
+
_syncFromDisk() {
|
|
3744
|
+
if (store.fileStamp(this._file) !== this._diskStamp) this._load();
|
|
3697
3745
|
}
|
|
3698
3746
|
/** 重新从文件加载(读路径先 reload,以权威文件为准)。 */
|
|
3699
3747
|
reload() {
|
|
@@ -3703,6 +3751,7 @@ var require_pool = __commonJS({
|
|
|
3703
3751
|
}
|
|
3704
3752
|
_save() {
|
|
3705
3753
|
store.saveRecords(this._file, [...this._records.values()]);
|
|
3754
|
+
this._diskStamp = store.fileStamp(this._file);
|
|
3706
3755
|
}
|
|
3707
3756
|
/** 通用记录迁移:owner 命中任一前缀的记录 oldFile 到 newFile,并从旧文件清除。 */
|
|
3708
3757
|
migrateByOwnerPrefix(oldFile, newFile, prefixes) {
|
|
@@ -3711,6 +3760,7 @@ var require_pool = __commonJS({
|
|
|
3711
3760
|
/* 登记(固定 / 用户 / 动态) */
|
|
3712
3761
|
/** 登记固定端口;同端口已被其它固定角色占用则报错;user/动态记录由固定权威覆盖。 */
|
|
3713
3762
|
register(role, port) {
|
|
3763
|
+
this._syncFromDisk();
|
|
3714
3764
|
const p = Number(port);
|
|
3715
3765
|
if (!Number.isInteger(p) || p <= 0 || p > 65535) throw new Error("ports.register: \u975E\u6CD5\u7AEF\u53E3 " + port);
|
|
3716
3766
|
const existing = this._records.get(p);
|
|
@@ -3737,6 +3787,7 @@ var require_pool = __commonJS({
|
|
|
3737
3787
|
}
|
|
3738
3788
|
/** 登记用户配置端口(实例内部端口等);冲突(固定/保留池/已占)抛错。 */
|
|
3739
3789
|
registerUser(port, owner) {
|
|
3790
|
+
this._syncFromDisk();
|
|
3740
3791
|
const p = Number(port);
|
|
3741
3792
|
if (!Number.isInteger(p) || p <= 0 || p > 65535) throw new Error("ports.registerUser: \u975E\u6CD5\u7AEF\u53E3 " + port);
|
|
3742
3793
|
if (this._records.has(p)) throw new Error("\u7AEF\u53E3 " + p + " \u5DF2\u88AB [" + this._records.get(p).role + "] \u5360\u7528");
|
|
@@ -3748,6 +3799,7 @@ var require_pool = __commonJS({
|
|
|
3748
3799
|
}
|
|
3749
3800
|
/** 按 owner 释放端口(对象删除/关闭时调用)。 */
|
|
3750
3801
|
unregister(owner) {
|
|
3802
|
+
this._syncFromDisk();
|
|
3751
3803
|
let removed = false;
|
|
3752
3804
|
for (const [p, r] of this._records) {
|
|
3753
3805
|
if (r.owner === owner) {
|
|
@@ -3760,6 +3812,7 @@ var require_pool = __commonJS({
|
|
|
3760
3812
|
/** 释放端口:不传 ownerId 按端口号;传了则仅当登记 owner 匹配才释放。空值检查必须先于 owner 比较。
|
|
3761
3813
|
* @returns {boolean} 是否真的释放了一条记录 */
|
|
3762
3814
|
release(port, ownerId) {
|
|
3815
|
+
this._syncFromDisk();
|
|
3763
3816
|
const p = Number(port);
|
|
3764
3817
|
const rec = this._records.get(p);
|
|
3765
3818
|
if (!rec) return false;
|
|
@@ -3772,6 +3825,7 @@ var require_pool = __commonJS({
|
|
|
3772
3825
|
/** 按 role 取端口(固定端口)。同 role 有多条(老版本避让留下的残留记录)时取**最新登记**:
|
|
3773
3826
|
* 桌面壳读 ports.json 用的是同一判据,两侧不许对「哪个端口是当前的」给出不同答案。 */
|
|
3774
3827
|
get(role) {
|
|
3828
|
+
this._syncFromDisk();
|
|
3775
3829
|
let best = null;
|
|
3776
3830
|
for (const r of this._records.values()) {
|
|
3777
3831
|
if (r.role !== role) continue;
|
|
@@ -3780,12 +3834,15 @@ var require_pool = __commonJS({
|
|
|
3780
3834
|
return best ? best.port : null;
|
|
3781
3835
|
}
|
|
3782
3836
|
isRegistered(port) {
|
|
3837
|
+
this._syncFromDisk();
|
|
3783
3838
|
return this._records.has(Number(port));
|
|
3784
3839
|
}
|
|
3785
3840
|
recordOf(port) {
|
|
3841
|
+
this._syncFromDisk();
|
|
3786
3842
|
return this._records.get(Number(port)) || null;
|
|
3787
3843
|
}
|
|
3788
3844
|
byOwner(owner) {
|
|
3845
|
+
this._syncFromDisk();
|
|
3789
3846
|
for (const r of this._records.values()) if (r.owner === owner) return r.port;
|
|
3790
3847
|
return null;
|
|
3791
3848
|
}
|
|
@@ -3798,6 +3855,7 @@ var require_pool = __commonJS({
|
|
|
3798
3855
|
}
|
|
3799
3856
|
/** 全部端口清单(按端口升序)。 */
|
|
3800
3857
|
list() {
|
|
3858
|
+
this._syncFromDisk();
|
|
3801
3859
|
return [...this._records.values()].sort((a, b) => a.port - b.port);
|
|
3802
3860
|
}
|
|
3803
3861
|
/** 只读聚合:本注册表 + 同目录下其它注册表文件(去重,本表优先)。
|
|
@@ -3822,6 +3880,7 @@ var require_pool = __commonJS({
|
|
|
3822
3880
|
}
|
|
3823
3881
|
/** 显式登记已分配端口(复用持久化端口时调用)。 */
|
|
3824
3882
|
allocateMark(port, role, owner) {
|
|
3883
|
+
this._syncFromDisk();
|
|
3825
3884
|
const p = Number(port);
|
|
3826
3885
|
if (!this._records.has(p)) {
|
|
3827
3886
|
this._records.set(p, { port: p, role: role || "dynamic", owner: owner || "dynamic", createdAt: Date.now() });
|
|
@@ -3943,27 +4002,7 @@ var require_orphan_scan = __commonJS({
|
|
|
3943
4002
|
logger && logger.warn && logger.warn("[orphan] \u81EA\u68C0\u5F02\u5E38: " + (e && e.message || e));
|
|
3944
4003
|
}
|
|
3945
4004
|
}
|
|
3946
|
-
|
|
3947
|
-
return orphanAudit({
|
|
3948
|
-
getConfig: () => this.config,
|
|
3949
|
-
getLogger: () => this.logger,
|
|
3950
|
-
getEvents: () => this.events,
|
|
3951
|
-
getInstances: () => this.instances,
|
|
3952
|
-
getManagedObjects: () => this.managedObjects,
|
|
3953
|
-
getCtl: () => this.ctl,
|
|
3954
|
-
getDaemons: () => this.daemons,
|
|
3955
|
-
getStopping: () => this._stopping,
|
|
3956
|
-
getLastKey: () => this._lastOrphanKey,
|
|
3957
|
-
setLastKey: (v) => {
|
|
3958
|
-
this._lastOrphanKey = v;
|
|
3959
|
-
},
|
|
3960
|
-
getLastAt: () => this._lastOrphanAt,
|
|
3961
|
-
setLastAt: (v) => {
|
|
3962
|
-
this._lastOrphanAt = v;
|
|
3963
|
-
}
|
|
3964
|
-
});
|
|
3965
|
-
}
|
|
3966
|
-
module2.exports = { methods: { _orphanAudit: hostOrphanAudit }, orphanAudit };
|
|
4005
|
+
module2.exports = { orphanAudit };
|
|
3967
4006
|
}
|
|
3968
4007
|
});
|
|
3969
4008
|
|
|
@@ -4016,6 +4055,7 @@ var require_collaborators = __commonJS({
|
|
|
4016
4055
|
var { createCtl } = require_collaborator3();
|
|
4017
4056
|
var { createOrphanScan } = require_collaborator4();
|
|
4018
4057
|
var { ENTRY_FIELDS, PROC_FIELDS } = require_field_tables();
|
|
4058
|
+
var { aliases: CONFIG_ALIASES } = require_domain_config();
|
|
4019
4059
|
var THIN_SPEC = {
|
|
4020
4060
|
ctl: {
|
|
4021
4061
|
call: "_ctlCall",
|
|
@@ -4068,7 +4108,6 @@ var require_collaborators = __commonJS({
|
|
|
4068
4108
|
routerStatus: "routerStatus",
|
|
4069
4109
|
status: "statusSummary"
|
|
4070
4110
|
},
|
|
4071
|
-
audit: { orphan: "_orphanAudit" },
|
|
4072
4111
|
ui: { notify: "notify" }
|
|
4073
4112
|
};
|
|
4074
4113
|
var THIN_NAMES = Object.keys(THIN_SPEC);
|
|
@@ -4105,6 +4144,7 @@ var require_collaborators = __commonJS({
|
|
|
4105
4144
|
const state = createStateStore({
|
|
4106
4145
|
getConfig: () => host2.config,
|
|
4107
4146
|
getConfigPath: () => host2.configPath,
|
|
4147
|
+
getConfigAliases: () => CONFIG_ALIASES,
|
|
4108
4148
|
getLogger: () => host2.logger,
|
|
4109
4149
|
getEvents: () => host2.events,
|
|
4110
4150
|
getManagedObjects: () => host2.managedObjects,
|
|
@@ -4150,7 +4190,6 @@ var require_collaborators = __commonJS({
|
|
|
4150
4190
|
return host2;
|
|
4151
4191
|
};
|
|
4152
4192
|
host2._dshEntry = () => state.dshEntry();
|
|
4153
|
-
host2._mainFallbackEntry = () => state.fallbackEntry();
|
|
4154
4193
|
host2._persistCrashField = () => state.persistCrashField();
|
|
4155
4194
|
host2._mStore = () => state.store();
|
|
4156
4195
|
host2._mField = function(name, v) {
|
|
@@ -4163,7 +4202,6 @@ var require_collaborators = __commonJS({
|
|
|
4163
4202
|
host2._registryFileName = () => state.registryFileName();
|
|
4164
4203
|
host2._readDshMain = () => state.readMainMeta();
|
|
4165
4204
|
host2._readDshMainFile = () => state.readMainMetaFile();
|
|
4166
|
-
host2._writeDshMain = (meta) => state.writeMainMeta(meta);
|
|
4167
4205
|
host2.writeState = (force) => state.write(force);
|
|
4168
4206
|
host2.loadState = () => state.loadState();
|
|
4169
4207
|
host2._migrateMainRecord = () => state.migrateMainRecord();
|
|
@@ -7817,8 +7855,8 @@ var require_instance_adapter = __commonJS({
|
|
|
7817
7855
|
return { ok: running, error: running ? null : "\u6C99\u7BB1\u5B9E\u4F8B\u672A\u8FD0\u884C" };
|
|
7818
7856
|
},
|
|
7819
7857
|
/** 目录项 <- 实例域状态对齐(监督拍后调用):实例已删 -> 注销(防死登记);存在 -> 经
|
|
7820
|
-
* sandboxSpec 同步 name/guardian/ownership + phase
|
|
7821
|
-
*
|
|
7858
|
+
* sandboxSpec 同步 name/guardian/ownership + phase 落目录词表。沙箱不申报 desired
|
|
7859
|
+
* (运行意图无第二落点,B2-1),观测路径因此不可能改写任何意图。 */
|
|
7822
7860
|
_syncSandboxRegistryEntry(entry) {
|
|
7823
7861
|
const d = depsOf(this);
|
|
7824
7862
|
if (!entry || !d.managedObjects() || !d.instances()) return;
|
|
@@ -7851,6 +7889,9 @@ var require_decide = __commonJS({
|
|
|
7851
7889
|
"src/app/main/decide.js"(exports2, module2) {
|
|
7852
7890
|
"use strict";
|
|
7853
7891
|
var pidlook = require_pidlookup();
|
|
7892
|
+
function startDeadlinePassed(deadline, now) {
|
|
7893
|
+
return !!(deadline && now > deadline);
|
|
7894
|
+
}
|
|
7854
7895
|
var DEPS = /* @__PURE__ */ new WeakMap();
|
|
7855
7896
|
function depsOf(host2) {
|
|
7856
7897
|
let d = DEPS.get(host2);
|
|
@@ -7938,7 +7979,7 @@ var require_decide = __commonJS({
|
|
|
7938
7979
|
upgradeHold: d.upgradeHold() === true,
|
|
7939
7980
|
manualRestart: d.manualRestart() === true,
|
|
7940
7981
|
spawnBlocked: !!(d.mSpawnBlockedUntil() && now < d.mSpawnBlockedUntil()),
|
|
7941
|
-
startDeadlinePassed:
|
|
7982
|
+
startDeadlinePassed: startDeadlinePassed(d.mStartDeadline(), now),
|
|
7942
7983
|
restartDue: d.mRestartAt() === null || now >= d.mRestartAt(),
|
|
7943
7984
|
backoffDue: d.mBackoffUntil() === null || now >= d.mBackoffUntil(),
|
|
7944
7985
|
// `_shouldRun()` 有两个否决位,快照必须建模(crashHalted/sessionHalting),否则影子每拍
|
|
@@ -8013,7 +8054,9 @@ var require_decide = __commonJS({
|
|
|
8013
8054
|
_decideCrashRestart(reason) {
|
|
8014
8055
|
return decideCrashRestart(reason);
|
|
8015
8056
|
}
|
|
8016
|
-
}
|
|
8057
|
+
},
|
|
8058
|
+
// 非 host 方法:纯谓词导出,controller 与本文件快照判据共用(facets 只安装 methods)。
|
|
8059
|
+
startDeadlinePassed
|
|
8017
8060
|
};
|
|
8018
8061
|
}
|
|
8019
8062
|
});
|
|
@@ -8064,6 +8107,7 @@ var require_controller = __commonJS({
|
|
|
8064
8107
|
"use strict";
|
|
8065
8108
|
var pidlook = require_pidlookup();
|
|
8066
8109
|
var monitor = require_monitor();
|
|
8110
|
+
var { startDeadlinePassed } = require_decide();
|
|
8067
8111
|
var DEPS = /* @__PURE__ */ new WeakMap();
|
|
8068
8112
|
function depsOf(host2) {
|
|
8069
8113
|
let d = DEPS.get(host2);
|
|
@@ -8168,6 +8212,9 @@ var require_controller = __commonJS({
|
|
|
8168
8212
|
mStartDeadline() {
|
|
8169
8213
|
return host2._mStartDeadline();
|
|
8170
8214
|
},
|
|
8215
|
+
mSetStartDeadline(v) {
|
|
8216
|
+
return host2._mSetStartDeadline(v);
|
|
8217
|
+
},
|
|
8171
8218
|
mRestartAt() {
|
|
8172
8219
|
return host2._mRestartAt();
|
|
8173
8220
|
},
|
|
@@ -8315,7 +8362,9 @@ var require_controller = __commonJS({
|
|
|
8315
8362
|
}
|
|
8316
8363
|
case "STARTING": {
|
|
8317
8364
|
if (portUp && healthOk) d.main().enterRunning();
|
|
8318
|
-
else if (
|
|
8365
|
+
else if (d.mStartDeadline() === null) {
|
|
8366
|
+
d.mSetStartDeadline(Date.now() + d.config().startTimeoutMs);
|
|
8367
|
+
} else if (startDeadlinePassed(d.mStartDeadline(), Date.now())) d.main().beginRestart("start_timeout", { countCrash: true });
|
|
8319
8368
|
break;
|
|
8320
8369
|
}
|
|
8321
8370
|
case "RUNNING": {
|
|
@@ -9569,13 +9618,7 @@ var require_process_wait = __commonJS({
|
|
|
9569
9618
|
async function waitProcessExit(pid, timeoutMs) {
|
|
9570
9619
|
const deadline = Date.now() + timeoutMs;
|
|
9571
9620
|
while (Date.now() < deadline) {
|
|
9572
|
-
|
|
9573
|
-
try {
|
|
9574
|
-
alive = pidlook.isAlive ? pidlook.isAlive(pid) : true;
|
|
9575
|
-
} catch {
|
|
9576
|
-
alive = false;
|
|
9577
|
-
}
|
|
9578
|
-
if (!alive) return true;
|
|
9621
|
+
if (!pidlook.isAlive(pid)) return true;
|
|
9579
9622
|
await new Promise((r) => setTimeout(r, 200));
|
|
9580
9623
|
}
|
|
9581
9624
|
return false;
|
|
@@ -9693,13 +9736,15 @@ var require_process3 = __commonJS({
|
|
|
9693
9736
|
} catch {
|
|
9694
9737
|
}
|
|
9695
9738
|
}
|
|
9739
|
+
/** 判活(platform/pidlookup.probeAlive 单源):unknown 不 fail-open——必须有第二条证据
|
|
9740
|
+
* (ctl 端口属主正是该 pid 且 cmdline 匹配本服务)才认活,否则按死走 reclaim/spawn。
|
|
9741
|
+
* fail-open 会让已死 daemon 被判活,此后既不接管也不拉起,永不自愈。 */
|
|
9696
9742
|
_pidAlive(pid) {
|
|
9697
9743
|
if (!pid) return false;
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
}
|
|
9744
|
+
const st = pidlook.probeAlive(pid);
|
|
9745
|
+
if (st === "alive") return true;
|
|
9746
|
+
if (st === "dead") return false;
|
|
9747
|
+
return this._ctlOwnerPid() === pid;
|
|
9703
9748
|
}
|
|
9704
9749
|
/** ctl 端口的监听者是否就是本服务进程(cmdline 匹配)。 */
|
|
9705
9750
|
_ctlOwnerPid() {
|
|
@@ -10205,6 +10250,7 @@ var require_identity = __commonJS({
|
|
|
10205
10250
|
"use strict";
|
|
10206
10251
|
var fs2 = require("node:fs");
|
|
10207
10252
|
var path2 = require("node:path");
|
|
10253
|
+
var { isAlive } = require_pidlookup();
|
|
10208
10254
|
function lockPid(p) {
|
|
10209
10255
|
if (!p) return null;
|
|
10210
10256
|
try {
|
|
@@ -10215,13 +10261,7 @@ var require_identity = __commonJS({
|
|
|
10215
10261
|
}
|
|
10216
10262
|
}
|
|
10217
10263
|
function pidAlive2(pid) {
|
|
10218
|
-
|
|
10219
|
-
try {
|
|
10220
|
-
process.kill(pid, 0);
|
|
10221
|
-
return true;
|
|
10222
|
-
} catch (e) {
|
|
10223
|
-
return !!(e && e.code === "EPERM");
|
|
10224
|
-
}
|
|
10264
|
+
return isAlive(pid);
|
|
10225
10265
|
}
|
|
10226
10266
|
function acquireLock2(p, onErr) {
|
|
10227
10267
|
if (!p) return false;
|
|
@@ -10602,7 +10642,7 @@ var require_ports2 = __commonJS({
|
|
|
10602
10642
|
"use strict";
|
|
10603
10643
|
var probe = require_probe2();
|
|
10604
10644
|
var ports = require_ports().shared;
|
|
10605
|
-
var SIBLING_REGISTRIES = ["ports-
|
|
10645
|
+
var SIBLING_REGISTRIES = ["ports-router.json"];
|
|
10606
10646
|
var DEPS = /* @__PURE__ */ new WeakMap();
|
|
10607
10647
|
function depsOf(host2) {
|
|
10608
10648
|
let d = DEPS.get(host2);
|
|
@@ -11198,24 +11238,32 @@ var require_lan2 = __commonJS({
|
|
|
11198
11238
|
}
|
|
11199
11239
|
}
|
|
11200
11240
|
return {
|
|
11201
|
-
/** 远程控制模式唯一写入口(off|lan|wan)。
|
|
11241
|
+
/** 远程控制模式唯一写入口(off|lan|wan)。mode 必须显式给出——缺省归 'off' 会让
|
|
11242
|
+
* 漏字段的请求静默关闭远程控制。wan 前置闸:必须先有合规访问令牌。 */
|
|
11202
11243
|
setRemoteMode(id, mode) {
|
|
11203
|
-
|
|
11244
|
+
if (mode !== "off" && mode !== "lan" && mode !== "wan") {
|
|
11245
|
+
return { ok: false, error: "mode \u5FC5\u987B\u663E\u5F0F\u7ED9\u51FA\uFF08off|lan|wan\uFF09" };
|
|
11246
|
+
}
|
|
11204
11247
|
const target = resolveTarget(id);
|
|
11205
11248
|
if (!target) return { ok: false, error: "\u5B9E\u4F8B\u4E0D\u5B58\u5728" };
|
|
11206
|
-
if (
|
|
11249
|
+
if (mode === "wan") {
|
|
11207
11250
|
const v = validateWanAccess({ remoteToken: target.remoteToken });
|
|
11208
11251
|
if (!v.ok) return { ok: false, error: v.error };
|
|
11209
11252
|
}
|
|
11210
11253
|
if (target.kind === "main") {
|
|
11211
|
-
if (target.mode !==
|
|
11254
|
+
if (target.mode !== mode) applyMainIntent({ remoteMode: mode }, { id: "main", name: "\u539F\u751F DSH", mode });
|
|
11212
11255
|
return { ok: true };
|
|
11213
11256
|
}
|
|
11214
|
-
return g.getInstances().updateInstance(id, { remoteMode:
|
|
11257
|
+
return g.getInstances().updateInstance(id, { remoteMode: mode });
|
|
11215
11258
|
},
|
|
11216
|
-
/**
|
|
11259
|
+
/** 访问令牌唯一写入口。token 必须是字符串:空串=显式清除;缺字段/非字符串=请求方缺陷,
|
|
11260
|
+
* 拒绝而非当作清除(漏 token 字段清掉访问凭据是事故,不是语义)。lan 模式可无令牌,
|
|
11261
|
+
* wan 模式的守门由执行边界闸兜住。 */
|
|
11217
11262
|
setRemoteToken(id, token) {
|
|
11218
|
-
|
|
11263
|
+
if (typeof token !== "string") {
|
|
11264
|
+
return { ok: false, error: "token \u5FC5\u987B\u663E\u5F0F\u7ED9\u51FA\uFF08\u7A7A\u4E32=\u6E05\u9664\uFF09" };
|
|
11265
|
+
}
|
|
11266
|
+
const next = token;
|
|
11219
11267
|
if (next && !remoteTokenStrength(next).ok) {
|
|
11220
11268
|
return { ok: false, error: "\u8FDC\u7A0B\u8BBF\u95EE\u4EE4\u724C\uFF08remoteToken\uFF09\u81F3\u5C11 8 \u4F4D" };
|
|
11221
11269
|
}
|
|
@@ -11299,16 +11347,17 @@ var require_env_catalog = __commonJS({
|
|
|
11299
11347
|
const v = ex2.runOut(bin, (Array.isArray(args) ? args : []).concat(["--version"]), { timeoutMs: 3e3 });
|
|
11300
11348
|
return v ? v.trim() || null : null;
|
|
11301
11349
|
}
|
|
11350
|
+
function whichVersionAsync(bin, args) {
|
|
11351
|
+
return ex2.runOutAsync(bin, (Array.isArray(args) ? args : []).concat(["--version"]), { timeoutMs: 3e3 }).then((v) => v ? v.trim() || null : null);
|
|
11352
|
+
}
|
|
11302
11353
|
var _verCache = /* @__PURE__ */ new Map();
|
|
11303
11354
|
var CACHE_TTL = 1e4;
|
|
11304
|
-
function
|
|
11355
|
+
function cacheKey(bin, args) {
|
|
11305
11356
|
const a = Array.isArray(args) ? args : [];
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
const v = whichVersion(bin, a);
|
|
11311
|
-
_verCache.set(key, { at: now, v });
|
|
11357
|
+
return bin + "\0" + a.join("\0");
|
|
11358
|
+
}
|
|
11359
|
+
function cacheSet(key, v) {
|
|
11360
|
+
_verCache.set(key, { at: Date.now(), v });
|
|
11312
11361
|
if (_verCache.size > 16) {
|
|
11313
11362
|
let oldest = null;
|
|
11314
11363
|
for (const [k, e] of _verCache) if (!oldest || e.at < oldest.at) oldest = { k, at: e.at };
|
|
@@ -11316,6 +11365,19 @@ var require_env_catalog = __commonJS({
|
|
|
11316
11365
|
}
|
|
11317
11366
|
return v;
|
|
11318
11367
|
}
|
|
11368
|
+
function cachedWhichVersion(bin, args) {
|
|
11369
|
+
const key = cacheKey(bin, args);
|
|
11370
|
+
const hit = _verCache.get(key);
|
|
11371
|
+
const now = Date.now();
|
|
11372
|
+
if (hit && now - hit.at < CACHE_TTL) return hit.v;
|
|
11373
|
+
return cacheSet(key, whichVersion(bin, args));
|
|
11374
|
+
}
|
|
11375
|
+
function cachedWhichVersionAsync(bin, args) {
|
|
11376
|
+
const key = cacheKey(bin, args);
|
|
11377
|
+
const hit = _verCache.get(key);
|
|
11378
|
+
if (hit && Date.now() - hit.at < CACHE_TTL) return Promise.resolve(hit.v);
|
|
11379
|
+
return whichVersionAsync(bin, args).then((v) => cacheSet(key, v));
|
|
11380
|
+
}
|
|
11319
11381
|
var MIN_NODE_DEFAULT = "v22.12.0";
|
|
11320
11382
|
var _runtimeMetaCache = null;
|
|
11321
11383
|
var _runtimeMetaAt = 0;
|
|
@@ -11342,50 +11404,68 @@ var require_env_catalog = __commonJS({
|
|
|
11342
11404
|
}
|
|
11343
11405
|
return true;
|
|
11344
11406
|
}
|
|
11345
|
-
function
|
|
11346
|
-
const v = cachedWhichVersion("node");
|
|
11407
|
+
function nodeVerdict(v) {
|
|
11347
11408
|
if (!v) return null;
|
|
11348
11409
|
const m = /v?(\d+\.\d+\.\d+)/.exec(String(v));
|
|
11349
11410
|
const ver = m ? m[1] : String(v).trim();
|
|
11350
11411
|
const min = String(runtimeMeta().minNode || MIN_NODE_DEFAULT);
|
|
11351
11412
|
return { version: "v" + ver, min, meets: verAtLeast(ver, min) };
|
|
11352
11413
|
}
|
|
11414
|
+
function probeNode() {
|
|
11415
|
+
return nodeVerdict(cachedWhichVersion("node"));
|
|
11416
|
+
}
|
|
11417
|
+
function probeNodeAsync() {
|
|
11418
|
+
return cachedWhichVersionAsync("node").then(nodeVerdict);
|
|
11419
|
+
}
|
|
11353
11420
|
function probeNpm() {
|
|
11354
11421
|
const l = runtime.npmLauncher();
|
|
11355
11422
|
return cachedWhichVersion(l.program, l.args);
|
|
11356
11423
|
}
|
|
11424
|
+
function probeNpmAsync() {
|
|
11425
|
+
const l = runtime.npmLauncher();
|
|
11426
|
+
return cachedWhichVersionAsync(l.program, l.args);
|
|
11427
|
+
}
|
|
11357
11428
|
var SYSTEM_ENTRIES = {
|
|
11358
|
-
node: { label: "Node.js", required: true, probe: probeNode },
|
|
11359
|
-
npm: { label: "npm", required: true, probe: probeNpm },
|
|
11360
|
-
git: { label: "git", required: false, probe: () => cachedWhichVersion("git") }
|
|
11429
|
+
node: { label: "Node.js", required: true, probe: probeNode, probeAsync: probeNodeAsync },
|
|
11430
|
+
npm: { label: "npm", required: true, probe: probeNpm, probeAsync: probeNpmAsync },
|
|
11431
|
+
git: { label: "git", required: false, probe: () => cachedWhichVersion("git"), probeAsync: () => cachedWhichVersionAsync("git") }
|
|
11361
11432
|
};
|
|
11433
|
+
function entryView(id, e, v) {
|
|
11434
|
+
if (v && typeof v === "object" && typeof v.meets === "boolean") {
|
|
11435
|
+
return {
|
|
11436
|
+
label: e.label,
|
|
11437
|
+
required: e.required,
|
|
11438
|
+
state: v.meets ? "ok" : "outdated",
|
|
11439
|
+
version: v.version,
|
|
11440
|
+
min: v.min,
|
|
11441
|
+
meets: v.meets,
|
|
11442
|
+
detail: v.meets ? v.version : v.version + "\uFF08\u4F4E\u4E8E\u6700\u4F4E\u8981\u6C42 " + v.min + "\uFF09"
|
|
11443
|
+
};
|
|
11444
|
+
}
|
|
11445
|
+
return { label: e.label, required: e.required, state: v ? "ok" : "missing", detail: v };
|
|
11446
|
+
}
|
|
11362
11447
|
var EnvCatalog = class {
|
|
11363
11448
|
constructor(config) {
|
|
11364
11449
|
this.config = config || {};
|
|
11365
11450
|
}
|
|
11366
|
-
/**
|
|
11367
|
-
* ok = 存在且满足门槛(Node 需 >= 壳投放的 minNode);outdated = 存在但低于门槛;missing = 不存在。
|
|
11368
|
-
* 兼容:detail 保持字符串,新增字段(version/min/meets)放 detail 之外,不破坏既有契约。 */
|
|
11451
|
+
/** 系统二进制条目探测(同步口径):{ id: 条目视图 }。仅限启动早期/CLI;HTTP 路径用 probeAsync。 */
|
|
11369
11452
|
probe() {
|
|
11370
11453
|
const out = {};
|
|
11371
11454
|
for (const [id, e] of Object.entries(SYSTEM_ENTRIES)) {
|
|
11372
|
-
|
|
11373
|
-
if (v && typeof v === "object" && typeof v.meets === "boolean") {
|
|
11374
|
-
out[id] = {
|
|
11375
|
-
label: e.label,
|
|
11376
|
-
required: e.required,
|
|
11377
|
-
state: v.meets ? "ok" : "outdated",
|
|
11378
|
-
version: v.version,
|
|
11379
|
-
min: v.min,
|
|
11380
|
-
meets: v.meets,
|
|
11381
|
-
detail: v.meets ? v.version : v.version + "\uFF08\u4F4E\u4E8E\u6700\u4F4E\u8981\u6C42 " + v.min + "\uFF09"
|
|
11382
|
-
};
|
|
11383
|
-
} else {
|
|
11384
|
-
out[id] = { label: e.label, required: e.required, state: v ? "ok" : "missing", detail: v };
|
|
11385
|
-
}
|
|
11455
|
+
out[id] = entryView(id, e, e.probe() || null);
|
|
11386
11456
|
}
|
|
11387
11457
|
return out;
|
|
11388
11458
|
}
|
|
11459
|
+
/** 异步口径:条目并行探测(最坏 3s x N 的串行冻结 -> 全程不阻塞事件循环)。 */
|
|
11460
|
+
async probeAsync() {
|
|
11461
|
+
const entries = Object.entries(SYSTEM_ENTRIES);
|
|
11462
|
+
const vals = await Promise.all(entries.map(([, e]) => e.probeAsync()));
|
|
11463
|
+
const out = {};
|
|
11464
|
+
entries.forEach(([id, e], i) => {
|
|
11465
|
+
out[id] = entryView(id, e, vals[i] || null);
|
|
11466
|
+
});
|
|
11467
|
+
return out;
|
|
11468
|
+
}
|
|
11389
11469
|
/** 内核更新依赖条目(单写入者契约:安装/重启归桌面壳,守卫只读 corePackageName 查版本状态)。
|
|
11390
11470
|
* id 仍为 selfUpdate 以兼容既有 /env/status 消费方。 */
|
|
11391
11471
|
selfUpdateEntry() {
|
|
@@ -11429,20 +11509,22 @@ var require_env = __commonJS({
|
|
|
11429
11509
|
var fs2 = require("node:fs");
|
|
11430
11510
|
var { EnvCatalog } = require_env_catalog();
|
|
11431
11511
|
var runtimeContract = require_runtime();
|
|
11432
|
-
function envCatalogSummary(that) {
|
|
11512
|
+
async function envCatalogSummary(that) {
|
|
11433
11513
|
const cat = new EnvCatalog(that.config);
|
|
11434
11514
|
const extra = {};
|
|
11435
11515
|
const d = that.dshenvStatus();
|
|
11436
11516
|
extra.dsh = cat.dshEntry(d.binOk, d.installed, d.bin);
|
|
11437
11517
|
extra.selfUpdate = cat.selfUpdateEntry();
|
|
11438
|
-
return cat.summary(extra);
|
|
11518
|
+
return cat.summary(extra, await cat.probeAsync());
|
|
11439
11519
|
}
|
|
11440
11520
|
module2.exports = {
|
|
11441
11521
|
methods: {
|
|
11442
|
-
|
|
11522
|
+
// 异步:全部子进程探测(EnvCatalog/契约回读)走异步口径——本方法挂在 /env/status 上,
|
|
11523
|
+
// 同步 execFileSync 会把守卫事件循环冻结在探测超时上(心跳/自愈停摆,B1-6 收口)。
|
|
11524
|
+
async envStatus() {
|
|
11443
11525
|
const c = runtimeContract.read() || {};
|
|
11444
|
-
const cat = new EnvCatalog(this.config).
|
|
11445
|
-
const en = this.nativeManager && typeof this.nativeManager.checkEnvironment === "function" ? this.nativeManager.checkEnvironment() : null;
|
|
11526
|
+
const cat = await new EnvCatalog(this.config).probeAsync();
|
|
11527
|
+
const en = this.nativeManager && typeof this.nativeManager.checkEnvironment === "function" ? await this.nativeManager.checkEnvironment() : null;
|
|
11446
11528
|
return {
|
|
11447
11529
|
node: { detected: cat.node.detail || null, runtime: c.nodeVersion || null, path: c.nodePath || null },
|
|
11448
11530
|
// npm 与 node 同构三段:detected = 本机实跑版本;runtime = 壳实跑后投放的版本
|
|
@@ -11454,7 +11536,7 @@ var require_env = __commonJS({
|
|
|
11454
11536
|
ok: cat.node.state === "ok" && cat.npm.state === "ok",
|
|
11455
11537
|
npmRoot: en ? en.npmRoot : null,
|
|
11456
11538
|
// EnvCatalog 声明式视图(面板环境卡用)
|
|
11457
|
-
catalog: envCatalogSummary(this),
|
|
11539
|
+
catalog: await envCatalogSummary(this),
|
|
11458
11540
|
// 平台能力矩阵:三平台静态档位 x 实际工具探测;前端据此做能力感知呈现与降级提示。
|
|
11459
11541
|
capabilities: (() => {
|
|
11460
11542
|
try {
|
|
@@ -11680,15 +11762,16 @@ var require_versions = __commonJS({
|
|
|
11680
11762
|
return { ok: false, error: e.message };
|
|
11681
11763
|
}
|
|
11682
11764
|
},
|
|
11683
|
-
/** 读磁盘上运行位的自报版本:spawn --version
|
|
11765
|
+
/** 读磁盘上运行位的自报版本:spawn --version,解析版本行(异步:20s 上限的同步 exec
|
|
11766
|
+
* 在 HTTP 路径上会冻结守卫整条事件循环,判据不变)。
|
|
11684
11767
|
* 条件是 updatable(sea-binary 或 launcher):launcher 的 bin 入口同样可执行,
|
|
11685
11768
|
* 若只认 sea-binary 则发布态永远读不到磁盘实况,updatePending 恒 false。
|
|
11686
11769
|
* source-shell 不支持:其 --version 报的是开发目录版本,与 npm 安装无关。 */
|
|
11687
|
-
_readBinarySelfVersion() {
|
|
11770
|
+
async _readBinarySelfVersion() {
|
|
11688
11771
|
const dep = deploy.detect();
|
|
11689
11772
|
if (!dep.updatable || !dep.runningTarget) return null;
|
|
11690
11773
|
try {
|
|
11691
|
-
const out = ex2.
|
|
11774
|
+
const out = await ex2.runOutAsync(dep.runningTarget, ["--version"], { timeoutMs: 2e4 });
|
|
11692
11775
|
const m = /dsh-supervisor v([^\s]+)/.exec(out);
|
|
11693
11776
|
return m ? m[1] : null;
|
|
11694
11777
|
} catch {
|
|
@@ -11710,18 +11793,18 @@ var require_versions = __commonJS({
|
|
|
11710
11793
|
}
|
|
11711
11794
|
return dir;
|
|
11712
11795
|
},
|
|
11713
|
-
/** 本地视角(无网络 I/O
|
|
11714
|
-
|
|
11796
|
+
/** 本地视角(无网络 I/O;git 子进程异步执行——同步 spawn 会冻结事件循环,
|
|
11797
|
+
* 消费方含 HTTP 路径,见 exec.js 同步仅限启动早期/CLI 的纪律)。 */
|
|
11798
|
+
async guardVersionLocal() {
|
|
11715
11799
|
const d = depsOf(this);
|
|
11716
11800
|
const root = d.vcsRoot();
|
|
11717
|
-
|
|
11718
|
-
|
|
11801
|
+
const [rawCommit, rawUp] = await Promise.all([
|
|
11802
|
+
ex2.runOutAsync("git", ["-C", root, "rev-parse", "--short", "HEAD"]),
|
|
11803
|
+
ex2.runOutAsync("git", ["-C", root, "rev-parse", "--abbrev-ref", "@{u}"])
|
|
11804
|
+
]);
|
|
11805
|
+
const commit = (rawCommit || "").trim() || null;
|
|
11719
11806
|
let upstream = "local";
|
|
11720
|
-
|
|
11721
|
-
const up = (ex2.runOut("git", ["-C", root, "rev-parse", "--abbrev-ref", "@{u}"]) || "").trim();
|
|
11722
|
-
if (up) upstream = "git-repo";
|
|
11723
|
-
} catch {
|
|
11724
|
-
}
|
|
11807
|
+
if ((rawUp || "").trim()) upstream = "git-repo";
|
|
11725
11808
|
return { version: d.guardVersion(), runningVersion: d.guardVersion(), commit, updateAvailable: false, upstream, latest: d.guardVersion() };
|
|
11726
11809
|
},
|
|
11727
11810
|
/** 完整版本检查(async):本地 commit + 远端 fetch 比对。
|
|
@@ -11729,20 +11812,17 @@ var require_versions = __commonJS({
|
|
|
11729
11812
|
* fetch 失败/超时只降级为「本地视图」,不抛错。 */
|
|
11730
11813
|
async guardVersionCheck() {
|
|
11731
11814
|
const d = depsOf(this);
|
|
11732
|
-
const base = d.guardVersionLocal();
|
|
11815
|
+
const base = await d.guardVersionLocal();
|
|
11733
11816
|
if (base.upstream !== "git-repo") return base;
|
|
11734
11817
|
const root = d.vcsRoot();
|
|
11735
11818
|
const fetchOk = await ex2.runOutAsync("git", ["-C", root, "fetch", "--quiet"], { timeoutMs: 1e4 }) !== null;
|
|
11736
11819
|
if (!fetchOk) return base;
|
|
11737
11820
|
let updateAvailable = false;
|
|
11738
|
-
|
|
11739
|
-
|
|
11740
|
-
updateAvailable = parseInt(ahead, 10) > 0;
|
|
11741
|
-
} catch {
|
|
11742
|
-
}
|
|
11821
|
+
const ahead = (await ex2.runOutAsync("git", ["-C", root, "rev-list", "--count", "HEAD..@{u}"], { timeoutMs: 1e4 }) || "").trim();
|
|
11822
|
+
updateAvailable = parseInt(ahead, 10) > 0;
|
|
11743
11823
|
const dep = deploy.detect();
|
|
11744
11824
|
let diskVersion = null;
|
|
11745
|
-
if (dep.updatable) diskVersion = d.readBinarySelfVersion();
|
|
11825
|
+
if (dep.updatable) diskVersion = await d.readBinarySelfVersion();
|
|
11746
11826
|
const updatePending = !!(diskVersion && diskVersion !== d.guardVersion());
|
|
11747
11827
|
return { ...base, diskVersion, updatePending };
|
|
11748
11828
|
}
|
|
@@ -11826,7 +11906,9 @@ var require_access = __commonJS({
|
|
|
11826
11906
|
return { ok: false, error: e.message };
|
|
11827
11907
|
}
|
|
11828
11908
|
}
|
|
11829
|
-
}
|
|
11909
|
+
},
|
|
11910
|
+
// settings 门面的写口核验件(B2-4):lan-panel 共用同一「写后读回」口径,不各写各的。
|
|
11911
|
+
verifyPersisted
|
|
11830
11912
|
};
|
|
11831
11913
|
}
|
|
11832
11914
|
});
|
|
@@ -11933,9 +12015,8 @@ var require_netinfo = __commonJS({
|
|
|
11933
12015
|
var require_lan_panel = __commonJS({
|
|
11934
12016
|
"src/app/settings/lan-panel.js"(exports2, module2) {
|
|
11935
12017
|
"use strict";
|
|
11936
|
-
var fs2 = require("node:fs");
|
|
11937
12018
|
var netInfo = require_netinfo();
|
|
11938
|
-
var {
|
|
12019
|
+
var { verifyPersisted } = require_access();
|
|
11939
12020
|
var DEPS = /* @__PURE__ */ new WeakMap();
|
|
11940
12021
|
function depsOf(host2) {
|
|
11941
12022
|
let d = DEPS.get(host2);
|
|
@@ -11945,6 +12026,7 @@ var require_lan_panel = __commonJS({
|
|
|
11945
12026
|
logger: () => host2.logger,
|
|
11946
12027
|
events: () => host2.events,
|
|
11947
12028
|
configPath: () => host2.configPath,
|
|
12029
|
+
state: () => host2.state,
|
|
11948
12030
|
api: () => host2.api,
|
|
11949
12031
|
lanPanelStatus: () => host2.lanPanelStatus(),
|
|
11950
12032
|
apiRebind: () => host2._apiRebind()
|
|
@@ -11986,14 +12068,9 @@ var require_lan_panel = __commonJS({
|
|
|
11986
12068
|
d.config().apiHost = host2;
|
|
11987
12069
|
let persistError = null;
|
|
11988
12070
|
if (d.configPath()) {
|
|
11989
|
-
|
|
11990
|
-
|
|
11991
|
-
|
|
11992
|
-
writeAtomic(d.configPath(), JSON.stringify(doc, null, 2), { mode: 384 });
|
|
11993
|
-
} catch (e) {
|
|
11994
|
-
persistError = "persist apiHost: " + e.message;
|
|
11995
|
-
d.logger().error(persistError);
|
|
11996
|
-
}
|
|
12071
|
+
d.state().persistConfigPatch({ apiHost: host2 });
|
|
12072
|
+
persistError = verifyPersisted(d.configPath(), { apiHost: host2 });
|
|
12073
|
+
if (persistError) d.logger().error(persistError);
|
|
11997
12074
|
}
|
|
11998
12075
|
if (changed && d.api() && typeof d.api().close === "function") d.apiRebind();
|
|
11999
12076
|
if (d.events()) d.events().append("lan_panel_changed", { enabled: on });
|
|
@@ -12047,7 +12124,8 @@ var require_facets = __commonJS({
|
|
|
12047
12124
|
{ name: "domain-actions/router", mod: require_router2(), factory: "createRouterActions" },
|
|
12048
12125
|
{ name: "domain-actions/lan", mod: require_lan2(), factory: "createLanActions" },
|
|
12049
12126
|
{ name: "domain-actions/main", mod: require_main2(), factory: "createMainActions" },
|
|
12050
|
-
|
|
12127
|
+
// audit/orphan-scan 不在本清单:它是真 ctor 工厂(assembly/collaborators.js 的 installAuditFactory
|
|
12128
|
+
// 构造 host.audit),实现体本身只是纯函数,不再需要 host 兼容外壳切面。
|
|
12051
12129
|
{ name: "settings/env", mod: require_env() },
|
|
12052
12130
|
{ name: "settings/node-lts", mod: require_node_lts() },
|
|
12053
12131
|
{ name: "settings/versions", mod: require_versions() },
|
|
@@ -12611,6 +12689,8 @@ var require_pool2 = __commonJS({
|
|
|
12611
12689
|
this._bus = new FollowBus({ logger: this.logger });
|
|
12612
12690
|
this._schedules = /* @__PURE__ */ new Map();
|
|
12613
12691
|
this._seq = 0;
|
|
12692
|
+
this._attachGen = /* @__PURE__ */ new Map();
|
|
12693
|
+
this._journalFn = o.journal || capture.captureJournal;
|
|
12614
12694
|
this._backfillAt = /* @__PURE__ */ new Map();
|
|
12615
12695
|
this._poolFile = o.poolFile ? path2.resolve(o.poolFile) : null;
|
|
12616
12696
|
this._loaded = false;
|
|
@@ -12635,6 +12715,7 @@ var require_pool2 = __commonJS({
|
|
|
12635
12715
|
const unit = s.unit || prev && prev.unit || null;
|
|
12636
12716
|
const file = s.file || prev && prev.file || null;
|
|
12637
12717
|
this._sources.set(id, { kind, unit, file, lines: prev && prev.lines || [] });
|
|
12718
|
+
this._attachGen.set(id, (this._attachGen.get(id) || 0) + 1);
|
|
12638
12719
|
const rec = this._records.get(id);
|
|
12639
12720
|
if (rec) rec.kind = kind;
|
|
12640
12721
|
return true;
|
|
@@ -12659,9 +12740,16 @@ var require_pool2 = __commonJS({
|
|
|
12659
12740
|
return this._commit(id, hit.token, hit.source);
|
|
12660
12741
|
}
|
|
12661
12742
|
if (src.unit && kinds.isCaptured(src.kind)) {
|
|
12662
|
-
|
|
12743
|
+
const gen = this._attachGen.get(id) || 0;
|
|
12744
|
+
const fresh = () => (this._attachGen.get(id) || 0) === gen ? this._sources.get(id) : null;
|
|
12745
|
+
Promise.resolve().then(() => {
|
|
12746
|
+
const cur = fresh();
|
|
12747
|
+
return cur ? this._journalFn(cur.unit, { logger: this.logger }) : null;
|
|
12748
|
+
}).then((j) => {
|
|
12663
12749
|
if (!j) return;
|
|
12664
|
-
|
|
12750
|
+
const cur = fresh();
|
|
12751
|
+
if (!cur) return;
|
|
12752
|
+
if (cur.file) this._persistLine(id, cur.file, j.line);
|
|
12665
12753
|
this._commit(id, j.token, j.source);
|
|
12666
12754
|
}).catch(() => {
|
|
12667
12755
|
});
|
|
@@ -12729,6 +12817,7 @@ var require_pool2 = __commonJS({
|
|
|
12729
12817
|
this._backfillAt.delete(id);
|
|
12730
12818
|
const src = this._sources.get(id);
|
|
12731
12819
|
if (src && src.lines && src.lines.length) src.lines.length = 0;
|
|
12820
|
+
this._attachGen.set(id, (this._attachGen.get(id) || 0) + 1);
|
|
12732
12821
|
this._records.delete(id);
|
|
12733
12822
|
this._persistPool();
|
|
12734
12823
|
this._bus.emit(id, null, null);
|
|
@@ -13659,7 +13748,6 @@ var require_core5 = __commonJS({
|
|
|
13659
13748
|
host2._routerFacade = null;
|
|
13660
13749
|
host2._lc = null;
|
|
13661
13750
|
host2._dshMainLive = null;
|
|
13662
|
-
host2._fallbackEntry = null;
|
|
13663
13751
|
host2._lastStateBody = null;
|
|
13664
13752
|
host2._shadowSeq = 0;
|
|
13665
13753
|
host2._shadowConsistentBeats = 0;
|
|
@@ -13831,7 +13919,7 @@ var require_model = __commonJS({
|
|
|
13831
13919
|
adapter: p.adapter || null,
|
|
13832
13920
|
proxyAppId: p.proxyAppId || null,
|
|
13833
13921
|
proxyRunning: p.proxyRunning || false,
|
|
13834
|
-
selectedAccountKeyId: p.selectedAccountKeyId ||
|
|
13922
|
+
selectedAccountKeyId: p.selectedAccountKeyId || null,
|
|
13835
13923
|
activeAccountKeyId: p.activeAccount && p.activeAccount.keyId || null,
|
|
13836
13924
|
accounts: (p.accounts || []).map((a) => {
|
|
13837
13925
|
p._normalizeConsistency(a);
|
|
@@ -14243,7 +14331,6 @@ var require_freeze = __commonJS({
|
|
|
14243
14331
|
const usable = !!acc && acc.status === "ready" && (typeof provider.isAccountUsable !== "function" || provider.isAccountUsable(acc));
|
|
14244
14332
|
if (!usable) {
|
|
14245
14333
|
provider.selectedAccountKeyId = null;
|
|
14246
|
-
if (provider.selectedProxyKeyId === lockedId) provider.selectedProxyKeyId = null;
|
|
14247
14334
|
}
|
|
14248
14335
|
}
|
|
14249
14336
|
module2.exports = { setStatus, ensureLimit, previewLimit, setLimit, freezeLimited, markCreditsExhausted, markQuotaExhausted, markBanned, applyDetection, normalizeConsistency, reconcileLock };
|
|
@@ -17206,10 +17293,11 @@ var require_oauth = __commonJS({
|
|
|
17206
17293
|
const d = deps || {};
|
|
17207
17294
|
const ports = d.ports;
|
|
17208
17295
|
const openInBrowser = d.openInBrowser;
|
|
17209
|
-
const st = { _ccLogin: null, _ccLoginPromise: null, _ccLoginResolve: null, _ccLoginReject: null };
|
|
17296
|
+
const st = { _ccLogin: null, _ccLoginPromise: null, _ccLoginResolve: null, _ccLoginReject: null, _ccLoginRound: 0 };
|
|
17210
17297
|
async function commandcodeLoginStart() {
|
|
17211
17298
|
const STUDIO_BASE = "https://commandcode.ai";
|
|
17212
17299
|
const state = crypto.randomBytes(32).toString("base64url");
|
|
17300
|
+
const roundId = ++st._ccLoginRound;
|
|
17213
17301
|
if (st._ccLogin && st._ccLogin.server) {
|
|
17214
17302
|
const oldState = st._ccLogin.state;
|
|
17215
17303
|
try {
|
|
@@ -17271,6 +17359,11 @@ var require_oauth = __commonJS({
|
|
|
17271
17359
|
if (b.length > 1e4) req.destroy();
|
|
17272
17360
|
});
|
|
17273
17361
|
req.on("end", () => {
|
|
17362
|
+
if (st._ccLoginRound !== roundId) {
|
|
17363
|
+
res.writeHead(410);
|
|
17364
|
+
res.end(callbackJson({ success: false, error: "Stale login round" }));
|
|
17365
|
+
return;
|
|
17366
|
+
}
|
|
17274
17367
|
try {
|
|
17275
17368
|
const j = JSON.parse(b || "{}");
|
|
17276
17369
|
if (j && typeof j === "object" && "error" in j) {
|
|
@@ -17361,6 +17454,7 @@ var require_oauth = __commonJS({
|
|
|
17361
17454
|
});
|
|
17362
17455
|
st._ccLoginPromise = promise;
|
|
17363
17456
|
const tmpProfile = openInBrowser(authUrl, () => {
|
|
17457
|
+
if (st._ccLoginRound !== roundId) return;
|
|
17364
17458
|
if (st._ccLoginReject) {
|
|
17365
17459
|
const r = st._ccLoginReject;
|
|
17366
17460
|
st._ccLoginReject = null;
|
|
@@ -19247,10 +19341,7 @@ var require_model3 = __commonJS({
|
|
|
19247
19341
|
inst.state.lastError = null;
|
|
19248
19342
|
}
|
|
19249
19343
|
if (inst.state) inst.state.phase = inst.state.phase || "STOPPED";
|
|
19250
|
-
if (inst.state
|
|
19251
|
-
const p = inst.state.phase;
|
|
19252
|
-
inst.state.desired = p === "RUNNING" || p === "STARTING" || p === "INSTALLING" ? "running" : "stopped";
|
|
19253
|
-
}
|
|
19344
|
+
if (inst.state) delete inst.state.desired;
|
|
19254
19345
|
return inst;
|
|
19255
19346
|
}
|
|
19256
19347
|
function createRecord(payload, id) {
|
|
@@ -19275,7 +19366,7 @@ var require_model3 = __commonJS({
|
|
|
19275
19366
|
protectHome: payload.protectHome === void 0 ? false : !!payload.protectHome
|
|
19276
19367
|
// 资源配额不接收户输入:启动时由 governor 按机器预算与活跃实例数推导。
|
|
19277
19368
|
},
|
|
19278
|
-
state: { phase: "STOPPED",
|
|
19369
|
+
state: { phase: "STOPPED", restartCount: 0, backoffLevel: 0, lastProbeOk: null },
|
|
19279
19370
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
19280
19371
|
};
|
|
19281
19372
|
}
|
|
@@ -19515,6 +19606,7 @@ var require_lifecycle = __commonJS({
|
|
|
19515
19606
|
"use strict";
|
|
19516
19607
|
var fs2 = require("node:fs");
|
|
19517
19608
|
var monitor = require_monitor();
|
|
19609
|
+
var ports = require_ports().shared;
|
|
19518
19610
|
var guardian = require_guardian();
|
|
19519
19611
|
var sandbox = require_sandbox();
|
|
19520
19612
|
var governor = require_governor();
|
|
@@ -19557,7 +19649,7 @@ var require_lifecycle = __commonJS({
|
|
|
19557
19649
|
logger.info && logger.info("cleaned stale transient unit: " + unit);
|
|
19558
19650
|
}
|
|
19559
19651
|
}
|
|
19560
|
-
function _systemdStart(inst) {
|
|
19652
|
+
function _systemdStart(inst, opts) {
|
|
19561
19653
|
try {
|
|
19562
19654
|
const cmdArr = sandbox.effectiveCommand(instancesRoot, deps.dshBin, inst);
|
|
19563
19655
|
if (!cmdArr || !cmdArr.length) return { ok: false, error: "\u5B9E\u4F8B\u672A\u914D\u7F6E\u542F\u52A8\u547D\u4EE4" };
|
|
@@ -19573,6 +19665,15 @@ var require_lifecycle = __commonJS({
|
|
|
19573
19665
|
logger.warn && logger.warn("[" + inst.id + "] " + msg);
|
|
19574
19666
|
return { ok: false, error: msg };
|
|
19575
19667
|
}
|
|
19668
|
+
const takenBy = ports.recordOf(inst.port);
|
|
19669
|
+
if (takenBy && takenBy.owner !== "inst:" + inst.id) {
|
|
19670
|
+
const msg = "PORT_TAKEN:" + (takenBy.owner || takenBy.role);
|
|
19671
|
+
inst.state.lastError = msg;
|
|
19672
|
+
store.save();
|
|
19673
|
+
if (events) events.append("inst_start_refused", { id: inst.id, name: inst.name, error: msg });
|
|
19674
|
+
logger.warn && logger.warn("[" + inst.id + "] " + msg);
|
|
19675
|
+
return { ok: false, error: msg };
|
|
19676
|
+
}
|
|
19576
19677
|
if (probe(inst).running) return { ok: false, error: "\u7AEF\u53E3 " + inst.port + " \u5DF2\u88AB\u5360\u7528" };
|
|
19577
19678
|
const alloc = governor.currentAllocation(store.instances, inst.id, machineFactsNow());
|
|
19578
19679
|
inst.state.allocation = alloc;
|
|
@@ -19592,6 +19693,12 @@ var require_lifecycle = __commonJS({
|
|
|
19592
19693
|
inst.state.phase = "STARTING";
|
|
19593
19694
|
inst.state.startAt = Date.now();
|
|
19594
19695
|
inst.state.lastError = null;
|
|
19696
|
+
if (opts && opts.manual) {
|
|
19697
|
+
inst.state.restartCount = 0;
|
|
19698
|
+
inst.state.backoffLevel = 0;
|
|
19699
|
+
inst.state.backoffUntil = null;
|
|
19700
|
+
inst.state.lastFailAt = null;
|
|
19701
|
+
}
|
|
19595
19702
|
store.save();
|
|
19596
19703
|
if (inst.port && hooks.onInstanceStart) hooks.onInstanceStart(inst);
|
|
19597
19704
|
if (events) events.append("inst_started", { id: inst.id, port: inst.port });
|
|
@@ -19617,10 +19724,6 @@ var require_lifecycle = __commonJS({
|
|
|
19617
19724
|
return { ok: false, error: adm.error };
|
|
19618
19725
|
}
|
|
19619
19726
|
}
|
|
19620
|
-
if (inst.state.desired !== "running") {
|
|
19621
|
-
inst.state.desired = "running";
|
|
19622
|
-
store.save();
|
|
19623
|
-
}
|
|
19624
19727
|
store.ensureDirs(inst);
|
|
19625
19728
|
const dshEntry = sandbox.dshEntry(instancesRoot, inst);
|
|
19626
19729
|
if (!fs2.existsSync(dshEntry)) {
|
|
@@ -19629,10 +19732,9 @@ var require_lifecycle = __commonJS({
|
|
|
19629
19732
|
return { ok: true, installing: true };
|
|
19630
19733
|
}
|
|
19631
19734
|
}
|
|
19632
|
-
return _systemdStart(inst);
|
|
19735
|
+
return _systemdStart(inst, opts);
|
|
19633
19736
|
}
|
|
19634
|
-
function stop(id
|
|
19635
|
-
const transient = !!(opts && opts.intent === "transient");
|
|
19737
|
+
function stop(id) {
|
|
19636
19738
|
const inst = store.instances.find((i) => i.id === id);
|
|
19637
19739
|
if (!inst) return { ok: false, error: "\u5B9E\u4F8B\u4E0D\u5B58\u5728" };
|
|
19638
19740
|
if (!isSandboxSupported()) return { ok: false, error: "\u5F53\u524D\u5E73\u53F0\u4E0D\u652F\u6301\u6C99\u7BB1\u5B9E\u4F8B\uFF08\u80FD\u529B\u77E9\u9635\u89C1 GET /env/status \u7684 capabilities.sandboxLaunch\uFF1B\u9650\u989D\u6267\u884C\u6863\u4F4D\u89C1 capabilities.sandboxEnforcement\uFF09" };
|
|
@@ -19654,7 +19756,6 @@ var require_lifecycle = __commonJS({
|
|
|
19654
19756
|
}
|
|
19655
19757
|
inst.state.phase = "STOPPED";
|
|
19656
19758
|
inst.state.usage = null;
|
|
19657
|
-
if (!transient) inst.state.desired = "stopped";
|
|
19658
19759
|
runtime.delete(inst.id);
|
|
19659
19760
|
store.save();
|
|
19660
19761
|
if (inst.port && hooks.onInstanceStop) hooks.onInstanceStop(inst);
|
|
@@ -19710,15 +19811,17 @@ var require_lifecycle = __commonJS({
|
|
|
19710
19811
|
}).catch(() => {
|
|
19711
19812
|
});
|
|
19712
19813
|
}
|
|
19814
|
+
}
|
|
19815
|
+
function governSweep() {
|
|
19713
19816
|
const roster = _sandboxRoster();
|
|
19714
|
-
if (!roster.length) return;
|
|
19817
|
+
if (!roster.length) return { ok: true, entries: 0 };
|
|
19715
19818
|
let plan;
|
|
19716
19819
|
try {
|
|
19717
19820
|
const f = machineFactsNow();
|
|
19718
19821
|
plan = governor.decide({ totalMemBytes: f.totalMemBytes, cpuCount: f.cpuCount, roster });
|
|
19719
19822
|
} catch (e) {
|
|
19720
|
-
logger.warn && logger.warn("
|
|
19721
|
-
return;
|
|
19823
|
+
logger.warn && logger.warn("govern decide \u5931\u8D25: " + (e && e.message));
|
|
19824
|
+
return { ok: false, error: e && e.message || String(e) };
|
|
19722
19825
|
}
|
|
19723
19826
|
const now = Date.now();
|
|
19724
19827
|
for (const entry of plan.entries) {
|
|
@@ -19743,19 +19846,21 @@ var require_lifecycle = __commonJS({
|
|
|
19743
19846
|
}
|
|
19744
19847
|
}
|
|
19745
19848
|
}
|
|
19746
|
-
if (!entry.violation
|
|
19849
|
+
if (!entry.violation) continue;
|
|
19747
19850
|
const v = entry.violation;
|
|
19748
19851
|
const kindLabel = v.kind === "memory" ? "\u5185\u5B58" : "CPU";
|
|
19749
19852
|
const reason = "\u8D44\u6E90\u8FDD\u89C4:" + kindLabel + "\u6301\u7EED\u8D85\u9650(\u5B9E\u9645 " + v.actual + "/\u9650\u989D " + v.target + ")";
|
|
19750
|
-
if (events) events.append("inst_resource_violation", { id:
|
|
19751
|
-
logger.warn && logger.warn("[" +
|
|
19853
|
+
if (events) events.append("inst_resource_violation", { id: target.id, name: target.name, kind: v.kind, actual: v.actual, target: v.target });
|
|
19854
|
+
logger.warn && logger.warn("[" + target.id + "] " + reason);
|
|
19752
19855
|
try {
|
|
19753
|
-
service.stopUnit("dsh-web@" +
|
|
19856
|
+
service.stopUnit("dsh-web@" + target.id, Object.assign({ timeoutMs: 2e4 }, sandbox.launchCtx(instancesRoot, deps.dshBin, target)));
|
|
19754
19857
|
} catch (e) {
|
|
19755
|
-
logger.warn && logger.warn("[" +
|
|
19858
|
+
logger.warn && logger.warn("[" + target.id + "] \u8FDD\u89C4\u505C\u5355\u5143\u5F02\u5E38: " + (e && e.message));
|
|
19756
19859
|
}
|
|
19757
|
-
stateMachine.restart(stateDeps(),
|
|
19860
|
+
stateMachine.restart(stateDeps(), target, reason);
|
|
19758
19861
|
}
|
|
19862
|
+
store.save();
|
|
19863
|
+
return { ok: true, entries: plan.entries.length };
|
|
19759
19864
|
}
|
|
19760
19865
|
function supervise(id) {
|
|
19761
19866
|
const inst = store.instances.find((i) => i.id === id);
|
|
@@ -19849,7 +19954,7 @@ var require_lifecycle = __commonJS({
|
|
|
19849
19954
|
}
|
|
19850
19955
|
return { ok: true };
|
|
19851
19956
|
}
|
|
19852
|
-
return { _prepareSystemd, start, stop, probe, probeInstance, supervise };
|
|
19957
|
+
return { _prepareSystemd, start, stop, probe, probeInstance, supervise, governSweep };
|
|
19853
19958
|
}
|
|
19854
19959
|
module2.exports = { createLifecycle };
|
|
19855
19960
|
}
|
|
@@ -20158,7 +20263,7 @@ var require_upgrade = __commonJS({
|
|
|
20158
20263
|
tasks.stepState(task.id, tasks.get(task.id).steps.indexOf(s), "running");
|
|
20159
20264
|
}
|
|
20160
20265
|
try {
|
|
20161
|
-
await lifecycle.stop(id
|
|
20266
|
+
await lifecycle.stop(id);
|
|
20162
20267
|
} catch {
|
|
20163
20268
|
}
|
|
20164
20269
|
if (task) {
|
|
@@ -20206,7 +20311,7 @@ var require_upgrade = __commonJS({
|
|
|
20206
20311
|
tasks.log(task.id, "\u81EA\u52A8\u56DE\u6EDA\u5230 " + oldVersion + "\u2026");
|
|
20207
20312
|
}
|
|
20208
20313
|
try {
|
|
20209
|
-
const rs = await lifecycle.stop(id
|
|
20314
|
+
const rs = await lifecycle.stop(id);
|
|
20210
20315
|
if (rs && rs.ok === false && task) tasks.log(task.id, "\u56DE\u6EDA\u524D\u505C\u6B62\u5931\u8D25\uFF08\u7EE7\u7EED\u56DE\u88C5\u65E7\u7248\uFF09\uFF1A" + (rs.error || ""));
|
|
20211
20316
|
} catch (e) {
|
|
20212
20317
|
if (task) tasks.log(task.id, "\u56DE\u6EDA\u524D\u505C\u6B62\u5F02\u5E38\uFF08\u7EE7\u7EED\u56DE\u88C5\u65E7\u7248\uFF09\uFF1A" + (e && e.message || e));
|
|
@@ -20493,6 +20598,11 @@ var require_ops2 = __commonJS({
|
|
|
20493
20598
|
} catch {
|
|
20494
20599
|
}
|
|
20495
20600
|
}
|
|
20601
|
+
try {
|
|
20602
|
+
lifecycle.governSweep();
|
|
20603
|
+
} catch (e) {
|
|
20604
|
+
logger.warn && logger.warn("governSweep: " + (e && e.message));
|
|
20605
|
+
}
|
|
20496
20606
|
}, intervalMs || 5e3);
|
|
20497
20607
|
}
|
|
20498
20608
|
return { list, addInstance, removeInstance, updateInstance, startTimer };
|
|
@@ -20785,12 +20895,16 @@ var require_instance = __commonJS({
|
|
|
20785
20895
|
startInstance(id, opts) {
|
|
20786
20896
|
return this._lifecycle.start(id, opts);
|
|
20787
20897
|
}
|
|
20788
|
-
stopInstance(id
|
|
20789
|
-
return this._lifecycle.stop(id
|
|
20898
|
+
stopInstance(id) {
|
|
20899
|
+
return this._lifecycle.stop(id);
|
|
20790
20900
|
}
|
|
20791
20901
|
supervise(id) {
|
|
20792
20902
|
return this._lifecycle.supervise(id);
|
|
20793
20903
|
}
|
|
20904
|
+
/** 治理单拍(B2-6e):心跳拍末由 onBeatDone 调一次,全花名册 decide+下发+违规处置。 */
|
|
20905
|
+
governSweep() {
|
|
20906
|
+
return this._lifecycle.governSweep();
|
|
20907
|
+
}
|
|
20794
20908
|
probeInstance(id) {
|
|
20795
20909
|
return this._lifecycle.probeInstance(id);
|
|
20796
20910
|
}
|
|
@@ -21112,8 +21226,6 @@ var require_market = __commonJS({
|
|
|
21112
21226
|
this._ts = 0;
|
|
21113
21227
|
this._inFlight = null;
|
|
21114
21228
|
this.buildBudgetMs = opts.buildBudgetMs || 24e4;
|
|
21115
|
-
this._deadline = 0;
|
|
21116
|
-
this._truncatedSources = /* @__PURE__ */ new Set();
|
|
21117
21229
|
this.loadFromDisk();
|
|
21118
21230
|
}
|
|
21119
21231
|
loadFromDisk() {
|
|
@@ -21160,19 +21272,18 @@ var require_market = __commonJS({
|
|
|
21160
21272
|
}
|
|
21161
21273
|
async buildIndex() {
|
|
21162
21274
|
const start = Date.now();
|
|
21163
|
-
|
|
21164
|
-
this._truncatedSources = /* @__PURE__ */ new Set();
|
|
21275
|
+
const bctx = { deadline: start + this.buildBudgetMs, truncated: /* @__PURE__ */ new Set() };
|
|
21165
21276
|
try {
|
|
21166
|
-
return await this._buildIndexInner(start);
|
|
21277
|
+
return await this._buildIndexInner(start, bctx);
|
|
21167
21278
|
} finally {
|
|
21168
|
-
|
|
21279
|
+
bctx.deadline = 0;
|
|
21169
21280
|
}
|
|
21170
21281
|
}
|
|
21171
|
-
/**
|
|
21172
|
-
_budgetExhausted() {
|
|
21173
|
-
return
|
|
21282
|
+
/** 预算是否已耗尽(供各源的批次循环调用;无 ctx = 单源直调,不设预算)。 */
|
|
21283
|
+
_budgetExhausted(bctx) {
|
|
21284
|
+
return !!bctx && bctx.deadline > 0 && Date.now() >= bctx.deadline;
|
|
21174
21285
|
}
|
|
21175
|
-
async _buildIndexInner(start) {
|
|
21286
|
+
async _buildIndexInner(start, bctx) {
|
|
21176
21287
|
const plugins = [];
|
|
21177
21288
|
const seen = /* @__PURE__ */ new Set();
|
|
21178
21289
|
const add = (p) => {
|
|
@@ -21180,11 +21291,11 @@ var require_market = __commonJS({
|
|
|
21180
21291
|
seen.add(p.name);
|
|
21181
21292
|
plugins.push(p);
|
|
21182
21293
|
};
|
|
21183
|
-
const npm = await this.indexNpm();
|
|
21294
|
+
const npm = await this.indexNpm(bctx);
|
|
21184
21295
|
npm.forEach(add);
|
|
21185
|
-
const gh = await this.indexGithub();
|
|
21296
|
+
const gh = await this.indexGithub(bctx);
|
|
21186
21297
|
gh.forEach(add);
|
|
21187
|
-
const community = await this.indexCommunity();
|
|
21298
|
+
const community = await this.indexCommunity(bctx);
|
|
21188
21299
|
community.forEach(add);
|
|
21189
21300
|
for (const p of plugins) {
|
|
21190
21301
|
p.category = p.category || classify(p);
|
|
@@ -21192,7 +21303,7 @@ var require_market = __commonJS({
|
|
|
21192
21303
|
}
|
|
21193
21304
|
plugins.sort((a, b) => (b.stars || 0) - (a.stars || 0));
|
|
21194
21305
|
const prev = this._cache;
|
|
21195
|
-
const truncated =
|
|
21306
|
+
const truncated = bctx.truncated;
|
|
21196
21307
|
if (prev && prev.plugins && prev.plugins.length > 0 && truncated.size > 0) {
|
|
21197
21308
|
const freshNames = new Set(plugins.map((pp) => pp.name));
|
|
21198
21309
|
const kept = prev.plugins.filter((pp) => truncated.has(pp.source) && !freshNames.has(pp.name));
|
|
@@ -21227,8 +21338,8 @@ var require_market = __commonJS({
|
|
|
21227
21338
|
this.logger.info && this.logger.info("market index built in " + (Date.now() - start) + "ms: " + plugins.length + " plugins (npm=" + npm.length + ", gh=" + gh.length + ", community=" + community.length + ")");
|
|
21228
21339
|
return this._cache;
|
|
21229
21340
|
}
|
|
21230
|
-
/** npm 源:搜 deepseek-harness 受限 dsh,逐个检测 dsh.bundle。 */
|
|
21231
|
-
async indexNpm() {
|
|
21341
|
+
/** npm 源:搜 deepseek-harness 受限 dsh,逐个检测 dsh.bundle。bctx 为本次构建的预算上下文(见 buildIndex)。 */
|
|
21342
|
+
async indexNpm(bctx) {
|
|
21232
21343
|
const out = [];
|
|
21233
21344
|
const queries = ["keywords:deepseek-harness", "keywords:dsh-bundle", "keywords:dsh-plugin"];
|
|
21234
21345
|
const allNames = /* @__PURE__ */ new Set();
|
|
@@ -21255,8 +21366,8 @@ var require_market = __commonJS({
|
|
|
21255
21366
|
this.logger.info && this.logger.info("npm candidates: " + names.length);
|
|
21256
21367
|
const batch = 8;
|
|
21257
21368
|
for (let i = 0; i < names.length; i += batch) {
|
|
21258
|
-
if (this._budgetExhausted()) {
|
|
21259
|
-
|
|
21369
|
+
if (this._budgetExhausted(bctx)) {
|
|
21370
|
+
bctx.truncated.add("npm");
|
|
21260
21371
|
this.logger.warn && this.logger.warn("market: npm \u6E90\u9884\u7B97\u8017\u5C3D\uFF0C\u5DF2\u5904\u7406 " + i + "/" + names.length + " \u4E2A\u5019\u9009");
|
|
21261
21372
|
break;
|
|
21262
21373
|
}
|
|
@@ -21286,7 +21397,7 @@ var require_market = __commonJS({
|
|
|
21286
21397
|
return fetchLatest(await this._npmOrigin(), name);
|
|
21287
21398
|
}
|
|
21288
21399
|
/** GitHub 源:搜 topic:dsh-plugin + deepseek-harness,逐个验证 dsh.bundle。 */
|
|
21289
|
-
async indexGithub() {
|
|
21400
|
+
async indexGithub(bctx) {
|
|
21290
21401
|
const out = [];
|
|
21291
21402
|
const topics = ["dsh-plugin", "deepseek-harness"];
|
|
21292
21403
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -21316,7 +21427,7 @@ var require_market = __commonJS({
|
|
|
21316
21427
|
return repoPkg(fullName);
|
|
21317
21428
|
}
|
|
21318
21429
|
/** 社区列表:抓 awesome-dsh-plugin README 白名单(官方社区维护的精选)。 */
|
|
21319
|
-
async indexCommunity() {
|
|
21430
|
+
async indexCommunity(bctx) {
|
|
21320
21431
|
const out = [];
|
|
21321
21432
|
try {
|
|
21322
21433
|
const md = await rawGet("awesome-dsh-plugin/awesome-dsh-plugin/main/README.md", false, 3e4);
|
|
@@ -21328,8 +21439,8 @@ var require_market = __commonJS({
|
|
|
21328
21439
|
}
|
|
21329
21440
|
const seenName = /* @__PURE__ */ new Set();
|
|
21330
21441
|
for (let i = 0; i < links.length; i += 8) {
|
|
21331
|
-
if (this._budgetExhausted()) {
|
|
21332
|
-
|
|
21442
|
+
if (this._budgetExhausted(bctx)) {
|
|
21443
|
+
bctx.truncated.add("community");
|
|
21333
21444
|
this.logger.warn && this.logger.warn("market: community \u6E90\u9884\u7B97\u8017\u5C3D\uFF0C\u5DF2\u5904\u7406 " + i + "/" + links.length + " \u4E2A\u5019\u9009");
|
|
21334
21445
|
break;
|
|
21335
21446
|
}
|
|
@@ -21851,7 +21962,7 @@ var require_restart3 = __commonJS({
|
|
|
21851
21962
|
log("\u91CD\u542F\u5B9E\u4F8B\u300C" + (target.name || target.id) + "\u300D\u4F7F\u63D2\u4EF6\u53D8\u66F4\u751F\u6548\u2026");
|
|
21852
21963
|
if (ctx.events) ctx.events.append("plugin_restart_started", { name: target.name || target.id, target: target.id, kind });
|
|
21853
21964
|
try {
|
|
21854
|
-
ctx.instances.stopInstance(target.id
|
|
21965
|
+
ctx.instances.stopInstance(target.id);
|
|
21855
21966
|
} catch (e) {
|
|
21856
21967
|
log("\u505C\u6B62\u5B9E\u4F8B\u5931\u8D25: " + e.message);
|
|
21857
21968
|
}
|
|
@@ -22562,10 +22673,6 @@ var require_managed_object = __commonJS({
|
|
|
22562
22673
|
function registerKind(kind, meta) {
|
|
22563
22674
|
_customKinds[kind] = Object.assign({ label: kind, startable: false, guardable: false }, meta || {});
|
|
22564
22675
|
}
|
|
22565
|
-
var DOMAIN_A_KINDS = /* @__PURE__ */ new Set(["dsh", "sandbox-instance"]);
|
|
22566
|
-
function isDomainA(kind) {
|
|
22567
|
-
return DOMAIN_A_KINDS.has(kind);
|
|
22568
|
-
}
|
|
22569
22676
|
function createEntry(o) {
|
|
22570
22677
|
const meta = kindMeta(o.kind);
|
|
22571
22678
|
if (!meta) throw new Error("\u672A\u77E5\u53D7\u7BA1\u5BF9\u8C61\u7C7B\u578B: " + o.kind + "\uFF08\u5148 registerKind \u58F0\u660E\uFF09");
|
|
@@ -22576,8 +22683,9 @@ var require_managed_object = __commonJS({
|
|
|
22576
22683
|
name: String(o.name || o.id),
|
|
22577
22684
|
// desired 两域共用字段名但语义不同:域 A=用户意图;域 B=「当前业务是否需要它」的条件
|
|
22578
22685
|
desired: o.desired === "stopped" ? "stopped" : "running",
|
|
22579
|
-
// guardian
|
|
22580
|
-
|
|
22686
|
+
// guardian 开关的权威在域记录本身(dsh-main.json / inst.guardian),消费者全部直读源;
|
|
22687
|
+
// 目录曾在域 A entry 上物化该字段但零读者(B2-2 收口)。createEntry 永不物化 guardian 键
|
|
22688
|
+
// = 老库残留的天然一次性清理口(load 经本函数重建即消失),无需迁移脚本。
|
|
22581
22689
|
ownership: normalizeOwnership(o.ownership),
|
|
22582
22690
|
// 初始 stopped;业务不得直接改,由 heartbeat 调谐循环写入
|
|
22583
22691
|
phase: "stopped",
|
|
@@ -22612,7 +22720,7 @@ var require_managed_object = __commonJS({
|
|
|
22612
22720
|
// 域备注(只读参考)
|
|
22613
22721
|
};
|
|
22614
22722
|
}
|
|
22615
|
-
module2.exports = { DESIRED, MANAGED_KINDS, kindMeta, registerKind,
|
|
22723
|
+
module2.exports = { DESIRED, MANAGED_KINDS, kindMeta, registerKind, createEntry, normalizeOwnership };
|
|
22616
22724
|
}
|
|
22617
22725
|
});
|
|
22618
22726
|
|
|
@@ -22679,6 +22787,13 @@ var require_heartbeat = __commonJS({
|
|
|
22679
22787
|
registry._log("warn", "heartbeat " + (ad.supervise ? "supervise" : "observe") + "(" + e.kind + ":" + e.id + "): " + (err && err.message || err));
|
|
22680
22788
|
}
|
|
22681
22789
|
}
|
|
22790
|
+
if (typeof registry.onBeatDone === "function") {
|
|
22791
|
+
try {
|
|
22792
|
+
await registry.onBeatDone({ observed, errors });
|
|
22793
|
+
} catch (err) {
|
|
22794
|
+
registry._log("warn", "heartbeat onBeatDone: " + (err && err.message || err));
|
|
22795
|
+
}
|
|
22796
|
+
}
|
|
22682
22797
|
return { observed, errors };
|
|
22683
22798
|
}
|
|
22684
22799
|
module2.exports = { runHeartbeat, withTimeout, ADAPTER_TIMEOUT_TICKS };
|
|
@@ -22692,7 +22807,7 @@ var require_registry3 = __commonJS({
|
|
|
22692
22807
|
var fs2 = require("node:fs");
|
|
22693
22808
|
var path2 = require("node:path");
|
|
22694
22809
|
var { writeAtomic } = require_fs();
|
|
22695
|
-
var { DESIRED, MANAGED_KINDS, kindMeta, registerKind: registerManagedKind,
|
|
22810
|
+
var { DESIRED, MANAGED_KINDS, kindMeta, registerKind: registerManagedKind, createEntry, normalizeOwnership } = require_managed_object();
|
|
22696
22811
|
var PHASES = ["stopped", "installing", "starting", "running", "draining", "backoff", "failed", "restarting"];
|
|
22697
22812
|
var { runHeartbeat } = require_heartbeat();
|
|
22698
22813
|
var ManagedRegistry = class {
|
|
@@ -22743,7 +22858,7 @@ var require_registry3 = __commonJS({
|
|
|
22743
22858
|
for (const o of arr) {
|
|
22744
22859
|
try {
|
|
22745
22860
|
if (!o || !kindMeta(o.kind)) continue;
|
|
22746
|
-
const e = createEntry({ kind: o.kind, id: o.id, name: o.name, desired: o.desired,
|
|
22861
|
+
const e = createEntry({ kind: o.kind, id: o.id, name: o.name, desired: o.desired, ownership: o.ownership });
|
|
22747
22862
|
if (PHASES.includes(o.phase)) e.phase = o.phase;
|
|
22748
22863
|
if (Number.isInteger(o.backoffLevel)) e.backoffLevel = o.backoffLevel;
|
|
22749
22864
|
if (typeof o.backoffUntil === "number" && o.backoffUntil > Date.now()) e.backoffUntil = o.backoffUntil;
|
|
@@ -22770,7 +22885,7 @@ var require_registry3 = __commonJS({
|
|
|
22770
22885
|
kind: o.kind,
|
|
22771
22886
|
id: o.id,
|
|
22772
22887
|
name: o.name,
|
|
22773
|
-
// desired 两域共用(语义不同,见 createEntry);guardian
|
|
22888
|
+
// desired 两域共用(语义不同,见 createEntry);guardian 不落盘(B2-2,权威在域记录)。
|
|
22774
22889
|
desired: o.desired,
|
|
22775
22890
|
ownership: o.ownership,
|
|
22776
22891
|
phase: o.phase,
|
|
@@ -22782,7 +22897,7 @@ var require_registry3 = __commonJS({
|
|
|
22782
22897
|
startedAt: o.startedAt,
|
|
22783
22898
|
createdAt: o.createdAt,
|
|
22784
22899
|
updatedAt: o.updatedAt
|
|
22785
|
-
}
|
|
22900
|
+
}))
|
|
22786
22901
|
}, null, 2);
|
|
22787
22902
|
writeAtomic(this.file, body, { mode: 384 });
|
|
22788
22903
|
} catch (e) {
|
|
@@ -22844,8 +22959,8 @@ var require_registry3 = __commonJS({
|
|
|
22844
22959
|
this._event("managed_object_registered", { kind: e.kind, id: e.id, name: e.name });
|
|
22845
22960
|
return e;
|
|
22846
22961
|
}
|
|
22847
|
-
/** 对象变更申报(desired/
|
|
22848
|
-
*
|
|
22962
|
+
/** 对象变更申报(desired/ownership/name)。guardian 不接受申报(B2-2):createEntry 永不
|
|
22963
|
+
* 物化该键,patch 里带 guardian 一律忽略,老库残留由 load 重建时清理。 */
|
|
22849
22964
|
update(id, patch) {
|
|
22850
22965
|
const e = this.get(id);
|
|
22851
22966
|
if (!e) return { ok: false, error: "\u672A\u6CE8\u518C: " + id };
|
|
@@ -22854,11 +22969,6 @@ var require_registry3 = __commonJS({
|
|
|
22854
22969
|
if (!DESIRED.includes(p.desired)) return { ok: false, error: "\u975E\u6CD5 desired: " + p.desired };
|
|
22855
22970
|
e.desired = p.desired;
|
|
22856
22971
|
}
|
|
22857
|
-
if (isDomainA(e.kind)) {
|
|
22858
|
-
if (p.guardian !== void 0) e.guardian = p.guardian === true;
|
|
22859
|
-
} else if ("guardian" in e) {
|
|
22860
|
-
delete e.guardian;
|
|
22861
|
-
}
|
|
22862
22972
|
if (p.name !== void 0) e.name = String(p.name || e.id);
|
|
22863
22973
|
if (p.ownership !== void 0) {
|
|
22864
22974
|
const old = e.ownership.ports;
|
|
@@ -23276,20 +23386,23 @@ var require_npm = __commonJS({
|
|
|
23276
23386
|
const l = runtimeContract.npmLauncher();
|
|
23277
23387
|
return { program: l.program, args: l.args };
|
|
23278
23388
|
}
|
|
23279
|
-
function resolveNpmRoot(host2) {
|
|
23389
|
+
async function resolveNpmRoot(host2) {
|
|
23280
23390
|
if (host2.npmRoot) return host2.npmRoot;
|
|
23281
23391
|
const l = npmLaunch(host2);
|
|
23282
|
-
const r = ex2.
|
|
23392
|
+
const r = await ex2.runOutAsync(l.program, l.args.concat(["root", "-g"]));
|
|
23283
23393
|
return r ? r.trim() : null;
|
|
23284
23394
|
}
|
|
23285
|
-
function checkEnvironment(host2) {
|
|
23395
|
+
async function checkEnvironment(host2) {
|
|
23286
23396
|
const errors = [];
|
|
23287
|
-
const nv = ex2.runOut("node", ["--version"]);
|
|
23288
|
-
if (!nv || !nv.trim()) errors.push("node \u672A\u5B89\u88C5\u6216\u4E0D\u53EF\u6267\u884C");
|
|
23289
23397
|
const l = npmLaunch(host2);
|
|
23290
|
-
const npmv =
|
|
23398
|
+
const [nv, npmv, npmRoot] = await Promise.all([
|
|
23399
|
+
ex2.runOutAsync("node", ["--version"]),
|
|
23400
|
+
ex2.runOutAsync(l.program, l.args.concat(["--version"])),
|
|
23401
|
+
resolveNpmRoot(host2)
|
|
23402
|
+
]);
|
|
23403
|
+
if (!nv || !nv.trim()) errors.push("node \u672A\u5B89\u88C5\u6216\u4E0D\u53EF\u6267\u884C");
|
|
23291
23404
|
if (!npmv || !npmv.trim()) errors.push("npm \u672A\u5B89\u88C5\u6216\u4E0D\u53EF\u6267\u884C");
|
|
23292
|
-
return { ok: errors.length === 0, errors, npmRoot
|
|
23405
|
+
return { ok: errors.length === 0, errors, npmRoot };
|
|
23293
23406
|
}
|
|
23294
23407
|
async function latestVersion(host2) {
|
|
23295
23408
|
if (!host2.dist || !host2.config.packageName) throw new Error("\u5206\u53D1\u670D\u52A1\u672A\u521D\u59CB\u5316\uFF0C\u65E0\u6CD5\u67E5\u8BE2\u6700\u65B0\u7248\u672C");
|
|
@@ -23388,13 +23501,14 @@ var require_ops4 = __commonJS({
|
|
|
23388
23501
|
}
|
|
23389
23502
|
async function install(host2, version) {
|
|
23390
23503
|
if (!policies.isValidVersion(version)) return { ok: false, error: "\u975E\u6CD5\u7248\u672C\u53F7: " + version };
|
|
23391
|
-
const env = host2.checkEnvironment();
|
|
23392
|
-
if (!env.ok) return { ok: false, error: "\u73AF\u5883\u68C0\u67E5\u5931\u8D25: " + env.errors.join("; ") };
|
|
23393
23504
|
host2.installing = true;
|
|
23394
23505
|
host2.installLog = [];
|
|
23395
|
-
|
|
23396
|
-
let target = version;
|
|
23506
|
+
let task = null;
|
|
23397
23507
|
try {
|
|
23508
|
+
const env = await host2.checkEnvironment();
|
|
23509
|
+
if (!env.ok) return { ok: false, error: "\u73AF\u5883\u68C0\u67E5\u5931\u8D25: " + env.errors.join("; ") };
|
|
23510
|
+
task = beginTask(host2, "install", { to: version || null, createdBy: "user" });
|
|
23511
|
+
let target = version;
|
|
23398
23512
|
if (!target) {
|
|
23399
23513
|
target = await host2._latestVersion().catch(() => null);
|
|
23400
23514
|
if (!target) {
|
|
@@ -23417,7 +23531,7 @@ var require_ops4 = __commonJS({
|
|
|
23417
23531
|
return { ok: false, error: res.error, output: res.output };
|
|
23418
23532
|
}
|
|
23419
23533
|
const isFirstInstall = !host2._manifest();
|
|
23420
|
-
host2._recordManifest(target, isFirstInstall ? host2._claimDataPaths() : void 0);
|
|
23534
|
+
await host2._recordManifest(target, isFirstInstall ? host2._claimDataPaths() : void 0);
|
|
23421
23535
|
try {
|
|
23422
23536
|
if (typeof host2._bindNativeDshCommand === "function") host2._bindNativeDshCommand();
|
|
23423
23537
|
} catch (e) {
|
|
@@ -23442,8 +23556,6 @@ var require_ops4 = __commonJS({
|
|
|
23442
23556
|
if (host2.uninstalling) return { ok: false, error: "\u5378\u8F7D\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u518D\u88C5" };
|
|
23443
23557
|
if (policies.busy(host2)) return { ok: false, error: "\u5347\u7EA7\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u518D\u88C5\uFF08state=" + host2.upgradeState + "\uFF09" };
|
|
23444
23558
|
if (!policies.isValidVersion(version)) return { ok: false, error: "\u975E\u6CD5\u7248\u672C\u53F7: " + version };
|
|
23445
|
-
const env = host2.checkEnvironment();
|
|
23446
|
-
if (!env.ok) return { ok: false, error: "\u73AF\u5883\u68C0\u67E5\u5931\u8D25: " + env.errors.join("; ") };
|
|
23447
23559
|
install(host2, version).then(() => {
|
|
23448
23560
|
}).catch((e) => {
|
|
23449
23561
|
host2.installing = null;
|
|
@@ -23636,7 +23748,7 @@ var require_upgrade2 = __commonJS({
|
|
|
23636
23748
|
if (!res.ok) throw new Error(res.error || "install failed");
|
|
23637
23749
|
const newV = host2.installedVersion();
|
|
23638
23750
|
if (newV !== target) throw new Error("\u5B89\u88C5\u540E\u7248\u672C\u6821\u9A8C\u5931\u8D25\uFF1A\u671F\u671B " + target + "\uFF0C\u5B9E\u9645 " + newV);
|
|
23639
|
-
host2._recordManifest(newV || target);
|
|
23751
|
+
await host2._recordManifest(newV || target);
|
|
23640
23752
|
if (host2.events) host2.events.append("upgrade_installed", { from: oldV, to: target });
|
|
23641
23753
|
log(host2, "\u5B89\u88C5\u5B8C\u6210\uFF0C\u78C1\u76D8\u7248\u672C " + newV);
|
|
23642
23754
|
if (task) {
|
|
@@ -23706,9 +23818,9 @@ var require_upgrade2 = __commonJS({
|
|
|
23706
23818
|
async function rollbackAfterFailedVerify(host2, oldV, task, healthy) {
|
|
23707
23819
|
log(host2, "\u5065\u5EB7\u9A8C\u8BC1\u5931\u8D25\uFF08" + healthy.reason + "\uFF09");
|
|
23708
23820
|
if (task) host2.tasks.log(task.id, "\u5065\u5EB7\u9A8C\u8BC1\u5931\u8D25\uFF08" + healthy.reason + "\uFF09");
|
|
23709
|
-
host2.rolledBack = true;
|
|
23710
23821
|
host2.upgradeState = "rolling_back";
|
|
23711
23822
|
const rb = await rollbackNative(host2, oldV, task);
|
|
23823
|
+
host2.rolledBack = rb.ok === true;
|
|
23712
23824
|
host2.upgradeError = rb.ok ? "\u5347\u7EA7\u5931\u8D25\uFF0C\u5DF2\u56DE\u6EDA\u5230 " + oldV : "\u5347\u7EA7\u5931\u8D25\u4E14\u56DE\u6EDA\u5931\u8D25\uFF1A" + (rb.error || "");
|
|
23713
23825
|
host2.upgradeState = "failed";
|
|
23714
23826
|
host2.upgradeFinishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -23740,7 +23852,7 @@ var require_upgrade2 = __commonJS({
|
|
|
23740
23852
|
}
|
|
23741
23853
|
tlog("\u56DE\u6EDA\u5B8C\u6210\uFF0C\u78C1\u76D8\u7248\u672C " + oldVersion);
|
|
23742
23854
|
try {
|
|
23743
|
-
host2._recordManifest(oldVersion);
|
|
23855
|
+
await host2._recordManifest(oldVersion);
|
|
23744
23856
|
} catch (e2) {
|
|
23745
23857
|
tlog("manifest \u66F4\u65B0\u5931\u8D25: " + e2.message);
|
|
23746
23858
|
}
|
|
@@ -23755,7 +23867,6 @@ var require_upgrade2 = __commonJS({
|
|
|
23755
23867
|
}
|
|
23756
23868
|
async function rollbackAfterFailure(host2) {
|
|
23757
23869
|
host2.upgradeState = "rolling_back";
|
|
23758
|
-
host2.rolledBack = true;
|
|
23759
23870
|
if (host2.events) host2.events.append("upgrade_rollback_started", { to: host2.oldVersion });
|
|
23760
23871
|
log(host2, "\u56DE\u6EDA\u5230 " + host2.oldVersion + "\u2026");
|
|
23761
23872
|
const registry = await host2._selectRegistry();
|
|
@@ -23776,8 +23887,9 @@ var require_upgrade2 = __commonJS({
|
|
|
23776
23887
|
return { ok: false };
|
|
23777
23888
|
}
|
|
23778
23889
|
log(host2, "\u56DE\u6EDA\u5B8C\u6210\u3002");
|
|
23890
|
+
host2.rolledBack = true;
|
|
23779
23891
|
try {
|
|
23780
|
-
host2._recordManifest(host2.oldVersion);
|
|
23892
|
+
await host2._recordManifest(host2.oldVersion);
|
|
23781
23893
|
} catch (e2) {
|
|
23782
23894
|
log(host2, "manifest \u66F4\u65B0\u5931\u8D25: " + e2.message);
|
|
23783
23895
|
}
|
|
@@ -23927,8 +24039,8 @@ var require_installer = __commonJS({
|
|
|
23927
24039
|
_saveManifest(m) {
|
|
23928
24040
|
return manifest.save(this, m);
|
|
23929
24041
|
}
|
|
23930
|
-
_recordManifest(version, dataPaths) {
|
|
23931
|
-
return manifest.record(this, version, dataPaths, this.npmRoot || npm.resolveNpmRoot(this));
|
|
24042
|
+
async _recordManifest(version, dataPaths) {
|
|
24043
|
+
return manifest.record(this, version, dataPaths, this.npmRoot || await npm.resolveNpmRoot(this));
|
|
23932
24044
|
}
|
|
23933
24045
|
_claimDataPaths() {
|
|
23934
24046
|
return manifest.claimDataPaths(this);
|
|
@@ -24310,6 +24422,7 @@ var require_domains = __commonJS({
|
|
|
24310
24422
|
host2.managedObjects.registerAdapter("dsh", { supervise: () => host2._dshSuperviseOnce(), tickEvery: 1 });
|
|
24311
24423
|
host2.managedObjects.registerAdapter("sandbox-instance", { supervise: (entry) => host2._sandboxSuperviseOnce(entry), tickEvery: 1 });
|
|
24312
24424
|
}
|
|
24425
|
+
if (host2.managedObjects) host2.managedObjects.onBeatDone = () => host2.instances.governSweep();
|
|
24313
24426
|
} catch (e) {
|
|
24314
24427
|
host2.logger && host2.logger.warn && host2.logger.warn("managed registry init: " + (e && e.message));
|
|
24315
24428
|
}
|
|
@@ -24904,7 +25017,7 @@ var require_guard = __commonJS({
|
|
|
24904
25017
|
}
|
|
24905
25018
|
}
|
|
24906
25019
|
if (req.method === "GET" && pathname === "/guard/version") {
|
|
24907
|
-
return send(200,
|
|
25020
|
+
return Promise.resolve(sup.guardVersionLocal()).then((r) => send(200, r)).catch((e) => send(500, { ok: false, error: e.message }));
|
|
24908
25021
|
}
|
|
24909
25022
|
if (req.method === "POST" && pathname === "/guard/version/check") {
|
|
24910
25023
|
req.resume();
|
|
@@ -25049,7 +25162,7 @@ var require_guard = __commonJS({
|
|
|
25049
25162
|
req.resume();
|
|
25050
25163
|
return send(403, {});
|
|
25051
25164
|
}
|
|
25052
|
-
return send(200,
|
|
25165
|
+
return Promise.resolve(sup.envStatus()).then((r) => send(200, r)).catch((e) => send(500, { ok: false, error: e.message }));
|
|
25053
25166
|
}
|
|
25054
25167
|
if (req.method === "GET" && pathname === "/env/node-lts") {
|
|
25055
25168
|
return sup.nodeLtsStatus().then((r) => send(200, r)).catch((e) => send(500, { ok: false, error: e.message }));
|
|
@@ -25704,7 +25817,7 @@ var require_instances = __commonJS({
|
|
|
25704
25817
|
const r = sup.instances.updateInstance(j.id, j);
|
|
25705
25818
|
return send(r && r.ok ? 200 : 400, r);
|
|
25706
25819
|
}
|
|
25707
|
-
if (act === "start" && j.id) return Promise.resolve(sup.instances.startInstance(j.id)).then((r) => send(r && r.ok ? 200 : 400, r)).catch((e) => send(500, { ok: false, error: e.message }));
|
|
25820
|
+
if (act === "start" && j.id) return Promise.resolve(sup.instances.startInstance(j.id, { manual: true })).then((r) => send(r && r.ok ? 200 : 400, r)).catch((e) => send(500, { ok: false, error: e.message }));
|
|
25708
25821
|
if (act === "stop" && j.id) {
|
|
25709
25822
|
const r = sup.instances.stopInstance(j.id);
|
|
25710
25823
|
return send(r && r.ok ? 200 : 400, r);
|
|
@@ -26772,10 +26885,7 @@ var require_managed = __commonJS({
|
|
|
26772
26885
|
const main = typeof mainOf === "function" ? mainOf() : null;
|
|
26773
26886
|
return main ? [...sandboxes, main] : sandboxes;
|
|
26774
26887
|
}
|
|
26775
|
-
|
|
26776
|
-
return (list || []).find((x) => x.id === id) || null;
|
|
26777
|
-
}
|
|
26778
|
-
module2.exports = { localAddresses, allManaged, findManaged };
|
|
26888
|
+
module2.exports = { localAddresses, allManaged };
|
|
26779
26889
|
}
|
|
26780
26890
|
});
|
|
26781
26891
|
|
|
@@ -27481,7 +27591,6 @@ var require_ops5 = __commonJS({
|
|
|
27481
27591
|
this.instances = opts.instances;
|
|
27482
27592
|
this.configPath = opts.configPath || "";
|
|
27483
27593
|
this.mainOf = opts.mainOf || null;
|
|
27484
|
-
this.persist = opts.persist || null;
|
|
27485
27594
|
this.frp = opts.frp || new FrpManager({ dir: opts.stateDir, logger: this.logger, events: this.events });
|
|
27486
27595
|
this.lanInstances = [];
|
|
27487
27596
|
this._reconcileInFlight = null;
|
|
@@ -27492,31 +27601,10 @@ var require_ops5 = __commonJS({
|
|
|
27492
27601
|
localAddresses() {
|
|
27493
27602
|
return managed.localAddresses();
|
|
27494
27603
|
}
|
|
27495
|
-
/** 持久化:优先注入的 persist 路由,否则回退沙箱 instances.save()。 */
|
|
27496
|
-
_saveAll() {
|
|
27497
|
-
if (typeof this.persist === "function") {
|
|
27498
|
-
try {
|
|
27499
|
-
this.persist();
|
|
27500
|
-
} catch (e) {
|
|
27501
|
-
this.logger && this.logger.warn && this.logger.warn("lan persist: " + (e && e.message));
|
|
27502
|
-
}
|
|
27503
|
-
return;
|
|
27504
|
-
}
|
|
27505
|
-
if (this.instances && typeof this.instances.save === "function") {
|
|
27506
|
-
try {
|
|
27507
|
-
this.instances.save();
|
|
27508
|
-
} catch {
|
|
27509
|
-
}
|
|
27510
|
-
}
|
|
27511
|
-
}
|
|
27512
27604
|
/** 受管 DSH 合成清单(沙箱 + 原生主干 main)。 */
|
|
27513
27605
|
_allManaged() {
|
|
27514
27606
|
return managed.allManaged({ instances: this.instances, mainOf: this.mainOf });
|
|
27515
27607
|
}
|
|
27516
|
-
/** 合成查找:按 id 取首个匹配。 */
|
|
27517
|
-
_findManaged(id) {
|
|
27518
|
-
return managed.findManaged(this._allManaged(), id);
|
|
27519
|
-
}
|
|
27520
27608
|
/** frpc 子进程句柄只读访问器:不暴露 frp 私有对象,供 daemon 优雅停机等待其退出。 */
|
|
27521
27609
|
frpChild() {
|
|
27522
27610
|
return this.frp && this.frp.child || null;
|
|
@@ -27796,13 +27884,6 @@ var require_supervisor = __commonJS({
|
|
|
27796
27884
|
m.kind = "native";
|
|
27797
27885
|
return m;
|
|
27798
27886
|
},
|
|
27799
|
-
persist: () => {
|
|
27800
|
-
try {
|
|
27801
|
-
if (this.instances && this.instances.save) this.instances.save();
|
|
27802
|
-
} catch {
|
|
27803
|
-
}
|
|
27804
|
-
this._writeDshMain({});
|
|
27805
|
-
},
|
|
27806
27887
|
tokenOf: (id) => this.tokenService.get(id)
|
|
27807
27888
|
});
|
|
27808
27889
|
}
|
|
@@ -27918,28 +27999,45 @@ function printSelfVersion() {
|
|
|
27918
27999
|
const { guardVersion } = require_version();
|
|
27919
28000
|
console.log("dsh-supervisor v" + guardVersion());
|
|
27920
28001
|
}
|
|
27921
|
-
function
|
|
28002
|
+
function apiRaw(method, apiPath, body) {
|
|
27922
28003
|
return new Promise((resolve) => {
|
|
27923
28004
|
const addr = readApiAddress();
|
|
27924
28005
|
const req = http.request(
|
|
27925
|
-
{
|
|
28006
|
+
{
|
|
28007
|
+
hostname: addr.host,
|
|
28008
|
+
port: addr.port,
|
|
28009
|
+
path: apiPath,
|
|
28010
|
+
method,
|
|
28011
|
+
timeout: 5e3,
|
|
28012
|
+
headers: body ? { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(body) } : {}
|
|
28013
|
+
},
|
|
27926
28014
|
(res) => {
|
|
27927
|
-
let
|
|
27928
|
-
res.
|
|
27929
|
-
res.on("
|
|
27930
|
-
|
|
27931
|
-
|
|
27932
|
-
} catch {
|
|
27933
|
-
resolve({ error: "parse error", raw: body });
|
|
27934
|
-
}
|
|
27935
|
-
});
|
|
27936
|
-
res.on("error", () => resolve({ error: "response error" }));
|
|
28015
|
+
let text = "";
|
|
28016
|
+
res.setEncoding("utf8");
|
|
28017
|
+
res.on("data", (d) => text += d);
|
|
28018
|
+
res.on("end", () => resolve({ status: res.statusCode, text }));
|
|
28019
|
+
res.on("error", (e) => resolve({ status: 0, text: "", error: e.message }));
|
|
27937
28020
|
}
|
|
27938
28021
|
);
|
|
27939
|
-
req.on("
|
|
28022
|
+
req.on("timeout", () => req.destroy(new Error("api-timeout")));
|
|
28023
|
+
req.on(
|
|
28024
|
+
"error",
|
|
28025
|
+
(e) => resolve({ status: 0, text: "", error: e && e.message === "api-timeout" ? "daemon \u54CD\u5E94\u8D85\u65F6\uFF085s\uFF09" : "daemon \u672A\u8FD0\u884C\u6216\u8FDE\u63A5\u5931\u8D25" })
|
|
28026
|
+
);
|
|
28027
|
+
if (body) req.write(body);
|
|
27940
28028
|
req.end();
|
|
27941
28029
|
});
|
|
27942
28030
|
}
|
|
28031
|
+
function apiRequest(method, apiPath) {
|
|
28032
|
+
return apiRaw(method, apiPath).then(({ status, text, error }) => {
|
|
28033
|
+
if (error) return { error };
|
|
28034
|
+
try {
|
|
28035
|
+
return JSON.parse(text);
|
|
28036
|
+
} catch {
|
|
28037
|
+
return { error: "parse error", raw: text };
|
|
28038
|
+
}
|
|
28039
|
+
});
|
|
28040
|
+
}
|
|
27943
28041
|
var LOCK_FILE = process.env.DSH_SUPERVISOR_LOCK_FILE || path.join(SUPERVISOR_DIR, "guard.lock");
|
|
27944
28042
|
var LOCK_OWNER = { pid: process.pid, started: Date.now(), entry: process.argv[1] || "" };
|
|
27945
28043
|
function readLock() {
|
|
@@ -28258,26 +28356,9 @@ function cmdVersion() {
|
|
|
28258
28356
|
});
|
|
28259
28357
|
}
|
|
28260
28358
|
function cmdSelfUpdate(action) {
|
|
28261
|
-
const addr = readApiAddress();
|
|
28262
|
-
const apiOne = (method, p, body) => new Promise((resolve) => {
|
|
28263
|
-
const req = http.request({ hostname: addr.host, port: addr.port, path: p, method, timeout: 5e3, headers: body ? { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(body) } : {} }, (res) => {
|
|
28264
|
-
let b = "";
|
|
28265
|
-
res.on("data", (d) => b += d);
|
|
28266
|
-
res.on("end", () => {
|
|
28267
|
-
try {
|
|
28268
|
-
resolve(JSON.parse(b));
|
|
28269
|
-
} catch {
|
|
28270
|
-
resolve({ error: "parse error", raw: b });
|
|
28271
|
-
}
|
|
28272
|
-
});
|
|
28273
|
-
});
|
|
28274
|
-
req.on("error", () => resolve({ error: "daemon \u672A\u8FD0\u884C\u6216\u8FDE\u63A5\u5931\u8D25" }));
|
|
28275
|
-
if (body) req.write(body);
|
|
28276
|
-
req.end();
|
|
28277
|
-
});
|
|
28278
28359
|
(async () => {
|
|
28279
28360
|
if (action === "check" || !action) {
|
|
28280
|
-
const s = await
|
|
28361
|
+
const s = await apiRequest("GET", "/self-update/status");
|
|
28281
28362
|
if (s.error) return console.log("\u68C0\u67E5\u5931\u8D25: " + s.error);
|
|
28282
28363
|
if (s.ok) {
|
|
28283
28364
|
console.log("\u5B88\u536B\u5F53\u524D\u7248\u672C: " + s.installed);
|
|
@@ -28295,31 +28376,13 @@ function cmdSelfUpdate(action) {
|
|
|
28295
28376
|
})();
|
|
28296
28377
|
}
|
|
28297
28378
|
function cmdUpgrade(requested) {
|
|
28298
|
-
const
|
|
28299
|
-
|
|
28300
|
-
|
|
28301
|
-
const
|
|
28302
|
-
|
|
28303
|
-
hostname: addr.host,
|
|
28304
|
-
port: addr.port,
|
|
28305
|
-
path: "/native/upgrade",
|
|
28306
|
-
method: "POST",
|
|
28307
|
-
timeout: 5e3,
|
|
28308
|
-
headers: body ? { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(body) } : {}
|
|
28309
|
-
},
|
|
28310
|
-
(res) => {
|
|
28311
|
-
let b = "";
|
|
28312
|
-
res.on("data", (d) => b += d);
|
|
28313
|
-
res.on("end", () => resolve({ code: res.statusCode, body: b }));
|
|
28314
|
-
}
|
|
28315
|
-
);
|
|
28316
|
-
req.on("error", () => resolve({ code: 0, body: "" }));
|
|
28317
|
-
if (body) req.write(body);
|
|
28318
|
-
req.end();
|
|
28319
|
-
});
|
|
28320
|
-
post().then(({ code, body }) => {
|
|
28379
|
+
const body = requested ? JSON.stringify({ version: requested }) : void 0;
|
|
28380
|
+
const post = () => apiRaw("POST", "/native/upgrade", body);
|
|
28381
|
+
post().then(({ status, text, error }) => {
|
|
28382
|
+
const code = error ? 0 : status;
|
|
28383
|
+
const outText = error ? "" : text;
|
|
28321
28384
|
if (code !== 202) {
|
|
28322
|
-
console.log("\u5347\u7EA7\u672A\u88AB\u63A5\u53D7:",
|
|
28385
|
+
console.log("\u5347\u7EA7\u672A\u88AB\u63A5\u53D7:", outText || "HTTP " + code);
|
|
28323
28386
|
process.exit(1);
|
|
28324
28387
|
}
|
|
28325
28388
|
console.log("\u5347\u7EA7\u5DF2\u5F00\u59CB\uFF0C\u8DDF\u8E2A\u8FDB\u5EA6\uFF08\u5148\u505C DSH \u2192 \u5B89\u88C5 \u2192 \u81EA\u52A8\u62C9\u8D77\uFF0C\u9700\u6570\u5206\u949F\uFF09\u2026");
|