@dsh-sup/dsh-core-linux-x64 0.1.6-BETA.5 → 0.1.6-BETA.6
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 +397 -276
- 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.6");
|
|
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();
|
|
@@ -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();
|
|
@@ -3172,6 +3207,14 @@ var require_store2 = __commonJS({
|
|
|
3172
3207
|
}
|
|
3173
3208
|
return out;
|
|
3174
3209
|
}
|
|
3210
|
+
function fileStamp(file) {
|
|
3211
|
+
try {
|
|
3212
|
+
const st = fs2.statSync(file);
|
|
3213
|
+
return st.mtimeMs + ":" + st.size;
|
|
3214
|
+
} catch {
|
|
3215
|
+
return "0";
|
|
3216
|
+
}
|
|
3217
|
+
}
|
|
3175
3218
|
function saveRecords(file, records) {
|
|
3176
3219
|
try {
|
|
3177
3220
|
fs2.mkdirSync(path2.dirname(file), { recursive: true });
|
|
@@ -3197,7 +3240,7 @@ var require_store2 = __commonJS({
|
|
|
3197
3240
|
}
|
|
3198
3241
|
return out;
|
|
3199
3242
|
}
|
|
3200
|
-
module2.exports = { loadRecords, saveRecords, extraRecords };
|
|
3243
|
+
module2.exports = { loadRecords, saveRecords, extraRecords, fileStamp };
|
|
3201
3244
|
}
|
|
3202
3245
|
});
|
|
3203
3246
|
|
|
@@ -3440,6 +3483,7 @@ var require_alloc = __commonJS({
|
|
|
3440
3483
|
}
|
|
3441
3484
|
r._allocLock = true;
|
|
3442
3485
|
this._xrel = await this._acquireXLock();
|
|
3486
|
+
r._syncFromDisk();
|
|
3443
3487
|
}
|
|
3444
3488
|
_releaseAlloc() {
|
|
3445
3489
|
this._registry._allocLock = false;
|
|
@@ -3694,6 +3738,14 @@ var require_pool = __commonJS({
|
|
|
3694
3738
|
_load() {
|
|
3695
3739
|
this._records = /* @__PURE__ */ new Map();
|
|
3696
3740
|
for (const r of store.loadRecords(this._file)) this._records.set(r.port, r);
|
|
3741
|
+
this._diskStamp = store.fileStamp(this._file);
|
|
3742
|
+
}
|
|
3743
|
+
/** 跨进程对时(B2-5):ports.json 是多进程(守卫 + lan-daemon)共享事实源,各方全量
|
|
3744
|
+
* read-modify-write,陈旧内存快照会在 _save 时把他人新增整段覆盖丢失、或让分配器抢注
|
|
3745
|
+
* 他进程已登记的端口。指纹(mtime+size)变化即重载——所有写口与冲突判读口的入口。
|
|
3746
|
+
* 不动 _allocLock(复位会击穿本进程在飞分配的互斥)。 */
|
|
3747
|
+
_syncFromDisk() {
|
|
3748
|
+
if (store.fileStamp(this._file) !== this._diskStamp) this._load();
|
|
3697
3749
|
}
|
|
3698
3750
|
/** 重新从文件加载(读路径先 reload,以权威文件为准)。 */
|
|
3699
3751
|
reload() {
|
|
@@ -3703,6 +3755,7 @@ var require_pool = __commonJS({
|
|
|
3703
3755
|
}
|
|
3704
3756
|
_save() {
|
|
3705
3757
|
store.saveRecords(this._file, [...this._records.values()]);
|
|
3758
|
+
this._diskStamp = store.fileStamp(this._file);
|
|
3706
3759
|
}
|
|
3707
3760
|
/** 通用记录迁移:owner 命中任一前缀的记录 oldFile 到 newFile,并从旧文件清除。 */
|
|
3708
3761
|
migrateByOwnerPrefix(oldFile, newFile, prefixes) {
|
|
@@ -3711,6 +3764,7 @@ var require_pool = __commonJS({
|
|
|
3711
3764
|
/* 登记(固定 / 用户 / 动态) */
|
|
3712
3765
|
/** 登记固定端口;同端口已被其它固定角色占用则报错;user/动态记录由固定权威覆盖。 */
|
|
3713
3766
|
register(role, port) {
|
|
3767
|
+
this._syncFromDisk();
|
|
3714
3768
|
const p = Number(port);
|
|
3715
3769
|
if (!Number.isInteger(p) || p <= 0 || p > 65535) throw new Error("ports.register: \u975E\u6CD5\u7AEF\u53E3 " + port);
|
|
3716
3770
|
const existing = this._records.get(p);
|
|
@@ -3737,6 +3791,7 @@ var require_pool = __commonJS({
|
|
|
3737
3791
|
}
|
|
3738
3792
|
/** 登记用户配置端口(实例内部端口等);冲突(固定/保留池/已占)抛错。 */
|
|
3739
3793
|
registerUser(port, owner) {
|
|
3794
|
+
this._syncFromDisk();
|
|
3740
3795
|
const p = Number(port);
|
|
3741
3796
|
if (!Number.isInteger(p) || p <= 0 || p > 65535) throw new Error("ports.registerUser: \u975E\u6CD5\u7AEF\u53E3 " + port);
|
|
3742
3797
|
if (this._records.has(p)) throw new Error("\u7AEF\u53E3 " + p + " \u5DF2\u88AB [" + this._records.get(p).role + "] \u5360\u7528");
|
|
@@ -3748,6 +3803,7 @@ var require_pool = __commonJS({
|
|
|
3748
3803
|
}
|
|
3749
3804
|
/** 按 owner 释放端口(对象删除/关闭时调用)。 */
|
|
3750
3805
|
unregister(owner) {
|
|
3806
|
+
this._syncFromDisk();
|
|
3751
3807
|
let removed = false;
|
|
3752
3808
|
for (const [p, r] of this._records) {
|
|
3753
3809
|
if (r.owner === owner) {
|
|
@@ -3760,6 +3816,7 @@ var require_pool = __commonJS({
|
|
|
3760
3816
|
/** 释放端口:不传 ownerId 按端口号;传了则仅当登记 owner 匹配才释放。空值检查必须先于 owner 比较。
|
|
3761
3817
|
* @returns {boolean} 是否真的释放了一条记录 */
|
|
3762
3818
|
release(port, ownerId) {
|
|
3819
|
+
this._syncFromDisk();
|
|
3763
3820
|
const p = Number(port);
|
|
3764
3821
|
const rec = this._records.get(p);
|
|
3765
3822
|
if (!rec) return false;
|
|
@@ -3772,6 +3829,7 @@ var require_pool = __commonJS({
|
|
|
3772
3829
|
/** 按 role 取端口(固定端口)。同 role 有多条(老版本避让留下的残留记录)时取**最新登记**:
|
|
3773
3830
|
* 桌面壳读 ports.json 用的是同一判据,两侧不许对「哪个端口是当前的」给出不同答案。 */
|
|
3774
3831
|
get(role) {
|
|
3832
|
+
this._syncFromDisk();
|
|
3775
3833
|
let best = null;
|
|
3776
3834
|
for (const r of this._records.values()) {
|
|
3777
3835
|
if (r.role !== role) continue;
|
|
@@ -3780,12 +3838,15 @@ var require_pool = __commonJS({
|
|
|
3780
3838
|
return best ? best.port : null;
|
|
3781
3839
|
}
|
|
3782
3840
|
isRegistered(port) {
|
|
3841
|
+
this._syncFromDisk();
|
|
3783
3842
|
return this._records.has(Number(port));
|
|
3784
3843
|
}
|
|
3785
3844
|
recordOf(port) {
|
|
3845
|
+
this._syncFromDisk();
|
|
3786
3846
|
return this._records.get(Number(port)) || null;
|
|
3787
3847
|
}
|
|
3788
3848
|
byOwner(owner) {
|
|
3849
|
+
this._syncFromDisk();
|
|
3789
3850
|
for (const r of this._records.values()) if (r.owner === owner) return r.port;
|
|
3790
3851
|
return null;
|
|
3791
3852
|
}
|
|
@@ -3798,6 +3859,7 @@ var require_pool = __commonJS({
|
|
|
3798
3859
|
}
|
|
3799
3860
|
/** 全部端口清单(按端口升序)。 */
|
|
3800
3861
|
list() {
|
|
3862
|
+
this._syncFromDisk();
|
|
3801
3863
|
return [...this._records.values()].sort((a, b) => a.port - b.port);
|
|
3802
3864
|
}
|
|
3803
3865
|
/** 只读聚合:本注册表 + 同目录下其它注册表文件(去重,本表优先)。
|
|
@@ -3822,6 +3884,7 @@ var require_pool = __commonJS({
|
|
|
3822
3884
|
}
|
|
3823
3885
|
/** 显式登记已分配端口(复用持久化端口时调用)。 */
|
|
3824
3886
|
allocateMark(port, role, owner) {
|
|
3887
|
+
this._syncFromDisk();
|
|
3825
3888
|
const p = Number(port);
|
|
3826
3889
|
if (!this._records.has(p)) {
|
|
3827
3890
|
this._records.set(p, { port: p, role: role || "dynamic", owner: owner || "dynamic", createdAt: Date.now() });
|
|
@@ -4016,6 +4079,7 @@ var require_collaborators = __commonJS({
|
|
|
4016
4079
|
var { createCtl } = require_collaborator3();
|
|
4017
4080
|
var { createOrphanScan } = require_collaborator4();
|
|
4018
4081
|
var { ENTRY_FIELDS, PROC_FIELDS } = require_field_tables();
|
|
4082
|
+
var { aliases: CONFIG_ALIASES } = require_domain_config();
|
|
4019
4083
|
var THIN_SPEC = {
|
|
4020
4084
|
ctl: {
|
|
4021
4085
|
call: "_ctlCall",
|
|
@@ -4105,6 +4169,7 @@ var require_collaborators = __commonJS({
|
|
|
4105
4169
|
const state = createStateStore({
|
|
4106
4170
|
getConfig: () => host2.config,
|
|
4107
4171
|
getConfigPath: () => host2.configPath,
|
|
4172
|
+
getConfigAliases: () => CONFIG_ALIASES,
|
|
4108
4173
|
getLogger: () => host2.logger,
|
|
4109
4174
|
getEvents: () => host2.events,
|
|
4110
4175
|
getManagedObjects: () => host2.managedObjects,
|
|
@@ -4150,7 +4215,6 @@ var require_collaborators = __commonJS({
|
|
|
4150
4215
|
return host2;
|
|
4151
4216
|
};
|
|
4152
4217
|
host2._dshEntry = () => state.dshEntry();
|
|
4153
|
-
host2._mainFallbackEntry = () => state.fallbackEntry();
|
|
4154
4218
|
host2._persistCrashField = () => state.persistCrashField();
|
|
4155
4219
|
host2._mStore = () => state.store();
|
|
4156
4220
|
host2._mField = function(name, v) {
|
|
@@ -7817,8 +7881,8 @@ var require_instance_adapter = __commonJS({
|
|
|
7817
7881
|
return { ok: running, error: running ? null : "\u6C99\u7BB1\u5B9E\u4F8B\u672A\u8FD0\u884C" };
|
|
7818
7882
|
},
|
|
7819
7883
|
/** 目录项 <- 实例域状态对齐(监督拍后调用):实例已删 -> 注销(防死登记);存在 -> 经
|
|
7820
|
-
* sandboxSpec 同步 name/guardian/ownership + phase
|
|
7821
|
-
*
|
|
7884
|
+
* sandboxSpec 同步 name/guardian/ownership + phase 落目录词表。沙箱不申报 desired
|
|
7885
|
+
* (运行意图无第二落点,B2-1),观测路径因此不可能改写任何意图。 */
|
|
7822
7886
|
_syncSandboxRegistryEntry(entry) {
|
|
7823
7887
|
const d = depsOf(this);
|
|
7824
7888
|
if (!entry || !d.managedObjects() || !d.instances()) return;
|
|
@@ -7851,6 +7915,9 @@ var require_decide = __commonJS({
|
|
|
7851
7915
|
"src/app/main/decide.js"(exports2, module2) {
|
|
7852
7916
|
"use strict";
|
|
7853
7917
|
var pidlook = require_pidlookup();
|
|
7918
|
+
function startDeadlinePassed(deadline, now) {
|
|
7919
|
+
return !!(deadline && now > deadline);
|
|
7920
|
+
}
|
|
7854
7921
|
var DEPS = /* @__PURE__ */ new WeakMap();
|
|
7855
7922
|
function depsOf(host2) {
|
|
7856
7923
|
let d = DEPS.get(host2);
|
|
@@ -7938,7 +8005,7 @@ var require_decide = __commonJS({
|
|
|
7938
8005
|
upgradeHold: d.upgradeHold() === true,
|
|
7939
8006
|
manualRestart: d.manualRestart() === true,
|
|
7940
8007
|
spawnBlocked: !!(d.mSpawnBlockedUntil() && now < d.mSpawnBlockedUntil()),
|
|
7941
|
-
startDeadlinePassed:
|
|
8008
|
+
startDeadlinePassed: startDeadlinePassed(d.mStartDeadline(), now),
|
|
7942
8009
|
restartDue: d.mRestartAt() === null || now >= d.mRestartAt(),
|
|
7943
8010
|
backoffDue: d.mBackoffUntil() === null || now >= d.mBackoffUntil(),
|
|
7944
8011
|
// `_shouldRun()` 有两个否决位,快照必须建模(crashHalted/sessionHalting),否则影子每拍
|
|
@@ -8013,7 +8080,9 @@ var require_decide = __commonJS({
|
|
|
8013
8080
|
_decideCrashRestart(reason) {
|
|
8014
8081
|
return decideCrashRestart(reason);
|
|
8015
8082
|
}
|
|
8016
|
-
}
|
|
8083
|
+
},
|
|
8084
|
+
// 非 host 方法:纯谓词导出,controller 与本文件快照判据共用(facets 只安装 methods)。
|
|
8085
|
+
startDeadlinePassed
|
|
8017
8086
|
};
|
|
8018
8087
|
}
|
|
8019
8088
|
});
|
|
@@ -8064,6 +8133,7 @@ var require_controller = __commonJS({
|
|
|
8064
8133
|
"use strict";
|
|
8065
8134
|
var pidlook = require_pidlookup();
|
|
8066
8135
|
var monitor = require_monitor();
|
|
8136
|
+
var { startDeadlinePassed } = require_decide();
|
|
8067
8137
|
var DEPS = /* @__PURE__ */ new WeakMap();
|
|
8068
8138
|
function depsOf(host2) {
|
|
8069
8139
|
let d = DEPS.get(host2);
|
|
@@ -8168,6 +8238,9 @@ var require_controller = __commonJS({
|
|
|
8168
8238
|
mStartDeadline() {
|
|
8169
8239
|
return host2._mStartDeadline();
|
|
8170
8240
|
},
|
|
8241
|
+
mSetStartDeadline(v) {
|
|
8242
|
+
return host2._mSetStartDeadline(v);
|
|
8243
|
+
},
|
|
8171
8244
|
mRestartAt() {
|
|
8172
8245
|
return host2._mRestartAt();
|
|
8173
8246
|
},
|
|
@@ -8315,7 +8388,9 @@ var require_controller = __commonJS({
|
|
|
8315
8388
|
}
|
|
8316
8389
|
case "STARTING": {
|
|
8317
8390
|
if (portUp && healthOk) d.main().enterRunning();
|
|
8318
|
-
else if (
|
|
8391
|
+
else if (d.mStartDeadline() === null) {
|
|
8392
|
+
d.mSetStartDeadline(Date.now() + d.config().startTimeoutMs);
|
|
8393
|
+
} else if (startDeadlinePassed(d.mStartDeadline(), Date.now())) d.main().beginRestart("start_timeout", { countCrash: true });
|
|
8319
8394
|
break;
|
|
8320
8395
|
}
|
|
8321
8396
|
case "RUNNING": {
|
|
@@ -9569,13 +9644,7 @@ var require_process_wait = __commonJS({
|
|
|
9569
9644
|
async function waitProcessExit(pid, timeoutMs) {
|
|
9570
9645
|
const deadline = Date.now() + timeoutMs;
|
|
9571
9646
|
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;
|
|
9647
|
+
if (!pidlook.isAlive(pid)) return true;
|
|
9579
9648
|
await new Promise((r) => setTimeout(r, 200));
|
|
9580
9649
|
}
|
|
9581
9650
|
return false;
|
|
@@ -9693,13 +9762,15 @@ var require_process3 = __commonJS({
|
|
|
9693
9762
|
} catch {
|
|
9694
9763
|
}
|
|
9695
9764
|
}
|
|
9765
|
+
/** 判活(platform/pidlookup.probeAlive 单源):unknown 不 fail-open——必须有第二条证据
|
|
9766
|
+
* (ctl 端口属主正是该 pid 且 cmdline 匹配本服务)才认活,否则按死走 reclaim/spawn。
|
|
9767
|
+
* fail-open 会让已死 daemon 被判活,此后既不接管也不拉起,永不自愈。 */
|
|
9696
9768
|
_pidAlive(pid) {
|
|
9697
9769
|
if (!pid) return false;
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
|
|
9701
|
-
|
|
9702
|
-
}
|
|
9770
|
+
const st = pidlook.probeAlive(pid);
|
|
9771
|
+
if (st === "alive") return true;
|
|
9772
|
+
if (st === "dead") return false;
|
|
9773
|
+
return this._ctlOwnerPid() === pid;
|
|
9703
9774
|
}
|
|
9704
9775
|
/** ctl 端口的监听者是否就是本服务进程(cmdline 匹配)。 */
|
|
9705
9776
|
_ctlOwnerPid() {
|
|
@@ -10205,6 +10276,7 @@ var require_identity = __commonJS({
|
|
|
10205
10276
|
"use strict";
|
|
10206
10277
|
var fs2 = require("node:fs");
|
|
10207
10278
|
var path2 = require("node:path");
|
|
10279
|
+
var { isAlive } = require_pidlookup();
|
|
10208
10280
|
function lockPid(p) {
|
|
10209
10281
|
if (!p) return null;
|
|
10210
10282
|
try {
|
|
@@ -10215,13 +10287,7 @@ var require_identity = __commonJS({
|
|
|
10215
10287
|
}
|
|
10216
10288
|
}
|
|
10217
10289
|
function pidAlive2(pid) {
|
|
10218
|
-
|
|
10219
|
-
try {
|
|
10220
|
-
process.kill(pid, 0);
|
|
10221
|
-
return true;
|
|
10222
|
-
} catch (e) {
|
|
10223
|
-
return !!(e && e.code === "EPERM");
|
|
10224
|
-
}
|
|
10290
|
+
return isAlive(pid);
|
|
10225
10291
|
}
|
|
10226
10292
|
function acquireLock2(p, onErr) {
|
|
10227
10293
|
if (!p) return false;
|
|
@@ -10602,7 +10668,7 @@ var require_ports2 = __commonJS({
|
|
|
10602
10668
|
"use strict";
|
|
10603
10669
|
var probe = require_probe2();
|
|
10604
10670
|
var ports = require_ports().shared;
|
|
10605
|
-
var SIBLING_REGISTRIES = ["ports-
|
|
10671
|
+
var SIBLING_REGISTRIES = ["ports-router.json"];
|
|
10606
10672
|
var DEPS = /* @__PURE__ */ new WeakMap();
|
|
10607
10673
|
function depsOf(host2) {
|
|
10608
10674
|
let d = DEPS.get(host2);
|
|
@@ -11198,24 +11264,32 @@ var require_lan2 = __commonJS({
|
|
|
11198
11264
|
}
|
|
11199
11265
|
}
|
|
11200
11266
|
return {
|
|
11201
|
-
/** 远程控制模式唯一写入口(off|lan|wan)。
|
|
11267
|
+
/** 远程控制模式唯一写入口(off|lan|wan)。mode 必须显式给出——缺省归 'off' 会让
|
|
11268
|
+
* 漏字段的请求静默关闭远程控制。wan 前置闸:必须先有合规访问令牌。 */
|
|
11202
11269
|
setRemoteMode(id, mode) {
|
|
11203
|
-
|
|
11270
|
+
if (mode !== "off" && mode !== "lan" && mode !== "wan") {
|
|
11271
|
+
return { ok: false, error: "mode \u5FC5\u987B\u663E\u5F0F\u7ED9\u51FA\uFF08off|lan|wan\uFF09" };
|
|
11272
|
+
}
|
|
11204
11273
|
const target = resolveTarget(id);
|
|
11205
11274
|
if (!target) return { ok: false, error: "\u5B9E\u4F8B\u4E0D\u5B58\u5728" };
|
|
11206
|
-
if (
|
|
11275
|
+
if (mode === "wan") {
|
|
11207
11276
|
const v = validateWanAccess({ remoteToken: target.remoteToken });
|
|
11208
11277
|
if (!v.ok) return { ok: false, error: v.error };
|
|
11209
11278
|
}
|
|
11210
11279
|
if (target.kind === "main") {
|
|
11211
|
-
if (target.mode !==
|
|
11280
|
+
if (target.mode !== mode) applyMainIntent({ remoteMode: mode }, { id: "main", name: "\u539F\u751F DSH", mode });
|
|
11212
11281
|
return { ok: true };
|
|
11213
11282
|
}
|
|
11214
|
-
return g.getInstances().updateInstance(id, { remoteMode:
|
|
11283
|
+
return g.getInstances().updateInstance(id, { remoteMode: mode });
|
|
11215
11284
|
},
|
|
11216
|
-
/**
|
|
11285
|
+
/** 访问令牌唯一写入口。token 必须是字符串:空串=显式清除;缺字段/非字符串=请求方缺陷,
|
|
11286
|
+
* 拒绝而非当作清除(漏 token 字段清掉访问凭据是事故,不是语义)。lan 模式可无令牌,
|
|
11287
|
+
* wan 模式的守门由执行边界闸兜住。 */
|
|
11217
11288
|
setRemoteToken(id, token) {
|
|
11218
|
-
|
|
11289
|
+
if (typeof token !== "string") {
|
|
11290
|
+
return { ok: false, error: "token \u5FC5\u987B\u663E\u5F0F\u7ED9\u51FA\uFF08\u7A7A\u4E32=\u6E05\u9664\uFF09" };
|
|
11291
|
+
}
|
|
11292
|
+
const next = token;
|
|
11219
11293
|
if (next && !remoteTokenStrength(next).ok) {
|
|
11220
11294
|
return { ok: false, error: "\u8FDC\u7A0B\u8BBF\u95EE\u4EE4\u724C\uFF08remoteToken\uFF09\u81F3\u5C11 8 \u4F4D" };
|
|
11221
11295
|
}
|
|
@@ -11299,16 +11373,17 @@ var require_env_catalog = __commonJS({
|
|
|
11299
11373
|
const v = ex2.runOut(bin, (Array.isArray(args) ? args : []).concat(["--version"]), { timeoutMs: 3e3 });
|
|
11300
11374
|
return v ? v.trim() || null : null;
|
|
11301
11375
|
}
|
|
11376
|
+
function whichVersionAsync(bin, args) {
|
|
11377
|
+
return ex2.runOutAsync(bin, (Array.isArray(args) ? args : []).concat(["--version"]), { timeoutMs: 3e3 }).then((v) => v ? v.trim() || null : null);
|
|
11378
|
+
}
|
|
11302
11379
|
var _verCache = /* @__PURE__ */ new Map();
|
|
11303
11380
|
var CACHE_TTL = 1e4;
|
|
11304
|
-
function
|
|
11381
|
+
function cacheKey(bin, args) {
|
|
11305
11382
|
const a = Array.isArray(args) ? args : [];
|
|
11306
|
-
|
|
11307
|
-
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
const v = whichVersion(bin, a);
|
|
11311
|
-
_verCache.set(key, { at: now, v });
|
|
11383
|
+
return bin + "\0" + a.join("\0");
|
|
11384
|
+
}
|
|
11385
|
+
function cacheSet(key, v) {
|
|
11386
|
+
_verCache.set(key, { at: Date.now(), v });
|
|
11312
11387
|
if (_verCache.size > 16) {
|
|
11313
11388
|
let oldest = null;
|
|
11314
11389
|
for (const [k, e] of _verCache) if (!oldest || e.at < oldest.at) oldest = { k, at: e.at };
|
|
@@ -11316,6 +11391,19 @@ var require_env_catalog = __commonJS({
|
|
|
11316
11391
|
}
|
|
11317
11392
|
return v;
|
|
11318
11393
|
}
|
|
11394
|
+
function cachedWhichVersion(bin, args) {
|
|
11395
|
+
const key = cacheKey(bin, args);
|
|
11396
|
+
const hit = _verCache.get(key);
|
|
11397
|
+
const now = Date.now();
|
|
11398
|
+
if (hit && now - hit.at < CACHE_TTL) return hit.v;
|
|
11399
|
+
return cacheSet(key, whichVersion(bin, args));
|
|
11400
|
+
}
|
|
11401
|
+
function cachedWhichVersionAsync(bin, args) {
|
|
11402
|
+
const key = cacheKey(bin, args);
|
|
11403
|
+
const hit = _verCache.get(key);
|
|
11404
|
+
if (hit && Date.now() - hit.at < CACHE_TTL) return Promise.resolve(hit.v);
|
|
11405
|
+
return whichVersionAsync(bin, args).then((v) => cacheSet(key, v));
|
|
11406
|
+
}
|
|
11319
11407
|
var MIN_NODE_DEFAULT = "v22.12.0";
|
|
11320
11408
|
var _runtimeMetaCache = null;
|
|
11321
11409
|
var _runtimeMetaAt = 0;
|
|
@@ -11342,50 +11430,68 @@ var require_env_catalog = __commonJS({
|
|
|
11342
11430
|
}
|
|
11343
11431
|
return true;
|
|
11344
11432
|
}
|
|
11345
|
-
function
|
|
11346
|
-
const v = cachedWhichVersion("node");
|
|
11433
|
+
function nodeVerdict(v) {
|
|
11347
11434
|
if (!v) return null;
|
|
11348
11435
|
const m = /v?(\d+\.\d+\.\d+)/.exec(String(v));
|
|
11349
11436
|
const ver = m ? m[1] : String(v).trim();
|
|
11350
11437
|
const min = String(runtimeMeta().minNode || MIN_NODE_DEFAULT);
|
|
11351
11438
|
return { version: "v" + ver, min, meets: verAtLeast(ver, min) };
|
|
11352
11439
|
}
|
|
11440
|
+
function probeNode() {
|
|
11441
|
+
return nodeVerdict(cachedWhichVersion("node"));
|
|
11442
|
+
}
|
|
11443
|
+
function probeNodeAsync() {
|
|
11444
|
+
return cachedWhichVersionAsync("node").then(nodeVerdict);
|
|
11445
|
+
}
|
|
11353
11446
|
function probeNpm() {
|
|
11354
11447
|
const l = runtime.npmLauncher();
|
|
11355
11448
|
return cachedWhichVersion(l.program, l.args);
|
|
11356
11449
|
}
|
|
11450
|
+
function probeNpmAsync() {
|
|
11451
|
+
const l = runtime.npmLauncher();
|
|
11452
|
+
return cachedWhichVersionAsync(l.program, l.args);
|
|
11453
|
+
}
|
|
11357
11454
|
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") }
|
|
11455
|
+
node: { label: "Node.js", required: true, probe: probeNode, probeAsync: probeNodeAsync },
|
|
11456
|
+
npm: { label: "npm", required: true, probe: probeNpm, probeAsync: probeNpmAsync },
|
|
11457
|
+
git: { label: "git", required: false, probe: () => cachedWhichVersion("git"), probeAsync: () => cachedWhichVersionAsync("git") }
|
|
11361
11458
|
};
|
|
11459
|
+
function entryView(id, e, v) {
|
|
11460
|
+
if (v && typeof v === "object" && typeof v.meets === "boolean") {
|
|
11461
|
+
return {
|
|
11462
|
+
label: e.label,
|
|
11463
|
+
required: e.required,
|
|
11464
|
+
state: v.meets ? "ok" : "outdated",
|
|
11465
|
+
version: v.version,
|
|
11466
|
+
min: v.min,
|
|
11467
|
+
meets: v.meets,
|
|
11468
|
+
detail: v.meets ? v.version : v.version + "\uFF08\u4F4E\u4E8E\u6700\u4F4E\u8981\u6C42 " + v.min + "\uFF09"
|
|
11469
|
+
};
|
|
11470
|
+
}
|
|
11471
|
+
return { label: e.label, required: e.required, state: v ? "ok" : "missing", detail: v };
|
|
11472
|
+
}
|
|
11362
11473
|
var EnvCatalog = class {
|
|
11363
11474
|
constructor(config) {
|
|
11364
11475
|
this.config = config || {};
|
|
11365
11476
|
}
|
|
11366
|
-
/**
|
|
11367
|
-
* ok = 存在且满足门槛(Node 需 >= 壳投放的 minNode);outdated = 存在但低于门槛;missing = 不存在。
|
|
11368
|
-
* 兼容:detail 保持字符串,新增字段(version/min/meets)放 detail 之外,不破坏既有契约。 */
|
|
11477
|
+
/** 系统二进制条目探测(同步口径):{ id: 条目视图 }。仅限启动早期/CLI;HTTP 路径用 probeAsync。 */
|
|
11369
11478
|
probe() {
|
|
11370
11479
|
const out = {};
|
|
11371
11480
|
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
|
-
}
|
|
11481
|
+
out[id] = entryView(id, e, e.probe() || null);
|
|
11386
11482
|
}
|
|
11387
11483
|
return out;
|
|
11388
11484
|
}
|
|
11485
|
+
/** 异步口径:条目并行探测(最坏 3s x N 的串行冻结 -> 全程不阻塞事件循环)。 */
|
|
11486
|
+
async probeAsync() {
|
|
11487
|
+
const entries = Object.entries(SYSTEM_ENTRIES);
|
|
11488
|
+
const vals = await Promise.all(entries.map(([, e]) => e.probeAsync()));
|
|
11489
|
+
const out = {};
|
|
11490
|
+
entries.forEach(([id, e], i) => {
|
|
11491
|
+
out[id] = entryView(id, e, vals[i] || null);
|
|
11492
|
+
});
|
|
11493
|
+
return out;
|
|
11494
|
+
}
|
|
11389
11495
|
/** 内核更新依赖条目(单写入者契约:安装/重启归桌面壳,守卫只读 corePackageName 查版本状态)。
|
|
11390
11496
|
* id 仍为 selfUpdate 以兼容既有 /env/status 消费方。 */
|
|
11391
11497
|
selfUpdateEntry() {
|
|
@@ -11429,20 +11535,22 @@ var require_env = __commonJS({
|
|
|
11429
11535
|
var fs2 = require("node:fs");
|
|
11430
11536
|
var { EnvCatalog } = require_env_catalog();
|
|
11431
11537
|
var runtimeContract = require_runtime();
|
|
11432
|
-
function envCatalogSummary(that) {
|
|
11538
|
+
async function envCatalogSummary(that) {
|
|
11433
11539
|
const cat = new EnvCatalog(that.config);
|
|
11434
11540
|
const extra = {};
|
|
11435
11541
|
const d = that.dshenvStatus();
|
|
11436
11542
|
extra.dsh = cat.dshEntry(d.binOk, d.installed, d.bin);
|
|
11437
11543
|
extra.selfUpdate = cat.selfUpdateEntry();
|
|
11438
|
-
return cat.summary(extra);
|
|
11544
|
+
return cat.summary(extra, await cat.probeAsync());
|
|
11439
11545
|
}
|
|
11440
11546
|
module2.exports = {
|
|
11441
11547
|
methods: {
|
|
11442
|
-
|
|
11548
|
+
// 异步:全部子进程探测(EnvCatalog/契约回读)走异步口径——本方法挂在 /env/status 上,
|
|
11549
|
+
// 同步 execFileSync 会把守卫事件循环冻结在探测超时上(心跳/自愈停摆,B1-6 收口)。
|
|
11550
|
+
async envStatus() {
|
|
11443
11551
|
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;
|
|
11552
|
+
const cat = await new EnvCatalog(this.config).probeAsync();
|
|
11553
|
+
const en = this.nativeManager && typeof this.nativeManager.checkEnvironment === "function" ? await this.nativeManager.checkEnvironment() : null;
|
|
11446
11554
|
return {
|
|
11447
11555
|
node: { detected: cat.node.detail || null, runtime: c.nodeVersion || null, path: c.nodePath || null },
|
|
11448
11556
|
// npm 与 node 同构三段:detected = 本机实跑版本;runtime = 壳实跑后投放的版本
|
|
@@ -11454,7 +11562,7 @@ var require_env = __commonJS({
|
|
|
11454
11562
|
ok: cat.node.state === "ok" && cat.npm.state === "ok",
|
|
11455
11563
|
npmRoot: en ? en.npmRoot : null,
|
|
11456
11564
|
// EnvCatalog 声明式视图(面板环境卡用)
|
|
11457
|
-
catalog: envCatalogSummary(this),
|
|
11565
|
+
catalog: await envCatalogSummary(this),
|
|
11458
11566
|
// 平台能力矩阵:三平台静态档位 x 实际工具探测;前端据此做能力感知呈现与降级提示。
|
|
11459
11567
|
capabilities: (() => {
|
|
11460
11568
|
try {
|
|
@@ -11680,15 +11788,16 @@ var require_versions = __commonJS({
|
|
|
11680
11788
|
return { ok: false, error: e.message };
|
|
11681
11789
|
}
|
|
11682
11790
|
},
|
|
11683
|
-
/** 读磁盘上运行位的自报版本:spawn --version
|
|
11791
|
+
/** 读磁盘上运行位的自报版本:spawn --version,解析版本行(异步:20s 上限的同步 exec
|
|
11792
|
+
* 在 HTTP 路径上会冻结守卫整条事件循环,判据不变)。
|
|
11684
11793
|
* 条件是 updatable(sea-binary 或 launcher):launcher 的 bin 入口同样可执行,
|
|
11685
11794
|
* 若只认 sea-binary 则发布态永远读不到磁盘实况,updatePending 恒 false。
|
|
11686
11795
|
* source-shell 不支持:其 --version 报的是开发目录版本,与 npm 安装无关。 */
|
|
11687
|
-
_readBinarySelfVersion() {
|
|
11796
|
+
async _readBinarySelfVersion() {
|
|
11688
11797
|
const dep = deploy.detect();
|
|
11689
11798
|
if (!dep.updatable || !dep.runningTarget) return null;
|
|
11690
11799
|
try {
|
|
11691
|
-
const out = ex2.
|
|
11800
|
+
const out = await ex2.runOutAsync(dep.runningTarget, ["--version"], { timeoutMs: 2e4 });
|
|
11692
11801
|
const m = /dsh-supervisor v([^\s]+)/.exec(out);
|
|
11693
11802
|
return m ? m[1] : null;
|
|
11694
11803
|
} catch {
|
|
@@ -11710,18 +11819,18 @@ var require_versions = __commonJS({
|
|
|
11710
11819
|
}
|
|
11711
11820
|
return dir;
|
|
11712
11821
|
},
|
|
11713
|
-
/** 本地视角(无网络 I/O
|
|
11714
|
-
|
|
11822
|
+
/** 本地视角(无网络 I/O;git 子进程异步执行——同步 spawn 会冻结事件循环,
|
|
11823
|
+
* 消费方含 HTTP 路径,见 exec.js 同步仅限启动早期/CLI 的纪律)。 */
|
|
11824
|
+
async guardVersionLocal() {
|
|
11715
11825
|
const d = depsOf(this);
|
|
11716
11826
|
const root = d.vcsRoot();
|
|
11717
|
-
|
|
11718
|
-
|
|
11827
|
+
const [rawCommit, rawUp] = await Promise.all([
|
|
11828
|
+
ex2.runOutAsync("git", ["-C", root, "rev-parse", "--short", "HEAD"]),
|
|
11829
|
+
ex2.runOutAsync("git", ["-C", root, "rev-parse", "--abbrev-ref", "@{u}"])
|
|
11830
|
+
]);
|
|
11831
|
+
const commit = (rawCommit || "").trim() || null;
|
|
11719
11832
|
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
|
-
}
|
|
11833
|
+
if ((rawUp || "").trim()) upstream = "git-repo";
|
|
11725
11834
|
return { version: d.guardVersion(), runningVersion: d.guardVersion(), commit, updateAvailable: false, upstream, latest: d.guardVersion() };
|
|
11726
11835
|
},
|
|
11727
11836
|
/** 完整版本检查(async):本地 commit + 远端 fetch 比对。
|
|
@@ -11729,20 +11838,17 @@ var require_versions = __commonJS({
|
|
|
11729
11838
|
* fetch 失败/超时只降级为「本地视图」,不抛错。 */
|
|
11730
11839
|
async guardVersionCheck() {
|
|
11731
11840
|
const d = depsOf(this);
|
|
11732
|
-
const base = d.guardVersionLocal();
|
|
11841
|
+
const base = await d.guardVersionLocal();
|
|
11733
11842
|
if (base.upstream !== "git-repo") return base;
|
|
11734
11843
|
const root = d.vcsRoot();
|
|
11735
11844
|
const fetchOk = await ex2.runOutAsync("git", ["-C", root, "fetch", "--quiet"], { timeoutMs: 1e4 }) !== null;
|
|
11736
11845
|
if (!fetchOk) return base;
|
|
11737
11846
|
let updateAvailable = false;
|
|
11738
|
-
|
|
11739
|
-
|
|
11740
|
-
updateAvailable = parseInt(ahead, 10) > 0;
|
|
11741
|
-
} catch {
|
|
11742
|
-
}
|
|
11847
|
+
const ahead = (await ex2.runOutAsync("git", ["-C", root, "rev-list", "--count", "HEAD..@{u}"], { timeoutMs: 1e4 }) || "").trim();
|
|
11848
|
+
updateAvailable = parseInt(ahead, 10) > 0;
|
|
11743
11849
|
const dep = deploy.detect();
|
|
11744
11850
|
let diskVersion = null;
|
|
11745
|
-
if (dep.updatable) diskVersion = d.readBinarySelfVersion();
|
|
11851
|
+
if (dep.updatable) diskVersion = await d.readBinarySelfVersion();
|
|
11746
11852
|
const updatePending = !!(diskVersion && diskVersion !== d.guardVersion());
|
|
11747
11853
|
return { ...base, diskVersion, updatePending };
|
|
11748
11854
|
}
|
|
@@ -11826,7 +11932,9 @@ var require_access = __commonJS({
|
|
|
11826
11932
|
return { ok: false, error: e.message };
|
|
11827
11933
|
}
|
|
11828
11934
|
}
|
|
11829
|
-
}
|
|
11935
|
+
},
|
|
11936
|
+
// settings 门面的写口核验件(B2-4):lan-panel 共用同一「写后读回」口径,不各写各的。
|
|
11937
|
+
verifyPersisted
|
|
11830
11938
|
};
|
|
11831
11939
|
}
|
|
11832
11940
|
});
|
|
@@ -11933,9 +12041,8 @@ var require_netinfo = __commonJS({
|
|
|
11933
12041
|
var require_lan_panel = __commonJS({
|
|
11934
12042
|
"src/app/settings/lan-panel.js"(exports2, module2) {
|
|
11935
12043
|
"use strict";
|
|
11936
|
-
var fs2 = require("node:fs");
|
|
11937
12044
|
var netInfo = require_netinfo();
|
|
11938
|
-
var {
|
|
12045
|
+
var { verifyPersisted } = require_access();
|
|
11939
12046
|
var DEPS = /* @__PURE__ */ new WeakMap();
|
|
11940
12047
|
function depsOf(host2) {
|
|
11941
12048
|
let d = DEPS.get(host2);
|
|
@@ -11945,6 +12052,7 @@ var require_lan_panel = __commonJS({
|
|
|
11945
12052
|
logger: () => host2.logger,
|
|
11946
12053
|
events: () => host2.events,
|
|
11947
12054
|
configPath: () => host2.configPath,
|
|
12055
|
+
state: () => host2.state,
|
|
11948
12056
|
api: () => host2.api,
|
|
11949
12057
|
lanPanelStatus: () => host2.lanPanelStatus(),
|
|
11950
12058
|
apiRebind: () => host2._apiRebind()
|
|
@@ -11986,14 +12094,9 @@ var require_lan_panel = __commonJS({
|
|
|
11986
12094
|
d.config().apiHost = host2;
|
|
11987
12095
|
let persistError = null;
|
|
11988
12096
|
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
|
-
}
|
|
12097
|
+
d.state().persistConfigPatch({ apiHost: host2 });
|
|
12098
|
+
persistError = verifyPersisted(d.configPath(), { apiHost: host2 });
|
|
12099
|
+
if (persistError) d.logger().error(persistError);
|
|
11997
12100
|
}
|
|
11998
12101
|
if (changed && d.api() && typeof d.api().close === "function") d.apiRebind();
|
|
11999
12102
|
if (d.events()) d.events().append("lan_panel_changed", { enabled: on });
|
|
@@ -12611,6 +12714,8 @@ var require_pool2 = __commonJS({
|
|
|
12611
12714
|
this._bus = new FollowBus({ logger: this.logger });
|
|
12612
12715
|
this._schedules = /* @__PURE__ */ new Map();
|
|
12613
12716
|
this._seq = 0;
|
|
12717
|
+
this._attachGen = /* @__PURE__ */ new Map();
|
|
12718
|
+
this._journalFn = o.journal || capture.captureJournal;
|
|
12614
12719
|
this._backfillAt = /* @__PURE__ */ new Map();
|
|
12615
12720
|
this._poolFile = o.poolFile ? path2.resolve(o.poolFile) : null;
|
|
12616
12721
|
this._loaded = false;
|
|
@@ -12635,6 +12740,7 @@ var require_pool2 = __commonJS({
|
|
|
12635
12740
|
const unit = s.unit || prev && prev.unit || null;
|
|
12636
12741
|
const file = s.file || prev && prev.file || null;
|
|
12637
12742
|
this._sources.set(id, { kind, unit, file, lines: prev && prev.lines || [] });
|
|
12743
|
+
this._attachGen.set(id, (this._attachGen.get(id) || 0) + 1);
|
|
12638
12744
|
const rec = this._records.get(id);
|
|
12639
12745
|
if (rec) rec.kind = kind;
|
|
12640
12746
|
return true;
|
|
@@ -12659,9 +12765,16 @@ var require_pool2 = __commonJS({
|
|
|
12659
12765
|
return this._commit(id, hit.token, hit.source);
|
|
12660
12766
|
}
|
|
12661
12767
|
if (src.unit && kinds.isCaptured(src.kind)) {
|
|
12662
|
-
|
|
12768
|
+
const gen = this._attachGen.get(id) || 0;
|
|
12769
|
+
const fresh = () => (this._attachGen.get(id) || 0) === gen ? this._sources.get(id) : null;
|
|
12770
|
+
Promise.resolve().then(() => {
|
|
12771
|
+
const cur = fresh();
|
|
12772
|
+
return cur ? this._journalFn(cur.unit, { logger: this.logger }) : null;
|
|
12773
|
+
}).then((j) => {
|
|
12663
12774
|
if (!j) return;
|
|
12664
|
-
|
|
12775
|
+
const cur = fresh();
|
|
12776
|
+
if (!cur) return;
|
|
12777
|
+
if (cur.file) this._persistLine(id, cur.file, j.line);
|
|
12665
12778
|
this._commit(id, j.token, j.source);
|
|
12666
12779
|
}).catch(() => {
|
|
12667
12780
|
});
|
|
@@ -12729,6 +12842,7 @@ var require_pool2 = __commonJS({
|
|
|
12729
12842
|
this._backfillAt.delete(id);
|
|
12730
12843
|
const src = this._sources.get(id);
|
|
12731
12844
|
if (src && src.lines && src.lines.length) src.lines.length = 0;
|
|
12845
|
+
this._attachGen.set(id, (this._attachGen.get(id) || 0) + 1);
|
|
12732
12846
|
this._records.delete(id);
|
|
12733
12847
|
this._persistPool();
|
|
12734
12848
|
this._bus.emit(id, null, null);
|
|
@@ -13659,7 +13773,6 @@ var require_core5 = __commonJS({
|
|
|
13659
13773
|
host2._routerFacade = null;
|
|
13660
13774
|
host2._lc = null;
|
|
13661
13775
|
host2._dshMainLive = null;
|
|
13662
|
-
host2._fallbackEntry = null;
|
|
13663
13776
|
host2._lastStateBody = null;
|
|
13664
13777
|
host2._shadowSeq = 0;
|
|
13665
13778
|
host2._shadowConsistentBeats = 0;
|
|
@@ -17206,10 +17319,11 @@ var require_oauth = __commonJS({
|
|
|
17206
17319
|
const d = deps || {};
|
|
17207
17320
|
const ports = d.ports;
|
|
17208
17321
|
const openInBrowser = d.openInBrowser;
|
|
17209
|
-
const st = { _ccLogin: null, _ccLoginPromise: null, _ccLoginResolve: null, _ccLoginReject: null };
|
|
17322
|
+
const st = { _ccLogin: null, _ccLoginPromise: null, _ccLoginResolve: null, _ccLoginReject: null, _ccLoginRound: 0 };
|
|
17210
17323
|
async function commandcodeLoginStart() {
|
|
17211
17324
|
const STUDIO_BASE = "https://commandcode.ai";
|
|
17212
17325
|
const state = crypto.randomBytes(32).toString("base64url");
|
|
17326
|
+
const roundId = ++st._ccLoginRound;
|
|
17213
17327
|
if (st._ccLogin && st._ccLogin.server) {
|
|
17214
17328
|
const oldState = st._ccLogin.state;
|
|
17215
17329
|
try {
|
|
@@ -17271,6 +17385,11 @@ var require_oauth = __commonJS({
|
|
|
17271
17385
|
if (b.length > 1e4) req.destroy();
|
|
17272
17386
|
});
|
|
17273
17387
|
req.on("end", () => {
|
|
17388
|
+
if (st._ccLoginRound !== roundId) {
|
|
17389
|
+
res.writeHead(410);
|
|
17390
|
+
res.end(callbackJson({ success: false, error: "Stale login round" }));
|
|
17391
|
+
return;
|
|
17392
|
+
}
|
|
17274
17393
|
try {
|
|
17275
17394
|
const j = JSON.parse(b || "{}");
|
|
17276
17395
|
if (j && typeof j === "object" && "error" in j) {
|
|
@@ -17361,6 +17480,7 @@ var require_oauth = __commonJS({
|
|
|
17361
17480
|
});
|
|
17362
17481
|
st._ccLoginPromise = promise;
|
|
17363
17482
|
const tmpProfile = openInBrowser(authUrl, () => {
|
|
17483
|
+
if (st._ccLoginRound !== roundId) return;
|
|
17364
17484
|
if (st._ccLoginReject) {
|
|
17365
17485
|
const r = st._ccLoginReject;
|
|
17366
17486
|
st._ccLoginReject = null;
|
|
@@ -19247,10 +19367,7 @@ var require_model3 = __commonJS({
|
|
|
19247
19367
|
inst.state.lastError = null;
|
|
19248
19368
|
}
|
|
19249
19369
|
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
|
-
}
|
|
19370
|
+
if (inst.state) delete inst.state.desired;
|
|
19254
19371
|
return inst;
|
|
19255
19372
|
}
|
|
19256
19373
|
function createRecord(payload, id) {
|
|
@@ -19275,7 +19392,7 @@ var require_model3 = __commonJS({
|
|
|
19275
19392
|
protectHome: payload.protectHome === void 0 ? false : !!payload.protectHome
|
|
19276
19393
|
// 资源配额不接收户输入:启动时由 governor 按机器预算与活跃实例数推导。
|
|
19277
19394
|
},
|
|
19278
|
-
state: { phase: "STOPPED",
|
|
19395
|
+
state: { phase: "STOPPED", restartCount: 0, backoffLevel: 0, lastProbeOk: null },
|
|
19279
19396
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
19280
19397
|
};
|
|
19281
19398
|
}
|
|
@@ -19515,6 +19632,7 @@ var require_lifecycle = __commonJS({
|
|
|
19515
19632
|
"use strict";
|
|
19516
19633
|
var fs2 = require("node:fs");
|
|
19517
19634
|
var monitor = require_monitor();
|
|
19635
|
+
var ports = require_ports().shared;
|
|
19518
19636
|
var guardian = require_guardian();
|
|
19519
19637
|
var sandbox = require_sandbox();
|
|
19520
19638
|
var governor = require_governor();
|
|
@@ -19557,7 +19675,7 @@ var require_lifecycle = __commonJS({
|
|
|
19557
19675
|
logger.info && logger.info("cleaned stale transient unit: " + unit);
|
|
19558
19676
|
}
|
|
19559
19677
|
}
|
|
19560
|
-
function _systemdStart(inst) {
|
|
19678
|
+
function _systemdStart(inst, opts) {
|
|
19561
19679
|
try {
|
|
19562
19680
|
const cmdArr = sandbox.effectiveCommand(instancesRoot, deps.dshBin, inst);
|
|
19563
19681
|
if (!cmdArr || !cmdArr.length) return { ok: false, error: "\u5B9E\u4F8B\u672A\u914D\u7F6E\u542F\u52A8\u547D\u4EE4" };
|
|
@@ -19573,6 +19691,15 @@ var require_lifecycle = __commonJS({
|
|
|
19573
19691
|
logger.warn && logger.warn("[" + inst.id + "] " + msg);
|
|
19574
19692
|
return { ok: false, error: msg };
|
|
19575
19693
|
}
|
|
19694
|
+
const takenBy = ports.recordOf(inst.port);
|
|
19695
|
+
if (takenBy && takenBy.owner !== "inst:" + inst.id) {
|
|
19696
|
+
const msg = "PORT_TAKEN:" + (takenBy.owner || takenBy.role);
|
|
19697
|
+
inst.state.lastError = msg;
|
|
19698
|
+
store.save();
|
|
19699
|
+
if (events) events.append("inst_start_refused", { id: inst.id, name: inst.name, error: msg });
|
|
19700
|
+
logger.warn && logger.warn("[" + inst.id + "] " + msg);
|
|
19701
|
+
return { ok: false, error: msg };
|
|
19702
|
+
}
|
|
19576
19703
|
if (probe(inst).running) return { ok: false, error: "\u7AEF\u53E3 " + inst.port + " \u5DF2\u88AB\u5360\u7528" };
|
|
19577
19704
|
const alloc = governor.currentAllocation(store.instances, inst.id, machineFactsNow());
|
|
19578
19705
|
inst.state.allocation = alloc;
|
|
@@ -19592,6 +19719,12 @@ var require_lifecycle = __commonJS({
|
|
|
19592
19719
|
inst.state.phase = "STARTING";
|
|
19593
19720
|
inst.state.startAt = Date.now();
|
|
19594
19721
|
inst.state.lastError = null;
|
|
19722
|
+
if (opts && opts.manual) {
|
|
19723
|
+
inst.state.restartCount = 0;
|
|
19724
|
+
inst.state.backoffLevel = 0;
|
|
19725
|
+
inst.state.backoffUntil = null;
|
|
19726
|
+
inst.state.lastFailAt = null;
|
|
19727
|
+
}
|
|
19595
19728
|
store.save();
|
|
19596
19729
|
if (inst.port && hooks.onInstanceStart) hooks.onInstanceStart(inst);
|
|
19597
19730
|
if (events) events.append("inst_started", { id: inst.id, port: inst.port });
|
|
@@ -19617,10 +19750,6 @@ var require_lifecycle = __commonJS({
|
|
|
19617
19750
|
return { ok: false, error: adm.error };
|
|
19618
19751
|
}
|
|
19619
19752
|
}
|
|
19620
|
-
if (inst.state.desired !== "running") {
|
|
19621
|
-
inst.state.desired = "running";
|
|
19622
|
-
store.save();
|
|
19623
|
-
}
|
|
19624
19753
|
store.ensureDirs(inst);
|
|
19625
19754
|
const dshEntry = sandbox.dshEntry(instancesRoot, inst);
|
|
19626
19755
|
if (!fs2.existsSync(dshEntry)) {
|
|
@@ -19629,10 +19758,9 @@ var require_lifecycle = __commonJS({
|
|
|
19629
19758
|
return { ok: true, installing: true };
|
|
19630
19759
|
}
|
|
19631
19760
|
}
|
|
19632
|
-
return _systemdStart(inst);
|
|
19761
|
+
return _systemdStart(inst, opts);
|
|
19633
19762
|
}
|
|
19634
|
-
function stop(id
|
|
19635
|
-
const transient = !!(opts && opts.intent === "transient");
|
|
19763
|
+
function stop(id) {
|
|
19636
19764
|
const inst = store.instances.find((i) => i.id === id);
|
|
19637
19765
|
if (!inst) return { ok: false, error: "\u5B9E\u4F8B\u4E0D\u5B58\u5728" };
|
|
19638
19766
|
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 +19782,6 @@ var require_lifecycle = __commonJS({
|
|
|
19654
19782
|
}
|
|
19655
19783
|
inst.state.phase = "STOPPED";
|
|
19656
19784
|
inst.state.usage = null;
|
|
19657
|
-
if (!transient) inst.state.desired = "stopped";
|
|
19658
19785
|
runtime.delete(inst.id);
|
|
19659
19786
|
store.save();
|
|
19660
19787
|
if (inst.port && hooks.onInstanceStop) hooks.onInstanceStop(inst);
|
|
@@ -19710,15 +19837,17 @@ var require_lifecycle = __commonJS({
|
|
|
19710
19837
|
}).catch(() => {
|
|
19711
19838
|
});
|
|
19712
19839
|
}
|
|
19840
|
+
}
|
|
19841
|
+
function governSweep() {
|
|
19713
19842
|
const roster = _sandboxRoster();
|
|
19714
|
-
if (!roster.length) return;
|
|
19843
|
+
if (!roster.length) return { ok: true, entries: 0 };
|
|
19715
19844
|
let plan;
|
|
19716
19845
|
try {
|
|
19717
19846
|
const f = machineFactsNow();
|
|
19718
19847
|
plan = governor.decide({ totalMemBytes: f.totalMemBytes, cpuCount: f.cpuCount, roster });
|
|
19719
19848
|
} catch (e) {
|
|
19720
|
-
logger.warn && logger.warn("
|
|
19721
|
-
return;
|
|
19849
|
+
logger.warn && logger.warn("govern decide \u5931\u8D25: " + (e && e.message));
|
|
19850
|
+
return { ok: false, error: e && e.message || String(e) };
|
|
19722
19851
|
}
|
|
19723
19852
|
const now = Date.now();
|
|
19724
19853
|
for (const entry of plan.entries) {
|
|
@@ -19743,19 +19872,21 @@ var require_lifecycle = __commonJS({
|
|
|
19743
19872
|
}
|
|
19744
19873
|
}
|
|
19745
19874
|
}
|
|
19746
|
-
if (!entry.violation
|
|
19875
|
+
if (!entry.violation) continue;
|
|
19747
19876
|
const v = entry.violation;
|
|
19748
19877
|
const kindLabel = v.kind === "memory" ? "\u5185\u5B58" : "CPU";
|
|
19749
19878
|
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("[" +
|
|
19879
|
+
if (events) events.append("inst_resource_violation", { id: target.id, name: target.name, kind: v.kind, actual: v.actual, target: v.target });
|
|
19880
|
+
logger.warn && logger.warn("[" + target.id + "] " + reason);
|
|
19752
19881
|
try {
|
|
19753
|
-
service.stopUnit("dsh-web@" +
|
|
19882
|
+
service.stopUnit("dsh-web@" + target.id, Object.assign({ timeoutMs: 2e4 }, sandbox.launchCtx(instancesRoot, deps.dshBin, target)));
|
|
19754
19883
|
} catch (e) {
|
|
19755
|
-
logger.warn && logger.warn("[" +
|
|
19884
|
+
logger.warn && logger.warn("[" + target.id + "] \u8FDD\u89C4\u505C\u5355\u5143\u5F02\u5E38: " + (e && e.message));
|
|
19756
19885
|
}
|
|
19757
|
-
stateMachine.restart(stateDeps(),
|
|
19886
|
+
stateMachine.restart(stateDeps(), target, reason);
|
|
19758
19887
|
}
|
|
19888
|
+
store.save();
|
|
19889
|
+
return { ok: true, entries: plan.entries.length };
|
|
19759
19890
|
}
|
|
19760
19891
|
function supervise(id) {
|
|
19761
19892
|
const inst = store.instances.find((i) => i.id === id);
|
|
@@ -19849,7 +19980,7 @@ var require_lifecycle = __commonJS({
|
|
|
19849
19980
|
}
|
|
19850
19981
|
return { ok: true };
|
|
19851
19982
|
}
|
|
19852
|
-
return { _prepareSystemd, start, stop, probe, probeInstance, supervise };
|
|
19983
|
+
return { _prepareSystemd, start, stop, probe, probeInstance, supervise, governSweep };
|
|
19853
19984
|
}
|
|
19854
19985
|
module2.exports = { createLifecycle };
|
|
19855
19986
|
}
|
|
@@ -20158,7 +20289,7 @@ var require_upgrade = __commonJS({
|
|
|
20158
20289
|
tasks.stepState(task.id, tasks.get(task.id).steps.indexOf(s), "running");
|
|
20159
20290
|
}
|
|
20160
20291
|
try {
|
|
20161
|
-
await lifecycle.stop(id
|
|
20292
|
+
await lifecycle.stop(id);
|
|
20162
20293
|
} catch {
|
|
20163
20294
|
}
|
|
20164
20295
|
if (task) {
|
|
@@ -20206,7 +20337,7 @@ var require_upgrade = __commonJS({
|
|
|
20206
20337
|
tasks.log(task.id, "\u81EA\u52A8\u56DE\u6EDA\u5230 " + oldVersion + "\u2026");
|
|
20207
20338
|
}
|
|
20208
20339
|
try {
|
|
20209
|
-
const rs = await lifecycle.stop(id
|
|
20340
|
+
const rs = await lifecycle.stop(id);
|
|
20210
20341
|
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
20342
|
} catch (e) {
|
|
20212
20343
|
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 +20624,11 @@ var require_ops2 = __commonJS({
|
|
|
20493
20624
|
} catch {
|
|
20494
20625
|
}
|
|
20495
20626
|
}
|
|
20627
|
+
try {
|
|
20628
|
+
lifecycle.governSweep();
|
|
20629
|
+
} catch (e) {
|
|
20630
|
+
logger.warn && logger.warn("governSweep: " + (e && e.message));
|
|
20631
|
+
}
|
|
20496
20632
|
}, intervalMs || 5e3);
|
|
20497
20633
|
}
|
|
20498
20634
|
return { list, addInstance, removeInstance, updateInstance, startTimer };
|
|
@@ -20785,12 +20921,16 @@ var require_instance = __commonJS({
|
|
|
20785
20921
|
startInstance(id, opts) {
|
|
20786
20922
|
return this._lifecycle.start(id, opts);
|
|
20787
20923
|
}
|
|
20788
|
-
stopInstance(id
|
|
20789
|
-
return this._lifecycle.stop(id
|
|
20924
|
+
stopInstance(id) {
|
|
20925
|
+
return this._lifecycle.stop(id);
|
|
20790
20926
|
}
|
|
20791
20927
|
supervise(id) {
|
|
20792
20928
|
return this._lifecycle.supervise(id);
|
|
20793
20929
|
}
|
|
20930
|
+
/** 治理单拍(B2-6e):心跳拍末由 onBeatDone 调一次,全花名册 decide+下发+违规处置。 */
|
|
20931
|
+
governSweep() {
|
|
20932
|
+
return this._lifecycle.governSweep();
|
|
20933
|
+
}
|
|
20794
20934
|
probeInstance(id) {
|
|
20795
20935
|
return this._lifecycle.probeInstance(id);
|
|
20796
20936
|
}
|
|
@@ -21112,8 +21252,6 @@ var require_market = __commonJS({
|
|
|
21112
21252
|
this._ts = 0;
|
|
21113
21253
|
this._inFlight = null;
|
|
21114
21254
|
this.buildBudgetMs = opts.buildBudgetMs || 24e4;
|
|
21115
|
-
this._deadline = 0;
|
|
21116
|
-
this._truncatedSources = /* @__PURE__ */ new Set();
|
|
21117
21255
|
this.loadFromDisk();
|
|
21118
21256
|
}
|
|
21119
21257
|
loadFromDisk() {
|
|
@@ -21160,19 +21298,18 @@ var require_market = __commonJS({
|
|
|
21160
21298
|
}
|
|
21161
21299
|
async buildIndex() {
|
|
21162
21300
|
const start = Date.now();
|
|
21163
|
-
|
|
21164
|
-
this._truncatedSources = /* @__PURE__ */ new Set();
|
|
21301
|
+
const bctx = { deadline: start + this.buildBudgetMs, truncated: /* @__PURE__ */ new Set() };
|
|
21165
21302
|
try {
|
|
21166
|
-
return await this._buildIndexInner(start);
|
|
21303
|
+
return await this._buildIndexInner(start, bctx);
|
|
21167
21304
|
} finally {
|
|
21168
|
-
|
|
21305
|
+
bctx.deadline = 0;
|
|
21169
21306
|
}
|
|
21170
21307
|
}
|
|
21171
|
-
/**
|
|
21172
|
-
_budgetExhausted() {
|
|
21173
|
-
return
|
|
21308
|
+
/** 预算是否已耗尽(供各源的批次循环调用;无 ctx = 单源直调,不设预算)。 */
|
|
21309
|
+
_budgetExhausted(bctx) {
|
|
21310
|
+
return !!bctx && bctx.deadline > 0 && Date.now() >= bctx.deadline;
|
|
21174
21311
|
}
|
|
21175
|
-
async _buildIndexInner(start) {
|
|
21312
|
+
async _buildIndexInner(start, bctx) {
|
|
21176
21313
|
const plugins = [];
|
|
21177
21314
|
const seen = /* @__PURE__ */ new Set();
|
|
21178
21315
|
const add = (p) => {
|
|
@@ -21180,11 +21317,11 @@ var require_market = __commonJS({
|
|
|
21180
21317
|
seen.add(p.name);
|
|
21181
21318
|
plugins.push(p);
|
|
21182
21319
|
};
|
|
21183
|
-
const npm = await this.indexNpm();
|
|
21320
|
+
const npm = await this.indexNpm(bctx);
|
|
21184
21321
|
npm.forEach(add);
|
|
21185
|
-
const gh = await this.indexGithub();
|
|
21322
|
+
const gh = await this.indexGithub(bctx);
|
|
21186
21323
|
gh.forEach(add);
|
|
21187
|
-
const community = await this.indexCommunity();
|
|
21324
|
+
const community = await this.indexCommunity(bctx);
|
|
21188
21325
|
community.forEach(add);
|
|
21189
21326
|
for (const p of plugins) {
|
|
21190
21327
|
p.category = p.category || classify(p);
|
|
@@ -21192,7 +21329,7 @@ var require_market = __commonJS({
|
|
|
21192
21329
|
}
|
|
21193
21330
|
plugins.sort((a, b) => (b.stars || 0) - (a.stars || 0));
|
|
21194
21331
|
const prev = this._cache;
|
|
21195
|
-
const truncated =
|
|
21332
|
+
const truncated = bctx.truncated;
|
|
21196
21333
|
if (prev && prev.plugins && prev.plugins.length > 0 && truncated.size > 0) {
|
|
21197
21334
|
const freshNames = new Set(plugins.map((pp) => pp.name));
|
|
21198
21335
|
const kept = prev.plugins.filter((pp) => truncated.has(pp.source) && !freshNames.has(pp.name));
|
|
@@ -21227,8 +21364,8 @@ var require_market = __commonJS({
|
|
|
21227
21364
|
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
21365
|
return this._cache;
|
|
21229
21366
|
}
|
|
21230
|
-
/** npm 源:搜 deepseek-harness 受限 dsh,逐个检测 dsh.bundle。 */
|
|
21231
|
-
async indexNpm() {
|
|
21367
|
+
/** npm 源:搜 deepseek-harness 受限 dsh,逐个检测 dsh.bundle。bctx 为本次构建的预算上下文(见 buildIndex)。 */
|
|
21368
|
+
async indexNpm(bctx) {
|
|
21232
21369
|
const out = [];
|
|
21233
21370
|
const queries = ["keywords:deepseek-harness", "keywords:dsh-bundle", "keywords:dsh-plugin"];
|
|
21234
21371
|
const allNames = /* @__PURE__ */ new Set();
|
|
@@ -21255,8 +21392,8 @@ var require_market = __commonJS({
|
|
|
21255
21392
|
this.logger.info && this.logger.info("npm candidates: " + names.length);
|
|
21256
21393
|
const batch = 8;
|
|
21257
21394
|
for (let i = 0; i < names.length; i += batch) {
|
|
21258
|
-
if (this._budgetExhausted()) {
|
|
21259
|
-
|
|
21395
|
+
if (this._budgetExhausted(bctx)) {
|
|
21396
|
+
bctx.truncated.add("npm");
|
|
21260
21397
|
this.logger.warn && this.logger.warn("market: npm \u6E90\u9884\u7B97\u8017\u5C3D\uFF0C\u5DF2\u5904\u7406 " + i + "/" + names.length + " \u4E2A\u5019\u9009");
|
|
21261
21398
|
break;
|
|
21262
21399
|
}
|
|
@@ -21286,7 +21423,7 @@ var require_market = __commonJS({
|
|
|
21286
21423
|
return fetchLatest(await this._npmOrigin(), name);
|
|
21287
21424
|
}
|
|
21288
21425
|
/** GitHub 源:搜 topic:dsh-plugin + deepseek-harness,逐个验证 dsh.bundle。 */
|
|
21289
|
-
async indexGithub() {
|
|
21426
|
+
async indexGithub(bctx) {
|
|
21290
21427
|
const out = [];
|
|
21291
21428
|
const topics = ["dsh-plugin", "deepseek-harness"];
|
|
21292
21429
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -21316,7 +21453,7 @@ var require_market = __commonJS({
|
|
|
21316
21453
|
return repoPkg(fullName);
|
|
21317
21454
|
}
|
|
21318
21455
|
/** 社区列表:抓 awesome-dsh-plugin README 白名单(官方社区维护的精选)。 */
|
|
21319
|
-
async indexCommunity() {
|
|
21456
|
+
async indexCommunity(bctx) {
|
|
21320
21457
|
const out = [];
|
|
21321
21458
|
try {
|
|
21322
21459
|
const md = await rawGet("awesome-dsh-plugin/awesome-dsh-plugin/main/README.md", false, 3e4);
|
|
@@ -21328,8 +21465,8 @@ var require_market = __commonJS({
|
|
|
21328
21465
|
}
|
|
21329
21466
|
const seenName = /* @__PURE__ */ new Set();
|
|
21330
21467
|
for (let i = 0; i < links.length; i += 8) {
|
|
21331
|
-
if (this._budgetExhausted()) {
|
|
21332
|
-
|
|
21468
|
+
if (this._budgetExhausted(bctx)) {
|
|
21469
|
+
bctx.truncated.add("community");
|
|
21333
21470
|
this.logger.warn && this.logger.warn("market: community \u6E90\u9884\u7B97\u8017\u5C3D\uFF0C\u5DF2\u5904\u7406 " + i + "/" + links.length + " \u4E2A\u5019\u9009");
|
|
21334
21471
|
break;
|
|
21335
21472
|
}
|
|
@@ -21851,7 +21988,7 @@ var require_restart3 = __commonJS({
|
|
|
21851
21988
|
log("\u91CD\u542F\u5B9E\u4F8B\u300C" + (target.name || target.id) + "\u300D\u4F7F\u63D2\u4EF6\u53D8\u66F4\u751F\u6548\u2026");
|
|
21852
21989
|
if (ctx.events) ctx.events.append("plugin_restart_started", { name: target.name || target.id, target: target.id, kind });
|
|
21853
21990
|
try {
|
|
21854
|
-
ctx.instances.stopInstance(target.id
|
|
21991
|
+
ctx.instances.stopInstance(target.id);
|
|
21855
21992
|
} catch (e) {
|
|
21856
21993
|
log("\u505C\u6B62\u5B9E\u4F8B\u5931\u8D25: " + e.message);
|
|
21857
21994
|
}
|
|
@@ -22562,10 +22699,6 @@ var require_managed_object = __commonJS({
|
|
|
22562
22699
|
function registerKind(kind, meta) {
|
|
22563
22700
|
_customKinds[kind] = Object.assign({ label: kind, startable: false, guardable: false }, meta || {});
|
|
22564
22701
|
}
|
|
22565
|
-
var DOMAIN_A_KINDS = /* @__PURE__ */ new Set(["dsh", "sandbox-instance"]);
|
|
22566
|
-
function isDomainA(kind) {
|
|
22567
|
-
return DOMAIN_A_KINDS.has(kind);
|
|
22568
|
-
}
|
|
22569
22702
|
function createEntry(o) {
|
|
22570
22703
|
const meta = kindMeta(o.kind);
|
|
22571
22704
|
if (!meta) throw new Error("\u672A\u77E5\u53D7\u7BA1\u5BF9\u8C61\u7C7B\u578B: " + o.kind + "\uFF08\u5148 registerKind \u58F0\u660E\uFF09");
|
|
@@ -22576,8 +22709,9 @@ var require_managed_object = __commonJS({
|
|
|
22576
22709
|
name: String(o.name || o.id),
|
|
22577
22710
|
// desired 两域共用字段名但语义不同:域 A=用户意图;域 B=「当前业务是否需要它」的条件
|
|
22578
22711
|
desired: o.desired === "stopped" ? "stopped" : "running",
|
|
22579
|
-
// guardian
|
|
22580
|
-
|
|
22712
|
+
// guardian 开关的权威在域记录本身(dsh-main.json / inst.guardian),消费者全部直读源;
|
|
22713
|
+
// 目录曾在域 A entry 上物化该字段但零读者(B2-2 收口)。createEntry 永不物化 guardian 键
|
|
22714
|
+
// = 老库残留的天然一次性清理口(load 经本函数重建即消失),无需迁移脚本。
|
|
22581
22715
|
ownership: normalizeOwnership(o.ownership),
|
|
22582
22716
|
// 初始 stopped;业务不得直接改,由 heartbeat 调谐循环写入
|
|
22583
22717
|
phase: "stopped",
|
|
@@ -22612,7 +22746,7 @@ var require_managed_object = __commonJS({
|
|
|
22612
22746
|
// 域备注(只读参考)
|
|
22613
22747
|
};
|
|
22614
22748
|
}
|
|
22615
|
-
module2.exports = { DESIRED, MANAGED_KINDS, kindMeta, registerKind,
|
|
22749
|
+
module2.exports = { DESIRED, MANAGED_KINDS, kindMeta, registerKind, createEntry, normalizeOwnership };
|
|
22616
22750
|
}
|
|
22617
22751
|
});
|
|
22618
22752
|
|
|
@@ -22679,6 +22813,13 @@ var require_heartbeat = __commonJS({
|
|
|
22679
22813
|
registry._log("warn", "heartbeat " + (ad.supervise ? "supervise" : "observe") + "(" + e.kind + ":" + e.id + "): " + (err && err.message || err));
|
|
22680
22814
|
}
|
|
22681
22815
|
}
|
|
22816
|
+
if (typeof registry.onBeatDone === "function") {
|
|
22817
|
+
try {
|
|
22818
|
+
await registry.onBeatDone({ observed, errors });
|
|
22819
|
+
} catch (err) {
|
|
22820
|
+
registry._log("warn", "heartbeat onBeatDone: " + (err && err.message || err));
|
|
22821
|
+
}
|
|
22822
|
+
}
|
|
22682
22823
|
return { observed, errors };
|
|
22683
22824
|
}
|
|
22684
22825
|
module2.exports = { runHeartbeat, withTimeout, ADAPTER_TIMEOUT_TICKS };
|
|
@@ -22692,7 +22833,7 @@ var require_registry3 = __commonJS({
|
|
|
22692
22833
|
var fs2 = require("node:fs");
|
|
22693
22834
|
var path2 = require("node:path");
|
|
22694
22835
|
var { writeAtomic } = require_fs();
|
|
22695
|
-
var { DESIRED, MANAGED_KINDS, kindMeta, registerKind: registerManagedKind,
|
|
22836
|
+
var { DESIRED, MANAGED_KINDS, kindMeta, registerKind: registerManagedKind, createEntry, normalizeOwnership } = require_managed_object();
|
|
22696
22837
|
var PHASES = ["stopped", "installing", "starting", "running", "draining", "backoff", "failed", "restarting"];
|
|
22697
22838
|
var { runHeartbeat } = require_heartbeat();
|
|
22698
22839
|
var ManagedRegistry = class {
|
|
@@ -22743,7 +22884,7 @@ var require_registry3 = __commonJS({
|
|
|
22743
22884
|
for (const o of arr) {
|
|
22744
22885
|
try {
|
|
22745
22886
|
if (!o || !kindMeta(o.kind)) continue;
|
|
22746
|
-
const e = createEntry({ kind: o.kind, id: o.id, name: o.name, desired: o.desired,
|
|
22887
|
+
const e = createEntry({ kind: o.kind, id: o.id, name: o.name, desired: o.desired, ownership: o.ownership });
|
|
22747
22888
|
if (PHASES.includes(o.phase)) e.phase = o.phase;
|
|
22748
22889
|
if (Number.isInteger(o.backoffLevel)) e.backoffLevel = o.backoffLevel;
|
|
22749
22890
|
if (typeof o.backoffUntil === "number" && o.backoffUntil > Date.now()) e.backoffUntil = o.backoffUntil;
|
|
@@ -22770,7 +22911,7 @@ var require_registry3 = __commonJS({
|
|
|
22770
22911
|
kind: o.kind,
|
|
22771
22912
|
id: o.id,
|
|
22772
22913
|
name: o.name,
|
|
22773
|
-
// desired 两域共用(语义不同,见 createEntry);guardian
|
|
22914
|
+
// desired 两域共用(语义不同,见 createEntry);guardian 不落盘(B2-2,权威在域记录)。
|
|
22774
22915
|
desired: o.desired,
|
|
22775
22916
|
ownership: o.ownership,
|
|
22776
22917
|
phase: o.phase,
|
|
@@ -22782,7 +22923,7 @@ var require_registry3 = __commonJS({
|
|
|
22782
22923
|
startedAt: o.startedAt,
|
|
22783
22924
|
createdAt: o.createdAt,
|
|
22784
22925
|
updatedAt: o.updatedAt
|
|
22785
|
-
}
|
|
22926
|
+
}))
|
|
22786
22927
|
}, null, 2);
|
|
22787
22928
|
writeAtomic(this.file, body, { mode: 384 });
|
|
22788
22929
|
} catch (e) {
|
|
@@ -22844,8 +22985,8 @@ var require_registry3 = __commonJS({
|
|
|
22844
22985
|
this._event("managed_object_registered", { kind: e.kind, id: e.id, name: e.name });
|
|
22845
22986
|
return e;
|
|
22846
22987
|
}
|
|
22847
|
-
/** 对象变更申报(desired/
|
|
22848
|
-
*
|
|
22988
|
+
/** 对象变更申报(desired/ownership/name)。guardian 不接受申报(B2-2):createEntry 永不
|
|
22989
|
+
* 物化该键,patch 里带 guardian 一律忽略,老库残留由 load 重建时清理。 */
|
|
22849
22990
|
update(id, patch) {
|
|
22850
22991
|
const e = this.get(id);
|
|
22851
22992
|
if (!e) return { ok: false, error: "\u672A\u6CE8\u518C: " + id };
|
|
@@ -22854,11 +22995,6 @@ var require_registry3 = __commonJS({
|
|
|
22854
22995
|
if (!DESIRED.includes(p.desired)) return { ok: false, error: "\u975E\u6CD5 desired: " + p.desired };
|
|
22855
22996
|
e.desired = p.desired;
|
|
22856
22997
|
}
|
|
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
22998
|
if (p.name !== void 0) e.name = String(p.name || e.id);
|
|
22863
22999
|
if (p.ownership !== void 0) {
|
|
22864
23000
|
const old = e.ownership.ports;
|
|
@@ -23276,20 +23412,23 @@ var require_npm = __commonJS({
|
|
|
23276
23412
|
const l = runtimeContract.npmLauncher();
|
|
23277
23413
|
return { program: l.program, args: l.args };
|
|
23278
23414
|
}
|
|
23279
|
-
function resolveNpmRoot(host2) {
|
|
23415
|
+
async function resolveNpmRoot(host2) {
|
|
23280
23416
|
if (host2.npmRoot) return host2.npmRoot;
|
|
23281
23417
|
const l = npmLaunch(host2);
|
|
23282
|
-
const r = ex2.
|
|
23418
|
+
const r = await ex2.runOutAsync(l.program, l.args.concat(["root", "-g"]));
|
|
23283
23419
|
return r ? r.trim() : null;
|
|
23284
23420
|
}
|
|
23285
|
-
function checkEnvironment(host2) {
|
|
23421
|
+
async function checkEnvironment(host2) {
|
|
23286
23422
|
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
23423
|
const l = npmLaunch(host2);
|
|
23290
|
-
const npmv =
|
|
23424
|
+
const [nv, npmv, npmRoot] = await Promise.all([
|
|
23425
|
+
ex2.runOutAsync("node", ["--version"]),
|
|
23426
|
+
ex2.runOutAsync(l.program, l.args.concat(["--version"])),
|
|
23427
|
+
resolveNpmRoot(host2)
|
|
23428
|
+
]);
|
|
23429
|
+
if (!nv || !nv.trim()) errors.push("node \u672A\u5B89\u88C5\u6216\u4E0D\u53EF\u6267\u884C");
|
|
23291
23430
|
if (!npmv || !npmv.trim()) errors.push("npm \u672A\u5B89\u88C5\u6216\u4E0D\u53EF\u6267\u884C");
|
|
23292
|
-
return { ok: errors.length === 0, errors, npmRoot
|
|
23431
|
+
return { ok: errors.length === 0, errors, npmRoot };
|
|
23293
23432
|
}
|
|
23294
23433
|
async function latestVersion(host2) {
|
|
23295
23434
|
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 +23527,14 @@ var require_ops4 = __commonJS({
|
|
|
23388
23527
|
}
|
|
23389
23528
|
async function install(host2, version) {
|
|
23390
23529
|
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
23530
|
host2.installing = true;
|
|
23394
23531
|
host2.installLog = [];
|
|
23395
|
-
|
|
23396
|
-
let target = version;
|
|
23532
|
+
let task = null;
|
|
23397
23533
|
try {
|
|
23534
|
+
const env = await host2.checkEnvironment();
|
|
23535
|
+
if (!env.ok) return { ok: false, error: "\u73AF\u5883\u68C0\u67E5\u5931\u8D25: " + env.errors.join("; ") };
|
|
23536
|
+
task = beginTask(host2, "install", { to: version || null, createdBy: "user" });
|
|
23537
|
+
let target = version;
|
|
23398
23538
|
if (!target) {
|
|
23399
23539
|
target = await host2._latestVersion().catch(() => null);
|
|
23400
23540
|
if (!target) {
|
|
@@ -23417,7 +23557,7 @@ var require_ops4 = __commonJS({
|
|
|
23417
23557
|
return { ok: false, error: res.error, output: res.output };
|
|
23418
23558
|
}
|
|
23419
23559
|
const isFirstInstall = !host2._manifest();
|
|
23420
|
-
host2._recordManifest(target, isFirstInstall ? host2._claimDataPaths() : void 0);
|
|
23560
|
+
await host2._recordManifest(target, isFirstInstall ? host2._claimDataPaths() : void 0);
|
|
23421
23561
|
try {
|
|
23422
23562
|
if (typeof host2._bindNativeDshCommand === "function") host2._bindNativeDshCommand();
|
|
23423
23563
|
} catch (e) {
|
|
@@ -23442,8 +23582,6 @@ var require_ops4 = __commonJS({
|
|
|
23442
23582
|
if (host2.uninstalling) return { ok: false, error: "\u5378\u8F7D\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u518D\u88C5" };
|
|
23443
23583
|
if (policies.busy(host2)) return { ok: false, error: "\u5347\u7EA7\u8FDB\u884C\u4E2D\uFF0C\u8BF7\u7A0D\u540E\u518D\u88C5\uFF08state=" + host2.upgradeState + "\uFF09" };
|
|
23444
23584
|
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
23585
|
install(host2, version).then(() => {
|
|
23448
23586
|
}).catch((e) => {
|
|
23449
23587
|
host2.installing = null;
|
|
@@ -23636,7 +23774,7 @@ var require_upgrade2 = __commonJS({
|
|
|
23636
23774
|
if (!res.ok) throw new Error(res.error || "install failed");
|
|
23637
23775
|
const newV = host2.installedVersion();
|
|
23638
23776
|
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);
|
|
23777
|
+
await host2._recordManifest(newV || target);
|
|
23640
23778
|
if (host2.events) host2.events.append("upgrade_installed", { from: oldV, to: target });
|
|
23641
23779
|
log(host2, "\u5B89\u88C5\u5B8C\u6210\uFF0C\u78C1\u76D8\u7248\u672C " + newV);
|
|
23642
23780
|
if (task) {
|
|
@@ -23706,9 +23844,9 @@ var require_upgrade2 = __commonJS({
|
|
|
23706
23844
|
async function rollbackAfterFailedVerify(host2, oldV, task, healthy) {
|
|
23707
23845
|
log(host2, "\u5065\u5EB7\u9A8C\u8BC1\u5931\u8D25\uFF08" + healthy.reason + "\uFF09");
|
|
23708
23846
|
if (task) host2.tasks.log(task.id, "\u5065\u5EB7\u9A8C\u8BC1\u5931\u8D25\uFF08" + healthy.reason + "\uFF09");
|
|
23709
|
-
host2.rolledBack = true;
|
|
23710
23847
|
host2.upgradeState = "rolling_back";
|
|
23711
23848
|
const rb = await rollbackNative(host2, oldV, task);
|
|
23849
|
+
host2.rolledBack = rb.ok === true;
|
|
23712
23850
|
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
23851
|
host2.upgradeState = "failed";
|
|
23714
23852
|
host2.upgradeFinishedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -23740,7 +23878,7 @@ var require_upgrade2 = __commonJS({
|
|
|
23740
23878
|
}
|
|
23741
23879
|
tlog("\u56DE\u6EDA\u5B8C\u6210\uFF0C\u78C1\u76D8\u7248\u672C " + oldVersion);
|
|
23742
23880
|
try {
|
|
23743
|
-
host2._recordManifest(oldVersion);
|
|
23881
|
+
await host2._recordManifest(oldVersion);
|
|
23744
23882
|
} catch (e2) {
|
|
23745
23883
|
tlog("manifest \u66F4\u65B0\u5931\u8D25: " + e2.message);
|
|
23746
23884
|
}
|
|
@@ -23755,7 +23893,6 @@ var require_upgrade2 = __commonJS({
|
|
|
23755
23893
|
}
|
|
23756
23894
|
async function rollbackAfterFailure(host2) {
|
|
23757
23895
|
host2.upgradeState = "rolling_back";
|
|
23758
|
-
host2.rolledBack = true;
|
|
23759
23896
|
if (host2.events) host2.events.append("upgrade_rollback_started", { to: host2.oldVersion });
|
|
23760
23897
|
log(host2, "\u56DE\u6EDA\u5230 " + host2.oldVersion + "\u2026");
|
|
23761
23898
|
const registry = await host2._selectRegistry();
|
|
@@ -23776,8 +23913,9 @@ var require_upgrade2 = __commonJS({
|
|
|
23776
23913
|
return { ok: false };
|
|
23777
23914
|
}
|
|
23778
23915
|
log(host2, "\u56DE\u6EDA\u5B8C\u6210\u3002");
|
|
23916
|
+
host2.rolledBack = true;
|
|
23779
23917
|
try {
|
|
23780
|
-
host2._recordManifest(host2.oldVersion);
|
|
23918
|
+
await host2._recordManifest(host2.oldVersion);
|
|
23781
23919
|
} catch (e2) {
|
|
23782
23920
|
log(host2, "manifest \u66F4\u65B0\u5931\u8D25: " + e2.message);
|
|
23783
23921
|
}
|
|
@@ -23927,8 +24065,8 @@ var require_installer = __commonJS({
|
|
|
23927
24065
|
_saveManifest(m) {
|
|
23928
24066
|
return manifest.save(this, m);
|
|
23929
24067
|
}
|
|
23930
|
-
_recordManifest(version, dataPaths) {
|
|
23931
|
-
return manifest.record(this, version, dataPaths, this.npmRoot || npm.resolveNpmRoot(this));
|
|
24068
|
+
async _recordManifest(version, dataPaths) {
|
|
24069
|
+
return manifest.record(this, version, dataPaths, this.npmRoot || await npm.resolveNpmRoot(this));
|
|
23932
24070
|
}
|
|
23933
24071
|
_claimDataPaths() {
|
|
23934
24072
|
return manifest.claimDataPaths(this);
|
|
@@ -24310,6 +24448,7 @@ var require_domains = __commonJS({
|
|
|
24310
24448
|
host2.managedObjects.registerAdapter("dsh", { supervise: () => host2._dshSuperviseOnce(), tickEvery: 1 });
|
|
24311
24449
|
host2.managedObjects.registerAdapter("sandbox-instance", { supervise: (entry) => host2._sandboxSuperviseOnce(entry), tickEvery: 1 });
|
|
24312
24450
|
}
|
|
24451
|
+
if (host2.managedObjects) host2.managedObjects.onBeatDone = () => host2.instances.governSweep();
|
|
24313
24452
|
} catch (e) {
|
|
24314
24453
|
host2.logger && host2.logger.warn && host2.logger.warn("managed registry init: " + (e && e.message));
|
|
24315
24454
|
}
|
|
@@ -24904,7 +25043,7 @@ var require_guard = __commonJS({
|
|
|
24904
25043
|
}
|
|
24905
25044
|
}
|
|
24906
25045
|
if (req.method === "GET" && pathname === "/guard/version") {
|
|
24907
|
-
return send(200,
|
|
25046
|
+
return Promise.resolve(sup.guardVersionLocal()).then((r) => send(200, r)).catch((e) => send(500, { ok: false, error: e.message }));
|
|
24908
25047
|
}
|
|
24909
25048
|
if (req.method === "POST" && pathname === "/guard/version/check") {
|
|
24910
25049
|
req.resume();
|
|
@@ -25049,7 +25188,7 @@ var require_guard = __commonJS({
|
|
|
25049
25188
|
req.resume();
|
|
25050
25189
|
return send(403, {});
|
|
25051
25190
|
}
|
|
25052
|
-
return send(200,
|
|
25191
|
+
return Promise.resolve(sup.envStatus()).then((r) => send(200, r)).catch((e) => send(500, { ok: false, error: e.message }));
|
|
25053
25192
|
}
|
|
25054
25193
|
if (req.method === "GET" && pathname === "/env/node-lts") {
|
|
25055
25194
|
return sup.nodeLtsStatus().then((r) => send(200, r)).catch((e) => send(500, { ok: false, error: e.message }));
|
|
@@ -25704,7 +25843,7 @@ var require_instances = __commonJS({
|
|
|
25704
25843
|
const r = sup.instances.updateInstance(j.id, j);
|
|
25705
25844
|
return send(r && r.ok ? 200 : 400, r);
|
|
25706
25845
|
}
|
|
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 }));
|
|
25846
|
+
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
25847
|
if (act === "stop" && j.id) {
|
|
25709
25848
|
const r = sup.instances.stopInstance(j.id);
|
|
25710
25849
|
return send(r && r.ok ? 200 : 400, r);
|
|
@@ -27918,28 +28057,45 @@ function printSelfVersion() {
|
|
|
27918
28057
|
const { guardVersion } = require_version();
|
|
27919
28058
|
console.log("dsh-supervisor v" + guardVersion());
|
|
27920
28059
|
}
|
|
27921
|
-
function
|
|
28060
|
+
function apiRaw(method, apiPath, body) {
|
|
27922
28061
|
return new Promise((resolve) => {
|
|
27923
28062
|
const addr = readApiAddress();
|
|
27924
28063
|
const req = http.request(
|
|
27925
|
-
{
|
|
28064
|
+
{
|
|
28065
|
+
hostname: addr.host,
|
|
28066
|
+
port: addr.port,
|
|
28067
|
+
path: apiPath,
|
|
28068
|
+
method,
|
|
28069
|
+
timeout: 5e3,
|
|
28070
|
+
headers: body ? { "Content-Type": "application/json", "Content-Length": Buffer.byteLength(body) } : {}
|
|
28071
|
+
},
|
|
27926
28072
|
(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" }));
|
|
28073
|
+
let text = "";
|
|
28074
|
+
res.setEncoding("utf8");
|
|
28075
|
+
res.on("data", (d) => text += d);
|
|
28076
|
+
res.on("end", () => resolve({ status: res.statusCode, text }));
|
|
28077
|
+
res.on("error", (e) => resolve({ status: 0, text: "", error: e.message }));
|
|
27937
28078
|
}
|
|
27938
28079
|
);
|
|
27939
|
-
req.on("
|
|
28080
|
+
req.on("timeout", () => req.destroy(new Error("api-timeout")));
|
|
28081
|
+
req.on(
|
|
28082
|
+
"error",
|
|
28083
|
+
(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" })
|
|
28084
|
+
);
|
|
28085
|
+
if (body) req.write(body);
|
|
27940
28086
|
req.end();
|
|
27941
28087
|
});
|
|
27942
28088
|
}
|
|
28089
|
+
function apiRequest(method, apiPath) {
|
|
28090
|
+
return apiRaw(method, apiPath).then(({ status, text, error }) => {
|
|
28091
|
+
if (error) return { error };
|
|
28092
|
+
try {
|
|
28093
|
+
return JSON.parse(text);
|
|
28094
|
+
} catch {
|
|
28095
|
+
return { error: "parse error", raw: text };
|
|
28096
|
+
}
|
|
28097
|
+
});
|
|
28098
|
+
}
|
|
27943
28099
|
var LOCK_FILE = process.env.DSH_SUPERVISOR_LOCK_FILE || path.join(SUPERVISOR_DIR, "guard.lock");
|
|
27944
28100
|
var LOCK_OWNER = { pid: process.pid, started: Date.now(), entry: process.argv[1] || "" };
|
|
27945
28101
|
function readLock() {
|
|
@@ -28258,26 +28414,9 @@ function cmdVersion() {
|
|
|
28258
28414
|
});
|
|
28259
28415
|
}
|
|
28260
28416
|
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
28417
|
(async () => {
|
|
28279
28418
|
if (action === "check" || !action) {
|
|
28280
|
-
const s = await
|
|
28419
|
+
const s = await apiRequest("GET", "/self-update/status");
|
|
28281
28420
|
if (s.error) return console.log("\u68C0\u67E5\u5931\u8D25: " + s.error);
|
|
28282
28421
|
if (s.ok) {
|
|
28283
28422
|
console.log("\u5B88\u536B\u5F53\u524D\u7248\u672C: " + s.installed);
|
|
@@ -28295,31 +28434,13 @@ function cmdSelfUpdate(action) {
|
|
|
28295
28434
|
})();
|
|
28296
28435
|
}
|
|
28297
28436
|
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 }) => {
|
|
28437
|
+
const body = requested ? JSON.stringify({ version: requested }) : void 0;
|
|
28438
|
+
const post = () => apiRaw("POST", "/native/upgrade", body);
|
|
28439
|
+
post().then(({ status, text, error }) => {
|
|
28440
|
+
const code = error ? 0 : status;
|
|
28441
|
+
const outText = error ? "" : text;
|
|
28321
28442
|
if (code !== 202) {
|
|
28322
|
-
console.log("\u5347\u7EA7\u672A\u88AB\u63A5\u53D7:",
|
|
28443
|
+
console.log("\u5347\u7EA7\u672A\u88AB\u63A5\u53D7:", outText || "HTTP " + code);
|
|
28323
28444
|
process.exit(1);
|
|
28324
28445
|
}
|
|
28325
28446
|
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");
|