@camstack/server 1.2.687 → 1.2.689

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.
@@ -62,6 +62,8 @@ const addon_pages_service_1 = require("./core/addon-pages/addon-pages.service");
62
62
  const addon_widgets_service_1 = require("./core/addon-widgets/addon-widgets.service");
63
63
  const agent_registry_service_1 = require("./core/agent/agent-registry.service");
64
64
  const cluster_node_history_store_1 = require("./core/agent/cluster-node-history-store");
65
+ const forgotten_node_revoker_1 = require("./core/agent/forgotten-node-revoker");
66
+ const node_removal_hooks_1 = require("./core/agent/node-removal-hooks");
65
67
  const auth_service_1 = require("./core/auth/auth.service");
66
68
  const capability_service_1 = require("./core/capability/capability.service");
67
69
  const config_service_1 = require("./core/config/config.service");
@@ -163,6 +165,11 @@ async function bootManual(opts) {
163
165
  // Same post-construction reason: the cluster-node lifecycle (forget, catalog
164
166
  // removal) must leave a per-node line, and `console.log` is not a log store.
165
167
  agentRegistryService.setLogger(loggingService.createLogger('ClusterNodes'));
168
+ // Forgetting a node revokes its mesh certificates, so an old box that is powered on again
169
+ // is refused instead of walking back in (D857).
170
+ agentRegistryService.setNodeCertificateRevoker((0, forgotten_node_revoker_1.createForgottenNodeRevoker)({
171
+ logger: loggingService.createLogger('ClusterNodes'),
172
+ }));
166
173
  // A1: durable, routing-blind offline-node history — the `cluster-agent`
167
174
  // records kind, bound by the addon registry once the records provider is up
168
175
  // (unavailable until then, D902). Wired post-construction so the service's
@@ -170,6 +177,33 @@ async function bootManual(opts) {
170
177
  const clusterNodeHistoryStore = new cluster_node_history_store_1.ClusterNodeHistoryStore(loggingService.createLogger('cluster-node-history'));
171
178
  agentRegistryService.setClusterNodeHistoryStore(clusterNodeHistoryStore);
172
179
  addonRegistryService.setClusterNodeHistoryStore(clusterNodeHistoryStore);
180
+ // A forgotten node leaves no node-scoped data behind (#265): a tombstone is
181
+ // recorded, then every `node-removal-hook` implementer is told; the hub-owned
182
+ // per-node singleton overrides are cleared in the same step.
183
+ const nodeRemovalLogger = loggingService.createLogger('node-removal');
184
+ const nodeTombstoneStore = new node_removal_hooks_1.NodeTombstoneStore(nodeRemovalLogger);
185
+ addonRegistryService.setNodeTombstoneStore(nodeTombstoneStore);
186
+ const nodeRemovalDispatcher = new node_removal_hooks_1.NodeRemovalDispatcher({
187
+ hooks: (0, node_removal_hooks_1.registryNodeRemovalHooks)(addonRegistryService.getCapabilityRegistry()),
188
+ store: nodeTombstoneStore,
189
+ logger: nodeRemovalLogger,
190
+ });
191
+ agentRegistryService.setNodeRemovalCleanup(async (nodeId, removedAt) => {
192
+ const overrides = await (0, node_removal_hooks_1.clearSingletonNodeOverrides)(nodeId, addonRegistryService.getCapabilityRegistry(), configService);
193
+ if (overrides > 0) {
194
+ nodeRemovalLogger.info('cleared per-node singleton overrides of a forgotten node', {
195
+ tags: { nodeId },
196
+ meta: { overrides },
197
+ });
198
+ }
199
+ await nodeRemovalDispatcher.nodeForgotten(nodeId, removedAt);
200
+ });
201
+ // An implementer that was down at forget time is told once the addons are up.
202
+ eventBusService.subscribe({ category: types_1.EventCategory.SystemAddonsReady }, () => {
203
+ void nodeRemovalDispatcher.redrive().catch((err) => nodeRemovalLogger.warn('node removal re-drive failed', {
204
+ meta: { error: err instanceof Error ? err.message : String(err) },
205
+ }));
206
+ });
173
207
  // ---- Layer 4: need AddonRegistry ---------------------------------------
174
208
  // AddonWidgetsService — needs AddonRegistryService for the bundled-addon
175
209
  // dist sub-folder lookup (see service docstring).
@@ -210,7 +244,10 @@ async function bootManual(opts) {
210
244
  return (installed ?? (await addonPackageService.packPackage(name, version))).buffer;
211
245
  },
212
246
  deploy: async (nodeId, packageName, bundle) => {
213
- await moleculerService.broker.call('$agent.deploy', { addonId: packageName, source: (0, addon_upload_1.buildHubHttpSource)(bundle, await resolveClusterBaseUrl()) }, { nodeID: nodeId, timeout: agent_registry_service_1.AGENT_BACKFILL_RPC_TIMEOUT_MS });
247
+ await moleculerService.broker.call('$agent.deploy', {
248
+ addonId: packageName,
249
+ source: (0, addon_upload_1.buildHubHttpSource)(bundle, await resolveClusterBaseUrl()),
250
+ }, { nodeID: nodeId, timeout: agent_registry_service_1.AGENT_BACKFILL_RPC_TIMEOUT_MS });
214
251
  },
215
252
  reload: async (nodeId) => {
216
253
  await moleculerService.broker.call('$agent.reload', {}, { nodeID: nodeId, timeout: agent_registry_service_1.AGENT_BACKFILL_RPC_TIMEOUT_MS });
@@ -281,7 +318,10 @@ async function bootManual(opts) {
281
318
  expected: check.expected,
282
319
  running: check.running,
283
320
  failed: [...check.failed],
284
- refused: check.refused.map((r) => ({ runnerId: r.runnerId, reason: r.reason })),
321
+ refused: check.refused.map((r) => ({
322
+ runnerId: r.runnerId,
323
+ reason: r.reason,
324
+ })),
285
325
  missing: [...check.missing],
286
326
  },
287
327
  });
@@ -325,8 +365,7 @@ async function bootManual(opts) {
325
365
  // downloads this process makes anyway.
326
366
  const registryReachability = new registry_reachability_js_1.RegistryReachabilityTracker({
327
367
  logger: updateCheckLogger,
328
- getAlerts: () => addonRegistryService.getCapabilityRegistry().getSingleton('alerts') ??
329
- undefined,
368
+ getAlerts: () => addonRegistryService.getCapabilityRegistry().getSingleton('alerts') ?? undefined,
330
369
  });
331
370
  addonPackageService.setNpmReachabilityObserver({
332
371
  reached: () => registryReachability.reached('npm'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/server",
3
- "version": "1.2.687",
3
+ "version": "1.2.689",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -49,20 +49,20 @@
49
49
  ]
50
50
  },
51
51
  "dependencies": {
52
- "@camstack/addon-admin-ui": "1.2.515",
53
- "@camstack/addon-agent-ui": "1.2.290",
52
+ "@camstack/addon-admin-ui": "1.2.517",
53
+ "@camstack/addon-agent-ui": "1.2.292",
54
54
  "@camstack/addon-auth": "1.2.170",
55
- "@camstack/addon-benchmark": "1.2.289",
55
+ "@camstack/addon-benchmark": "1.2.291",
56
56
  "@camstack/addon-decoder-nodeav": "1.2.144",
57
57
  "@camstack/addon-notifiers": "1.2.623",
58
58
  "@camstack/addon-pipeline": "1.2.634",
59
- "@camstack/addon-pipeline-orchestrator": "1.2.638",
60
- "@camstack/addon-post-analysis": "1.2.650",
59
+ "@camstack/addon-pipeline-orchestrator": "1.2.639",
60
+ "@camstack/addon-post-analysis": "1.2.651",
61
61
  "@camstack/develop": "0.1.39",
62
62
  "@camstack/sdk": "1.2.154",
63
- "@camstack/system": "1.2.516",
64
- "@camstack/types": "1.2.442",
65
- "@camstack/ui-library": "1.2.348",
63
+ "@camstack/system": "1.2.518",
64
+ "@camstack/types": "1.2.444",
65
+ "@camstack/ui-library": "1.2.350",
66
66
  "@fastify/compress": "^9.0.0",
67
67
  "@fastify/cookie": "^11.0.2",
68
68
  "@fastify/cors": "^11.2.0",