@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
|
@@ -1,52 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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.resolveDeployAction = resolveDeployAction;
|
|
37
|
-
exports.createAgentService = createAgentService;
|
|
38
|
-
const node_crypto_1 = require("node:crypto");
|
|
39
|
-
const fs = __importStar(require("node:fs"));
|
|
40
|
-
const os = __importStar(require("node:os"));
|
|
41
|
-
const path = __importStar(require("node:path"));
|
|
42
|
-
const system_1 = require("@camstack/system");
|
|
43
|
-
const moleculer_1 = require("moleculer");
|
|
44
|
-
const agent_deploy_swap_js_1 = require("./agent-deploy-swap.js");
|
|
45
|
-
const agent_undeploy_js_1 = require("./agent-undeploy.js");
|
|
46
|
-
const apply_model_distribution_js_1 = require("./apply-model-distribution.js");
|
|
47
|
-
const apply_stage_dev_uploads_js_1 = require("./apply-stage-dev-uploads.js");
|
|
48
|
-
const dev_uploads_bundle_js_1 = require("../api/dev-uploads-bundle.js");
|
|
49
|
-
const fetch_bundle_from_hub_js_1 = require("./fetch-bundle-from-hub.js");
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as os from 'node:os';
|
|
4
|
+
import * as path from 'node:path';
|
|
5
|
+
import { asBrokerLike, isAddonDeploySource, localSupportedPythonRuntimes, mapSignalsToInferenceHardware, probePlatform, resolveHwAccel, } from '@camstack/system';
|
|
6
|
+
import { Errors } from 'moleculer';
|
|
7
|
+
import { applyDeployedBundle } from './agent-deploy-swap.js';
|
|
8
|
+
import { undeployFromAgent, } from './agent-undeploy.js';
|
|
9
|
+
import { applyModelDistribution } from './apply-model-distribution.js';
|
|
10
|
+
import { applyStageDevUploads } from './apply-stage-dev-uploads.js';
|
|
11
|
+
import { unpackDevUploadVersionBundle } from '../api/dev-uploads-bundle.js';
|
|
12
|
+
import { fetchBundleFromHub } from './fetch-bundle-from-hub.js';
|
|
50
13
|
/**
|
|
51
14
|
* Console-backed scoped logger for the deploy swap (the only consumer in this
|
|
52
15
|
* file). `applyDeployedBundle` logs only on the rare restore-after-failed-swap
|
|
@@ -59,9 +22,9 @@ const DEFAULT_DRI_RENDER_NODE = '/dev/dri/renderD128';
|
|
|
59
22
|
* `software`; `detectionDevices` lists enabled accelerator keys.
|
|
60
23
|
*/
|
|
61
24
|
function buildDecodeDetectionSlice() {
|
|
62
|
-
const hw =
|
|
63
|
-
const signals =
|
|
64
|
-
const inference =
|
|
25
|
+
const hw = resolveHwAccel();
|
|
26
|
+
const signals = probePlatform();
|
|
27
|
+
const inference = mapSignalsToInferenceHardware(signals);
|
|
65
28
|
const driDevice = fs.existsSync(DEFAULT_DRI_RENDER_NODE) ? DEFAULT_DRI_RENDER_NODE : null;
|
|
66
29
|
const detectionDevices = [];
|
|
67
30
|
if (inference.gpu !== null)
|
|
@@ -134,16 +97,16 @@ async function withTimeout(p, ms, fallback) {
|
|
|
134
97
|
}
|
|
135
98
|
/** Bound for the metrics snapshot inside status/health — see `withTimeout`. */
|
|
136
99
|
const METRICS_SNAPSHOT_TIMEOUT_MS = 2_000;
|
|
137
|
-
function resolveDeployAction(seam) {
|
|
100
|
+
export function resolveDeployAction(seam) {
|
|
138
101
|
const applyAndReport = async (addonId, buf) => {
|
|
139
|
-
const appliedSha256 =
|
|
102
|
+
const appliedSha256 = createHash('sha256').update(buf).digest('hex');
|
|
140
103
|
const { addonDir } = await seam.applyBundle(buf);
|
|
141
104
|
seam.onApplied(addonDir);
|
|
142
105
|
return { success: true, addonId, path: addonDir, appliedSha256 };
|
|
143
106
|
};
|
|
144
107
|
return async (params) => {
|
|
145
108
|
const { addonId, source, bundle } = params;
|
|
146
|
-
if (source &&
|
|
109
|
+
if (source && isAddonDeploySource(source)) {
|
|
147
110
|
if (source.kind === 'npm') {
|
|
148
111
|
await seam.installFromNpm(addonId, source.version);
|
|
149
112
|
// npm path installs to disk via AddonInstaller and returns no addonDir; the
|
|
@@ -202,8 +165,7 @@ function readDeployedAddonIds(addonDir) {
|
|
|
202
165
|
}
|
|
203
166
|
function isHubConnected(broker) {
|
|
204
167
|
try {
|
|
205
|
-
const
|
|
206
|
-
const nodes = registry?.getNodeList?.({ onlyAvailable: true }) ?? [];
|
|
168
|
+
const nodes = broker.registry.getNodeList({ onlyAvailable: true });
|
|
207
169
|
return nodes.some((n) => n.id === 'hub');
|
|
208
170
|
}
|
|
209
171
|
catch {
|
|
@@ -261,7 +223,7 @@ function createAgentService(deps) {
|
|
|
261
223
|
// Cluster topology `engines` — supported python runtime ids
|
|
262
224
|
// (`onnx` / `openvino` / `coreml` / `edgetpu`). Was declared on
|
|
263
225
|
// AgentInfo but never reported, so every node badge stayed empty.
|
|
264
|
-
pythonRuntimes:
|
|
226
|
+
pythonRuntimes: localSupportedPythonRuntimes(),
|
|
265
227
|
addons: [...deps.loadedAddons.values()].map((a) => ({
|
|
266
228
|
id: a.id,
|
|
267
229
|
status: a.status,
|
|
@@ -367,8 +329,7 @@ function createAgentService(deps) {
|
|
|
367
329
|
},
|
|
368
330
|
deploy: {
|
|
369
331
|
handler: async (ctx) => {
|
|
370
|
-
const {
|
|
371
|
-
const { addonId, source, bundle } = params;
|
|
332
|
+
const { addonId, source, bundle } = ctx.params;
|
|
372
333
|
// execFile (no shell) instead of execSync — addonId comes from RPC
|
|
373
334
|
// params and was previously interpolated into a shell command, which
|
|
374
335
|
// is a command-injection vector. argv form doesn't go through a shell
|
|
@@ -377,8 +338,8 @@ function createAgentService(deps) {
|
|
|
377
338
|
// event loop for the whole untar, which on a large package starves
|
|
378
339
|
// concurrent hub RPCs ($agent.status heartbeat) long enough for the
|
|
379
340
|
// hub to time them out and drop the node from topology mid-deploy.
|
|
380
|
-
const { execFile } = await
|
|
381
|
-
const { promisify } = await
|
|
341
|
+
const { execFile } = await import('node:child_process');
|
|
342
|
+
const { promisify } = await import('node:util');
|
|
382
343
|
const execFileAsync = promisify(execFile);
|
|
383
344
|
// Atomic install: extract into a temp dir then swap into place. The
|
|
384
345
|
// old body `rm`'d the live dir THEN untarred — a killed/timed-out
|
|
@@ -434,7 +395,7 @@ function createAgentService(deps) {
|
|
|
434
395
|
}
|
|
435
396
|
}
|
|
436
397
|
}
|
|
437
|
-
return
|
|
398
|
+
return applyDeployedBundle({
|
|
438
399
|
addonsDir: deps.addonsDir,
|
|
439
400
|
addonId,
|
|
440
401
|
bundle: buf,
|
|
@@ -442,7 +403,7 @@ function createAgentService(deps) {
|
|
|
442
403
|
logger: deploySwapLogger,
|
|
443
404
|
});
|
|
444
405
|
},
|
|
445
|
-
fetchBundle: (s) =>
|
|
406
|
+
fetchBundle: (s) => fetchBundleFromHub(s),
|
|
446
407
|
// Evict every addon DECLARATION id this package contributes
|
|
447
408
|
// from `loadedAddons` so the follow-up `$agent.reload` actually
|
|
448
409
|
// re-instantiates it. `loadDeployedAddons` skips any addon
|
|
@@ -469,13 +430,13 @@ function createAgentService(deps) {
|
|
|
469
430
|
*/
|
|
470
431
|
stageDevUploads: {
|
|
471
432
|
handler: async (ctx) => {
|
|
472
|
-
const
|
|
433
|
+
const params = ctx.params;
|
|
473
434
|
const seam = {
|
|
474
435
|
dataDir: deps.dataDir,
|
|
475
|
-
fetchBundle: (s) =>
|
|
476
|
-
unpack:
|
|
436
|
+
fetchBundle: (s) => fetchBundleFromHub(s),
|
|
437
|
+
unpack: unpackDevUploadVersionBundle,
|
|
477
438
|
};
|
|
478
|
-
return
|
|
439
|
+
return applyStageDevUploads(seam, params);
|
|
479
440
|
},
|
|
480
441
|
},
|
|
481
442
|
/**
|
|
@@ -487,14 +448,14 @@ function createAgentService(deps) {
|
|
|
487
448
|
*/
|
|
488
449
|
distributeModel: {
|
|
489
450
|
handler: async (ctx) => {
|
|
490
|
-
const
|
|
491
|
-
const { execFile } = await
|
|
492
|
-
const { promisify } = await
|
|
451
|
+
const params = ctx.params;
|
|
452
|
+
const { execFile } = await import('node:child_process');
|
|
453
|
+
const { promisify } = await import('node:util');
|
|
493
454
|
const execFileAsync = promisify(execFile);
|
|
494
455
|
const modelsDir = path.join(deps.dataDir, 'models');
|
|
495
456
|
const seam = {
|
|
496
457
|
modelsDir,
|
|
497
|
-
fetchBundle: (s) =>
|
|
458
|
+
fetchBundle: (s) => fetchBundleFromHub(s),
|
|
498
459
|
extract: async (tgz, destDir) => {
|
|
499
460
|
const tmp = path.join(destDir, `.dist-${Date.now()}-${Math.random().toString(36).slice(2)}.tgz`);
|
|
500
461
|
fs.writeFileSync(tmp, tgz);
|
|
@@ -512,7 +473,7 @@ function createAgentService(deps) {
|
|
|
512
473
|
},
|
|
513
474
|
mkdirp: (dir) => fs.mkdirSync(dir, { recursive: true }),
|
|
514
475
|
};
|
|
515
|
-
return
|
|
476
|
+
return applyModelDistribution(seam, params);
|
|
516
477
|
},
|
|
517
478
|
},
|
|
518
479
|
/**
|
|
@@ -526,12 +487,13 @@ function createAgentService(deps) {
|
|
|
526
487
|
undeploy: {
|
|
527
488
|
handler: async (ctx) => {
|
|
528
489
|
const { params, broker } = ctx;
|
|
529
|
-
|
|
490
|
+
const bkr = asBrokerLike(broker);
|
|
491
|
+
return undeployFromAgent({
|
|
530
492
|
addonsDir: deps.addonsDir,
|
|
531
493
|
loadedAddons: deps.loadedAddons,
|
|
532
494
|
bootstrapPackages: deps.bootstrapPackages ?? DEFAULT_AGENT_BOOTSTRAP_PACKAGES,
|
|
533
|
-
listRunnersByAddon: (addonId) =>
|
|
534
|
-
stopRunner: (name) =>
|
|
495
|
+
listRunnersByAddon: (addonId) => bkr.call('$process.listByAddon', { addonId }, { nodeID: broker.nodeID, timeout: AGENT_PROCESS_RESTART_TIMEOUT_MS }),
|
|
496
|
+
stopRunner: (name) => bkr.call('$process.stop', { name }, { nodeID: broker.nodeID, timeout: AGENT_PROCESS_RESTART_TIMEOUT_MS }),
|
|
535
497
|
destroyService: (addonId) => broker.destroyService(addonId),
|
|
536
498
|
unregisterProvider: (capName, addonId) => deps.unregisterProvider?.(capName, addonId),
|
|
537
499
|
respawnSurvivors: deps.reloadDeployedAddons,
|
|
@@ -566,6 +528,7 @@ function createAgentService(deps) {
|
|
|
566
528
|
restart: {
|
|
567
529
|
handler: async (ctx) => {
|
|
568
530
|
const { params, broker } = ctx;
|
|
531
|
+
const bkr = asBrokerLike(broker);
|
|
569
532
|
const { addonId } = params;
|
|
570
533
|
// Delegate to THIS agent's own `$process` service — the SAME primitive
|
|
571
534
|
// the hub uses for a local forked addon (AddonRegistryService.restartAddon
|
|
@@ -575,11 +538,11 @@ function createAgentService(deps) {
|
|
|
575
538
|
// Moleculer node evicted, and the addon's caps re-registered — identical
|
|
576
539
|
// semantics to a hub-local restart. Pin to the agent's own node so the
|
|
577
540
|
// call always hits THIS agent's `$process`, never the hub's.
|
|
578
|
-
const result = await
|
|
541
|
+
const result = await bkr.call('$process.restart', { name: addonId }, { nodeID: broker.nodeID, timeout: AGENT_PROCESS_RESTART_TIMEOUT_MS });
|
|
579
542
|
if (!result.success) {
|
|
580
543
|
// Fail loudly so the hub's `nodes.restartAddon` surfaces the real
|
|
581
544
|
// error instead of the old fire-and-forget phantom success.
|
|
582
|
-
throw new
|
|
545
|
+
throw new Errors.MoleculerError(`$agent.restart: process restart failed for "${addonId}": ${result.reason ?? 'unknown'}`, 500, 'AGENT_RESTART_FAILED');
|
|
583
546
|
}
|
|
584
547
|
return { success: true, addonId, pid: result.pid };
|
|
585
548
|
},
|
|
@@ -614,3 +577,4 @@ function createAgentService(deps) {
|
|
|
614
577
|
},
|
|
615
578
|
};
|
|
616
579
|
}
|
|
580
|
+
export { createAgentService };
|
|
@@ -1,40 +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.HANDSHAKE_TIMEOUT_MS = exports.SNIFF_TIMEOUT_MS = exports.TLS_HANDSHAKE_RECORD = void 0;
|
|
37
|
-
exports.startSniffingListener = startSniffingListener;
|
|
38
1
|
/**
|
|
39
2
|
* One port, two protocols (D856): the agent's HTTP port also speaks TLS.
|
|
40
3
|
*
|
|
@@ -54,12 +17,12 @@ exports.startSniffingListener = startSniffingListener;
|
|
|
54
17
|
* The serving certificate is swapped with `setSecureContext` - new handshakes use
|
|
55
18
|
* it at once, existing connections keep the old one, nothing restarts.
|
|
56
19
|
*/
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
20
|
+
import * as net from 'node:net';
|
|
21
|
+
import { Duplex } from 'node:stream';
|
|
22
|
+
import * as tls from 'node:tls';
|
|
23
|
+
export const TLS_HANDSHAKE_RECORD = 0x16;
|
|
24
|
+
export const SNIFF_TIMEOUT_MS = 10_000;
|
|
25
|
+
export const HANDSHAKE_TIMEOUT_MS = 10_000;
|
|
63
26
|
const STALL_WARN_EVERY_MS = 60_000;
|
|
64
27
|
/** On shutdown, connections still open after this long are destroyed. */
|
|
65
28
|
const CLOSE_GRACE_MS = 2_000;
|
|
@@ -70,7 +33,7 @@ const CLOSE_GRACE_MS = 2_000;
|
|
|
70
33
|
* sniffed. This duplex replays the first chunk and then forwards the socket, and
|
|
71
34
|
* exposes the address fields the servers (and the agent's loopback check) read.
|
|
72
35
|
*/
|
|
73
|
-
class ReplayDuplex extends
|
|
36
|
+
class ReplayDuplex extends Duplex {
|
|
74
37
|
socket;
|
|
75
38
|
pending;
|
|
76
39
|
constructor(socket, first) {
|
|
@@ -142,12 +105,12 @@ class ReplayDuplex extends node_stream_1.Duplex {
|
|
|
142
105
|
callback(error);
|
|
143
106
|
}
|
|
144
107
|
}
|
|
145
|
-
function startSniffingListener(options) {
|
|
108
|
+
export function startSniffingListener(options) {
|
|
146
109
|
// The serving context. A swap replaces it: every NEW handshake uses the new one,
|
|
147
110
|
// connections already established keep what they negotiated.
|
|
148
111
|
let secureContext = null;
|
|
149
112
|
let refused = 0;
|
|
150
|
-
const sniffTimeoutMs = options.sniffTimeoutMs ??
|
|
113
|
+
const sniffTimeoutMs = options.sniffTimeoutMs ?? SNIFF_TIMEOUT_MS;
|
|
151
114
|
/** Every live connection, so shutdown can end them instead of waiting on idle keep-alives. */
|
|
152
115
|
const live = new Set();
|
|
153
116
|
const track = (socket) => {
|
|
@@ -158,7 +121,7 @@ function startSniffingListener(options) {
|
|
|
158
121
|
// with how many were suppressed.
|
|
159
122
|
let lastStallWarnAt = 0;
|
|
160
123
|
let suppressedStalls = 0;
|
|
161
|
-
const handshakeTimeoutMs = options.handshakeTimeoutMs ??
|
|
124
|
+
const handshakeTimeoutMs = options.handshakeTimeoutMs ?? HANDSHAKE_TIMEOUT_MS;
|
|
162
125
|
const setMaterial = (material) => {
|
|
163
126
|
try {
|
|
164
127
|
secureContext = tls.createSecureContext({ key: material.keyPem, cert: material.certPem });
|
|
@@ -221,7 +184,7 @@ function startSniffingListener(options) {
|
|
|
221
184
|
socket.once('data', (chunk) => {
|
|
222
185
|
clearTimeout(timer);
|
|
223
186
|
socket.pause();
|
|
224
|
-
if (chunk[0] ===
|
|
187
|
+
if (chunk[0] === TLS_HANDSHAKE_RECORD) {
|
|
225
188
|
if (secureContext === null) {
|
|
226
189
|
refused += 1;
|
|
227
190
|
options.onTlsRefused?.();
|
|
@@ -1,42 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
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.undeployFromAgent = undeployFromAgent;
|
|
37
|
-
const fs = __importStar(require("node:fs"));
|
|
38
|
-
const path = __importStar(require("node:path"));
|
|
39
|
-
const agent_group_runner_js_1 = require("./agent-group-runner.js");
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { readPackageManifestAddons } from './agent-group-runner.js';
|
|
40
4
|
function capName(cap) {
|
|
41
5
|
return typeof cap === 'string' ? cap : cap.name;
|
|
42
6
|
}
|
|
@@ -55,7 +19,7 @@ function resolveTarget(seam, request) {
|
|
|
55
19
|
? seam.loadedAddons.get(request.addonId)?.packageName
|
|
56
20
|
: undefined);
|
|
57
21
|
const packageDir = packageName !== undefined ? packageDirFor(seam.addonsDir, packageName) : null;
|
|
58
|
-
const manifest = packageDir !== null ?
|
|
22
|
+
const manifest = packageDir !== null ? readPackageManifestAddons(packageDir) : null;
|
|
59
23
|
const capsByAddon = new Map();
|
|
60
24
|
let protectedBy = null;
|
|
61
25
|
for (const decl of manifest?.declarations ?? []) {
|
|
@@ -170,7 +134,7 @@ function removeDirs(seam, request, target) {
|
|
|
170
134
|
return removed;
|
|
171
135
|
}
|
|
172
136
|
/** Run one `$agent.undeploy`. Never throws for a refusal — it answers `refused`. */
|
|
173
|
-
async function undeployFromAgent(seam, request) {
|
|
137
|
+
export async function undeployFromAgent(seam, request) {
|
|
174
138
|
const target = resolveTarget(seam, request);
|
|
175
139
|
const scope = request.packageName !== undefined ? 'package' : 'addon';
|
|
176
140
|
const base = {
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ADDON_HUB_UPDATE_UNAVAILABLE_REASON = exports.ADDON_UPDATE_UNAVAILABLE_REASON = exports.SERVER_UPDATE_UNAVAILABLE_REASON = exports.APPLY_ALREADY_RUNNING_MESSAGE = void 0;
|
|
4
|
-
exports.createAgentServerUpdateControls = createAgentServerUpdateControls;
|
|
5
|
-
exports.registerAgentUpdateRoutes = registerAgentUpdateRoutes;
|
|
6
|
-
const agent_hub_addon_update_js_1 = require("./agent-hub-addon-update.js");
|
|
1
|
+
import { isBehindHub, } from './agent-hub-addon-update.js';
|
|
7
2
|
/** The message a second concurrent apply gets. Exported so the test names it once. */
|
|
8
|
-
|
|
3
|
+
export const APPLY_ALREADY_RUNNING_MESSAGE = 'Refused: an update is already in flight on this node.';
|
|
9
4
|
/**
|
|
10
5
|
* Bind the routes' controls to a real update engine.
|
|
11
6
|
*
|
|
@@ -14,7 +9,7 @@ exports.APPLY_ALREADY_RUNNING_MESSAGE = 'Refused: an update is already in flight
|
|
|
14
9
|
* not happen, and both of these arrive on a different tick from the poll that
|
|
15
10
|
* has to render them.
|
|
16
11
|
*/
|
|
17
|
-
function createAgentServerUpdateControls(engine, onError) {
|
|
12
|
+
export function createAgentServerUpdateControls(engine, onError) {
|
|
18
13
|
let lastCheckError = null;
|
|
19
14
|
let lastApply = null;
|
|
20
15
|
let applyInFlight = false;
|
|
@@ -32,7 +27,7 @@ function createAgentServerUpdateControls(engine, onError) {
|
|
|
32
27
|
},
|
|
33
28
|
applyLatest: () => {
|
|
34
29
|
if (applyInFlight) {
|
|
35
|
-
return { started: false, message:
|
|
30
|
+
return { started: false, message: APPLY_ALREADY_RUNNING_MESSAGE };
|
|
36
31
|
}
|
|
37
32
|
applyInFlight = true;
|
|
38
33
|
lastApply = null;
|
|
@@ -64,11 +59,11 @@ function createAgentServerUpdateControls(engine, onError) {
|
|
|
64
59
|
// Routes
|
|
65
60
|
// ---------------------------------------------------------------------------
|
|
66
61
|
/** Why the framework card renders empty when nothing was wired. */
|
|
67
|
-
|
|
62
|
+
export const SERVER_UPDATE_UNAVAILABLE_REASON = 'Framework updates are not available on this agent build.';
|
|
68
63
|
/** Why the addon report renders empty when nothing was wired. */
|
|
69
|
-
|
|
64
|
+
export const ADDON_UPDATE_UNAVAILABLE_REASON = 'The addon roster is not available on this agent build.';
|
|
70
65
|
/** Why the Update action is absent when the hub channel was not wired. */
|
|
71
|
-
|
|
66
|
+
export const ADDON_HUB_UPDATE_UNAVAILABLE_REASON = 'Updating an addon through the hub is not available on this agent build.';
|
|
72
67
|
async function withHubVersions(report, hub) {
|
|
73
68
|
const versions = hub === undefined ? null : await hub.getHubVersions();
|
|
74
69
|
const progress = hub?.progress();
|
|
@@ -80,7 +75,7 @@ async function withHubVersions(report, hub) {
|
|
|
80
75
|
return {
|
|
81
76
|
...entry,
|
|
82
77
|
hubVersion,
|
|
83
|
-
behindHub:
|
|
78
|
+
behindHub: isBehindHub(entry.installedVersion, hubVersion),
|
|
84
79
|
update: progress?.get(entry.packageName) ?? null,
|
|
85
80
|
};
|
|
86
81
|
}),
|
|
@@ -90,38 +85,38 @@ async function withHubVersions(report, hub) {
|
|
|
90
85
|
* Mount the update routes on an already-built agent HTTP server. Called from
|
|
91
86
|
* `createAgentHttpServer` AFTER the auth hook, so every path here inherits it.
|
|
92
87
|
*/
|
|
93
|
-
function registerAgentUpdateRoutes(app, controls) {
|
|
88
|
+
export function registerAgentUpdateRoutes(app, controls) {
|
|
94
89
|
const server = controls.server;
|
|
95
90
|
const addons = controls.addons;
|
|
96
91
|
app.get('/api/agent/server-update', async () => {
|
|
97
92
|
if (server === undefined) {
|
|
98
|
-
return { available: false, reason:
|
|
93
|
+
return { available: false, reason: SERVER_UPDATE_UNAVAILABLE_REASON };
|
|
99
94
|
}
|
|
100
95
|
return { available: true, ...(await server.getView()) };
|
|
101
96
|
});
|
|
102
97
|
app.post('/api/agent/server-update/check', async (_req, reply) => {
|
|
103
98
|
if (server === undefined) {
|
|
104
|
-
return reply.status(503).send({ error:
|
|
99
|
+
return reply.status(503).send({ error: SERVER_UPDATE_UNAVAILABLE_REASON });
|
|
105
100
|
}
|
|
106
101
|
return server.check();
|
|
107
102
|
});
|
|
108
103
|
// No request body is read: the target is always registry `latest`.
|
|
109
104
|
app.post('/api/agent/server-update/apply', async (_req, reply) => {
|
|
110
105
|
if (server === undefined) {
|
|
111
|
-
return reply.status(503).send({ error:
|
|
106
|
+
return reply.status(503).send({ error: SERVER_UPDATE_UNAVAILABLE_REASON });
|
|
112
107
|
}
|
|
113
108
|
return server.applyLatest();
|
|
114
109
|
});
|
|
115
110
|
app.get('/api/agent/addon-updates', async () => {
|
|
116
111
|
if (addons === undefined) {
|
|
117
|
-
return { available: false, reason:
|
|
112
|
+
return { available: false, reason: ADDON_UPDATE_UNAVAILABLE_REASON };
|
|
118
113
|
}
|
|
119
114
|
const report = await addons.getReport();
|
|
120
115
|
return { available: true, ...(await withHubVersions(report, addons.hub)) };
|
|
121
116
|
});
|
|
122
117
|
app.post('/api/agent/addon-updates/update', async (req, reply) => {
|
|
123
118
|
if (addons?.hub === undefined) {
|
|
124
|
-
return reply.status(503).send({ error:
|
|
119
|
+
return reply.status(503).send({ error: ADDON_HUB_UPDATE_UNAVAILABLE_REASON });
|
|
125
120
|
}
|
|
126
121
|
const packageName = req.body?.packageName;
|
|
127
122
|
if (typeof packageName !== 'string' || packageName.length === 0) {
|