@camstack/server 1.2.593 → 1.2.594
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/addon-root-inventory.js +11 -50
- package/dist/agent/addon-scan.js +6 -44
- package/dist/agent/agent-addon-runtime.js +3 -8
- package/dist/agent/agent-addon-updates.js +12 -52
- package/dist/agent/agent-cap-dispatch-service.js +3 -5
- package/dist/agent/agent-config.js +7 -42
- package/dist/agent/agent-deploy-swap.js +5 -41
- package/dist/agent/agent-group-runner.js +8 -47
- package/dist/agent/agent-http-auth.js +10 -22
- package/dist/agent/agent-http.js +69 -115
- package/dist/agent/agent-hub-addon-update.js +10 -16
- package/dist/agent/agent-hub-registration.js +4 -7
- package/dist/agent/agent-infra-capabilities.js +5 -9
- package/dist/agent/agent-json-file.js +5 -42
- package/dist/agent/agent-mesh-gate.js +5 -8
- package/dist/agent/agent-node-certificates.js +25 -28
- package/dist/agent/agent-pairing-local.js +10 -47
- package/dist/agent/agent-pairing-routes.js +16 -20
- package/dist/agent/agent-pairing-store.js +18 -58
- package/dist/agent/agent-reconnect.js +1 -4
- package/dist/agent/agent-service.js +42 -78
- package/dist/agent/agent-sniffing-listener.js +11 -48
- package/dist/agent/agent-undeploy.js +5 -41
- package/dist/agent/agent-update-routes.js +14 -19
- package/dist/agent/agent-update-service.js +38 -80
- package/dist/agent/apply-model-distribution.js +1 -4
- package/dist/agent/apply-stage-dev-uploads.js +6 -9
- package/dist/agent/derive-hub-url.js +3 -8
- package/dist/agent/fetch-bundle-from-hub.js +6 -9
- package/dist/agent/hubs-found.js +6 -43
- package/dist/agent/infra-boot-guard.js +1 -4
- package/dist/agent/infra-boot-plan.js +2 -6
- package/dist/agent/main.js +158 -186
- package/dist/agent/register-agent-cap-dispatch.js +3 -6
- package/dist/agent/serial-queue.js +2 -7
- package/dist/agent-status-page.js +1 -4
- package/dist/api/addon-upload.js +22 -61
- package/dist/api/agent-addon-delivery.js +6 -11
- package/dist/api/auth-whoami.js +1 -4
- package/dist/api/backup-download-pump.js +5 -9
- package/dist/api/backup-download.js +7 -10
- package/dist/api/core/addon-settings.router.js +16 -19
- package/dist/api/core/agent-pairing.router.js +76 -79
- package/dist/api/core/agents.router.js +21 -24
- package/dist/api/core/auth-admin-tokens.procedures.js +48 -52
- package/dist/api/core/auth-device-cert.procedures.js +62 -67
- package/dist/api/core/auth-limits.js +16 -25
- package/dist/api/core/auth-reauth.procedures.js +32 -37
- package/dist/api/core/auth-revoke-credentials.procedures.js +22 -26
- package/dist/api/core/auth-sessions.procedures.js +52 -56
- package/dist/api/core/auth.router.js +300 -304
- package/dist/api/core/cap-providers.js +74 -121
- package/dist/api/core/capabilities.router.js +34 -37
- package/dist/api/core/capability-preference-writes.js +10 -17
- package/dist/api/core/certificates.router.js +106 -109
- package/dist/api/core/cluster-nodes.router.js +15 -18
- package/dist/api/core/collection-preference.js +2 -6
- package/dist/api/core/event-bus-proxy.router.js +34 -37
- package/dist/api/core/failure-contributions.js +4 -8
- package/dist/api/core/hwaccel.router.js +17 -20
- package/dist/api/core/integration-secrets.js +8 -12
- package/dist/api/core/lifecycle-job-runner.js +13 -49
- package/dist/api/core/live-events.router.js +29 -32
- package/dist/api/core/load-contributions.js +4 -8
- package/dist/api/core/logging-settings.js +30 -43
- package/dist/api/core/logs.router.js +40 -43
- package/dist/api/core/notifications.router.js +15 -18
- package/dist/api/core/public-event-filter.js +4 -8
- package/dist/api/core/repl.router.js +18 -21
- package/dist/api/core/request-census-settings.js +11 -16
- package/dist/api/core/server-management.provider.js +1 -4
- package/dist/api/core/server-name.js +9 -17
- package/dist/api/core/site-location.js +16 -24
- package/dist/api/core/stream-probe.router.js +21 -24
- package/dist/api/core/system-events.router.js +23 -26
- package/dist/api/cors/cors-policy.js +20 -29
- package/dist/api/cors/register-cors-policy.js +9 -14
- package/dist/api/deploy-stage-registry.js +6 -10
- package/dist/api/dev-uploads-bundle.js +12 -50
- package/dist/api/health/adaptive-probe.routes.js +9 -13
- package/dist/api/health/health.routes.js +8 -13
- package/dist/api/hub-cluster-url.js +3 -9
- package/dist/api/model-distributor.js +12 -50
- package/dist/api/oauth2/consent-page.js +10 -13
- package/dist/api/oauth2/oauth2-routes.js +17 -25
- package/dist/api/oauth2/private-host.js +1 -4
- package/dist/api/server-upload-propagate.js +15 -51
- package/dist/api/server-upload.js +13 -50
- package/dist/api/sse-no-compression.js +1 -4
- package/dist/api/static/frame-policy.js +4 -9
- package/dist/api/static/precompressed-asset.js +15 -57
- package/dist/api/static/spa-mount.js +8 -47
- package/dist/api/static/spa-static.js +5 -12
- package/dist/api/tarball-manifest.js +7 -44
- package/dist/api/trpc/cap-mount-helpers.js +7 -12
- package/dist/api/trpc/cap-route-error-formatter.js +10 -13
- package/dist/api/trpc/cap-router-runtime.js +40 -51
- package/dist/api/trpc/client-ip.js +9 -20
- package/dist/api/trpc/core-cap-bridge.js +32 -42
- package/dist/api/trpc/device-collection-dispatch.js +23 -27
- package/dist/api/trpc/device-config-secret-redaction.js +24 -40
- package/dist/api/trpc/generated-cap-mounts.js +218 -222
- package/dist/api/trpc/generated-cap-routers.js +4688 -4850
- package/dist/api/trpc/http-request-census-hook.js +8 -11
- package/dist/api/trpc/http-request-census.js +34 -41
- package/dist/api/trpc/http-request-census.singleton.js +4 -8
- package/dist/api/trpc/localized-schema-paths.js +1 -4
- package/dist/api/trpc/principal-visibility.js +14 -22
- package/dist/api/trpc/remote-addon-update-grant.js +1 -4
- package/dist/api/trpc/scope-access.js +10 -15
- package/dist/api/trpc/server-provided-caps.js +3 -7
- package/dist/api/trpc/share-view-access.js +6 -14
- package/dist/api/trpc/trpc-error-device-tags.js +3 -6
- package/dist/api/trpc/trpc-error-principal.js +2 -6
- package/dist/api/trpc/trpc.context.js +20 -25
- package/dist/api/trpc/trpc.middleware.js +38 -46
- package/dist/api/trpc/trpc.router.js +58 -99
- package/dist/api/trpc/user-error.js +5 -8
- package/dist/api/trpc/ws-request-census.js +17 -24
- package/dist/api/trpc/ws-slow-consumer-guard.js +11 -16
- package/dist/api/upload-auth.js +5 -9
- package/dist/auth/addon-route-jwt-gate.js +4 -7
- package/dist/auth/addon-route-share-gate.js +7 -12
- package/dist/auth/app-confirm-page.js +17 -22
- package/dist/auth/app-confirm-routes.js +26 -31
- package/dist/auth/app-confirmations.js +7 -44
- package/dist/auth/app-page-shell.js +17 -30
- package/dist/auth/app-page-strings.js +11 -17
- package/dist/auth/app-passkey-page.js +16 -21
- package/dist/auth/app-passkey-routes.js +37 -41
- package/dist/auth/app-refused-route.js +13 -18
- package/dist/auth/auth-network-policy.js +11 -15
- package/dist/auth/auth-provider-gate.js +4 -9
- package/dist/auth/auth-rate-limit.js +3 -7
- package/dist/auth/client-address.js +6 -9
- package/dist/auth/device-enroll-proofs.js +6 -43
- package/dist/auth/external-link-intents.js +3 -7
- package/dist/auth/hub-sessions.js +6 -12
- package/dist/auth/native-link-completions.js +7 -11
- package/dist/auth/native-return.js +9 -13
- package/dist/auth/passkey-provider.js +26 -32
- package/dist/auth/second-factors.js +6 -10
- package/dist/auth/session-connections.js +6 -12
- package/dist/auth/session-cookie.js +12 -23
- package/dist/auth/session-lifetimes.js +8 -12
- package/dist/auth/session-mint.js +4 -11
- package/dist/auth/sso-finish-app.js +13 -16
- package/dist/auth/sso-finish-deps.js +21 -27
- package/dist/auth/sso-finish.js +28 -38
- package/dist/auth/sso-routes.js +22 -25
- package/dist/auth/used-bridge-ids.js +1 -5
- package/dist/boot/boot-config.js +16 -55
- package/dist/boot/init-sequence.js +1 -4
- package/dist/boot/integration-id-backfill.js +3 -8
- package/dist/boot/platform-keychain-key.js +5 -42
- package/dist/boot/post-boot.service.js +14 -18
- package/dist/boot/reconcile-lifecycle-jobs.js +3 -6
- package/dist/boot/retired-public-url-env.js +4 -8
- package/dist/bootstrap-packages.js +1 -4
- package/dist/closure-node-modules.js +2 -38
- package/dist/closure-patches/patch-reach.json +6 -2
- package/dist/core/addon/addon-call-gateway.js +1 -5
- package/dist/core/addon/addon-package.service.js +83 -123
- package/dist/core/addon/addon-process-view.js +2 -6
- package/dist/core/addon/addon-realign-plan.js +1 -4
- package/dist/core/addon/addon-registry.service.js +199 -185
- package/dist/core/addon/addon-row-manifest.js +1 -4
- package/dist/core/addon/addon-search.service.js +3 -7
- package/dist/core/addon/addon-settings-provider.js +1 -3
- package/dist/core/addon/addon-uninstall.js +4 -11
- package/dist/core/addon/addon.tokens.js +2 -5
- package/dist/core/addon/device-meta-mirror.js +8 -13
- package/dist/core/addon/forked-custom-actions.js +6 -11
- package/dist/core/addon/integration-visibility.js +3 -6
- package/dist/core/addon/materialize-route-path.js +1 -4
- package/dist/core/addon/package-dir-utils.js +8 -45
- package/dist/core/addon/prune-misplaced-addons.js +5 -43
- package/dist/core/addon/runner-convergence.js +1 -4
- package/dist/core/addon/runner-serialization.js +1 -4
- package/dist/core/addon/runner-spawn-fanout.js +3 -8
- package/dist/core/addon/settings-door-wiring.js +5 -8
- package/dist/core/addon/single-flight-refresh.js +1 -4
- package/dist/core/addon-bridge/addon-bridge.service.js +7 -44
- package/dist/core/addon-pages/addon-pages.service.js +3 -40
- package/dist/core/addon-widgets/addon-widgets.service.js +4 -42
- package/dist/core/agent/agent-addon-backfill.js +9 -17
- package/dist/core/agent/agent-delivery-ledger.js +3 -7
- package/dist/core/agent/agent-liveness-event.js +2 -6
- package/dist/core/agent/agent-pairing-http.js +41 -45
- package/dist/core/agent/agent-registry.service.js +53 -92
- package/dist/core/agent/cluster-node-history-mirror.js +3 -7
- package/dist/core/agent/cluster-node-history-store.js +113 -58
- package/dist/core/agent/hub-agent-pairing.js +1 -5
- package/dist/core/agent/node-certificates-client.js +3 -6
- package/dist/core/agent/node-directory.js +1 -4
- package/dist/core/app-links/well-known-app-links.js +2 -6
- package/dist/core/auth/auth.service.js +3 -8
- package/dist/core/auth/handoff-code.service.js +11 -49
- package/dist/core/auth/record-kinds.js +35 -0
- package/dist/core/auth/share-token.service.js +174 -122
- package/dist/core/capability/capability.service.js +1 -5
- package/dist/core/config/config.schema.js +1 -6
- package/dist/core/config/config.service.js +2 -6
- package/dist/core/events/event-bus.service.js +3 -7
- package/dist/core/feature/feature.service.js +2 -6
- package/dist/core/lifecycle/lifecycle-runner.singleton.js +5 -10
- package/dist/core/lifecycle/lifecycle-state-machine.js +1 -5
- package/dist/core/logging/log-ring-buffer.js +1 -5
- package/dist/core/logging/logging.service.js +5 -9
- package/dist/core/logging/scoped-logger.js +1 -5
- package/dist/core/moleculer/agent-readiness-pull.js +1 -4
- package/dist/core/moleculer/agent-registration-request.js +3 -7
- package/dist/core/moleculer/cap-call-fn.js +39 -5
- package/dist/core/moleculer/cap-route-authority.js +3 -8
- package/dist/core/moleculer/hub-mesh-guard.js +5 -9
- package/dist/core/moleculer/moleculer.service.js +108 -119
- package/dist/core/network/network-quality.service.js +2 -6
- package/dist/core/notification/notification-wrapper.service.js +3 -7
- package/dist/core/notification/toast-wrapper.service.js +3 -7
- package/dist/core/provider/provider.tokens.js +1 -4
- package/dist/core/repl/repl-engine.service.js +4 -8
- package/dist/core/runner-health/runner-boot-check.js +7 -15
- package/dist/core/runner-health/update-preflight.js +9 -14
- package/dist/core/server-update/server-update.service.js +12 -49
- package/dist/core/server-update/system-apply-closure-patches.js +6 -42
- package/dist/core/server-update/system-ensure-prebuilds.js +3 -6
- package/dist/core/server-update/system-exec-npm.js +2 -5
- package/dist/core/storage/fs-storage-backend.js +1 -5
- package/dist/core/storage/storage-location-manager.js +1 -5
- package/dist/core/storage/storage.service.js +2 -6
- package/dist/core/streaming/ffmpeg-stream-info.js +3 -8
- package/dist/core/streaming/stream-probe.service.js +12 -16
- package/dist/core/streaming/ttl-cache.js +1 -5
- package/dist/core/topology/topology-emitter.service.js +19 -23
- package/dist/core/update-availability-emitter.js +3 -7
- package/dist/core/update-availability-store.js +8 -45
- package/dist/core/updates/agent-installed-packages.js +5 -9
- package/dist/core/updates/restart-marker.js +3 -8
- package/dist/core/updates/update-check-scheduler.js +13 -18
- package/dist/core/updates/wrapper-update-checker.js +3 -7
- package/dist/first-boot-addon-plan.js +2 -6
- package/dist/framework-nodepath.js +2 -38
- package/dist/i18n/request-lang.js +7 -11
- package/dist/launcher.js +30 -65
- package/dist/lifecycle-journal-path.js +2 -38
- package/dist/main.js +287 -324
- package/dist/manual-boot.js +120 -157
- package/dist/node-role.js +1 -4
- package/dist/package-inventory.js +7 -48
- package/dist/pending-restore.js +7 -43
- package/dist/single-copy-cleanup-runner.js +9 -45
- package/dist/single-copy-cleanup.js +7 -15
- package/dist/sqlite-restore.js +9 -48
- package/dist/starter.js +4 -39
- package/dist/ui-serving/lazy-ui-serving.js +3 -39
- package/package.json +13 -13
package/dist/pending-restore.js
CHANGED
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.applyPendingRestore = applyPendingRestore;
|
|
37
1
|
/**
|
|
38
2
|
* The boot-time system restore — the ONLY restore there is. The launcher calls
|
|
39
3
|
* it before the addon installer and before any runner starts, so nothing has a
|
|
@@ -54,10 +18,10 @@ exports.applyPendingRestore = applyPendingRestore;
|
|
|
54
18
|
* - archive missing → log + clear marker (auto-recover from stale)
|
|
55
19
|
* - tar fails → throw → launcher exits non-zero, marker preserved
|
|
56
20
|
*/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
21
|
+
import * as fs from 'node:fs';
|
|
22
|
+
import * as path from 'node:path';
|
|
23
|
+
import * as tar from 'tar';
|
|
24
|
+
import { applySqliteRestore, missingPromisedSnapshots, planSqliteRestore, } from './sqlite-restore.js';
|
|
61
25
|
/** Path of the manifest file embedded inside every archive. */
|
|
62
26
|
const ARCHIVE_MANIFEST_NAME = '.camstack-backup-manifest.json';
|
|
63
27
|
const RESTORE_MARKER_FILE = '.pending-restore.json';
|
|
@@ -66,7 +30,7 @@ const RESTORE_MARKER_FILE = '.pending-restore.json';
|
|
|
66
30
|
* present. Runs BEFORE the addon installer so the restored snapshot's
|
|
67
31
|
* `addons/` folder is what `ensureRequiredPackages` picks up.
|
|
68
32
|
*/
|
|
69
|
-
async function applyPendingRestore(dataDir, log) {
|
|
33
|
+
export async function applyPendingRestore(dataDir, log) {
|
|
70
34
|
const markerPath = path.join(dataDir, RESTORE_MARKER_FILE);
|
|
71
35
|
if (!fs.existsSync(markerPath))
|
|
72
36
|
return;
|
|
@@ -127,10 +91,10 @@ async function applyPendingRestore(dataDir, log) {
|
|
|
127
91
|
return keep;
|
|
128
92
|
},
|
|
129
93
|
});
|
|
130
|
-
|
|
94
|
+
applySqliteRestore(dataDir, planSqliteRestore(extracted), log);
|
|
131
95
|
// A database the archive promised and the extraction did not write was NOT
|
|
132
96
|
// restored. Say so before "Restore complete" — silence would read as done.
|
|
133
|
-
const { missing, outOfScope } =
|
|
97
|
+
const { missing, outOfScope } = missingPromisedSnapshots(promised, extracted, inScope);
|
|
134
98
|
for (const rel of missing) {
|
|
135
99
|
log(`[launcher] WARNING Restore: the archive promised the database snapshot ${rel} but carried none — that database was NOT restored`);
|
|
136
100
|
}
|
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.runSingleCopyCleanup = runSingleCopyCleanup;
|
|
37
1
|
/**
|
|
38
2
|
* The one adapter that runs the post-boot single-copy sweep on BOTH roles.
|
|
39
3
|
*
|
|
@@ -50,9 +14,9 @@ exports.runSingleCopyCleanup = runSingleCopyCleanup;
|
|
|
50
14
|
* sweep that ends a process is an outage, and the copies it removes exist
|
|
51
15
|
* precisely because a node once could not boot.
|
|
52
16
|
*/
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
17
|
+
import * as fs from 'node:fs';
|
|
18
|
+
import * as path from 'node:path';
|
|
19
|
+
import { discoverRedundantCopies, executeSingleCopyCleanup, formatCleanupPlan, isCleanupEnabled, planSingleCopyCleanup, } from './single-copy-cleanup.js';
|
|
56
20
|
const EMPTY_RESULT = { removed: [], failed: [], refused: true };
|
|
57
21
|
/**
|
|
58
22
|
* Discover, plan, report, sweep. Called only from a point where the role has
|
|
@@ -60,13 +24,13 @@ const EMPTY_RESULT = { removed: [], failed: [], refused: true };
|
|
|
60
24
|
* re-stated as `bootHealthy: true` here so the pure planner can be exercised
|
|
61
25
|
* from both sides in a test.
|
|
62
26
|
*/
|
|
63
|
-
async function runSingleCopyCleanup(opts) {
|
|
27
|
+
export async function runSingleCopyCleanup(opts) {
|
|
64
28
|
try {
|
|
65
|
-
if (!
|
|
29
|
+
if (!isCleanupEnabled(process.env)) {
|
|
66
30
|
opts.log('single-copy cleanup disabled by CAMSTACK_SINGLE_COPY_CLEANUP — nothing removed');
|
|
67
31
|
return EMPTY_RESULT;
|
|
68
32
|
}
|
|
69
|
-
const candidates =
|
|
33
|
+
const candidates = discoverRedundantCopies({
|
|
70
34
|
dataDir: opts.dataDir,
|
|
71
35
|
addonRoot: opts.addonRoot,
|
|
72
36
|
closureProvides: (pkg) => {
|
|
@@ -82,7 +46,7 @@ async function runSingleCopyCleanup(opts) {
|
|
|
82
46
|
exists: (p) => fs.existsSync(p),
|
|
83
47
|
readVersion: (dir) => readVersion(dir),
|
|
84
48
|
});
|
|
85
|
-
const plan =
|
|
49
|
+
const plan = planSingleCopyCleanup({
|
|
86
50
|
activeRoot: process.env['CAMSTACK_SERVER_ACTIVE_ROOT'] ?? null,
|
|
87
51
|
closureResolvedFrom: resolveSystemPath(),
|
|
88
52
|
bootHealthy: true,
|
|
@@ -92,9 +56,9 @@ async function runSingleCopyCleanup(opts) {
|
|
|
92
56
|
.filter((entry) => entry.length > 0),
|
|
93
57
|
candidates,
|
|
94
58
|
});
|
|
95
|
-
for (const line of
|
|
59
|
+
for (const line of formatCleanupPlan(plan))
|
|
96
60
|
opts.log(line);
|
|
97
|
-
return await
|
|
61
|
+
return await executeSingleCopyCleanup(plan, {
|
|
98
62
|
exists: (p) => fs.existsSync(p),
|
|
99
63
|
rename: (from, to) => fs.renameSync(from, to),
|
|
100
64
|
remove: async (p) => {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Post-boot convergence to ONE copy per node — [D45](../../../docs/decisions/adr-0045.md),
|
|
4
3
|
* task 32.
|
|
@@ -36,13 +35,6 @@
|
|
|
36
35
|
* Pure planning + an injected filesystem, so the whole thing is testable
|
|
37
36
|
* against a described layout rather than a real disk.
|
|
38
37
|
*/
|
|
39
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
-
exports.CLOSURE_PROVIDED_PACKAGES = void 0;
|
|
41
|
-
exports.planSingleCopyCleanup = planSingleCopyCleanup;
|
|
42
|
-
exports.executeSingleCopyCleanup = executeSingleCopyCleanup;
|
|
43
|
-
exports.formatCleanupPlan = formatCleanupPlan;
|
|
44
|
-
exports.discoverRedundantCopies = discoverRedundantCopies;
|
|
45
|
-
exports.isCleanupEnabled = isCleanupEnabled;
|
|
46
38
|
/** Image trees. The fallback source lives here and is never data-side. */
|
|
47
39
|
const IMAGE_PREFIX = '/opt/';
|
|
48
40
|
/**
|
|
@@ -51,7 +43,7 @@ const IMAGE_PREFIX = '/opt/';
|
|
|
51
43
|
* The node-wide gates come first and are absolute: a blocked plan removes
|
|
52
44
|
* nothing at all, whatever the individual candidates look like.
|
|
53
45
|
*/
|
|
54
|
-
function planSingleCopyCleanup(input) {
|
|
46
|
+
export function planSingleCopyCleanup(input) {
|
|
55
47
|
const blockedReason = nodeWideBlock(input);
|
|
56
48
|
if (blockedReason !== null) {
|
|
57
49
|
return {
|
|
@@ -118,7 +110,7 @@ function isInside(child, parent) {
|
|
|
118
110
|
* only intended producer, but a hand-assembled plan must not be able to walk
|
|
119
111
|
* past the one gate that keeps this from running at the wrong moment.
|
|
120
112
|
*/
|
|
121
|
-
async function executeSingleCopyCleanup(plan, fs, log) {
|
|
113
|
+
export async function executeSingleCopyCleanup(plan, fs, log) {
|
|
122
114
|
if (plan.blocked) {
|
|
123
115
|
log(`single-copy cleanup REFUSED — ${plan.blockedReason ?? 'blocked'}`);
|
|
124
116
|
return { removed: [], failed: [], refused: true };
|
|
@@ -160,7 +152,7 @@ function errMsg(err) {
|
|
|
160
152
|
* BLOCKED sweep names every copy it left behind, because those are exactly the
|
|
161
153
|
* ones an operator would otherwise believe were gone.
|
|
162
154
|
*/
|
|
163
|
-
function formatCleanupPlan(plan) {
|
|
155
|
+
export function formatCleanupPlan(plan) {
|
|
164
156
|
const lines = [];
|
|
165
157
|
if (plan.blocked) {
|
|
166
158
|
lines.push(`single-copy cleanup blocked — ${plan.blockedReason ?? 'unknown reason'}; ` +
|
|
@@ -185,7 +177,7 @@ function formatCleanupPlan(plan) {
|
|
|
185
177
|
* and the reason `<dataDir>/addons/@camstack/system` is on the agent's disk at
|
|
186
178
|
* 1.2.78 while it runs a newer closure.
|
|
187
179
|
*/
|
|
188
|
-
|
|
180
|
+
export const CLOSURE_PROVIDED_PACKAGES = [
|
|
189
181
|
'@camstack/system',
|
|
190
182
|
'@camstack/types',
|
|
191
183
|
'@camstack/sdk',
|
|
@@ -199,7 +191,7 @@ exports.CLOSURE_PROVIDED_PACKAGES = [
|
|
|
199
191
|
* version — dropping it would under-report exactly the kind that has been
|
|
200
192
|
* sitting somewhere since an interrupted install.
|
|
201
193
|
*/
|
|
202
|
-
function discoverRedundantCopies(input, fs) {
|
|
194
|
+
export function discoverRedundantCopies(input, fs) {
|
|
203
195
|
const found = [];
|
|
204
196
|
const legacyFramework = `${trimSlash(input.dataDir)}/framework`;
|
|
205
197
|
if (fs.exists(legacyFramework)) {
|
|
@@ -210,7 +202,7 @@ function discoverRedundantCopies(input, fs) {
|
|
|
210
202
|
version: fs.readVersion(`${legacyFramework}/node_modules/@camstack/system`),
|
|
211
203
|
});
|
|
212
204
|
}
|
|
213
|
-
for (const pkg of
|
|
205
|
+
for (const pkg of CLOSURE_PROVIDED_PACKAGES) {
|
|
214
206
|
if (!input.closureProvides(pkg))
|
|
215
207
|
continue;
|
|
216
208
|
const dir = `${trimSlash(input.addonRoot)}/${pkg}`;
|
|
@@ -234,7 +226,7 @@ function trimSlash(p) {
|
|
|
234
226
|
* an operator has to edit code to stop. `CAMSTACK_SINGLE_COPY_CLEANUP=off`
|
|
235
227
|
* (or `0` / `false`) leaves every copy where it is, and the boot says so.
|
|
236
228
|
*/
|
|
237
|
-
function isCleanupEnabled(env) {
|
|
229
|
+
export function isCleanupEnabled(env) {
|
|
238
230
|
const raw = env['CAMSTACK_SINGLE_COPY_CLEANUP']?.trim().toLowerCase();
|
|
239
231
|
return raw !== 'off' && raw !== '0' && raw !== 'false';
|
|
240
232
|
}
|
package/dist/sqlite-restore.js
CHANGED
|
@@ -1,42 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.SQLITE_SNAPSHOT_SUFFIX = void 0;
|
|
37
|
-
exports.planSqliteRestore = planSqliteRestore;
|
|
38
|
-
exports.applySqliteRestore = applySqliteRestore;
|
|
39
|
-
exports.missingPromisedSnapshots = missingPromisedSnapshots;
|
|
40
1
|
/**
|
|
41
2
|
* The SQLite half of the boot-time restore (D693). Runs in the launcher,
|
|
42
3
|
* BEFORE any runner exists — on databases nobody has open, which is the one
|
|
@@ -64,20 +25,20 @@ exports.missingPromisedSnapshots = missingPromisedSnapshots;
|
|
|
64
25
|
* suffix is spelled here and pinned to `DATABASE_SNAPSHOT_SUFFIX` by
|
|
65
26
|
* `pending-restore-sqlite.spec.ts`.
|
|
66
27
|
*/
|
|
67
|
-
|
|
68
|
-
|
|
28
|
+
import * as fs from 'node:fs';
|
|
29
|
+
import * as path from 'node:path';
|
|
69
30
|
/** Mirrors `DATABASE_SNAPSHOT_SUFFIX` in `@camstack/types` (spec-pinned). */
|
|
70
|
-
|
|
31
|
+
export const SQLITE_SNAPSHOT_SUFFIX = '.backup-snapshot';
|
|
71
32
|
const SIDECARS = ['-wal', '-shm', '-journal'];
|
|
72
33
|
const DATABASE_SUFFIXES = ['.db', '.sqlite', '.sqlite3'];
|
|
73
34
|
/** Decide, from the paths an extraction wrote, what the target needs. */
|
|
74
|
-
function planSqliteRestore(extracted) {
|
|
35
|
+
export function planSqliteRestore(extracted) {
|
|
75
36
|
const written = new Set(extracted);
|
|
76
37
|
const promote = [];
|
|
77
38
|
const dropSidecars = new Map();
|
|
78
39
|
for (const rel of written) {
|
|
79
|
-
if (rel.endsWith(
|
|
80
|
-
const database = rel.slice(0, -
|
|
40
|
+
if (rel.endsWith(SQLITE_SNAPSHOT_SUFFIX)) {
|
|
41
|
+
const database = rel.slice(0, -SQLITE_SNAPSHOT_SUFFIX.length);
|
|
81
42
|
promote.push(rel);
|
|
82
43
|
// Whatever sits beside the target belongs to the database being replaced.
|
|
83
44
|
dropSidecars.set(database, [...SIDECARS]);
|
|
@@ -105,7 +66,7 @@ function fsyncDirectory(dir) {
|
|
|
105
66
|
* and each touched directory is fsynced before the caller clears its marker —
|
|
106
67
|
* a power cut after "Restore complete" must not bring the stale WAL back.
|
|
107
68
|
*/
|
|
108
|
-
function applySqliteRestore(dataDir, plan, log, syncDirectory = fsyncDirectory) {
|
|
69
|
+
export function applySqliteRestore(dataDir, plan, log, syncDirectory = fsyncDirectory) {
|
|
109
70
|
const touched = new Set();
|
|
110
71
|
for (const [database, sidecars] of plan.dropSidecars) {
|
|
111
72
|
for (const sidecar of sidecars) {
|
|
@@ -118,7 +79,7 @@ function applySqliteRestore(dataDir, plan, log, syncDirectory = fsyncDirectory)
|
|
|
118
79
|
}
|
|
119
80
|
}
|
|
120
81
|
for (const snapshot of plan.promote) {
|
|
121
|
-
const database = snapshot.slice(0, -
|
|
82
|
+
const database = snapshot.slice(0, -SQLITE_SNAPSHOT_SUFFIX.length);
|
|
122
83
|
fs.renameSync(path.join(dataDir, snapshot), path.join(dataDir, database));
|
|
123
84
|
touched.add(path.dirname(path.join(dataDir, database)));
|
|
124
85
|
log(`[launcher] Restore: promoted the owner snapshot ${snapshot} → ${database}`);
|
|
@@ -134,7 +95,7 @@ function applySqliteRestore(dataDir, plan, log, syncDirectory = fsyncDirectory)
|
|
|
134
95
|
}
|
|
135
96
|
}
|
|
136
97
|
}
|
|
137
|
-
function missingPromisedSnapshots(promised, extracted, inScope) {
|
|
98
|
+
export function missingPromisedSnapshots(promised, extracted, inScope) {
|
|
138
99
|
const written = new Set(extracted);
|
|
139
100
|
const missing = [];
|
|
140
101
|
const outOfScope = [];
|
package/dist/starter.js
CHANGED
|
@@ -1,38 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
1
|
/**
|
|
37
2
|
* STARTER — the tiny, immutable, dependency-free entry baked into the hub
|
|
38
3
|
* image. Everything above it (launcher, main, framework, addons) is runtime-
|
|
@@ -49,15 +14,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
49
14
|
*
|
|
50
15
|
* Console usage is intentional: the starter runs before any logging exists.
|
|
51
16
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
17
|
+
import * as path from 'node:path';
|
|
18
|
+
import { HUB_ROOT_SPEC, runNodeStarter } from './server-root/index.js';
|
|
54
19
|
function start() {
|
|
55
20
|
const seedPackageDir = path.resolve(__dirname, '..');
|
|
56
21
|
if (process.env['CAMSTACK_SEED_SERVER_DIR'] === undefined) {
|
|
57
22
|
process.env['CAMSTACK_SEED_SERVER_DIR'] = seedPackageDir;
|
|
58
23
|
}
|
|
59
|
-
|
|
60
|
-
spec:
|
|
24
|
+
runNodeStarter({
|
|
25
|
+
spec: HUB_ROOT_SPEC,
|
|
61
26
|
envNames: {
|
|
62
27
|
bootMode: 'CAMSTACK_SERVER_BOOT_MODE',
|
|
63
28
|
activeRoot: 'CAMSTACK_SERVER_ACTIVE_ROOT',
|
|
@@ -1,41 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.createLazyUiServing = createLazyUiServing;
|
|
37
|
-
const fs = __importStar(require("node:fs"));
|
|
38
|
-
const path = __importStar(require("node:path"));
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
39
3
|
const DEFAULT_ATTEMPT_GAP_MS = 2_000;
|
|
40
4
|
const DEFAULT_REQUEST_WAIT_MS = 4_000;
|
|
41
5
|
/** Wait for `work`, but never longer than `ms`: a hung provider RPC must not hang every request. */
|
|
@@ -60,7 +24,7 @@ async function waitAtMost(work, ms) {
|
|
|
60
24
|
* provider (addon update/restart) or a vanished index re-resolves, so the
|
|
61
25
|
* served directory follows the provider. No timers, no retry loop.
|
|
62
26
|
*/
|
|
63
|
-
function createLazyUiServing(options) {
|
|
27
|
+
export function createLazyUiServing(options) {
|
|
64
28
|
const gapMs = options.minAttemptGapMs ?? DEFAULT_ATTEMPT_GAP_MS;
|
|
65
29
|
const waitMs = options.requestWaitMs ?? DEFAULT_REQUEST_WAIT_MS;
|
|
66
30
|
const now = options.now ?? Date.now;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.594",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"private": false,
|
|
6
6
|
"files": [
|
|
@@ -38,19 +38,19 @@
|
|
|
38
38
|
]
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@camstack/addon-admin-ui": "1.2.
|
|
42
|
-
"@camstack/addon-agent-ui": "1.2.
|
|
43
|
-
"@camstack/addon-auth": "1.2.
|
|
41
|
+
"@camstack/addon-admin-ui": "1.2.436",
|
|
42
|
+
"@camstack/addon-agent-ui": "1.2.243",
|
|
43
|
+
"@camstack/addon-auth": "1.2.149",
|
|
44
44
|
"@camstack/addon-decoder-nodeav": "1.2.123",
|
|
45
|
-
"@camstack/addon-notifiers": "1.2.
|
|
46
|
-
"@camstack/addon-pipeline": "1.2.
|
|
47
|
-
"@camstack/addon-pipeline-orchestrator": "1.2.
|
|
48
|
-
"@camstack/addon-post-analysis": "1.2.
|
|
49
|
-
"@camstack/develop": "0.1.
|
|
50
|
-
"@camstack/sdk": "1.2.
|
|
51
|
-
"@camstack/system": "1.2.
|
|
52
|
-
"@camstack/types": "1.2.
|
|
53
|
-
"@camstack/ui-library": "1.2.
|
|
45
|
+
"@camstack/addon-notifiers": "1.2.601",
|
|
46
|
+
"@camstack/addon-pipeline": "1.2.601",
|
|
47
|
+
"@camstack/addon-pipeline-orchestrator": "1.2.601",
|
|
48
|
+
"@camstack/addon-post-analysis": "1.2.601",
|
|
49
|
+
"@camstack/develop": "0.1.12",
|
|
50
|
+
"@camstack/sdk": "1.2.133",
|
|
51
|
+
"@camstack/system": "1.2.445",
|
|
52
|
+
"@camstack/types": "1.2.381",
|
|
53
|
+
"@camstack/ui-library": "1.2.299",
|
|
54
54
|
"@fastify/compress": "^9.0.0",
|
|
55
55
|
"@fastify/cookie": "^11.0.2",
|
|
56
56
|
"@fastify/cors": "^11.2.0",
|