camstack 1.2.213 → 1.2.214
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/CHANGELOG.md +7 -0
- package/README.md +6 -0
- package/dist/chunk-37A556YF.js +822 -0
- package/dist/{chunk-MJJWVAEM.js → chunk-4Y3CBGOY.js} +53 -109
- package/dist/chunk-BYNP7S4W.js +56 -0
- package/dist/chunk-JPGJK5DC.js +75 -0
- package/dist/cli.js +127 -70
- package/dist/doctor-command-S7Q2U6HO.js +227 -0
- package/dist/{launcher-6TBFW332.js → launcher-JAOMC5YY.js} +716 -243
- package/dist/{server-EFXGQ7FD.js → server-TZCZTLBW.js} +215 -1007
- package/package.json +1 -1
|
@@ -7149,9 +7149,9 @@ var require_chunk_Cek0wNdY = __commonJS({
|
|
|
7149
7149
|
}
|
|
7150
7150
|
});
|
|
7151
7151
|
|
|
7152
|
-
// ../system/dist/dist-
|
|
7153
|
-
var
|
|
7154
|
-
"../system/dist/dist-
|
|
7152
|
+
// ../system/dist/dist-BVrPqzF0.js
|
|
7153
|
+
var require_dist_BVrPqzF0 = __commonJS({
|
|
7154
|
+
"../system/dist/dist-BVrPqzF0.js"(exports) {
|
|
7155
7155
|
"use strict";
|
|
7156
7156
|
var zod = __require("zod");
|
|
7157
7157
|
__require("crypto");
|
|
@@ -62827,6 +62827,12 @@ var require_dist_D98erEr = __commonJS({
|
|
|
62827
62827
|
instanceId: zod.z.string(),
|
|
62828
62828
|
cameraStableId: zod.z.string(),
|
|
62829
62829
|
nodeId: zod.z.string(),
|
|
62830
|
+
/**
|
|
62831
|
+
* False while the node the instance is bound to is not in the cluster
|
|
62832
|
+
* topology (forgotten, renamed, re-paired). The instance is kept; the
|
|
62833
|
+
* operator re-points it with `updateInstance({ targetNodeId })`.
|
|
62834
|
+
*/
|
|
62835
|
+
nodeInCluster: zod.z.boolean(),
|
|
62830
62836
|
profileId: zod.z.string(),
|
|
62831
62837
|
profileLabel: zod.z.string(),
|
|
62832
62838
|
name: zod.z.string(),
|
|
@@ -62886,6 +62892,8 @@ var require_dist_D98erEr = __commonJS({
|
|
|
62886
62892
|
}),
|
|
62887
62893
|
updateInstance: method(zod.z.object({
|
|
62888
62894
|
instanceId: zod.z.string().min(1),
|
|
62895
|
+
/** Re-point the instance to another node; the profile must exist there. */
|
|
62896
|
+
targetNodeId: zod.z.string().min(1).max(256).optional(),
|
|
62889
62897
|
name: zod.z.string().trim().min(1).max(160).optional(),
|
|
62890
62898
|
executable: zod.z.string().max(1024).optional(),
|
|
62891
62899
|
args: zod.z.array(zod.z.string().max(2048)).max(64).optional(),
|
|
@@ -66058,7 +66066,14 @@ var require_dist_D98erEr = __commonJS({
|
|
|
66058
66066
|
col: zod.z.number().int().min(0).max(24),
|
|
66059
66067
|
rowSpan: zod.z.number().int().min(1).max(24),
|
|
66060
66068
|
colSpan: zod.z.number().int().min(1).max(24),
|
|
66061
|
-
title: zod.z.string().min(1).max(40).optional()
|
|
66069
|
+
title: zod.z.string().min(1).max(40).optional(),
|
|
66070
|
+
/**
|
|
66071
|
+
* How much room a divider takes: `compact` (the default) is a slim rule,
|
|
66072
|
+
* `normal` a full grid row. Other frames ignore it.
|
|
66073
|
+
*/
|
|
66074
|
+
size: zod.z.enum(["compact", "normal"]).optional(),
|
|
66075
|
+
/** Keep the title in the layout but draw only the rule. */
|
|
66076
|
+
hideTitle: zod.z.boolean().optional()
|
|
66062
66077
|
});
|
|
66063
66078
|
function rectsOverlap(a, b) {
|
|
66064
66079
|
return a.row < b.row + b.rowSpan && b.row < a.row + a.rowSpan && a.col < b.col + b.colSpan && b.col < a.col + a.colSpan;
|
|
@@ -112533,11 +112548,11 @@ ${values.join("\n")}` : `${blockName} :`;
|
|
|
112533
112548
|
}
|
|
112534
112549
|
});
|
|
112535
112550
|
|
|
112536
|
-
// ../system/dist/device-ca-
|
|
112537
|
-
var
|
|
112538
|
-
"../system/dist/device-ca-
|
|
112551
|
+
// ../system/dist/device-ca-COyWgERw.js
|
|
112552
|
+
var require_device_ca_COyWgERw = __commonJS({
|
|
112553
|
+
"../system/dist/device-ca-COyWgERw.js"(exports) {
|
|
112539
112554
|
"use strict";
|
|
112540
|
-
var require_dist10 =
|
|
112555
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
112541
112556
|
var require_x509_es = require_x509_es_WtnRNyYS();
|
|
112542
112557
|
var node_crypto = __require("crypto");
|
|
112543
112558
|
var SYSTEM_SECRET_OWNER = "system";
|
|
@@ -112996,7 +113011,7 @@ var require_alerts_addon = __commonJS({
|
|
|
112996
113011
|
[Symbol.toStringTag]: { value: "Module" }
|
|
112997
113012
|
});
|
|
112998
113013
|
require_chunk_Cek0wNdY();
|
|
112999
|
-
var require_dist10 =
|
|
113014
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
113000
113015
|
var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
|
|
113001
113016
|
function nextEpisodeId(input) {
|
|
113002
113017
|
const { previous } = input;
|
|
@@ -114464,7 +114479,7 @@ var require_calendars_addon = __commonJS({
|
|
|
114464
114479
|
[Symbol.toStringTag]: { value: "Module" }
|
|
114465
114480
|
});
|
|
114466
114481
|
require_chunk_Cek0wNdY();
|
|
114467
|
-
var require_dist10 =
|
|
114482
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
114468
114483
|
var require_settle_sources = require_settle_sources_Bhsy57y();
|
|
114469
114484
|
var zod = __require("zod");
|
|
114470
114485
|
var CALENDAR_COLOR_PALETTE = [
|
|
@@ -114680,11 +114695,11 @@ var require_calendars = __commonJS({
|
|
|
114680
114695
|
}
|
|
114681
114696
|
});
|
|
114682
114697
|
|
|
114683
|
-
// ../system/dist/composition-sources-
|
|
114684
|
-
var
|
|
114685
|
-
"../system/dist/composition-sources-
|
|
114698
|
+
// ../system/dist/composition-sources-Ccap9mGu.js
|
|
114699
|
+
var require_composition_sources_Ccap9mGu = __commonJS({
|
|
114700
|
+
"../system/dist/composition-sources-Ccap9mGu.js"(exports) {
|
|
114686
114701
|
"use strict";
|
|
114687
|
-
var require_dist10 =
|
|
114702
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
114688
114703
|
function normalizedNativeOwner(owner) {
|
|
114689
114704
|
const trimmed = owner?.trim();
|
|
114690
114705
|
return trimmed ? trimmed : null;
|
|
@@ -114792,11 +114807,11 @@ var require_composition_sources_9_KhSHJA = __commonJS({
|
|
|
114792
114807
|
}
|
|
114793
114808
|
});
|
|
114794
114809
|
|
|
114795
|
-
// ../system/dist/retention-
|
|
114796
|
-
var
|
|
114797
|
-
"../system/dist/retention-
|
|
114810
|
+
// ../system/dist/retention-Br19kWJ2.js
|
|
114811
|
+
var require_retention_Br19kWJ2 = __commonJS({
|
|
114812
|
+
"../system/dist/retention-Br19kWJ2.js"(exports) {
|
|
114798
114813
|
"use strict";
|
|
114799
|
-
var require_dist10 =
|
|
114814
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
114800
114815
|
function subjectIdOf(subject) {
|
|
114801
114816
|
return subject.kind === "device" ? `d:${subject.deviceId}` : `n:${subject.nodeId}`;
|
|
114802
114817
|
}
|
|
@@ -115734,9 +115749,9 @@ var require_composer_addon = __commonJS({
|
|
|
115734
115749
|
[Symbol.toStringTag]: { value: "Module" }
|
|
115735
115750
|
});
|
|
115736
115751
|
require_chunk_Cek0wNdY();
|
|
115737
|
-
var require_dist10 =
|
|
115738
|
-
var require_composition_sources =
|
|
115739
|
-
var require_retention =
|
|
115752
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
115753
|
+
var require_composition_sources = require_composition_sources_Ccap9mGu();
|
|
115754
|
+
var require_retention = require_retention_Br19kWJ2();
|
|
115740
115755
|
var zod = __require("zod");
|
|
115741
115756
|
function isRecord$4(value) {
|
|
115742
115757
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -121450,7 +121465,7 @@ var require_console_logging = __commonJS({
|
|
|
121450
121465
|
[Symbol.toStringTag]: { value: "Module" }
|
|
121451
121466
|
});
|
|
121452
121467
|
require_chunk_Cek0wNdY();
|
|
121453
|
-
var require_dist10 =
|
|
121468
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
121454
121469
|
var require_formatter = require_formatter_xbxeV4GD();
|
|
121455
121470
|
var LEVEL_RANK = {
|
|
121456
121471
|
debug: 0,
|
|
@@ -127504,9 +127519,9 @@ var require_core_blocks_addon = __commonJS({
|
|
|
127504
127519
|
"use strict";
|
|
127505
127520
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
127506
127521
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
127507
|
-
var require_dist10 =
|
|
127522
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
127508
127523
|
var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
|
|
127509
|
-
var require_composition_sources =
|
|
127524
|
+
var require_composition_sources = require_composition_sources_Ccap9mGu();
|
|
127510
127525
|
var require_prefix_range = require_prefix_range_D_KueXbQ();
|
|
127511
127526
|
var require_prefix_walk = require_prefix_walk_Dv6MLZlM();
|
|
127512
127527
|
var zod = __require("zod");
|
|
@@ -142956,7 +142971,7 @@ var require_device_manager_addon = __commonJS({
|
|
|
142956
142971
|
[Symbol.toStringTag]: { value: "Module" }
|
|
142957
142972
|
});
|
|
142958
142973
|
require_chunk_Cek0wNdY();
|
|
142959
|
-
var require_dist10 =
|
|
142974
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
142960
142975
|
var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
|
|
142961
142976
|
var require_prefix_range = require_prefix_range_D_KueXbQ();
|
|
142962
142977
|
var require_prefix_walk = require_prefix_walk_Dv6MLZlM();
|
|
@@ -152224,7 +152239,7 @@ var require_hub_forwarder = __commonJS({
|
|
|
152224
152239
|
[Symbol.toStringTag]: { value: "Module" }
|
|
152225
152240
|
});
|
|
152226
152241
|
require_chunk_Cek0wNdY();
|
|
152227
|
-
var require_dist10 =
|
|
152242
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
152228
152243
|
var require_formatter = require_formatter_xbxeV4GD();
|
|
152229
152244
|
var DEFAULT_OUTBOUND_BUFFER_SIZE = 500;
|
|
152230
152245
|
var HubForwarderDestination = class {
|
|
@@ -152358,7 +152373,7 @@ var require_liveness_monitor_addon = __commonJS({
|
|
|
152358
152373
|
"use strict";
|
|
152359
152374
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
152360
152375
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
152361
|
-
var require_dist10 =
|
|
152376
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
152362
152377
|
var node_fs_promises = __require("fs/promises");
|
|
152363
152378
|
node_fs_promises = require_chunk.__toESM(node_fs_promises);
|
|
152364
152379
|
var node_path = __require("path");
|
|
@@ -152877,10 +152892,10 @@ var require_local_auth_addon = __commonJS({
|
|
|
152877
152892
|
[Symbol.toStringTag]: { value: "Module" }
|
|
152878
152893
|
});
|
|
152879
152894
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
152880
|
-
var require_dist10 =
|
|
152895
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
152881
152896
|
var require_safe_buffer$1 = require_safe_buffer_D3aoa_7X();
|
|
152882
152897
|
var require_ms$1 = require_ms_LB3giGoU();
|
|
152883
|
-
var require_device_ca =
|
|
152898
|
+
var require_device_ca = require_device_ca_COyWgERw();
|
|
152884
152899
|
var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
|
|
152885
152900
|
var zod = __require("zod");
|
|
152886
152901
|
var node_crypto = __require("crypto");
|
|
@@ -163275,7 +163290,7 @@ var require_loki_logging = __commonJS({
|
|
|
163275
163290
|
[Symbol.toStringTag]: { value: "Module" }
|
|
163276
163291
|
});
|
|
163277
163292
|
require_chunk_Cek0wNdY();
|
|
163278
|
-
var require_dist10 =
|
|
163293
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
163279
163294
|
var require_log_read_filter = require_log_read_filter_Bi066jwU();
|
|
163280
163295
|
var zod = __require("zod");
|
|
163281
163296
|
function sanitizeLabelName(raw) {
|
|
@@ -164236,7 +164251,7 @@ var require_native_metrics_addon = __commonJS({
|
|
|
164236
164251
|
[Symbol.toStringTag]: { value: "Module" }
|
|
164237
164252
|
});
|
|
164238
164253
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
164239
|
-
var require_dist10 =
|
|
164254
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
164240
164255
|
var node_fs_promises = __require("fs/promises");
|
|
164241
164256
|
var node_util = __require("util");
|
|
164242
164257
|
var node_os = __require("os");
|
|
@@ -166856,8 +166871,8 @@ var require_device_history_addon = __commonJS({
|
|
|
166856
166871
|
[Symbol.toStringTag]: { value: "Module" }
|
|
166857
166872
|
});
|
|
166858
166873
|
require_chunk_Cek0wNdY();
|
|
166859
|
-
var require_dist10 =
|
|
166860
|
-
var require_retention =
|
|
166874
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
166875
|
+
var require_retention = require_retention_Br19kWJ2();
|
|
166861
166876
|
var FLUSH_INTERVAL_MS = 1e4;
|
|
166862
166877
|
var MAX_BUFFER_AGE_MS = 6e4;
|
|
166863
166878
|
var MAX_QUEUE_POINTS = 1e5;
|
|
@@ -169578,7 +169593,7 @@ var require_filesystem_storage_addon = __commonJS({
|
|
|
169578
169593
|
[Symbol.toStringTag]: { value: "Module" }
|
|
169579
169594
|
});
|
|
169580
169595
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
169581
|
-
var require_dist10 =
|
|
169596
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
169582
169597
|
var node_crypto = __require("crypto");
|
|
169583
169598
|
var node_fs_promises = __require("fs/promises");
|
|
169584
169599
|
var node_path = __require("path");
|
|
@@ -170688,12 +170703,12 @@ var require_lib = __commonJS({
|
|
|
170688
170703
|
}
|
|
170689
170704
|
});
|
|
170690
170705
|
|
|
170691
|
-
// ../system/dist/wal-maintenance-
|
|
170692
|
-
var
|
|
170693
|
-
"../system/dist/wal-maintenance-
|
|
170706
|
+
// ../system/dist/wal-maintenance-Cfc56oIs.js
|
|
170707
|
+
var require_wal_maintenance_Cfc56oIs = __commonJS({
|
|
170708
|
+
"../system/dist/wal-maintenance-Cfc56oIs.js"(exports) {
|
|
170694
170709
|
"use strict";
|
|
170695
170710
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
170696
|
-
var require_dist10 =
|
|
170711
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
170697
170712
|
var require_prefix_range = require_prefix_range_D_KueXbQ();
|
|
170698
170713
|
var node_crypto = __require("crypto");
|
|
170699
170714
|
var node_module = __require("module");
|
|
@@ -174931,9 +174946,9 @@ var require_sqlite_settings_addon = __commonJS({
|
|
|
174931
174946
|
[Symbol.toStringTag]: { value: "Module" }
|
|
174932
174947
|
});
|
|
174933
174948
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
174934
|
-
var require_dist10 =
|
|
174949
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
174935
174950
|
var require_retired_settings_keys = require_retired_settings_keys_DorakcxV();
|
|
174936
|
-
var require_wal_maintenance =
|
|
174951
|
+
var require_wal_maintenance = require_wal_maintenance_Cfc56oIs();
|
|
174937
174952
|
var require_sqlite_snapshot_protocol = require_sqlite_snapshot_protocol_B9OndqZv();
|
|
174938
174953
|
var require_wal_checkpoint_policy = require_wal_checkpoint_policy_d2z2qPqx();
|
|
174939
174954
|
var node_fs_promises = __require("fs/promises");
|
|
@@ -176903,7 +176918,7 @@ var require_sqlite_storage = __commonJS({
|
|
|
176903
176918
|
});
|
|
176904
176919
|
require_chunk_Cek0wNdY();
|
|
176905
176920
|
var require_builtins_sqlite_storage_filesystem_storage_addon = require_filesystem_storage_addon();
|
|
176906
|
-
var require_wal_maintenance =
|
|
176921
|
+
var require_wal_maintenance = require_wal_maintenance_Cfc56oIs();
|
|
176907
176922
|
var require_builtins_sqlite_storage_sqlite_settings_addon = require_sqlite_settings_addon();
|
|
176908
176923
|
var ConfigStore = class {
|
|
176909
176924
|
db;
|
|
@@ -176987,7 +177002,7 @@ var require_storage_orchestrator_addon = __commonJS({
|
|
|
176987
177002
|
[Symbol.toStringTag]: { value: "Module" }
|
|
176988
177003
|
});
|
|
176989
177004
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
176990
|
-
var require_dist10 =
|
|
177005
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
176991
177006
|
var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
|
|
176992
177007
|
var zod = __require("zod");
|
|
176993
177008
|
var node_crypto = __require("crypto");
|
|
@@ -181574,12 +181589,12 @@ var require_storage_orchestrator = __commonJS({
|
|
|
181574
181589
|
}
|
|
181575
181590
|
});
|
|
181576
181591
|
|
|
181577
|
-
// ../system/dist/agent-https-
|
|
181578
|
-
var
|
|
181579
|
-
"../system/dist/agent-https-
|
|
181592
|
+
// ../system/dist/agent-https-BrFzCJ3T.js
|
|
181593
|
+
var require_agent_https_BrFzCJ3T = __commonJS({
|
|
181594
|
+
"../system/dist/agent-https-BrFzCJ3T.js"(exports) {
|
|
181580
181595
|
"use strict";
|
|
181581
181596
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
181582
|
-
var require_dist10 =
|
|
181597
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
181583
181598
|
var require_x509_es = require_x509_es_WtnRNyYS();
|
|
181584
181599
|
var zod = __require("zod");
|
|
181585
181600
|
var node_crypto = __require("crypto");
|
|
@@ -182634,11 +182649,11 @@ var require_agent_https_D_yo1pzU = __commonJS({
|
|
|
182634
182649
|
}
|
|
182635
182650
|
});
|
|
182636
182651
|
|
|
182637
|
-
// ../system/dist/constants-
|
|
182638
|
-
var
|
|
182639
|
-
"../system/dist/constants-
|
|
182652
|
+
// ../system/dist/constants-BA4NvR5U.js
|
|
182653
|
+
var require_constants_BA4NvR5U = __commonJS({
|
|
182654
|
+
"../system/dist/constants-BA4NvR5U.js"(exports) {
|
|
182640
182655
|
"use strict";
|
|
182641
|
-
var MESH_CA_KEY_REF =
|
|
182656
|
+
var MESH_CA_KEY_REF = require_dist_BVrPqzF0().buildSecretRef({
|
|
182642
182657
|
owner: "system",
|
|
182643
182658
|
scope: { kind: "global" },
|
|
182644
182659
|
fieldPath: "meshCaKey"
|
|
@@ -199735,11 +199750,11 @@ var require_system_config_addon = __commonJS({
|
|
|
199735
199750
|
[Symbol.toStringTag]: { value: "Module" }
|
|
199736
199751
|
});
|
|
199737
199752
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
199738
|
-
var require_dist10 =
|
|
199753
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
199739
199754
|
var require_safe_buffer$1 = require_safe_buffer_D3aoa_7X();
|
|
199740
199755
|
var require_x509_es = require_x509_es_WtnRNyYS();
|
|
199741
|
-
var require_agent_https =
|
|
199742
|
-
var require_constants$8 =
|
|
199756
|
+
var require_agent_https = require_agent_https_BrFzCJ3T();
|
|
199757
|
+
var require_constants$8 = require_constants_BA4NvR5U();
|
|
199743
199758
|
var require_src$1 = require_src_CnAqG6EF();
|
|
199744
199759
|
var zod = __require("zod");
|
|
199745
199760
|
var node_crypto = __require("crypto");
|
|
@@ -281015,7 +281030,7 @@ var require_winston_logging = __commonJS({
|
|
|
281015
281030
|
[Symbol.toStringTag]: { value: "Module" }
|
|
281016
281031
|
});
|
|
281017
281032
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
281018
|
-
var require_dist10 =
|
|
281033
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
281019
281034
|
var require_formatter = require_formatter_xbxeV4GD();
|
|
281020
281035
|
var require_log_file_read_protocol = require_log_file_read_protocol_D0WcLbIV();
|
|
281021
281036
|
var node_path = __require("path");
|
|
@@ -288863,14 +288878,14 @@ var require_lib_C3U1yluo = __commonJS({
|
|
|
288863
288878
|
}
|
|
288864
288879
|
});
|
|
288865
288880
|
|
|
288866
|
-
// ../system/dist/hub-mdns-ciao-
|
|
288867
|
-
var
|
|
288868
|
-
"../system/dist/hub-mdns-ciao-
|
|
288881
|
+
// ../system/dist/hub-mdns-ciao-UNHb4yo0.js
|
|
288882
|
+
var require_hub_mdns_ciao_UNHb4yo0 = __commonJS({
|
|
288883
|
+
"../system/dist/hub-mdns-ciao-UNHb4yo0.js"(exports) {
|
|
288869
288884
|
"use strict";
|
|
288870
288885
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
288871
|
-
var require_dist10 =
|
|
288886
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
288872
288887
|
var require_x509_es = require_x509_es_WtnRNyYS();
|
|
288873
|
-
var require_agent_https =
|
|
288888
|
+
var require_agent_https = require_agent_https_BrFzCJ3T();
|
|
288874
288889
|
var node_crypto = __require("crypto");
|
|
288875
288890
|
var _camstack_types_node = require_node();
|
|
288876
288891
|
var node_fs_promises = __require("fs/promises");
|
|
@@ -289882,12 +289897,12 @@ var require_platform_key_source_Di7HrlGR = __commonJS({
|
|
|
289882
289897
|
}
|
|
289883
289898
|
});
|
|
289884
289899
|
|
|
289885
|
-
// ../system/dist/restore-archive-
|
|
289886
|
-
var
|
|
289887
|
-
"../system/dist/restore-archive-
|
|
289900
|
+
// ../system/dist/restore-archive-BS86n89m.js
|
|
289901
|
+
var require_restore_archive_BS86n89m = __commonJS({
|
|
289902
|
+
"../system/dist/restore-archive-BS86n89m.js"(exports) {
|
|
289888
289903
|
"use strict";
|
|
289889
289904
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
289890
|
-
var require_dist10 =
|
|
289905
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
289891
289906
|
var zod = __require("zod");
|
|
289892
289907
|
var node_crypto = __require("crypto");
|
|
289893
289908
|
var buffer = __require("buffer");
|
|
@@ -301184,8 +301199,8 @@ var require_dist3 = __commonJS({
|
|
|
301184
301199
|
"use strict";
|
|
301185
301200
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
301186
301201
|
var require_chunk = require_chunk_Cek0wNdY();
|
|
301187
|
-
var require_dist10 =
|
|
301188
|
-
var require_device_ca =
|
|
301202
|
+
var require_dist10 = require_dist_BVrPqzF0();
|
|
301203
|
+
var require_device_ca = require_device_ca_COyWgERw();
|
|
301189
301204
|
var require_read_all_rows$1 = require_read_all_rows_CVoO1ONM();
|
|
301190
301205
|
var require_builtins_alerts_alerts_addon = require_alerts_addon();
|
|
301191
301206
|
require_alerts();
|
|
@@ -301210,21 +301225,21 @@ var require_dist3 = __commonJS({
|
|
|
301210
301225
|
var require_builtins_native_metrics_native_metrics_addon = require_native_metrics_addon();
|
|
301211
301226
|
var require_builtins_device_history_device_history_addon = require_device_history_addon();
|
|
301212
301227
|
var require_builtins_sqlite_storage_filesystem_storage_addon = require_filesystem_storage_addon();
|
|
301213
|
-
var require_wal_maintenance =
|
|
301228
|
+
var require_wal_maintenance = require_wal_maintenance_Cfc56oIs();
|
|
301214
301229
|
var require_builtins_sqlite_storage_sqlite_settings_addon = require_sqlite_settings_addon();
|
|
301215
301230
|
var require_builtins_sqlite_storage_index = require_sqlite_storage();
|
|
301216
301231
|
var require_builtins_storage_orchestrator_storage_orchestrator_addon = require_storage_orchestrator_addon();
|
|
301217
301232
|
require_storage_orchestrator();
|
|
301218
|
-
var require_agent_https =
|
|
301219
|
-
var require_constants15 =
|
|
301233
|
+
var require_agent_https = require_agent_https_BrFzCJ3T();
|
|
301234
|
+
var require_constants15 = require_constants_BA4NvR5U();
|
|
301220
301235
|
var require_builtins_system_config_system_config_addon = require_system_config_addon();
|
|
301221
301236
|
require_system_config();
|
|
301222
301237
|
var require_builtins_winston_logging_index = require_winston_logging();
|
|
301223
301238
|
var require_custom_action_registry = require_custom_action_registry_JuMHGKEc();
|
|
301224
|
-
var require_hub_mdns_ciao =
|
|
301239
|
+
var require_hub_mdns_ciao = require_hub_mdns_ciao_UNHb4yo0();
|
|
301225
301240
|
var require_platform_key_source = require_platform_key_source_Di7HrlGR();
|
|
301226
301241
|
var require_resource_monitor = require_resource_monitor_mio9dSCT();
|
|
301227
|
-
var require_restore_archive =
|
|
301242
|
+
var require_restore_archive = require_restore_archive_BS86n89m();
|
|
301228
301243
|
var require_coral_accelerators = require_coral_accelerators_BSVsBVzt();
|
|
301229
301244
|
var zod = __require("zod");
|
|
301230
301245
|
var node_crypto = __require("crypto");
|
|
@@ -305690,7 +305705,8 @@ var require_dist3 = __commonJS({
|
|
|
305690
305705
|
isHub: zod.z.boolean(),
|
|
305691
305706
|
localIps: zod.z.array(zod.z.string()).readonly(),
|
|
305692
305707
|
addonIds: zod.z.array(zod.z.string()).readonly(),
|
|
305693
|
-
packages: zod.z.array(NodePackageEntrySchema).readonly().optional()
|
|
305708
|
+
packages: zod.z.array(NodePackageEntrySchema).readonly().optional(),
|
|
305709
|
+
tombstones: zod.z.array(zod.z.string()).readonly().optional()
|
|
305694
305710
|
});
|
|
305695
305711
|
var ClusterNodeHistoryBodySchema = zod.z.object({ descriptor: _clusterNodeDescriptorBody });
|
|
305696
305712
|
var clusterNodeHistoryKindSpec = {
|
|
@@ -313384,7 +313400,8 @@ var require_dist3 = __commonJS({
|
|
|
313384
313400
|
"auth.tokenExpiry",
|
|
313385
313401
|
"auth.accessTokenExpiry",
|
|
313386
313402
|
"auth.trustedProxies",
|
|
313387
|
-
"auth.trustedNetworks"
|
|
313403
|
+
"auth.trustedNetworks",
|
|
313404
|
+
"addons.convergence.dryRun"
|
|
313388
313405
|
];
|
|
313389
313406
|
function isPreloadedSystemKey(key) {
|
|
313390
313407
|
if (PRELOADED_SYSTEM_KEYS.includes(key)) return true;
|
|
@@ -379182,6 +379199,12 @@ ${eventLeaves.map(({ leaf, path }) => emitLeaf(leaf, path)).join("\n\n")}
|
|
|
379182
379199
|
instanceId: zod.z.string(),
|
|
379183
379200
|
cameraStableId: zod.z.string(),
|
|
379184
379201
|
nodeId: zod.z.string(),
|
|
379202
|
+
/**
|
|
379203
|
+
* False while the node the instance is bound to is not in the cluster
|
|
379204
|
+
* topology (forgotten, renamed, re-paired). The instance is kept; the
|
|
379205
|
+
* operator re-points it with `updateInstance({ targetNodeId })`.
|
|
379206
|
+
*/
|
|
379207
|
+
nodeInCluster: zod.z.boolean(),
|
|
379185
379208
|
profileId: zod.z.string(),
|
|
379186
379209
|
profileLabel: zod.z.string(),
|
|
379187
379210
|
name: zod.z.string(),
|
|
@@ -379241,6 +379264,8 @@ ${eventLeaves.map(({ leaf, path }) => emitLeaf(leaf, path)).join("\n\n")}
|
|
|
379241
379264
|
}),
|
|
379242
379265
|
updateInstance: require_sleep.method(zod.z.object({
|
|
379243
379266
|
instanceId: zod.z.string().min(1),
|
|
379267
|
+
/** Re-point the instance to another node; the profile must exist there. */
|
|
379268
|
+
targetNodeId: zod.z.string().min(1).max(256).optional(),
|
|
379244
379269
|
name: zod.z.string().trim().min(1).max(160).optional(),
|
|
379245
379270
|
executable: zod.z.string().max(1024).optional(),
|
|
379246
379271
|
args: zod.z.array(zod.z.string().max(2048)).max(64).optional(),
|
|
@@ -382515,7 +382540,14 @@ ${eventLeaves.map(({ leaf, path }) => emitLeaf(leaf, path)).join("\n\n")}
|
|
|
382515
382540
|
col: zod.z.number().int().min(0).max(24),
|
|
382516
382541
|
rowSpan: zod.z.number().int().min(1).max(24),
|
|
382517
382542
|
colSpan: zod.z.number().int().min(1).max(24),
|
|
382518
|
-
title: zod.z.string().min(1).max(40).optional()
|
|
382543
|
+
title: zod.z.string().min(1).max(40).optional(),
|
|
382544
|
+
/**
|
|
382545
|
+
* How much room a divider takes: `compact` (the default) is a slim rule,
|
|
382546
|
+
* `normal` a full grid row. Other frames ignore it.
|
|
382547
|
+
*/
|
|
382548
|
+
size: zod.z.enum(["compact", "normal"]).optional(),
|
|
382549
|
+
/** Keep the title in the layout but draw only the rule. */
|
|
382550
|
+
hideTitle: zod.z.boolean().optional()
|
|
382519
382551
|
});
|
|
382520
382552
|
function rectsOverlap(a, b) {
|
|
382521
382553
|
return a.row < b.row + b.rowSpan && b.row < a.row + a.rowSpan && a.col < b.col + b.colSpan && b.col < a.col + a.colSpan;
|
|
@@ -438029,6 +438061,69 @@ var require_agent_mesh_gate = __commonJS({
|
|
|
438029
438061
|
}
|
|
438030
438062
|
});
|
|
438031
438063
|
|
|
438064
|
+
// ../../server/backend/dist/agent/agent-shutdown.js
|
|
438065
|
+
var require_agent_shutdown = __commonJS({
|
|
438066
|
+
"../../server/backend/dist/agent/agent-shutdown.js"(exports) {
|
|
438067
|
+
"use strict";
|
|
438068
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
438069
|
+
exports.SHUTDOWN_DEADLINE_MS = exports.SHUTDOWN_STEP_TIMEOUT_MS = void 0;
|
|
438070
|
+
exports.createAgentShutdown = createAgentShutdown;
|
|
438071
|
+
exports.SHUTDOWN_STEP_TIMEOUT_MS = 5e3;
|
|
438072
|
+
exports.SHUTDOWN_DEADLINE_MS = 15e3;
|
|
438073
|
+
function errMessage(err) {
|
|
438074
|
+
return err instanceof Error ? err.message : String(err);
|
|
438075
|
+
}
|
|
438076
|
+
async function runBounded(step, timeoutMs) {
|
|
438077
|
+
let timer;
|
|
438078
|
+
const timeout = new Promise((resolve) => {
|
|
438079
|
+
timer = setTimeout(() => resolve("timed-out"), timeoutMs);
|
|
438080
|
+
});
|
|
438081
|
+
try {
|
|
438082
|
+
return await Promise.race([step.run().then(() => "done"), timeout]);
|
|
438083
|
+
} finally {
|
|
438084
|
+
clearTimeout(timer);
|
|
438085
|
+
}
|
|
438086
|
+
}
|
|
438087
|
+
function createAgentShutdown(deps) {
|
|
438088
|
+
const stepTimeoutMs = deps.stepTimeoutMs ?? exports.SHUTDOWN_STEP_TIMEOUT_MS;
|
|
438089
|
+
const deadlineMs = deps.deadlineMs ?? exports.SHUTDOWN_DEADLINE_MS;
|
|
438090
|
+
const { logger } = deps;
|
|
438091
|
+
let startedAt = null;
|
|
438092
|
+
return async (reason) => {
|
|
438093
|
+
if (startedAt !== null) {
|
|
438094
|
+
logger.error(`shutdown already in progress for ${Date.now() - startedAt}ms; ${reason} forces exit`);
|
|
438095
|
+
deps.exit(1);
|
|
438096
|
+
return;
|
|
438097
|
+
}
|
|
438098
|
+
const began = Date.now();
|
|
438099
|
+
startedAt = began;
|
|
438100
|
+
logger.info(`shutdown started by ${reason}`);
|
|
438101
|
+
const deadline = setTimeout(() => {
|
|
438102
|
+
logger.error(`shutdown deadline of ${deadlineMs}ms exceeded (started by ${reason}); exiting 1`);
|
|
438103
|
+
deps.exit(1);
|
|
438104
|
+
}, deadlineMs);
|
|
438105
|
+
for (const step of deps.steps) {
|
|
438106
|
+
const stepStart = Date.now();
|
|
438107
|
+
try {
|
|
438108
|
+
const outcome = await runBounded(step, stepTimeoutMs);
|
|
438109
|
+
const took = `${Date.now() - stepStart}ms`;
|
|
438110
|
+
if (outcome === "timed-out") {
|
|
438111
|
+
logger.warn(`shutdown step ${step.name} timed out after ${took}; continuing`);
|
|
438112
|
+
} else {
|
|
438113
|
+
logger.info(`shutdown step ${step.name} done in ${took}`);
|
|
438114
|
+
}
|
|
438115
|
+
} catch (err) {
|
|
438116
|
+
logger.warn(`shutdown step ${step.name} failed after ${Date.now() - stepStart}ms: ${errMessage(err)}`);
|
|
438117
|
+
}
|
|
438118
|
+
}
|
|
438119
|
+
clearTimeout(deadline);
|
|
438120
|
+
logger.info(`shutdown finished in ${Date.now() - began}ms (started by ${reason})`);
|
|
438121
|
+
deps.exit(0);
|
|
438122
|
+
};
|
|
438123
|
+
}
|
|
438124
|
+
}
|
|
438125
|
+
});
|
|
438126
|
+
|
|
438032
438127
|
// ../../server/backend/dist/agent/agent-pairing-local.js
|
|
438033
438128
|
var require_agent_pairing_local = __commonJS({
|
|
438034
438129
|
"../../server/backend/dist/agent/agent-pairing-local.js"(exports) {
|
|
@@ -574919,6 +575014,7 @@ var require_main2 = __commonJS({
|
|
|
574919
575014
|
var agent_addon_updates_js_1 = require_agent_addon_updates();
|
|
574920
575015
|
var agent_hub_registration_js_1 = require_agent_hub_registration();
|
|
574921
575016
|
var agent_mesh_gate_js_1 = require_agent_mesh_gate();
|
|
575017
|
+
var agent_shutdown_js_1 = require_agent_shutdown();
|
|
574922
575018
|
var agent_pairing_local_js_1 = require_agent_pairing_local();
|
|
574923
575019
|
var agent_membership_watch_js_1 = require_agent_membership_watch();
|
|
574924
575020
|
var agent_pairing_store_js_1 = require_agent_pairing_store();
|
|
@@ -575647,26 +575743,41 @@ var require_main2 = __commonJS({
|
|
|
575647
575743
|
}).then((listener) => {
|
|
575648
575744
|
agentHttpListener = listener;
|
|
575649
575745
|
});
|
|
575650
|
-
const shutdown =
|
|
575651
|
-
|
|
575652
|
-
|
|
575653
|
-
|
|
575654
|
-
|
|
575655
|
-
|
|
575656
|
-
|
|
575657
|
-
|
|
575658
|
-
|
|
575659
|
-
|
|
575746
|
+
const shutdown = (0, agent_shutdown_js_1.createAgentShutdown)({
|
|
575747
|
+
logger: consoleLogger,
|
|
575748
|
+
exit: (code) => process.exit(code),
|
|
575749
|
+
steps: [
|
|
575750
|
+
{
|
|
575751
|
+
name: "abort-registration",
|
|
575752
|
+
run: async () => {
|
|
575753
|
+
registerAbortController.abort();
|
|
575754
|
+
udsEventBridgeDispose?.();
|
|
575755
|
+
udsEventBridgeDispose = null;
|
|
575660
575756
|
}
|
|
575661
|
-
}
|
|
575662
|
-
|
|
575663
|
-
|
|
575664
|
-
|
|
575665
|
-
|
|
575666
|
-
|
|
575667
|
-
|
|
575668
|
-
|
|
575669
|
-
|
|
575757
|
+
},
|
|
575758
|
+
{
|
|
575759
|
+
name: "addons",
|
|
575760
|
+
// Concurrent: one slow addon must not eat the budget of the others.
|
|
575761
|
+
run: async () => {
|
|
575762
|
+
const stops = [];
|
|
575763
|
+
for (const [addonId, entry] of loadedAddons) {
|
|
575764
|
+
if (!entry.addon?.shutdown)
|
|
575765
|
+
continue;
|
|
575766
|
+
const began = Date.now();
|
|
575767
|
+
stops.push(Promise.resolve().then(() => entry.addon?.shutdown?.()).then(() => void 0).catch((err) => consoleLogger.warn(`addon ${addonId} shutdown failed: ${(0, types_2.errMsg)(err)}`)).finally(() => consoleLogger.info(`addon ${addonId} shutdown took ${Date.now() - began}ms`)));
|
|
575768
|
+
}
|
|
575769
|
+
await Promise.all(stops);
|
|
575770
|
+
}
|
|
575771
|
+
},
|
|
575772
|
+
// Withdraw the mDNS advertisement, then stop accepting new HTTP/HTTPS connections before
|
|
575773
|
+
// the broker goes away.
|
|
575774
|
+
{ name: "mdns", run: () => agentMdns.stop() },
|
|
575775
|
+
{ name: "http-listener", run: async () => void await agentHttpListener?.close() },
|
|
575776
|
+
{ name: "broker", run: () => broker.stop() }
|
|
575777
|
+
]
|
|
575778
|
+
});
|
|
575779
|
+
process.on("SIGTERM", () => void shutdown("SIGTERM"));
|
|
575780
|
+
process.on("SIGINT", () => void shutdown("SIGINT"));
|
|
575670
575781
|
if (!addonsBooted) {
|
|
575671
575782
|
console.log(`[Agent] Node "${config.nodeId}" is unpaired - serving pairing only; addons boot after pairing`);
|
|
575672
575783
|
return;
|
|
@@ -592486,6 +592597,14 @@ var require_addon_package_service = __commonJS({
|
|
|
592486
592597
|
fs.rmSync(destDir, { recursive: true, force: true });
|
|
592487
592598
|
}
|
|
592488
592599
|
}
|
|
592600
|
+
/**
|
|
592601
|
+
* The version the registry serves as `latest` for a package — what the hub
|
|
592602
|
+
* follows for an agent-only package it tracks without installing (D982).
|
|
592603
|
+
* Throws when the registry cannot answer.
|
|
592604
|
+
*/
|
|
592605
|
+
async resolveRegistryVersion(name) {
|
|
592606
|
+
return resolveNpmVersion(name, "latest", process.env["CAMSTACK_NPM_REGISTRY"]);
|
|
592607
|
+
}
|
|
592489
592608
|
/**
|
|
592490
592609
|
* Resolve `name@version` and `npm pack` it into a tarball buffer
|
|
592491
592610
|
* WITHOUT installing. Used to push a package update to an agent: the
|
|
@@ -598291,7 +598410,7 @@ var require_addon_upload = __commonJS({
|
|
|
598291
598410
|
bytes: staged.bytes
|
|
598292
598411
|
};
|
|
598293
598412
|
}
|
|
598294
|
-
async function registerAddonUploadRoute(fastify, addonBridge, authService, moleculer, addonRegistry, addonPackageService, logger, resolveClusterBaseUrl, deliveryLedger) {
|
|
598413
|
+
async function registerAddonUploadRoute(fastify, addonBridge, authService, moleculer, addonRegistry, addonPackageService, logger, resolveClusterBaseUrl, deliveryLedger, convergence) {
|
|
598295
598414
|
await fastify.register(Promise.resolve().then(() => __importStar(require_multipart2())), {
|
|
598296
598415
|
limits: { fileSize: MAX_UPLOAD_BYTES }
|
|
598297
598416
|
});
|
|
@@ -598322,10 +598441,10 @@ var require_addon_upload = __commonJS({
|
|
|
598322
598441
|
});
|
|
598323
598442
|
}
|
|
598324
598443
|
if (!nodeId || nodeId === "hub") {
|
|
598325
|
-
return installToHub(reply, addonBridge, addonRegistry, addonPackageService, moleculer, logger, data.filename, buffer, resolveClusterBaseUrl, deliveryLedger);
|
|
598444
|
+
return installToHub(reply, addonBridge, addonRegistry, addonPackageService, moleculer, logger, data.filename, buffer, resolveClusterBaseUrl, deliveryLedger, convergence);
|
|
598326
598445
|
}
|
|
598327
598446
|
const agentAddonId = addonIdHint ?? manifest.name;
|
|
598328
|
-
return deployToAgent(reply, moleculer, logger, nodeId, agentAddonId, buffer, resolveClusterBaseUrl, deliveryLedger);
|
|
598447
|
+
return deployToAgent(reply, moleculer, logger, nodeId, agentAddonId, buffer, resolveClusterBaseUrl, deliveryLedger, convergence);
|
|
598329
598448
|
});
|
|
598330
598449
|
}
|
|
598331
598450
|
function packageHasAgentDeployable(addonsDir, packageName) {
|
|
@@ -598378,7 +598497,7 @@ var require_addon_upload = __commonJS({
|
|
|
598378
598497
|
}
|
|
598379
598498
|
return results;
|
|
598380
598499
|
}
|
|
598381
|
-
async function installToHub(reply, addonBridge, addonRegistry, addonPackageService, moleculer, logger, filename, buffer, resolveClusterBaseUrl, deliveryLedger) {
|
|
598500
|
+
async function installToHub(reply, addonBridge, addonRegistry, addonPackageService, moleculer, logger, filename, buffer, resolveClusterBaseUrl, deliveryLedger, convergence) {
|
|
598382
598501
|
const tmpDir = path.join(os.tmpdir(), `camstack-addon-upload-${Date.now()}`);
|
|
598383
598502
|
fs.mkdirSync(tmpDir, { recursive: true });
|
|
598384
598503
|
const tgzPath = path.join(tmpDir, filename);
|
|
@@ -598453,7 +598572,10 @@ var require_addon_upload = __commonJS({
|
|
|
598453
598572
|
logger.info("propagation done", {
|
|
598454
598573
|
meta: { packageName: result.name, agents: agentResults }
|
|
598455
598574
|
});
|
|
598575
|
+
void convergence?.requestConvergence("hub-change");
|
|
598456
598576
|
});
|
|
598577
|
+
} else {
|
|
598578
|
+
void convergence?.requestConvergence("hub-change");
|
|
598457
598579
|
}
|
|
598458
598580
|
return reply.send({
|
|
598459
598581
|
success: true,
|
|
@@ -598469,7 +598591,7 @@ var require_addon_upload = __commonJS({
|
|
|
598469
598591
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
598470
598592
|
}
|
|
598471
598593
|
}
|
|
598472
|
-
async function deployToAgent(reply, moleculer, logger, nodeId, addonId, buffer, resolveClusterBaseUrl, deliveryLedger) {
|
|
598594
|
+
async function deployToAgent(reply, moleculer, logger, nodeId, addonId, buffer, resolveClusterBaseUrl, deliveryLedger, convergence) {
|
|
598473
598595
|
const hubBaseUrl = await resolveBaseUrlOrReason(resolveClusterBaseUrl);
|
|
598474
598596
|
if (!hubBaseUrl.ok) {
|
|
598475
598597
|
logger.error("agent deploy: no hub address the agent can reach \u2014 nothing delivered", {
|
|
@@ -598488,6 +598610,7 @@ var require_addon_upload = __commonJS({
|
|
|
598488
598610
|
if (!result.success) {
|
|
598489
598611
|
return reply.status(502).send({ error: `Agent deploy failed: ${result.error ?? "unknown"}` });
|
|
598490
598612
|
}
|
|
598613
|
+
await convergence?.noteExplicitDelivery(nodeId, addonId);
|
|
598491
598614
|
return reply.send({
|
|
598492
598615
|
success: true,
|
|
598493
598616
|
target: nodeId,
|
|
@@ -599374,6 +599497,96 @@ var require_addon_uninstall = __commonJS({
|
|
|
599374
599497
|
}
|
|
599375
599498
|
});
|
|
599376
599499
|
|
|
599500
|
+
// ../../server/backend/dist/core/agent/agent-desired-set.js
|
|
599501
|
+
var require_agent_desired_set = __commonJS({
|
|
599502
|
+
"../../server/backend/dist/core/agent/agent-desired-set.js"(exports) {
|
|
599503
|
+
"use strict";
|
|
599504
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
599505
|
+
exports.AGENT_TRACKED_PACKAGES = void 0;
|
|
599506
|
+
exports.isAgentTrackedPackage = isAgentTrackedPackage;
|
|
599507
|
+
exports.computeDesiredSet = computeDesiredSet;
|
|
599508
|
+
exports.diffNodeAgainstDesired = diffNodeAgainstDesired;
|
|
599509
|
+
var system_1 = require_dist3();
|
|
599510
|
+
exports.AGENT_TRACKED_PACKAGES = ["@camstack/addon-agent-ui"];
|
|
599511
|
+
function isAgentTrackedPackage(name) {
|
|
599512
|
+
return exports.AGENT_TRACKED_PACKAGES.includes(name);
|
|
599513
|
+
}
|
|
599514
|
+
function computeDesiredSet(input) {
|
|
599515
|
+
const desired = /* @__PURE__ */ new Map();
|
|
599516
|
+
const hubOnly = /* @__PURE__ */ new Set();
|
|
599517
|
+
const excluded = [];
|
|
599518
|
+
for (const [name, fact] of input.hubPackages) {
|
|
599519
|
+
if (input.bootstrap.has(name))
|
|
599520
|
+
continue;
|
|
599521
|
+
if (fact.placements.length > 0 && fact.placements.every((p) => p === "hub-only")) {
|
|
599522
|
+
hubOnly.add(name);
|
|
599523
|
+
excluded.push({ name, reason: "hub-only placement" });
|
|
599524
|
+
continue;
|
|
599525
|
+
}
|
|
599526
|
+
if (fact.placements.includes("hub-only")) {
|
|
599527
|
+
excluded.push({ name, reason: "mixes a hub-only addon" });
|
|
599528
|
+
continue;
|
|
599529
|
+
}
|
|
599530
|
+
if (!fact.placements.includes("any-node")) {
|
|
599531
|
+
excluded.push({ name, reason: "placement does not allow any node" });
|
|
599532
|
+
continue;
|
|
599533
|
+
}
|
|
599534
|
+
if (input.tombstones.has(name)) {
|
|
599535
|
+
excluded.push({ name, reason: "tombstoned" });
|
|
599536
|
+
continue;
|
|
599537
|
+
}
|
|
599538
|
+
if (fact.version === null) {
|
|
599539
|
+
excluded.push({ name, reason: "hub version unknown" });
|
|
599540
|
+
continue;
|
|
599541
|
+
}
|
|
599542
|
+
desired.set(name, { name, version: fact.version, origin: "hub-any-node" });
|
|
599543
|
+
}
|
|
599544
|
+
for (const [name, version] of input.trackedForAgents) {
|
|
599545
|
+
if (input.bootstrap.has(name))
|
|
599546
|
+
continue;
|
|
599547
|
+
if (input.tombstones.has(name)) {
|
|
599548
|
+
excluded.push({ name, reason: "tombstoned" });
|
|
599549
|
+
continue;
|
|
599550
|
+
}
|
|
599551
|
+
desired.set(name, { name, version, origin: "agent-tracked" });
|
|
599552
|
+
}
|
|
599553
|
+
return { desired, hubOnly, tombstones: input.tombstones, excluded };
|
|
599554
|
+
}
|
|
599555
|
+
function diffNodeAgainstDesired(input) {
|
|
599556
|
+
const observed = new Map(input.observed.map((p) => [p.name, p.version]));
|
|
599557
|
+
const install = [];
|
|
599558
|
+
const update = [];
|
|
599559
|
+
const remove = [];
|
|
599560
|
+
const retired = [];
|
|
599561
|
+
for (const entry of input.desired.desired.values()) {
|
|
599562
|
+
const present = observed.has(entry.name);
|
|
599563
|
+
const from = present ? observed.get(entry.name) ?? null : null;
|
|
599564
|
+
const decision = (0, system_1.decideAddonVersionMove)(from, entry.version, system_1.ADDON_VERSION_REASON_HUB);
|
|
599565
|
+
if (!decision.move)
|
|
599566
|
+
continue;
|
|
599567
|
+
if (input.retired.has(entry.name)) {
|
|
599568
|
+
retired.push(entry.name);
|
|
599569
|
+
continue;
|
|
599570
|
+
}
|
|
599571
|
+
const target = { ...entry, from };
|
|
599572
|
+
if (present)
|
|
599573
|
+
update.push(target);
|
|
599574
|
+
else
|
|
599575
|
+
install.push(target);
|
|
599576
|
+
}
|
|
599577
|
+
for (const name of observed.keys()) {
|
|
599578
|
+
if (input.bootstrap.has(name))
|
|
599579
|
+
continue;
|
|
599580
|
+
if (input.desired.tombstones.has(name))
|
|
599581
|
+
remove.push({ name, reason: "tombstoned" });
|
|
599582
|
+
else if (input.desired.hubOnly.has(name))
|
|
599583
|
+
remove.push({ name, reason: "hub-only placement" });
|
|
599584
|
+
}
|
|
599585
|
+
return { install, update, remove, retired };
|
|
599586
|
+
}
|
|
599587
|
+
}
|
|
599588
|
+
});
|
|
599589
|
+
|
|
599377
599590
|
// ../../server/backend/dist/core/updates/agent-installed-packages.js
|
|
599378
599591
|
var require_agent_installed_packages = __commonJS({
|
|
599379
599592
|
"../../server/backend/dist/core/updates/agent-installed-packages.js"(exports) {
|
|
@@ -601174,6 +601387,7 @@ var require_cap_providers = __commonJS({
|
|
|
601174
601387
|
var integration_id_backfill_1 = require_integration_id_backfill();
|
|
601175
601388
|
var addon_package_service_js_1 = require_addon_package_service();
|
|
601176
601389
|
var addon_uninstall_js_1 = require_addon_uninstall();
|
|
601390
|
+
var agent_desired_set_1 = require_agent_desired_set();
|
|
601177
601391
|
var lifecycle_runner_singleton_js_1 = require_lifecycle_runner_singleton();
|
|
601178
601392
|
var agent_installed_packages_js_1 = require_agent_installed_packages();
|
|
601179
601393
|
var http_request_census_singleton_js_1 = require_http_request_census_singleton();
|
|
@@ -602275,6 +602489,13 @@ var require_cap_providers = __commonJS({
|
|
|
602275
602489
|
const broker = (0, system_1.asBrokerLike)(moleculer.broker);
|
|
602276
602490
|
const uninstallSeam = buildUninstallSeam(ar, ps, broker, agentRegistry);
|
|
602277
602491
|
const frameworkAllowSet = /* @__PURE__ */ new Set([addon_package_service_js_1.SYSTEM_PACKAGE]);
|
|
602492
|
+
const requestHubChangeConvergence = () => {
|
|
602493
|
+
void agentRegistry?.requestConvergence("hub-change");
|
|
602494
|
+
};
|
|
602495
|
+
const deployPackedToAgent = async (agentNodeId, packageName, bundle) => {
|
|
602496
|
+
await broker.call("$agent.deploy", { addonId: packageName, bundle }, { nodeID: agentNodeId, timeout: 3e5 });
|
|
602497
|
+
await broker.call("$agent.reload", {}, { nodeID: agentNodeId, timeout: 3e5 });
|
|
602498
|
+
};
|
|
602278
602499
|
const lifecycleRunner = (0, lifecycle_runner_singleton_js_1.getLifecycleRunner)();
|
|
602279
602500
|
const lifecycleCreatedBy = ctx.user?.username ?? ctx.user?.id ?? "system";
|
|
602280
602501
|
return {
|
|
@@ -602325,13 +602546,23 @@ var require_cap_providers = __commonJS({
|
|
|
602325
602546
|
level: input.level
|
|
602326
602547
|
}),
|
|
602327
602548
|
listPackages: async () => ps.listInstalled(),
|
|
602328
|
-
installPackage: async (input) =>
|
|
602329
|
-
|
|
602549
|
+
installPackage: async (input) => {
|
|
602550
|
+
const result = await ps.installAndLoad(input.packageName, input.version);
|
|
602551
|
+
requestHubChangeConvergence();
|
|
602552
|
+
return result;
|
|
602553
|
+
},
|
|
602554
|
+
installFromWorkspace: async (input) => {
|
|
602555
|
+
const result = await ps.installFromWorkspaceAndLoad(input.packageName);
|
|
602556
|
+
requestHubChangeConvergence();
|
|
602557
|
+
return result;
|
|
602558
|
+
},
|
|
602330
602559
|
isWorkspaceAvailable: async () => ps.isWorkspaceAvailable(),
|
|
602331
602560
|
listWorkspacePackages: async () => ps.listWorkspacePackages(),
|
|
602332
602561
|
uninstallPackage: async (input) => {
|
|
602333
602562
|
try {
|
|
602334
|
-
|
|
602563
|
+
const result = await (0, addon_uninstall_js_1.uninstallPackage)(uninstallSeam, input);
|
|
602564
|
+
requestHubChangeConvergence();
|
|
602565
|
+
return result;
|
|
602335
602566
|
} catch (err) {
|
|
602336
602567
|
if (err instanceof addon_uninstall_js_1.PackageProtectedError) {
|
|
602337
602568
|
throw new server_1.TRPCError({ code: "FORBIDDEN", message: err.message });
|
|
@@ -602356,6 +602587,28 @@ var require_cap_providers = __commonJS({
|
|
|
602356
602587
|
},
|
|
602357
602588
|
updatePackage: async (input) => {
|
|
602358
602589
|
const nodeId = input.nodeId;
|
|
602590
|
+
if ((0, agent_desired_set_1.isAgentTrackedPackage)(input.name) && (nodeId === void 0 || isHubNode(nodeId))) {
|
|
602591
|
+
if (agentRegistry === void 0) {
|
|
602592
|
+
return {
|
|
602593
|
+
success: false,
|
|
602594
|
+
error: `${input.name} is delivered by the agent registry, which is not wired`
|
|
602595
|
+
};
|
|
602596
|
+
}
|
|
602597
|
+
const packed2 = await ps.packPackage(input.name, input.version);
|
|
602598
|
+
const targets = agentRegistry.onlineAgentIds();
|
|
602599
|
+
const failures = [];
|
|
602600
|
+
for (const target of targets) {
|
|
602601
|
+
try {
|
|
602602
|
+
await deployPackedToAgent(target, input.name, packed2.buffer);
|
|
602603
|
+
await agentRegistry.noteExplicitDelivery(target, input.name);
|
|
602604
|
+
} catch (err) {
|
|
602605
|
+
failures.push(`${target}: ${err instanceof Error ? err.message : String(err)}`);
|
|
602606
|
+
}
|
|
602607
|
+
}
|
|
602608
|
+
if (failures.length > 0)
|
|
602609
|
+
return { success: false, error: failures.join("; ") };
|
|
602610
|
+
return { success: true, name: input.name, version: packed2.version };
|
|
602611
|
+
}
|
|
602359
602612
|
if (nodeId === void 0 || isHubNode(nodeId)) {
|
|
602360
602613
|
const version = input.version ?? "latest";
|
|
602361
602614
|
const { jobId } = await lifecycleRunner.startJob({
|
|
@@ -602366,13 +602619,14 @@ var require_cap_providers = __commonJS({
|
|
|
602366
602619
|
const job = lifecycleRunner.getJob(jobId);
|
|
602367
602620
|
const task = job?.tasks[0];
|
|
602368
602621
|
if (task?.phase === "done") {
|
|
602622
|
+
requestHubChangeConvergence();
|
|
602369
602623
|
return { success: true, name: input.name, version, jobId };
|
|
602370
602624
|
}
|
|
602371
602625
|
return { success: false, error: task?.error ?? "update failed", jobId };
|
|
602372
602626
|
}
|
|
602373
602627
|
const packed = await ps.packPackage(input.name, input.version);
|
|
602374
|
-
await
|
|
602375
|
-
await
|
|
602628
|
+
await deployPackedToAgent(nodeId, input.name, packed.buffer);
|
|
602629
|
+
await agentRegistry?.noteExplicitDelivery(nodeId, input.name);
|
|
602376
602630
|
return { success: true, name: input.name, version: packed.version, nodeId };
|
|
602377
602631
|
},
|
|
602378
602632
|
rollbackPackage: async (input) => ps.rollbackPackage(input.name),
|
|
@@ -618889,92 +619143,18 @@ var require_agent_addon_backfill = __commonJS({
|
|
|
618889
619143
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
618890
619144
|
exports.BackfillAttemptTracker = exports.MAX_BACKFILL_ATTEMPTS = void 0;
|
|
618891
619145
|
exports.triggerMayDeliver = triggerMayDeliver;
|
|
618892
|
-
exports.freshNodeSkipReason = freshNodeSkipReason;
|
|
618893
|
-
exports.computeBackfillPlan = computeBackfillPlan;
|
|
618894
619146
|
exports.confirmBackfillPlan = confirmBackfillPlan;
|
|
618895
619147
|
exports.executeBackfill = executeBackfill;
|
|
618896
|
-
var system_1 = require_dist3();
|
|
618897
619148
|
var DELIVERING_TRIGGERS = /* @__PURE__ */ new Set([
|
|
618898
619149
|
"node-registration",
|
|
618899
619150
|
"hub-boot",
|
|
618900
|
-
"operator-repair"
|
|
619151
|
+
"operator-repair",
|
|
619152
|
+
"periodic",
|
|
619153
|
+
"hub-change"
|
|
618901
619154
|
]);
|
|
618902
619155
|
function triggerMayDeliver(trigger) {
|
|
618903
619156
|
return DELIVERING_TRIGGERS.has(trigger);
|
|
618904
619157
|
}
|
|
618905
|
-
function freshNodeSkipReason(placements) {
|
|
618906
|
-
if (placements.includes("hub-only"))
|
|
618907
|
-
return "hub-only placement";
|
|
618908
|
-
if (!placements.includes("any-node"))
|
|
618909
|
-
return "placement does not allow any node";
|
|
618910
|
-
return null;
|
|
618911
|
-
}
|
|
618912
|
-
function computeBackfillPlan(input) {
|
|
618913
|
-
if (input.freshNode !== void 0 && input.recorded.length === 0) {
|
|
618914
|
-
return computeFreshNodePlan(input, input.freshNode);
|
|
618915
|
-
}
|
|
618916
|
-
const liveByName = new Map(input.live.map((p) => [p.name, p.version]));
|
|
618917
|
-
const targets = [];
|
|
618918
|
-
const retired = [];
|
|
618919
|
-
const notOnHub = [];
|
|
618920
|
-
for (const entry of input.recorded) {
|
|
618921
|
-
if (input.bootstrap.has(entry.name))
|
|
618922
|
-
continue;
|
|
618923
|
-
if (input.undeployed.has(entry.name))
|
|
618924
|
-
continue;
|
|
618925
|
-
const hubVersion = input.hubVersions.get(entry.name);
|
|
618926
|
-
const present = liveByName.has(entry.name);
|
|
618927
|
-
const liveVersion = present ? liveByName.get(entry.name) ?? null : null;
|
|
618928
|
-
if (hubVersion === void 0) {
|
|
618929
|
-
if (!present && input.retired.has(entry.name))
|
|
618930
|
-
retired.push(entry.name);
|
|
618931
|
-
else if (!present)
|
|
618932
|
-
notOnHub.push(entry.name);
|
|
618933
|
-
continue;
|
|
618934
|
-
}
|
|
618935
|
-
const decision = (0, system_1.decideAddonVersionMove)(present ? liveVersion : null, hubVersion, system_1.ADDON_VERSION_REASON_HUB);
|
|
618936
|
-
if (!decision.move)
|
|
618937
|
-
continue;
|
|
618938
|
-
if (input.retired.has(entry.name)) {
|
|
618939
|
-
retired.push(entry.name);
|
|
618940
|
-
continue;
|
|
618941
|
-
}
|
|
618942
|
-
targets.push({ name: entry.name, version: hubVersion, versionSource: "hub-installed" });
|
|
618943
|
-
}
|
|
618944
|
-
return { targets, retired, notOnHub, liveCount: liveByName.size, skipped: [] };
|
|
618945
|
-
}
|
|
618946
|
-
function computeFreshNodePlan(input, fresh) {
|
|
618947
|
-
const liveByName = new Map(input.live.map((p) => [p.name, p.version]));
|
|
618948
|
-
const targets = [];
|
|
618949
|
-
const retired = [];
|
|
618950
|
-
const skipped = [];
|
|
618951
|
-
for (const [name, placements] of fresh.hubPackagePlacements) {
|
|
618952
|
-
if (input.bootstrap.has(name))
|
|
618953
|
-
continue;
|
|
618954
|
-
if (input.undeployed.has(name))
|
|
618955
|
-
continue;
|
|
618956
|
-
const reason = freshNodeSkipReason(placements);
|
|
618957
|
-
if (reason !== null) {
|
|
618958
|
-
skipped.push({ name, reason });
|
|
618959
|
-
continue;
|
|
618960
|
-
}
|
|
618961
|
-
const hubVersion = input.hubVersions.get(name);
|
|
618962
|
-
if (hubVersion === void 0) {
|
|
618963
|
-
skipped.push({ name, reason: "hub version unknown" });
|
|
618964
|
-
continue;
|
|
618965
|
-
}
|
|
618966
|
-
const present = liveByName.has(name);
|
|
618967
|
-
const decision = (0, system_1.decideAddonVersionMove)(present ? liveByName.get(name) ?? null : null, hubVersion, system_1.ADDON_VERSION_REASON_HUB);
|
|
618968
|
-
if (!decision.move)
|
|
618969
|
-
continue;
|
|
618970
|
-
if (input.retired.has(name)) {
|
|
618971
|
-
retired.push(name);
|
|
618972
|
-
continue;
|
|
618973
|
-
}
|
|
618974
|
-
targets.push({ name, version: hubVersion, versionSource: "hub-installed" });
|
|
618975
|
-
}
|
|
618976
|
-
return { targets, retired, notOnHub: [], liveCount: liveByName.size, skipped };
|
|
618977
|
-
}
|
|
618978
619158
|
function confirmBackfillPlan(plan, secondRead) {
|
|
618979
619159
|
const seen = new Map(secondRead.map((p) => [p.name, p.version]));
|
|
618980
619160
|
const targets = [];
|
|
@@ -619061,13 +619241,18 @@ var require_agent_addon_backfill = __commonJS({
|
|
|
619061
619241
|
} catch (err) {
|
|
619062
619242
|
const error = err instanceof Error ? err.message : String(err);
|
|
619063
619243
|
const { retired } = tracker.recordFailure(nodeId, target.name, target.version, error);
|
|
619064
|
-
failed.push({
|
|
619244
|
+
failed.push({
|
|
619245
|
+
name: target.name,
|
|
619246
|
+
version: target.version,
|
|
619247
|
+
error,
|
|
619248
|
+
retired
|
|
619249
|
+
});
|
|
619065
619250
|
}
|
|
619066
619251
|
}
|
|
619067
619252
|
if (delivered.length > 0) {
|
|
619068
619253
|
await seam.reload(nodeId);
|
|
619069
619254
|
}
|
|
619070
|
-
return { delivered, failed, skipped: plan.retired
|
|
619255
|
+
return { delivered, failed, skipped: plan.retired };
|
|
619071
619256
|
}
|
|
619072
619257
|
}
|
|
619073
619258
|
});
|
|
@@ -619311,7 +619496,7 @@ var require_agent_registry_service = __commonJS({
|
|
|
619311
619496
|
};
|
|
619312
619497
|
})();
|
|
619313
619498
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
619314
|
-
exports.AgentRegistryService = exports.AGENT_BACKFILL_RPC_TIMEOUT_MS = exports.FORGOTTEN_NODE_REVOCATION_REASON = void 0;
|
|
619499
|
+
exports.AgentRegistryService = exports.ADDON_CONVERGENCE_DRY_RUN_KEY = exports.ADDON_CONVERGENCE_INTERVAL_MS = exports.AGENT_BACKFILL_RPC_TIMEOUT_MS = exports.FORGOTTEN_NODE_REVOCATION_REASON = void 0;
|
|
619315
619500
|
exports.toNodeLiveness = toNodeLiveness;
|
|
619316
619501
|
exports.toDescriptor = toDescriptor;
|
|
619317
619502
|
var node_crypto_1 = __require("crypto");
|
|
@@ -619319,6 +619504,7 @@ var require_agent_registry_service = __commonJS({
|
|
|
619319
619504
|
var system_1 = require_dist3();
|
|
619320
619505
|
var types_1 = require_dist4();
|
|
619321
619506
|
var agent_addon_backfill_1 = require_agent_addon_backfill();
|
|
619507
|
+
var agent_desired_set_1 = require_agent_desired_set();
|
|
619322
619508
|
var agent_delivery_ledger_1 = require_agent_delivery_ledger();
|
|
619323
619509
|
var agent_liveness_event_1 = require_agent_liveness_event();
|
|
619324
619510
|
var cluster_node_history_mirror_1 = require_cluster_node_history_mirror();
|
|
@@ -619358,6 +619544,10 @@ var require_agent_registry_service = __commonJS({
|
|
|
619358
619544
|
"@camstack/system",
|
|
619359
619545
|
"@camstack/addon-agent-ui"
|
|
619360
619546
|
]);
|
|
619547
|
+
var CONVERGENCE_BOOTSTRAP = /* @__PURE__ */ new Set(["@camstack/system"]);
|
|
619548
|
+
exports.ADDON_CONVERGENCE_INTERVAL_MS = 10 * 6e4;
|
|
619549
|
+
exports.ADDON_CONVERGENCE_DRY_RUN_KEY = "addons.convergence.dryRun";
|
|
619550
|
+
var TRACKED_VERSION_TTL_MS = 5 * 6e4;
|
|
619361
619551
|
function rosterFromAddons(addons) {
|
|
619362
619552
|
const byName = /* @__PURE__ */ new Map();
|
|
619363
619553
|
for (const addon of addons) {
|
|
@@ -619470,6 +619660,14 @@ var require_agent_registry_service = __commonJS({
|
|
|
619470
619660
|
* diff and each deliver it.
|
|
619471
619661
|
*/
|
|
619472
619662
|
reconcilingNodes = /* @__PURE__ */ new Set();
|
|
619663
|
+
/** Resolves the version of an agent-tracked package (agent-ui); `null` = not wired. */
|
|
619664
|
+
trackedVersionResolver = null;
|
|
619665
|
+
trackedVersionCache = /* @__PURE__ */ new Map();
|
|
619666
|
+
/** Reads the dry-run switch per round, so flipping the setting needs no restart. */
|
|
619667
|
+
convergenceDryRun = () => true;
|
|
619668
|
+
convergenceTimer = null;
|
|
619669
|
+
convergenceRunning = false;
|
|
619670
|
+
convergenceRerun = null;
|
|
619473
619671
|
constructor(eventBus, moleculer, capabilityService) {
|
|
619474
619672
|
this.eventBus = eventBus;
|
|
619475
619673
|
this.moleculer = moleculer;
|
|
@@ -619533,6 +619731,15 @@ var require_agent_registry_service = __commonJS({
|
|
|
619533
619731
|
setAddonBackfill(seam) {
|
|
619534
619732
|
this.addonBackfill = seam;
|
|
619535
619733
|
}
|
|
619734
|
+
/** Wire how the hub resolves the version of an agent-only tracked package. */
|
|
619735
|
+
setTrackedVersionResolver(resolver) {
|
|
619736
|
+
this.trackedVersionResolver = resolver;
|
|
619737
|
+
this.trackedVersionCache.clear();
|
|
619738
|
+
}
|
|
619739
|
+
/** Wire the dry-run switch; unwired it is ON (D982: the first live run only logs). */
|
|
619740
|
+
setConvergenceDryRun(read) {
|
|
619741
|
+
this.convergenceDryRun = read;
|
|
619742
|
+
}
|
|
619536
619743
|
/**
|
|
619537
619744
|
* Delivery failures the breaker is tracking for a node — surfaced so a node
|
|
619538
619745
|
* that is missing capabilities never merely *looks* healthy.
|
|
@@ -619553,9 +619760,18 @@ var require_agent_registry_service = __commonJS({
|
|
|
619553
619760
|
const packageName = this.resolvePackageForAddon(addonId);
|
|
619554
619761
|
if (packageName === null)
|
|
619555
619762
|
return;
|
|
619556
|
-
if (
|
|
619763
|
+
if (CONVERGENCE_BOOTSTRAP.has(packageName))
|
|
619557
619764
|
return;
|
|
619558
619765
|
await this.historyStore?.prunePackages(nodeId, [packageName]);
|
|
619766
|
+
await this.historyStore?.addTombstones(nodeId, [packageName]);
|
|
619767
|
+
}
|
|
619768
|
+
/**
|
|
619769
|
+
* The operator delivered a package to ONE node on purpose (`updatePackage` with
|
|
619770
|
+
* a `nodeId`, `camstack deploy -n`): that lifts its tombstone, so the desired
|
|
619771
|
+
* set wants it there again.
|
|
619772
|
+
*/
|
|
619773
|
+
async noteExplicitDelivery(nodeId, packageName) {
|
|
619774
|
+
await this.historyStore?.clearTombstones(nodeId, [packageName]);
|
|
619559
619775
|
}
|
|
619560
619776
|
/**
|
|
619561
619777
|
* The operator removed a whole PACKAGE from a node (`addons.uninstallPackage`
|
|
@@ -619566,9 +619782,10 @@ var require_agent_registry_service = __commonJS({
|
|
|
619566
619782
|
* stale-addon reconcile does.
|
|
619567
619783
|
*/
|
|
619568
619784
|
async notePackageUndeployed(nodeId, packageName, addonIds) {
|
|
619569
|
-
if (
|
|
619785
|
+
if (CONVERGENCE_BOOTSTRAP.has(packageName))
|
|
619570
619786
|
return;
|
|
619571
619787
|
await this.historyStore?.prunePackages(nodeId, [packageName]);
|
|
619788
|
+
await this.historyStore?.addTombstones(nodeId, [packageName]);
|
|
619572
619789
|
for (const addonId of addonIds) {
|
|
619573
619790
|
this.eventBus.emit({
|
|
619574
619791
|
id: (0, node_crypto_1.randomUUID)(),
|
|
@@ -619826,6 +620043,89 @@ var require_agent_registry_service = __commonJS({
|
|
|
619826
620043
|
}
|
|
619827
620044
|
} catch {
|
|
619828
620045
|
}
|
|
620046
|
+
this.startConvergenceTimer();
|
|
620047
|
+
}
|
|
620048
|
+
/**
|
|
620049
|
+
* The fixed schedule of D982: every online agent is converged to its desired
|
|
620050
|
+
* set every {@link ADDON_CONVERGENCE_INTERVAL_MS}. A round never gates
|
|
620051
|
+
* registration (D3) and a failed delivery waits for the next round — the
|
|
620052
|
+
* per-`(node, package)` breaker bounds the retries, there is no tight loop.
|
|
620053
|
+
*/
|
|
620054
|
+
startConvergenceTimer() {
|
|
620055
|
+
if (this.convergenceTimer !== null)
|
|
620056
|
+
return;
|
|
620057
|
+
const timer = setInterval(() => {
|
|
620058
|
+
void this.requestConvergence("periodic");
|
|
620059
|
+
}, exports.ADDON_CONVERGENCE_INTERVAL_MS);
|
|
620060
|
+
timer.unref();
|
|
620061
|
+
this.convergenceTimer = timer;
|
|
620062
|
+
}
|
|
620063
|
+
/** Stop the convergence schedule (shutdown, specs). */
|
|
620064
|
+
stopConvergenceTimer() {
|
|
620065
|
+
if (this.convergenceTimer === null)
|
|
620066
|
+
return;
|
|
620067
|
+
clearInterval(this.convergenceTimer);
|
|
620068
|
+
this.convergenceTimer = null;
|
|
620069
|
+
}
|
|
620070
|
+
/**
|
|
620071
|
+
* Converge every online agent to its desired set. Requests that arrive while a
|
|
620072
|
+
* round runs collapse into ONE more round after it — a burst of hub installs
|
|
620073
|
+
* cannot stack passes, and a round never re-triggers itself.
|
|
620074
|
+
*/
|
|
620075
|
+
async requestConvergence(trigger) {
|
|
620076
|
+
if (this.convergenceRunning) {
|
|
620077
|
+
this.convergenceRerun = trigger;
|
|
620078
|
+
return;
|
|
620079
|
+
}
|
|
620080
|
+
this.convergenceRunning = true;
|
|
620081
|
+
try {
|
|
620082
|
+
let next = trigger;
|
|
620083
|
+
while (next !== null) {
|
|
620084
|
+
this.convergenceRerun = null;
|
|
620085
|
+
for (const agentId of this.onlineAgentIds()) {
|
|
620086
|
+
await this.reconcileAgentAddons(agentId, next);
|
|
620087
|
+
}
|
|
620088
|
+
next = this.convergenceRerun;
|
|
620089
|
+
}
|
|
620090
|
+
} finally {
|
|
620091
|
+
this.convergenceRunning = false;
|
|
620092
|
+
}
|
|
620093
|
+
}
|
|
620094
|
+
/** Bare agent ids currently online (workers and the hub excluded). */
|
|
620095
|
+
onlineAgentIds() {
|
|
620096
|
+
const registry = this.nodeCatalogRegistry();
|
|
620097
|
+
const nodes = registry?.getNodeList?.({ onlyAvailable: true }) ?? [];
|
|
620098
|
+
return nodes.map((n) => n.id).filter((id) => typeof id === "string" && id !== "hub" && !id.includes("/"));
|
|
620099
|
+
}
|
|
620100
|
+
/** The version the hub follows for an agent-only tracked package, or `null`. */
|
|
620101
|
+
async resolveTrackedVersions() {
|
|
620102
|
+
const resolver = this.trackedVersionResolver;
|
|
620103
|
+
const out = /* @__PURE__ */ new Map();
|
|
620104
|
+
if (resolver === null)
|
|
620105
|
+
return out;
|
|
620106
|
+
const now = Date.now();
|
|
620107
|
+
for (const name of agent_desired_set_1.AGENT_TRACKED_PACKAGES) {
|
|
620108
|
+
const cached = this.trackedVersionCache.get(name);
|
|
620109
|
+
if (cached !== void 0 && now - cached.at < TRACKED_VERSION_TTL_MS) {
|
|
620110
|
+
out.set(name, cached.version);
|
|
620111
|
+
continue;
|
|
620112
|
+
}
|
|
620113
|
+
try {
|
|
620114
|
+
const version = await resolver(name);
|
|
620115
|
+
if (version === null)
|
|
620116
|
+
continue;
|
|
620117
|
+
this.trackedVersionCache.set(name, { version, at: now });
|
|
620118
|
+
out.set(name, version);
|
|
620119
|
+
} catch (err) {
|
|
620120
|
+
this.logger?.warn("convergence: could not resolve a tracked package version", {
|
|
620121
|
+
meta: {
|
|
620122
|
+
package: name,
|
|
620123
|
+
error: err instanceof Error ? err.message : String(err)
|
|
620124
|
+
}
|
|
620125
|
+
});
|
|
620126
|
+
}
|
|
620127
|
+
}
|
|
620128
|
+
return out;
|
|
619829
620129
|
}
|
|
619830
620130
|
/** The durable history's display name for a node, when it knows a real one. */
|
|
619831
620131
|
knownNodeName(nodeId) {
|
|
@@ -619842,9 +620142,7 @@ var require_agent_registry_service = __commonJS({
|
|
|
619842
620142
|
* must not abort the pass or hub boot.
|
|
619843
620143
|
*/
|
|
619844
620144
|
async reconcileConnectedAgents() {
|
|
619845
|
-
const
|
|
619846
|
-
const nodes = registry?.getNodeList?.({ onlyAvailable: true }) ?? [];
|
|
619847
|
-
const agentIds = nodes.map((n) => n.id).filter((id) => typeof id === "string" && id !== "hub" && !id.includes("/"));
|
|
620145
|
+
const agentIds = this.onlineAgentIds();
|
|
619848
620146
|
if (agentIds.length === 0)
|
|
619849
620147
|
return;
|
|
619850
620148
|
console.log(`[agent-registry] Boot reconcile: ${agentIds.length} connected agent(s)`);
|
|
@@ -619945,7 +620243,10 @@ var require_agent_registry_service = __commonJS({
|
|
|
619945
620243
|
}
|
|
619946
620244
|
}
|
|
619947
620245
|
}
|
|
620246
|
+
const sweepsStale = trigger !== "periodic" && trigger !== "hub-change";
|
|
619948
620247
|
const stale = agentAddons.filter((addon) => {
|
|
620248
|
+
if (!sweepsStale)
|
|
620249
|
+
return false;
|
|
619949
620250
|
if (addon.packageName !== void 0 && AGENT_BOOTSTRAP_PACKAGES.has(addon.packageName)) {
|
|
619950
620251
|
return false;
|
|
619951
620252
|
}
|
|
@@ -619957,10 +620258,11 @@ var require_agent_registry_service = __commonJS({
|
|
|
619957
620258
|
}
|
|
619958
620259
|
return placement === "hub-only";
|
|
619959
620260
|
});
|
|
619960
|
-
if (stale.length === 0) {
|
|
620261
|
+
if (stale.length === 0 && sweepsStale) {
|
|
619961
620262
|
console.log(`[agent-registry] Reconcile ${agentId}: no stale addons (${agentAddons.length} checked)`);
|
|
619962
620263
|
}
|
|
619963
620264
|
const undeployedPackages = /* @__PURE__ */ new Set();
|
|
620265
|
+
const undeployedIds = /* @__PURE__ */ new Set();
|
|
619964
620266
|
const survivingIds = new Set(agentAddons.filter((a) => !stale.includes(a)).map((a) => a.id));
|
|
619965
620267
|
for (const addon of stale) {
|
|
619966
620268
|
const reason = hubPlacements.has(addon.id) ? "placement is hub-only" : "not installed on hub";
|
|
@@ -619969,6 +620271,7 @@ var require_agent_registry_service = __commonJS({
|
|
|
619969
620271
|
nodeID: agentId,
|
|
619970
620272
|
timeout: AGENT_RECONCILE_RPC_TIMEOUT_MS
|
|
619971
620273
|
});
|
|
620274
|
+
undeployedIds.add(addon.id);
|
|
619972
620275
|
console.log(`[agent-registry] Reconcile ${agentId}: undeployed stale addon "${addon.id}" (${reason})`);
|
|
619973
620276
|
const packageName = addon.packageName;
|
|
619974
620277
|
if (packageName !== void 0 && packageName.length > 0) {
|
|
@@ -619987,7 +620290,14 @@ var require_agent_registry_service = __commonJS({
|
|
|
619987
620290
|
console.error(`[agent-registry] Reconcile ${agentId}: failed to undeploy "${addon.id}":`, err instanceof Error ? err.message : String(err));
|
|
619988
620291
|
}
|
|
619989
620292
|
}
|
|
619990
|
-
|
|
620293
|
+
const hubPackageFacts = /* @__PURE__ */ new Map();
|
|
620294
|
+
for (const [name, placements] of hubPackagePlacements) {
|
|
620295
|
+
hubPackageFacts.set(name, {
|
|
620296
|
+
version: hubVersions.get(name) ?? null,
|
|
620297
|
+
placements
|
|
620298
|
+
});
|
|
620299
|
+
}
|
|
620300
|
+
await this.convergeAgentAddons(agentId, agentAddons.filter((a) => !undeployedIds.has(a.id)), undeployedPackages, hubPackageFacts, trigger);
|
|
619991
620301
|
} catch (err) {
|
|
619992
620302
|
console.error(`[agent-registry] Reconcile failed for agent ${agentId}:`, err instanceof Error ? err.message : String(err));
|
|
619993
620303
|
} finally {
|
|
@@ -619995,22 +620305,25 @@ var require_agent_registry_service = __commonJS({
|
|
|
619995
620305
|
}
|
|
619996
620306
|
}
|
|
619997
620307
|
/**
|
|
619998
|
-
* Converge a node
|
|
620308
|
+
* Converge a node to ITS DESIRED SET ([D982](../../../../docs/decisions/adr-0982-the-hub-owns-every-nodes-addon-set.md)).
|
|
620309
|
+
*
|
|
620310
|
+
* The desired set comes from the hub (placements, versions, the agent-only
|
|
620311
|
+
* packages it tracks, the node's tombstones); the roster the node reports is
|
|
620312
|
+
* the observation it is diffed against and is recorded only as history.
|
|
619999
620313
|
*
|
|
620000
620314
|
* Order matters and is deliberate:
|
|
620001
|
-
* 1. record what the node declares NOW
|
|
620002
|
-
*
|
|
620003
|
-
*
|
|
620004
|
-
*
|
|
620315
|
+
* 1. record what the node declares NOW — history, never intent;
|
|
620316
|
+
* 2. prune what the stale sweep undeployed from that record;
|
|
620317
|
+
* 3. compute the plan, then apply it behind the gates (trigger allowlist,
|
|
620318
|
+
* delivery window, confirmation read, dry-run switch).
|
|
620005
620319
|
*
|
|
620006
620320
|
* Every leg is idempotent: run twice with no change in between and step 3
|
|
620007
620321
|
* finds nothing to do.
|
|
620008
620322
|
*/
|
|
620009
|
-
async
|
|
620323
|
+
async convergeAgentAddons(agentId, agentAddons, undeployedPackages, hubPackages, trigger) {
|
|
620010
620324
|
const store = this.historyStore;
|
|
620011
620325
|
if (!store)
|
|
620012
620326
|
return;
|
|
620013
|
-
const priorRoster = await store.getPackages(agentId);
|
|
620014
620327
|
const live = rosterFromAddons(agentAddons);
|
|
620015
620328
|
await store.recordPackages(agentId, live);
|
|
620016
620329
|
if (undeployedPackages.size > 0) {
|
|
@@ -620019,63 +620332,153 @@ var require_agent_registry_service = __commonJS({
|
|
|
620019
620332
|
const seam = this.addonBackfill;
|
|
620020
620333
|
if (!seam)
|
|
620021
620334
|
return;
|
|
620022
|
-
const
|
|
620023
|
-
const
|
|
620024
|
-
|
|
620025
|
-
|
|
620026
|
-
|
|
620027
|
-
|
|
620335
|
+
const tombstones = await store.getTombstones(agentId);
|
|
620336
|
+
const desired = (0, agent_desired_set_1.computeDesiredSet)({
|
|
620337
|
+
hubPackages,
|
|
620338
|
+
trackedForAgents: await this.resolveTrackedVersions(),
|
|
620339
|
+
tombstones,
|
|
620340
|
+
bootstrap: CONVERGENCE_BOOTSTRAP
|
|
620341
|
+
});
|
|
620342
|
+
const planned = (0, agent_desired_set_1.diffNodeAgainstDesired)({
|
|
620343
|
+
desired,
|
|
620344
|
+
observed: live.filter((p) => !undeployedPackages.has(p.name)),
|
|
620028
620345
|
retired: this.backfillTracker.retiredFor(agentId),
|
|
620029
|
-
|
|
620030
|
-
freshNode: priorRoster.length === 0 ? { hubPackagePlacements } : void 0
|
|
620346
|
+
bootstrap: CONVERGENCE_BOOTSTRAP
|
|
620031
620347
|
});
|
|
620032
|
-
|
|
620033
|
-
|
|
620034
|
-
tags: { nodeId: agentId },
|
|
620035
|
-
meta: {
|
|
620036
|
-
planned: planned.targets.map((t) => `${t.name}@${t.version}`)
|
|
620037
|
-
}
|
|
620038
|
-
});
|
|
620039
|
-
for (const skip of planned.skipped) {
|
|
620040
|
-
this.logger?.info("back-fill: fresh node not given a hub package", {
|
|
620041
|
-
tags: { nodeId: agentId },
|
|
620042
|
-
meta: { package: skip.name, reason: skip.reason }
|
|
620043
|
-
});
|
|
620044
|
-
}
|
|
620045
|
-
}
|
|
620046
|
-
if (planned.notOnHub.length > 0) {
|
|
620047
|
-
console.log(`[agent-registry] Back-fill ${agentId}: NOT delivering ${planned.notOnHub.join(", ")} \u2014 in the node's declared roster but not installed on the hub`);
|
|
620048
|
-
}
|
|
620049
|
-
if (planned.targets.length === 0 && planned.retired.length === 0) {
|
|
620348
|
+
const changes = planned.install.length + planned.update.length + planned.remove.length;
|
|
620349
|
+
if (changes === 0 && planned.retired.length === 0)
|
|
620050
620350
|
return;
|
|
620051
|
-
|
|
620351
|
+
const dryRun = this.readConvergenceDryRun(agentId);
|
|
620352
|
+
this.logger?.info(dryRun ? "convergence plan (DRY RUN, removals held back)" : "convergence plan", {
|
|
620353
|
+
tags: { nodeId: agentId },
|
|
620354
|
+
meta: {
|
|
620355
|
+
trigger,
|
|
620356
|
+
install: planned.install.map((t) => `${t.name}@${t.version}`),
|
|
620357
|
+
update: planned.update.map((t) => `${t.name} ${t.from ?? "absent"} -> ${t.version}`),
|
|
620358
|
+
remove: planned.remove.map((r) => `${r.name} (${r.reason})`),
|
|
620359
|
+
retired: planned.retired,
|
|
620360
|
+
observed: live.length
|
|
620361
|
+
}
|
|
620362
|
+
});
|
|
620052
620363
|
if (!(0, agent_addon_backfill_1.triggerMayDeliver)(trigger)) {
|
|
620053
|
-
console.log(`[agent-registry]
|
|
620364
|
+
console.log(`[agent-registry] Convergence ${agentId}: SKIPPED \u2014 trigger "${trigger}" may not deliver (${changes} change(s) planned)`);
|
|
620054
620365
|
return;
|
|
620055
620366
|
}
|
|
620056
620367
|
const suppression = this.deliveryLedger.suppressionFor(agentId);
|
|
620057
620368
|
if (suppression !== null) {
|
|
620058
|
-
console.log(`[agent-registry]
|
|
620369
|
+
console.log(`[agent-registry] Convergence ${agentId}: SKIPPED \u2014 a hub delivery to this node is in flight or just finished (inFlight=${suppression.inFlight}, msSinceLastDelivery=${suppression.msSinceLastDelivery ?? "n/a"}, packages=${suppression.packages.join(", ") || "none"}); the roster gap is OURS, not the node's`);
|
|
620059
620370
|
return;
|
|
620060
620371
|
}
|
|
620061
|
-
|
|
620062
|
-
|
|
620372
|
+
if (!dryRun)
|
|
620373
|
+
await this.applyRemovals(agentId, agentAddons, planned);
|
|
620374
|
+
await this.applyDeliveries(agentId, live, planned, trigger, seam);
|
|
620375
|
+
}
|
|
620376
|
+
/**
|
|
620377
|
+
* The dry-run switch, read fail-safe: a read that cannot be answered counts
|
|
620378
|
+
* as ON (nothing is removed) and never fails the reconcile.
|
|
620379
|
+
*/
|
|
620380
|
+
readConvergenceDryRun(agentId) {
|
|
620381
|
+
try {
|
|
620382
|
+
return this.convergenceDryRun();
|
|
620383
|
+
} catch (err) {
|
|
620384
|
+
this.logger?.warn("convergence: dry-run switch unreadable, treated as ON", {
|
|
620385
|
+
tags: { nodeId: agentId },
|
|
620386
|
+
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
620387
|
+
});
|
|
620388
|
+
return true;
|
|
620389
|
+
}
|
|
620390
|
+
}
|
|
620391
|
+
/**
|
|
620392
|
+
* Remove tombstoned and hub-only leftovers. A removal DESTROYS work, so it
|
|
620393
|
+
* needs a second roster read to agree (D49) and fails closed when that read
|
|
620394
|
+
* cannot be taken. Every removal logs its reason.
|
|
620395
|
+
*/
|
|
620396
|
+
async applyRemovals(agentId, agentAddons, plan) {
|
|
620397
|
+
if (plan.remove.length === 0)
|
|
620063
620398
|
return;
|
|
620064
|
-
|
|
620399
|
+
let secondAddons = null;
|
|
620400
|
+
try {
|
|
620401
|
+
secondAddons = this.extractAgentAddons(await this.broker.call("$agent.status", {}, { nodeID: agentId, timeout: AGENT_RECONCILE_RPC_TIMEOUT_MS }));
|
|
620402
|
+
} catch (err) {
|
|
620403
|
+
this.logger?.warn("convergence: removals skipped, the confirmation read failed", {
|
|
620404
|
+
tags: { nodeId: agentId },
|
|
620405
|
+
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
620406
|
+
});
|
|
620065
620407
|
return;
|
|
620066
620408
|
}
|
|
620067
|
-
|
|
620409
|
+
if (secondAddons === null) {
|
|
620410
|
+
this.logger?.warn("convergence: removals skipped, the confirmation read had no addon list", {
|
|
620411
|
+
tags: { nodeId: agentId }
|
|
620412
|
+
});
|
|
620413
|
+
return;
|
|
620414
|
+
}
|
|
620415
|
+
const stillThere = new Set(secondAddons.flatMap((a) => a.packageName === void 0 ? [] : [a.packageName]));
|
|
620416
|
+
for (const removal of plan.remove) {
|
|
620417
|
+
if (!stillThere.has(removal.name))
|
|
620418
|
+
continue;
|
|
620419
|
+
const addonIds = agentAddons.filter((a) => a.packageName === removal.name).map((a) => a.id);
|
|
620420
|
+
try {
|
|
620421
|
+
await this.broker.call("$agent.undeploy", {
|
|
620422
|
+
packageName: removal.name,
|
|
620423
|
+
...addonIds[0] === void 0 ? {} : { addonId: addonIds[0] }
|
|
620424
|
+
}, { nodeID: agentId, timeout: AGENT_RECONCILE_RPC_TIMEOUT_MS });
|
|
620425
|
+
this.logger?.info("convergence: removed a package from the node", {
|
|
620426
|
+
tags: { nodeId: agentId },
|
|
620427
|
+
meta: { package: removal.name, reason: removal.reason, addonIds }
|
|
620428
|
+
});
|
|
620429
|
+
this.eventBus.emit({
|
|
620430
|
+
id: (0, node_crypto_1.randomUUID)(),
|
|
620431
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
620432
|
+
source: { type: "core", id: "agent-registry" },
|
|
620433
|
+
category: types_1.EventCategory.AddonUninstalled,
|
|
620434
|
+
data: {
|
|
620435
|
+
agentId,
|
|
620436
|
+
packageName: removal.name,
|
|
620437
|
+
reason: `convergence: ${removal.reason}`
|
|
620438
|
+
}
|
|
620439
|
+
});
|
|
620440
|
+
} catch (err) {
|
|
620441
|
+
this.logger?.warn("convergence: removing a package failed, the next round retries", {
|
|
620442
|
+
tags: { nodeId: agentId },
|
|
620443
|
+
meta: {
|
|
620444
|
+
package: removal.name,
|
|
620445
|
+
reason: removal.reason,
|
|
620446
|
+
error: err instanceof Error ? err.message : String(err)
|
|
620447
|
+
}
|
|
620448
|
+
});
|
|
620449
|
+
}
|
|
620450
|
+
}
|
|
620451
|
+
}
|
|
620452
|
+
/** Install and update, behind the D49 confirmation read. */
|
|
620453
|
+
async applyDeliveries(agentId, live, plan, trigger, seam) {
|
|
620454
|
+
const planned = {
|
|
620455
|
+
targets: [...plan.install, ...plan.update].map((t) => ({
|
|
620456
|
+
name: t.name,
|
|
620457
|
+
version: t.version,
|
|
620458
|
+
versionSource: t.origin === "agent-tracked" ? "agent-tracked" : "hub-installed"
|
|
620459
|
+
})),
|
|
620460
|
+
retired: plan.retired,
|
|
620461
|
+
liveCount: live.length
|
|
620462
|
+
};
|
|
620463
|
+
if (planned.targets.length === 0 && planned.retired.length === 0)
|
|
620464
|
+
return;
|
|
620465
|
+
const confirmed = await this.confirmBackfillTargets(agentId, planned);
|
|
620466
|
+
if (confirmed === null)
|
|
620467
|
+
return;
|
|
620468
|
+
if (confirmed.targets.length === 0 && confirmed.retired.length === 0)
|
|
620469
|
+
return;
|
|
620470
|
+
const closeWindow = this.deliveryLedger.begin(agentId, confirmed.targets.map((t) => t.name).join(", ") || "convergence");
|
|
620068
620471
|
let outcome;
|
|
620069
620472
|
try {
|
|
620070
|
-
outcome = await (0, agent_addon_backfill_1.executeBackfill)(seam, agentId,
|
|
620473
|
+
outcome = await (0, agent_addon_backfill_1.executeBackfill)(seam, agentId, confirmed, this.backfillTracker);
|
|
620071
620474
|
} finally {
|
|
620072
620475
|
closeWindow();
|
|
620073
620476
|
}
|
|
620074
620477
|
if (outcome.delivered.length > 0) {
|
|
620075
|
-
console.log(`[agent-registry]
|
|
620478
|
+
console.log(`[agent-registry] Convergence ${agentId}: delivered ${outcome.delivered.map((d) => {
|
|
620076
620479
|
const from = live.find((p) => p.name === d.name)?.version ?? "absent";
|
|
620077
|
-
return `${d.name} ${from} \u2192 ${d.version} (
|
|
620078
|
-
}).join(", ")} \u2014 trigger=${trigger}, node reported ${
|
|
620480
|
+
return `${d.name} ${from} \u2192 ${d.version} (${d.versionSource})`;
|
|
620481
|
+
}).join(", ")} \u2014 trigger=${trigger}, node reported ${confirmed.liveCount} package(s)`);
|
|
620079
620482
|
this.eventBus.emit({
|
|
620080
620483
|
id: (0, node_crypto_1.randomUUID)(),
|
|
620081
620484
|
timestamp: /* @__PURE__ */ new Date(),
|
|
@@ -620084,15 +620487,15 @@ var require_agent_registry_service = __commonJS({
|
|
|
620084
620487
|
data: {
|
|
620085
620488
|
agentId,
|
|
620086
620489
|
packages: outcome.delivered.map((d) => `${d.name}@${d.version}`),
|
|
620087
|
-
reason: "
|
|
620490
|
+
reason: "convergence: the hub desired set differs from what the node runs"
|
|
620088
620491
|
}
|
|
620089
620492
|
});
|
|
620090
620493
|
}
|
|
620091
620494
|
for (const failure of outcome.failed) {
|
|
620092
|
-
console.error(`[agent-registry]
|
|
620495
|
+
console.error(`[agent-registry] Convergence ${agentId}: FAILED to deliver ${failure.name}@${failure.version} \u2014 ${failure.error}` + (failure.retired ? ` (retired after ${agent_addon_backfill_1.MAX_BACKFILL_ATTEMPTS} attempts; this node is running WITHOUT that package)` : " (the next round retries)"));
|
|
620093
620496
|
}
|
|
620094
620497
|
for (const name of outcome.skipped) {
|
|
620095
|
-
console.error(`[agent-registry]
|
|
620498
|
+
console.error(`[agent-registry] Convergence ${agentId}: ${name} is still wrong and RETIRED \u2014 the node is degraded until an operator intervenes`);
|
|
620096
620499
|
}
|
|
620097
620500
|
}
|
|
620098
620501
|
/**
|
|
@@ -623281,7 +623684,8 @@ var require_cluster_node_history_store = __commonJS({
|
|
|
623281
623684
|
isHub: zod_1.z.boolean(),
|
|
623282
623685
|
localIps: zod_1.z.array(zod_1.z.string()).readonly(),
|
|
623283
623686
|
addonIds: zod_1.z.array(zod_1.z.string()).readonly(),
|
|
623284
|
-
packages: zod_1.z.array(zod_1.z.object({ name: zod_1.z.string(), version: zod_1.z.string().nullable() })).readonly().optional()
|
|
623687
|
+
packages: zod_1.z.array(zod_1.z.object({ name: zod_1.z.string(), version: zod_1.z.string().nullable() })).readonly().optional(),
|
|
623688
|
+
tombstones: zod_1.z.array(zod_1.z.string()).readonly().optional()
|
|
623285
623689
|
});
|
|
623286
623690
|
var RowDataSchema = zod_1.z.object({
|
|
623287
623691
|
lastActive: zod_1.z.number(),
|
|
@@ -623289,7 +623693,7 @@ var require_cluster_node_history_store = __commonJS({
|
|
|
623289
623693
|
});
|
|
623290
623694
|
var LAST_ACTIVE_HEARTBEAT_MS = 5 * 6e4;
|
|
623291
623695
|
function descriptorsEqual(a, b) {
|
|
623292
|
-
return a.id === b.id && a.name === b.name && a.hostname === b.hostname && a.platform === b.platform && a.arch === b.arch && a.cpuModel === b.cpuModel && a.cpuCores === b.cpuCores && a.memoryMB === b.memoryMB && a.isHub === b.isHub && sameStrings(a.engines, b.engines) && sameStrings(a.localIps, b.localIps) && sameStrings(a.addonIds, b.addonIds) && samePackages(a.packages, b.packages);
|
|
623696
|
+
return a.id === b.id && a.name === b.name && a.hostname === b.hostname && a.platform === b.platform && a.arch === b.arch && a.cpuModel === b.cpuModel && a.cpuCores === b.cpuCores && a.memoryMB === b.memoryMB && a.isHub === b.isHub && sameStrings(a.engines, b.engines) && sameStrings(a.localIps, b.localIps) && sameStrings(a.addonIds, b.addonIds) && samePackages(a.packages, b.packages) && sameStrings(a.tombstones ?? [], b.tombstones ?? []);
|
|
623293
623697
|
}
|
|
623294
623698
|
function sameStrings(a, b) {
|
|
623295
623699
|
return a.length === b.length && a.every((v, i) => v === b[i]);
|
|
@@ -623335,7 +623739,12 @@ var require_cluster_node_history_store = __commonJS({
|
|
|
623335
623739
|
try {
|
|
623336
623740
|
const existing = await this.readStored(kind, descriptor.id);
|
|
623337
623741
|
const packages = descriptor.packages ?? existing?.descriptor.packages;
|
|
623338
|
-
const
|
|
623742
|
+
const tombstones = descriptor.tombstones ?? existing?.descriptor.tombstones;
|
|
623743
|
+
const next = {
|
|
623744
|
+
...descriptor,
|
|
623745
|
+
...packages === void 0 ? {} : { packages },
|
|
623746
|
+
...tombstones === void 0 ? {} : { tombstones }
|
|
623747
|
+
};
|
|
623339
623748
|
if (existing !== null && !this.worthWriting(existing, next))
|
|
623340
623749
|
return;
|
|
623341
623750
|
await this.writeStored(kind, descriptor.id, Date.now(), next);
|
|
@@ -623477,6 +623886,61 @@ var require_cluster_node_history_store = __commonJS({
|
|
|
623477
623886
|
});
|
|
623478
623887
|
}
|
|
623479
623888
|
}
|
|
623889
|
+
/** The packages tombstoned for a node (D982). Empty when none or unreadable. */
|
|
623890
|
+
async getTombstones(nodeId) {
|
|
623891
|
+
const kind = this.resolveKind();
|
|
623892
|
+
if (kind === null)
|
|
623893
|
+
return /* @__PURE__ */ new Set();
|
|
623894
|
+
try {
|
|
623895
|
+
return new Set((await this.readStored(kind, nodeId))?.descriptor.tombstones ?? []);
|
|
623896
|
+
} catch (err) {
|
|
623897
|
+
this.logger.warn("getTombstones failed (best-effort)", {
|
|
623898
|
+
tags: { nodeId },
|
|
623899
|
+
meta: { error: (0, types_1.errMsg)(err) }
|
|
623900
|
+
});
|
|
623901
|
+
return /* @__PURE__ */ new Set();
|
|
623902
|
+
}
|
|
623903
|
+
}
|
|
623904
|
+
/** Keep packages off a node: an operator undeploy / hub uninstall for it. */
|
|
623905
|
+
async addTombstones(nodeId, names) {
|
|
623906
|
+
await this.editTombstones(nodeId, names, "add");
|
|
623907
|
+
}
|
|
623908
|
+
/** An explicit delivery to the node lifts the tombstone. */
|
|
623909
|
+
async clearTombstones(nodeId, names) {
|
|
623910
|
+
await this.editTombstones(nodeId, names, "clear");
|
|
623911
|
+
}
|
|
623912
|
+
async editTombstones(nodeId, names, mode) {
|
|
623913
|
+
if (names.length === 0)
|
|
623914
|
+
return;
|
|
623915
|
+
const kind = this.resolveKind();
|
|
623916
|
+
if (kind === null)
|
|
623917
|
+
return;
|
|
623918
|
+
try {
|
|
623919
|
+
const existing = await this.readStored(kind, nodeId);
|
|
623920
|
+
if (existing === null && mode === "clear")
|
|
623921
|
+
return;
|
|
623922
|
+
const current = new Set(existing?.descriptor.tombstones ?? []);
|
|
623923
|
+
const before = current.size;
|
|
623924
|
+
for (const name of names) {
|
|
623925
|
+
if (mode === "add")
|
|
623926
|
+
current.add(name);
|
|
623927
|
+
else
|
|
623928
|
+
current.delete(name);
|
|
623929
|
+
}
|
|
623930
|
+
if (current.size === before)
|
|
623931
|
+
return;
|
|
623932
|
+
const base = existing?.descriptor ?? _ClusterNodeHistoryStore.placeholderDescriptor(nodeId);
|
|
623933
|
+
await this.writeStored(kind, nodeId, existing?.lastActive ?? Date.now(), {
|
|
623934
|
+
...base,
|
|
623935
|
+
tombstones: [...current].sort()
|
|
623936
|
+
});
|
|
623937
|
+
} catch (err) {
|
|
623938
|
+
this.logger.warn("editTombstones failed (best-effort)", {
|
|
623939
|
+
tags: { nodeId },
|
|
623940
|
+
meta: { error: (0, types_1.errMsg)(err), mode }
|
|
623941
|
+
});
|
|
623942
|
+
}
|
|
623943
|
+
}
|
|
623480
623944
|
/**
|
|
623481
623945
|
* Touch `lastActive` for a node without rewriting its descriptor — used on
|
|
623482
623946
|
* `$node.disconnected` so an offline node's "last seen" is the disconnect
|
|
@@ -623527,11 +623991,16 @@ var require_cluster_node_history_store = __commonJS({
|
|
|
623527
623991
|
});
|
|
623528
623992
|
continue;
|
|
623529
623993
|
}
|
|
623530
|
-
result.push({
|
|
623994
|
+
result.push({
|
|
623995
|
+
...parsed.data.descriptor,
|
|
623996
|
+
lastActive: parsed.data.lastActive
|
|
623997
|
+
});
|
|
623531
623998
|
}
|
|
623532
623999
|
return result;
|
|
623533
624000
|
} catch (err) {
|
|
623534
|
-
this.logger.warn("history read failed (best-effort)", {
|
|
624001
|
+
this.logger.warn("history read failed (best-effort)", {
|
|
624002
|
+
meta: { error: (0, types_1.errMsg)(err) }
|
|
624003
|
+
});
|
|
623535
624004
|
return null;
|
|
623536
624005
|
}
|
|
623537
624006
|
}
|
|
@@ -623551,7 +624020,9 @@ var require_cluster_node_history_store = __commonJS({
|
|
|
623551
624020
|
const existed = await this.readStored(kind, nodeId) !== null;
|
|
623552
624021
|
await kind.delete(nodeId);
|
|
623553
624022
|
if (!existed) {
|
|
623554
|
-
this.logger.info("cluster node had no history row to forget", {
|
|
624023
|
+
this.logger.info("cluster node had no history row to forget", {
|
|
624024
|
+
tags: { nodeId }
|
|
624025
|
+
});
|
|
623555
624026
|
return "not-found";
|
|
623556
624027
|
}
|
|
623557
624028
|
this.logger.info("forgot cluster node", { tags: { nodeId } });
|
|
@@ -624379,6 +624850,8 @@ var require_manual_boot = __commonJS({
|
|
|
624379
624850
|
await moleculerService.broker.call("$agent.reload", {}, { nodeID: nodeId, timeout: agent_registry_service_1.AGENT_BACKFILL_RPC_TIMEOUT_MS });
|
|
624380
624851
|
}
|
|
624381
624852
|
});
|
|
624853
|
+
agentRegistryService.setTrackedVersionResolver((name) => addonPackageService.resolveRegistryVersion(name));
|
|
624854
|
+
agentRegistryService.setConvergenceDryRun(() => configService.get(agent_registry_service_1.ADDON_CONVERGENCE_DRY_RUN_KEY) !== false);
|
|
624382
624855
|
const lifecycleDataDir = path.resolve(process.env["CAMSTACK_DATA"] ?? "camstack-data");
|
|
624383
624856
|
(0, lifecycle_runner_singleton_1.initLifecycleRunner)({
|
|
624384
624857
|
dataDir: lifecycleDataDir,
|
|
@@ -624925,7 +625398,7 @@ var require_main4 = __commonJS({
|
|
|
624925
625398
|
const uploadAddonRegistry = app.get(addon_registry_service_1.AddonRegistryService);
|
|
624926
625399
|
const uploadAddonPackage = app.get(addon_package_service_1.AddonPackageService);
|
|
624927
625400
|
const uploadLogger = app.get(logging_service_1.LoggingService).createLogger("addon-upload");
|
|
624928
|
-
await (0, addon_upload_1.registerAddonUploadRoute)(fastify, uploadAddonBridge, uploadAuthService, uploadMoleculer, uploadAddonRegistry, uploadAddonPackage, uploadLogger, (0, hub_cluster_url_1.clusterBaseUrlResolver)(() => uploadAddonRegistry.getCapabilityRegistry().getSingleton("local-network")), app.get(agent_registry_service_1.AgentRegistryService).deliveryLedger);
|
|
625401
|
+
await (0, addon_upload_1.registerAddonUploadRoute)(fastify, uploadAddonBridge, uploadAuthService, uploadMoleculer, uploadAddonRegistry, uploadAddonPackage, uploadLogger, (0, hub_cluster_url_1.clusterBaseUrlResolver)(() => uploadAddonRegistry.getCapabilityRegistry().getSingleton("local-network")), app.get(agent_registry_service_1.AgentRegistryService).deliveryLedger, app.get(agent_registry_service_1.AgentRegistryService));
|
|
624929
625402
|
console.log("[bootstrap] Addon upload route registered at POST /api/addons/upload");
|
|
624930
625403
|
(0, server_upload_1.registerServerUploadRoute)(fastify, {
|
|
624931
625404
|
authService: uploadAuthService,
|