@camstack/server 1.2.500 → 1.2.502
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/agent/agent-service.js +19 -0
- package/dist/agent/apply-stage-dev-uploads.js +29 -0
- package/dist/api/dev-uploads-bundle.js +170 -0
- package/dist/api/server-upload-propagate.js +178 -0
- package/dist/api/trpc/generated-cap-mounts.js +2 -0
- package/dist/api/trpc/generated-cap-routers.js +72 -90
- package/dist/main.js +11 -0
- package/dist/server-root/index.js +1 -1
- package/package.json +8 -8
|
@@ -44,6 +44,8 @@ const moleculer_1 = require("moleculer");
|
|
|
44
44
|
const agent_deploy_swap_js_1 = require("./agent-deploy-swap.js");
|
|
45
45
|
const agent_undeploy_js_1 = require("./agent-undeploy.js");
|
|
46
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");
|
|
47
49
|
const fetch_bundle_from_hub_js_1 = require("./fetch-bundle-from-hub.js");
|
|
48
50
|
/**
|
|
49
51
|
* Console-backed scoped logger for the deploy swap (the only consumer in this
|
|
@@ -459,6 +461,23 @@ function createAgentService(deps) {
|
|
|
459
461
|
return resolveDeployAction(seam)({ addonId, source, bundle });
|
|
460
462
|
},
|
|
461
463
|
},
|
|
464
|
+
/**
|
|
465
|
+
* Stage a hub-packed `dev-uploads/<version>/` set under this node's
|
|
466
|
+
* `server-root/dev-uploads/` so a subsequent `applyServerUpdate` for a
|
|
467
|
+
* `-dev.<epoch>` version can promote locally (Path B fan-out). Does not
|
|
468
|
+
* restart or promote — only writes the upload layout.
|
|
469
|
+
*/
|
|
470
|
+
stageDevUploads: {
|
|
471
|
+
handler: async (ctx) => {
|
|
472
|
+
const { params } = ctx;
|
|
473
|
+
const seam = {
|
|
474
|
+
dataDir: deps.dataDir,
|
|
475
|
+
fetchBundle: (s) => (0, fetch_bundle_from_hub_js_1.fetchBundleFromHub)(s),
|
|
476
|
+
unpack: dev_uploads_bundle_js_1.unpackDevUploadVersionBundle,
|
|
477
|
+
};
|
|
478
|
+
return (0, apply_stage_dev_uploads_js_1.applyStageDevUploads)(seam, params);
|
|
479
|
+
},
|
|
480
|
+
},
|
|
462
481
|
/**
|
|
463
482
|
* Pull a staged model tarball from the hub and untar it into this node's
|
|
464
483
|
* `<dataDir>/models` (Model Studio P2). Reuses the agent-pull machinery:
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyStageDevUploads = applyStageDevUploads;
|
|
4
|
+
/**
|
|
5
|
+
* Pure seam for `$agent.stageDevUploads` — fetch a hub-staged pack of
|
|
6
|
+
* `dev-uploads/<version>/` and write it under this node's server-root.
|
|
7
|
+
*/
|
|
8
|
+
const node_crypto_1 = require("node:crypto");
|
|
9
|
+
const index_js_1 = require("../server-root/index.js");
|
|
10
|
+
async function applyStageDevUploads(seam, params) {
|
|
11
|
+
const { version, source } = params;
|
|
12
|
+
if (!(0, index_js_1.isDevChannelVersion)(version)) {
|
|
13
|
+
throw new Error(`$agent.stageDevUploads: version "${version}" is not dev-channel shaped`);
|
|
14
|
+
}
|
|
15
|
+
const bundle = await seam.fetchBundle(source);
|
|
16
|
+
const appliedSha256 = (0, node_crypto_1.createHash)('sha256').update(bundle).digest('hex');
|
|
17
|
+
const unpacked = await seam.unpack({
|
|
18
|
+
serverRoot: (0, index_js_1.serverRootDir)(seam.dataDir),
|
|
19
|
+
version,
|
|
20
|
+
bundle,
|
|
21
|
+
});
|
|
22
|
+
return {
|
|
23
|
+
success: true,
|
|
24
|
+
version,
|
|
25
|
+
path: unpacked.versionDir,
|
|
26
|
+
packageCount: unpacked.packageCount,
|
|
27
|
+
appliedSha256,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1,170 @@
|
|
|
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.isSafeDevUploadVersion = isSafeDevUploadVersion;
|
|
37
|
+
exports.packDevUploadVersionDir = packDevUploadVersionDir;
|
|
38
|
+
exports.unpackDevUploadVersionBundle = unpackDevUploadVersionBundle;
|
|
39
|
+
/**
|
|
40
|
+
* Pack / unpack a hub `server-root/dev-uploads/<version>/` directory for
|
|
41
|
+
* agent fan-out (`POST /api/server-upload/propagate` → `$agent.stageDevUploads`).
|
|
42
|
+
*
|
|
43
|
+
* One gzipped tar carries every tarball + `manifest.json`. Fail-closed on
|
|
44
|
+
* path traversal and on a layout that would not satisfy RootUpdateService.
|
|
45
|
+
*/
|
|
46
|
+
const fs = __importStar(require("node:fs"));
|
|
47
|
+
const os = __importStar(require("node:os"));
|
|
48
|
+
const path = __importStar(require("node:path"));
|
|
49
|
+
const tar = __importStar(require("tar"));
|
|
50
|
+
const index_js_1 = require("../server-root/index.js");
|
|
51
|
+
/** Version chars safe as a single path segment (matches server-upload). */
|
|
52
|
+
const SAFE_VERSION_RE = /^[0-9A-Za-z][0-9A-Za-z.-]*$/;
|
|
53
|
+
function isSafeDevUploadVersion(version) {
|
|
54
|
+
return SAFE_VERSION_RE.test(version) && (0, index_js_1.isDevChannelVersion)(version);
|
|
55
|
+
}
|
|
56
|
+
function hasPathTraversal(name) {
|
|
57
|
+
return name.includes('/') || name.includes('\\') || name.includes('..');
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Pack every file in `versionDir` (basename entries only) into a gzipped tar.
|
|
61
|
+
* Refuses if the manifest is missing/invalid or lists a missing tarball.
|
|
62
|
+
*/
|
|
63
|
+
async function packDevUploadVersionDir(versionDir) {
|
|
64
|
+
const manifest = (0, index_js_1.readDevUploadManifest)(versionDir);
|
|
65
|
+
if (manifest === null) {
|
|
66
|
+
throw new Error(`dev-uploads manifest missing or invalid in ${versionDir}`);
|
|
67
|
+
}
|
|
68
|
+
for (const filename of Object.values(manifest.packages)) {
|
|
69
|
+
if (hasPathTraversal(filename)) {
|
|
70
|
+
throw new Error(`dev-uploads package filename refuses path traversal: ${filename}`);
|
|
71
|
+
}
|
|
72
|
+
const abs = path.join(versionDir, filename);
|
|
73
|
+
if (!fs.existsSync(abs)) {
|
|
74
|
+
throw new Error(`dev-uploads tarball listed in manifest is missing: ${filename}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!fs.existsSync(path.join(versionDir, index_js_1.DEV_UPLOAD_MANIFEST_FILE))) {
|
|
78
|
+
throw new Error(`dev-uploads manifest file missing in ${versionDir}`);
|
|
79
|
+
}
|
|
80
|
+
const entries = fs.readdirSync(versionDir).filter((name) => {
|
|
81
|
+
const st = fs.statSync(path.join(versionDir, name));
|
|
82
|
+
return st.isFile() && !hasPathTraversal(name);
|
|
83
|
+
});
|
|
84
|
+
if (entries.length === 0) {
|
|
85
|
+
throw new Error(`dev-uploads version dir is empty: ${versionDir}`);
|
|
86
|
+
}
|
|
87
|
+
const chunks = [];
|
|
88
|
+
await new Promise((resolve, reject) => {
|
|
89
|
+
const stream = tar.c({ gzip: true, cwd: versionDir, portable: true }, entries);
|
|
90
|
+
stream.on('data', (chunk) => {
|
|
91
|
+
chunks.push(chunk);
|
|
92
|
+
});
|
|
93
|
+
stream.on('error', reject);
|
|
94
|
+
stream.on('end', () => resolve());
|
|
95
|
+
});
|
|
96
|
+
return Buffer.concat(chunks);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Extract a packed version dir into `serverRoot/dev-uploads/<version>/`
|
|
100
|
+
* atomically (stage sibling + rename). Validates version shape, entry names,
|
|
101
|
+
* and that the extracted layout matches the manifest.
|
|
102
|
+
*/
|
|
103
|
+
async function unpackDevUploadVersionBundle(args) {
|
|
104
|
+
const { serverRoot, version, bundle } = args;
|
|
105
|
+
if (!isSafeDevUploadVersion(version)) {
|
|
106
|
+
throw new Error(`Refused: version "${version}" is not a safe dev-channel version for staging`);
|
|
107
|
+
}
|
|
108
|
+
const uploadsRoot = path.join(serverRoot, 'dev-uploads');
|
|
109
|
+
fs.mkdirSync(uploadsRoot, { recursive: true });
|
|
110
|
+
const finalDir = path.join(uploadsRoot, version);
|
|
111
|
+
const stagingDir = path.join(uploadsRoot, `.staging-${version}-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
|
|
112
|
+
fs.mkdirSync(stagingDir, { recursive: true });
|
|
113
|
+
const tmpTgz = path.join(os.tmpdir(), `camstack-dev-uploads-${version.replace(/[^\w.-]/g, '_')}-${Date.now()}.tgz`);
|
|
114
|
+
try {
|
|
115
|
+
fs.writeFileSync(tmpTgz, bundle);
|
|
116
|
+
let refusedEntry = null;
|
|
117
|
+
await tar.x({
|
|
118
|
+
file: tmpTgz,
|
|
119
|
+
cwd: stagingDir,
|
|
120
|
+
gzip: true,
|
|
121
|
+
// Basename-only layout. Skipping the entry (filter false) then failing
|
|
122
|
+
// after extract avoids an unhandled throw from tar's async parser.
|
|
123
|
+
filter: (entryPath) => {
|
|
124
|
+
const name = entryPath.replace(/^\.\//, '');
|
|
125
|
+
if (hasPathTraversal(name) || path.isAbsolute(name) || name.includes('/')) {
|
|
126
|
+
refusedEntry = entryPath;
|
|
127
|
+
return false;
|
|
128
|
+
}
|
|
129
|
+
return true;
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
if (refusedEntry !== null) {
|
|
133
|
+
throw new Error(`Refused: archive entry is not a basename: ${refusedEntry}`);
|
|
134
|
+
}
|
|
135
|
+
const manifest = (0, index_js_1.readDevUploadManifest)(stagingDir);
|
|
136
|
+
if (manifest === null) {
|
|
137
|
+
throw new Error('extracted archive has no valid manifest.json');
|
|
138
|
+
}
|
|
139
|
+
if (manifest.version !== version) {
|
|
140
|
+
throw new Error(`extracted manifest version mismatch: expected ${version}, got ${manifest.version}`);
|
|
141
|
+
}
|
|
142
|
+
for (const filename of Object.values(manifest.packages)) {
|
|
143
|
+
if (hasPathTraversal(filename)) {
|
|
144
|
+
throw new Error(`manifest package filename refuses path traversal: ${filename}`);
|
|
145
|
+
}
|
|
146
|
+
if (!fs.existsSync(path.join(stagingDir, filename))) {
|
|
147
|
+
throw new Error(`extracted archive missing package tarball: ${filename}`);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Replace any previous incomplete/stale version dir.
|
|
151
|
+
fs.rmSync(finalDir, { recursive: true, force: true });
|
|
152
|
+
fs.renameSync(stagingDir, finalDir);
|
|
153
|
+
return {
|
|
154
|
+
versionDir: finalDir,
|
|
155
|
+
packageCount: Object.keys(manifest.packages).length,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
catch (err) {
|
|
159
|
+
fs.rmSync(stagingDir, { recursive: true, force: true });
|
|
160
|
+
throw err;
|
|
161
|
+
}
|
|
162
|
+
finally {
|
|
163
|
+
try {
|
|
164
|
+
fs.unlinkSync(tmpTgz);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
/* best-effort */
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
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.registerServerUploadPropagateRoute = registerServerUploadPropagateRoute;
|
|
37
|
+
/**
|
|
38
|
+
* POST /api/server-upload/propagate — deliver an already-uploaded
|
|
39
|
+
* `dev-uploads/<version>/` set from the hub onto one agent, then leave
|
|
40
|
+
* `applyServerUpdate` to the caller (CLI).
|
|
41
|
+
*
|
|
42
|
+
* Mirrors addon fan-out: pack the version dir → stage one-shot hub-http
|
|
43
|
+
* ticket → `$agent.stageDevUploads`. Does NOT promote the closure.
|
|
44
|
+
*/
|
|
45
|
+
const fs = __importStar(require("node:fs"));
|
|
46
|
+
const path = __importStar(require("node:path"));
|
|
47
|
+
const agent_addon_delivery_js_1 = require("./agent-addon-delivery.js");
|
|
48
|
+
const addon_upload_js_1 = require("./addon-upload.js");
|
|
49
|
+
const dev_uploads_bundle_js_1 = require("./dev-uploads-bundle.js");
|
|
50
|
+
const upload_auth_js_1 = require("./upload-auth.js");
|
|
51
|
+
const index_js_1 = require("../server-root/index.js");
|
|
52
|
+
function isStageResponse(value) {
|
|
53
|
+
if (value === null || typeof value !== 'object')
|
|
54
|
+
return false;
|
|
55
|
+
return typeof value.success === 'boolean';
|
|
56
|
+
}
|
|
57
|
+
function readBody(value) {
|
|
58
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
59
|
+
return { error: 'Expected JSON body { version, nodeId }' };
|
|
60
|
+
}
|
|
61
|
+
const body = value;
|
|
62
|
+
if (typeof body.version !== 'string' || body.version.length === 0) {
|
|
63
|
+
return { error: 'Missing "version" field' };
|
|
64
|
+
}
|
|
65
|
+
if (typeof body.nodeId !== 'string' || body.nodeId.length === 0) {
|
|
66
|
+
return { error: 'Missing "nodeId" field' };
|
|
67
|
+
}
|
|
68
|
+
if (body.nodeId === 'hub' || body.nodeId.includes('/')) {
|
|
69
|
+
return {
|
|
70
|
+
error: 'nodeId must be a top-level agent id (not "hub" and not a child runner id)',
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (!(0, dev_uploads_bundle_js_1.isSafeDevUploadVersion)(body.version)) {
|
|
74
|
+
return {
|
|
75
|
+
error: `Refused: version "${body.version}" is not a safe dev-channel version ` +
|
|
76
|
+
'(expected `<base>-dev.<epochSeconds>`)',
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
return { version: body.version, nodeId: body.nodeId };
|
|
80
|
+
}
|
|
81
|
+
function registerServerUploadPropagateRoute(fastify, options) {
|
|
82
|
+
const { authService, addonRegistry, logger, broker, resolveClusterBaseUrl } = options;
|
|
83
|
+
fastify.post('/api/server-upload/propagate', async (request, reply) => {
|
|
84
|
+
const auth = await (0, upload_auth_js_1.authorizeUploadRequest)({
|
|
85
|
+
authHeader: request.headers.authorization,
|
|
86
|
+
authService,
|
|
87
|
+
addonRegistry,
|
|
88
|
+
});
|
|
89
|
+
if (!auth.ok) {
|
|
90
|
+
return reply.status(auth.status).send({ error: auth.error });
|
|
91
|
+
}
|
|
92
|
+
const parsed = readBody(request.body);
|
|
93
|
+
if ('error' in parsed) {
|
|
94
|
+
return reply.status(400).send({ error: parsed.error });
|
|
95
|
+
}
|
|
96
|
+
const { version, nodeId } = parsed;
|
|
97
|
+
const dataDir = path.resolve(options.dataDir ?? process.env['CAMSTACK_DATA'] ?? 'camstack-data');
|
|
98
|
+
const versionDir = (0, index_js_1.devUploadVersionDir)((0, index_js_1.serverRootDir)(dataDir), version);
|
|
99
|
+
if (!fs.existsSync(versionDir)) {
|
|
100
|
+
return reply.status(404).send({
|
|
101
|
+
error: `No hub-side upload for ${version} at ${versionDir}. ` +
|
|
102
|
+
'Upload first with `camstack deploy-server` (POST /api/server-upload).',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
const manifest = (0, index_js_1.readDevUploadManifest)(versionDir);
|
|
106
|
+
if (manifest === null) {
|
|
107
|
+
return reply.status(400).send({
|
|
108
|
+
error: `Hub upload for ${version} has a missing or invalid manifest.json`,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
let hubBaseUrl;
|
|
112
|
+
try {
|
|
113
|
+
hubBaseUrl = await resolveClusterBaseUrl();
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
117
|
+
logger.error('server-upload propagate: no hub address agents can reach', {
|
|
118
|
+
meta: { version, nodeId, error: message },
|
|
119
|
+
});
|
|
120
|
+
return reply.status(502).send({ error: `Agent propagate failed: ${message}` });
|
|
121
|
+
}
|
|
122
|
+
let bundle;
|
|
123
|
+
let source;
|
|
124
|
+
try {
|
|
125
|
+
bundle = await (0, dev_uploads_bundle_js_1.packDevUploadVersionDir)(versionDir);
|
|
126
|
+
source = (0, addon_upload_js_1.buildHubHttpSource)(bundle, hubBaseUrl);
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
130
|
+
logger.error('server-upload propagate: pack/stage failed', {
|
|
131
|
+
meta: { version, nodeId, error: message },
|
|
132
|
+
});
|
|
133
|
+
return reply.status(500).send({ error: `Failed to stage upload pack: ${message}` });
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
const raw = await broker.call('$agent.stageDevUploads', { version, source }, { nodeID: nodeId, timeout: agent_addon_delivery_js_1.AGENT_DEPLOY_CONTROL_TIMEOUT_MS });
|
|
137
|
+
if (!isStageResponse(raw) || raw.success !== true) {
|
|
138
|
+
logger.warn('server-upload propagate: malformed agent response', {
|
|
139
|
+
meta: { version, nodeId },
|
|
140
|
+
});
|
|
141
|
+
return reply.status(502).send({ error: 'Agent returned a malformed stage response' });
|
|
142
|
+
}
|
|
143
|
+
const applied = raw.appliedSha256;
|
|
144
|
+
if (applied !== undefined && applied !== source.sha256) {
|
|
145
|
+
logger.error('server-upload propagate: applied hash mismatch', {
|
|
146
|
+
meta: { version, nodeId, expected: source.sha256, applied },
|
|
147
|
+
});
|
|
148
|
+
return reply.status(502).send({
|
|
149
|
+
error: `applied bundle hash mismatch (shipped ${source.sha256}, agent applied ${applied})`,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
logger.info('server-upload propagate: staged on agent', {
|
|
153
|
+
meta: {
|
|
154
|
+
version,
|
|
155
|
+
nodeId,
|
|
156
|
+
path: raw.path,
|
|
157
|
+
packageCount: raw.packageCount,
|
|
158
|
+
verifiedSha256: applied,
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
return reply.send({
|
|
162
|
+
success: true,
|
|
163
|
+
version,
|
|
164
|
+
nodeId,
|
|
165
|
+
path: raw.path,
|
|
166
|
+
packageCount: raw.packageCount ?? Object.keys(manifest.packages).length,
|
|
167
|
+
verifiedSha256: applied,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
172
|
+
logger.warn('server-upload propagate: agent call failed', {
|
|
173
|
+
meta: { version, nodeId, error: message },
|
|
174
|
+
});
|
|
175
|
+
return reply.status(502).send({ error: `Agent propagate failed: ${message}` });
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
@@ -545,6 +545,8 @@ function mountAllCaps(services) {
|
|
|
545
545
|
return {
|
|
546
546
|
...first,
|
|
547
547
|
describe: (0, cap_mount_helpers_js_1.concatCollection)(providers, 'describe'),
|
|
548
|
+
describeTypes: (0, cap_mount_helpers_js_1.concatCollection)(providers, 'describeTypes'),
|
|
549
|
+
listEntries: (0, cap_mount_helpers_js_1.concatCollection)(providers, 'listEntries'),
|
|
548
550
|
listJobs: (0, cap_mount_helpers_js_1.concatCollection)(providers, 'listJobs'),
|
|
549
551
|
};
|
|
550
552
|
}, remoteCapProxy),
|
|
@@ -7201,6 +7201,24 @@ function createCapRouter_pipelineAnalytics(getProvider, createRemoteProxy) {
|
|
|
7201
7201
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
7202
7202
|
return p.listRetrainStaging(methodInput);
|
|
7203
7203
|
}),
|
|
7204
|
+
listRetrainCorpusPage: trpc_middleware_js_1.adminProcedure
|
|
7205
|
+
.input(types_94.pipelineAnalyticsCapability.methods.listRetrainCorpusPage.input.loose())
|
|
7206
|
+
.output(types_94.pipelineAnalyticsCapability.methods.listRetrainCorpusPage.output)
|
|
7207
|
+
.query(async ({ input, ctx }) => {
|
|
7208
|
+
const { nodeId, ...methodInput } = input;
|
|
7209
|
+
const p = resolveProvider('pipeline-analytics', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
7210
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
7211
|
+
return p.listRetrainCorpusPage(methodInput);
|
|
7212
|
+
}),
|
|
7213
|
+
getRetrainCorpusKpi: trpc_middleware_js_1.adminProcedure
|
|
7214
|
+
.input(types_94.pipelineAnalyticsCapability.methods.getRetrainCorpusKpi.input.loose())
|
|
7215
|
+
.output(types_94.pipelineAnalyticsCapability.methods.getRetrainCorpusKpi.output)
|
|
7216
|
+
.query(async ({ input, ctx }) => {
|
|
7217
|
+
const { nodeId, ...methodInput } = input;
|
|
7218
|
+
const p = resolveProvider('pipeline-analytics', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
7219
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
7220
|
+
return p.getRetrainCorpusKpi(methodInput);
|
|
7221
|
+
}),
|
|
7204
7222
|
listRetrainFrames: trpc_middleware_js_1.adminProcedure
|
|
7205
7223
|
.input(types_94.pipelineAnalyticsCapability.methods.listRetrainFrames.input.loose())
|
|
7206
7224
|
.output(types_94.pipelineAnalyticsCapability.methods.listRetrainFrames.output)
|
|
@@ -7318,51 +7336,6 @@ function createCapRouter_pipelineAnalytics(getProvider, createRemoteProxy) {
|
|
|
7318
7336
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
7319
7337
|
return p.offerRetrainArchive(methodInput);
|
|
7320
7338
|
}),
|
|
7321
|
-
previewRetrainDataset: trpc_middleware_js_1.adminProcedure
|
|
7322
|
-
.input(types_94.pipelineAnalyticsCapability.methods.previewRetrainDataset.input.loose())
|
|
7323
|
-
.output(types_94.pipelineAnalyticsCapability.methods.previewRetrainDataset.output)
|
|
7324
|
-
.query(async ({ input, ctx }) => {
|
|
7325
|
-
const { nodeId, ...methodInput } = input;
|
|
7326
|
-
const p = resolveProvider('pipeline-analytics', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
7327
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
7328
|
-
return p.previewRetrainDataset(methodInput);
|
|
7329
|
-
}),
|
|
7330
|
-
createRetrainDatasetVersion: trpc_middleware_js_1.adminProcedure
|
|
7331
|
-
.input(types_94.pipelineAnalyticsCapability.methods.createRetrainDatasetVersion.input.loose())
|
|
7332
|
-
.output(types_94.pipelineAnalyticsCapability.methods.createRetrainDatasetVersion.output)
|
|
7333
|
-
.mutation(async ({ input, ctx }) => {
|
|
7334
|
-
const { nodeId, ...methodInput } = input;
|
|
7335
|
-
const p = resolveProvider('pipeline-analytics', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
7336
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
7337
|
-
return p.createRetrainDatasetVersion(methodInput);
|
|
7338
|
-
}),
|
|
7339
|
-
listRetrainDatasetVersions: trpc_middleware_js_1.adminProcedure
|
|
7340
|
-
.input(types_94.pipelineAnalyticsCapability.methods.listRetrainDatasetVersions.input.loose())
|
|
7341
|
-
.output(types_94.pipelineAnalyticsCapability.methods.listRetrainDatasetVersions.output)
|
|
7342
|
-
.query(async ({ input, ctx }) => {
|
|
7343
|
-
const { nodeId, ...methodInput } = input;
|
|
7344
|
-
const p = resolveProvider('pipeline-analytics', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
7345
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
7346
|
-
return p.listRetrainDatasetVersions(methodInput);
|
|
7347
|
-
}),
|
|
7348
|
-
deleteRetrainDatasetVersion: trpc_middleware_js_1.adminProcedure
|
|
7349
|
-
.input(types_94.pipelineAnalyticsCapability.methods.deleteRetrainDatasetVersion.input.loose())
|
|
7350
|
-
.output(types_94.pipelineAnalyticsCapability.methods.deleteRetrainDatasetVersion.output)
|
|
7351
|
-
.mutation(async ({ input, ctx }) => {
|
|
7352
|
-
const { nodeId, ...methodInput } = input;
|
|
7353
|
-
const p = resolveProvider('pipeline-analytics', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
7354
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
7355
|
-
return p.deleteRetrainDatasetVersion(methodInput);
|
|
7356
|
-
}),
|
|
7357
|
-
verifyRetrainDatasetVersion: trpc_middleware_js_1.adminProcedure
|
|
7358
|
-
.input(types_94.pipelineAnalyticsCapability.methods.verifyRetrainDatasetVersion.input.loose())
|
|
7359
|
-
.output(types_94.pipelineAnalyticsCapability.methods.verifyRetrainDatasetVersion.output)
|
|
7360
|
-
.query(async ({ input, ctx }) => {
|
|
7361
|
-
const { nodeId, ...methodInput } = input;
|
|
7362
|
-
const p = resolveProvider('pipeline-analytics', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
7363
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
7364
|
-
return p.verifyRetrainDatasetVersion(methodInput);
|
|
7365
|
-
}),
|
|
7366
7339
|
listRetrainAssistProfiles: trpc_middleware_js_1.adminProcedure
|
|
7367
7340
|
.input(types_94.pipelineAnalyticsCapability.methods.listRetrainAssistProfiles.input.loose())
|
|
7368
7341
|
.output(types_94.pipelineAnalyticsCapability.methods.listRetrainAssistProfiles.output)
|
|
@@ -7399,6 +7372,15 @@ function createCapRouter_pipelineAnalytics(getProvider, createRemoteProxy) {
|
|
|
7399
7372
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
7400
7373
|
return p.listRetrainCollections(methodInput);
|
|
7401
7374
|
}),
|
|
7375
|
+
resolveRetrainTrainingCorpus: trpc_middleware_js_1.adminProcedure
|
|
7376
|
+
.input(types_94.pipelineAnalyticsCapability.methods.resolveRetrainTrainingCorpus.input.loose())
|
|
7377
|
+
.output(types_94.pipelineAnalyticsCapability.methods.resolveRetrainTrainingCorpus.output)
|
|
7378
|
+
.query(async ({ input, ctx }) => {
|
|
7379
|
+
const { nodeId, ...methodInput } = input;
|
|
7380
|
+
const p = resolveProvider('pipeline-analytics', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
7381
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
7382
|
+
return p.resolveRetrainTrainingCorpus(methodInput);
|
|
7383
|
+
}),
|
|
7402
7384
|
renameRetrainCollection: trpc_middleware_js_1.adminProcedure
|
|
7403
7385
|
.input(types_94.pipelineAnalyticsCapability.methods.renameRetrainCollection.input.loose())
|
|
7404
7386
|
.output(types_94.pipelineAnalyticsCapability.methods.renameRetrainCollection.output)
|
|
@@ -11065,51 +11047,6 @@ function createCapRouter_toast(getProvider, _createRemoteProxy) {
|
|
|
11065
11047
|
}
|
|
11066
11048
|
function createCapRouter_training(getProvider, createRemoteProxy) {
|
|
11067
11049
|
return (0, trpc_middleware_js_1.trpcRouter)({
|
|
11068
|
-
putDatasetVersion: trpc_middleware_js_1.adminProcedure
|
|
11069
|
-
.input(types_128.trainingCapability.methods.putDatasetVersion.input.loose())
|
|
11070
|
-
.output(types_128.trainingCapability.methods.putDatasetVersion.output)
|
|
11071
|
-
.mutation(async ({ input, ctx }) => {
|
|
11072
|
-
const { nodeId, ...methodInput } = input;
|
|
11073
|
-
const p = resolveProvider('training', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
11074
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11075
|
-
return p.putDatasetVersion(methodInput);
|
|
11076
|
-
}),
|
|
11077
|
-
getDatasetVersion: trpc_middleware_js_1.adminProcedure
|
|
11078
|
-
.input(types_128.trainingCapability.methods.getDatasetVersion.input.loose())
|
|
11079
|
-
.output(types_128.trainingCapability.methods.getDatasetVersion.output)
|
|
11080
|
-
.query(async ({ input, ctx }) => {
|
|
11081
|
-
const { nodeId, ...methodInput } = input;
|
|
11082
|
-
const p = resolveProvider('training', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
11083
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11084
|
-
return p.getDatasetVersion(methodInput);
|
|
11085
|
-
}),
|
|
11086
|
-
listDatasetVersions: trpc_middleware_js_1.adminProcedure
|
|
11087
|
-
.input(types_128.trainingCapability.methods.listDatasetVersions.input.loose())
|
|
11088
|
-
.output(types_128.trainingCapability.methods.listDatasetVersions.output)
|
|
11089
|
-
.query(async ({ input, ctx }) => {
|
|
11090
|
-
const { nodeId, ...methodInput } = input;
|
|
11091
|
-
const p = resolveProvider('training', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
11092
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11093
|
-
return p.listDatasetVersions(methodInput);
|
|
11094
|
-
}),
|
|
11095
|
-
findDatasetVersionIdByName: trpc_middleware_js_1.adminProcedure
|
|
11096
|
-
.input(types_128.trainingCapability.methods.findDatasetVersionIdByName.input.loose())
|
|
11097
|
-
.output(types_128.trainingCapability.methods.findDatasetVersionIdByName.output)
|
|
11098
|
-
.query(async ({ input, ctx }) => {
|
|
11099
|
-
const { nodeId, ...methodInput } = input;
|
|
11100
|
-
const p = resolveProvider('training', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
11101
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11102
|
-
return p.findDatasetVersionIdByName(methodInput);
|
|
11103
|
-
}),
|
|
11104
|
-
removeDatasetVersion: trpc_middleware_js_1.adminProcedure
|
|
11105
|
-
.input(types_128.trainingCapability.methods.removeDatasetVersion.input.loose())
|
|
11106
|
-
.output(types_128.trainingCapability.methods.removeDatasetVersion.output)
|
|
11107
|
-
.mutation(async ({ input, ctx }) => {
|
|
11108
|
-
const { nodeId, ...methodInput } = input;
|
|
11109
|
-
const p = resolveProvider('training', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
11110
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11111
|
-
return p.removeDatasetVersion(methodInput);
|
|
11112
|
-
}),
|
|
11113
11050
|
listBaseModels: trpc_middleware_js_1.adminProcedure
|
|
11114
11051
|
.input(types_128.trainingCapability.methods.listBaseModels.input.loose())
|
|
11115
11052
|
.output(types_128.trainingCapability.methods.listBaseModels.output)
|
|
@@ -11137,6 +11074,15 @@ function createCapRouter_training(getProvider, createRemoteProxy) {
|
|
|
11137
11074
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11138
11075
|
return p.startJob(methodInput);
|
|
11139
11076
|
}),
|
|
11077
|
+
startJobBatch: trpc_middleware_js_1.adminProcedure
|
|
11078
|
+
.input(types_128.trainingCapability.methods.startJobBatch.input.loose())
|
|
11079
|
+
.output(types_128.trainingCapability.methods.startJobBatch.output)
|
|
11080
|
+
.mutation(async ({ input, ctx }) => {
|
|
11081
|
+
const { nodeId, ...methodInput } = input;
|
|
11082
|
+
const p = resolveProvider('training', nodeId, () => getProvider(ctx), createRemoteProxy);
|
|
11083
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11084
|
+
return p.startJobBatch(methodInput);
|
|
11085
|
+
}),
|
|
11140
11086
|
listJobs: trpc_middleware_js_1.adminProcedure
|
|
11141
11087
|
.input(types_128.trainingCapability.methods.listJobs.input.loose())
|
|
11142
11088
|
.output(types_128.trainingCapability.methods.listJobs.output)
|
|
@@ -11222,6 +11168,42 @@ function createCapRouter_trainingProvider(getProvider, createRemoteProxy) {
|
|
|
11222
11168
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11223
11169
|
return p.describe(methodInput);
|
|
11224
11170
|
}),
|
|
11171
|
+
describeTypes: trpc_middleware_js_1.adminProcedure
|
|
11172
|
+
.input(types_129.trainingProviderCapability.methods.describeTypes.input.loose())
|
|
11173
|
+
.output(types_129.trainingProviderCapability.methods.describeTypes.output)
|
|
11174
|
+
.query(async ({ input, ctx }) => {
|
|
11175
|
+
const { nodeId, addonId, ...methodInput } = input;
|
|
11176
|
+
const p = resolveProvider('training-provider', nodeId, () => getProvider(ctx, addonId), createRemoteProxy);
|
|
11177
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11178
|
+
return p.describeTypes(methodInput);
|
|
11179
|
+
}),
|
|
11180
|
+
listEntries: trpc_middleware_js_1.adminProcedure
|
|
11181
|
+
.input(types_129.trainingProviderCapability.methods.listEntries.input.loose())
|
|
11182
|
+
.output(types_129.trainingProviderCapability.methods.listEntries.output)
|
|
11183
|
+
.query(async ({ input, ctx }) => {
|
|
11184
|
+
const { nodeId, addonId, ...methodInput } = input;
|
|
11185
|
+
const p = resolveProvider('training-provider', nodeId, () => getProvider(ctx, addonId), createRemoteProxy);
|
|
11186
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11187
|
+
return p.listEntries(methodInput);
|
|
11188
|
+
}),
|
|
11189
|
+
createEntry: trpc_middleware_js_1.adminProcedure
|
|
11190
|
+
.input(types_129.trainingProviderCapability.methods.createEntry.input.loose())
|
|
11191
|
+
.output(types_129.trainingProviderCapability.methods.createEntry.output)
|
|
11192
|
+
.mutation(async ({ input, ctx }) => {
|
|
11193
|
+
const { nodeId, addonId, ...methodInput } = input;
|
|
11194
|
+
const p = resolveProvider('training-provider', nodeId, () => getProvider(ctx, addonId), createRemoteProxy);
|
|
11195
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11196
|
+
return p.createEntry(methodInput);
|
|
11197
|
+
}),
|
|
11198
|
+
deleteEntry: trpc_middleware_js_1.adminProcedure
|
|
11199
|
+
.input(types_129.trainingProviderCapability.methods.deleteEntry.input.loose())
|
|
11200
|
+
.output(types_129.trainingProviderCapability.methods.deleteEntry.output)
|
|
11201
|
+
.mutation(async ({ input, ctx }) => {
|
|
11202
|
+
const { nodeId, addonId, ...methodInput } = input;
|
|
11203
|
+
const p = resolveProvider('training-provider', nodeId, () => getProvider(ctx, addonId), createRemoteProxy);
|
|
11204
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-argument
|
|
11205
|
+
return p.deleteEntry(methodInput);
|
|
11206
|
+
}),
|
|
11225
11207
|
validateCredentials: trpc_middleware_js_1.adminProcedure
|
|
11226
11208
|
.input(types_129.trainingProviderCapability.methods.validateCredentials.input.loose())
|
|
11227
11209
|
.output(types_129.trainingProviderCapability.methods.validateCredentials.output)
|
package/dist/main.js
CHANGED
|
@@ -71,6 +71,7 @@ const hub_cluster_url_1 = require("./api/hub-cluster-url");
|
|
|
71
71
|
const model_distributor_js_1 = require("./api/model-distributor.js");
|
|
72
72
|
const oauth2_routes_js_1 = require("./api/oauth2/oauth2-routes.js");
|
|
73
73
|
const server_upload_1 = require("./api/server-upload");
|
|
74
|
+
const server_upload_propagate_1 = require("./api/server-upload-propagate");
|
|
74
75
|
const sse_no_compression_js_1 = require("./api/sse-no-compression.js");
|
|
75
76
|
const frame_policy_1 = require("./api/static/frame-policy");
|
|
76
77
|
const precompressed_asset_js_1 = require("./api/static/precompressed-asset.js");
|
|
@@ -453,6 +454,16 @@ async function bootstrap() {
|
|
|
453
454
|
logger: app.get(logging_service_1.LoggingService).createLogger('server-upload'),
|
|
454
455
|
});
|
|
455
456
|
console.log('[bootstrap] Server upload route registered at POST /api/server-upload');
|
|
457
|
+
(0, server_upload_propagate_1.registerServerUploadPropagateRoute)(fastify, {
|
|
458
|
+
authService: uploadAuthService,
|
|
459
|
+
addonRegistry: uploadAddonRegistry,
|
|
460
|
+
logger: app.get(logging_service_1.LoggingService).createLogger('server-upload-propagate'),
|
|
461
|
+
broker: uploadMoleculer.broker,
|
|
462
|
+
resolveClusterBaseUrl: (0, hub_cluster_url_1.clusterBaseUrlResolver)(() => uploadAddonRegistry
|
|
463
|
+
.getCapabilityRegistry()
|
|
464
|
+
.getSingleton('local-network')),
|
|
465
|
+
});
|
|
466
|
+
console.log('[bootstrap] Server upload propagate route registered at POST /api/server-upload/propagate');
|
|
456
467
|
// Companion endpoint: /api/auth/whoami — validates JWT or cst_*
|
|
457
468
|
// scoped tokens, returns the resolved identity + scope summary.
|
|
458
469
|
// Mirrors the addon-upload auth chain so the CLI can ping for
|
|
@@ -1474,7 +1474,7 @@ var require_dist = __commonJS({
|
|
|
1474
1474
|
if (isDevChannelVersion(target)) {
|
|
1475
1475
|
const uploadsDir = devUploadVersionDir(this.rootDir(), target);
|
|
1476
1476
|
if (!fs6.existsSync(uploadsDir)) {
|
|
1477
|
-
return this.refuseUpdate("dev-uploads-missing", target, `Refused: dev-channel version ${target} has no uploaded tarballs on this node (${uploadsDir} is missing).
|
|
1477
|
+
return this.refuseUpdate("dev-uploads-missing", target, `Refused: dev-channel version ${target} has no uploaded tarballs on this node (${uploadsDir} is missing). On the hub: \`camstack deploy-server\`. On an agent: \`camstack deploy-server -n <nodeId>\` (or \`--all\`) so the hub can POST /api/server-upload/propagate first.`);
|
|
1478
1478
|
}
|
|
1479
1479
|
}
|
|
1480
1480
|
this.inFlight = "staging";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/server",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.502",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"private": false,
|
|
6
6
|
"files": [
|
|
@@ -37,18 +37,18 @@
|
|
|
37
37
|
]
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@camstack/addon-admin-ui": "1.2.
|
|
41
|
-
"@camstack/addon-agent-ui": "1.2.
|
|
40
|
+
"@camstack/addon-admin-ui": "1.2.370",
|
|
41
|
+
"@camstack/addon-agent-ui": "1.2.203",
|
|
42
42
|
"@camstack/addon-auth": "1.2.136",
|
|
43
43
|
"@camstack/addon-decoder-nodeav": "1.2.122",
|
|
44
44
|
"@camstack/addon-notifiers": "1.2.129",
|
|
45
45
|
"@camstack/addon-pipeline": "1.2.351",
|
|
46
|
-
"@camstack/addon-pipeline-orchestrator": "1.2.
|
|
47
|
-
"@camstack/addon-post-analysis": "1.2.
|
|
46
|
+
"@camstack/addon-pipeline-orchestrator": "1.2.305",
|
|
47
|
+
"@camstack/addon-post-analysis": "1.2.352",
|
|
48
48
|
"@camstack/sdk": "1.2.129",
|
|
49
|
-
"@camstack/system": "1.2.
|
|
50
|
-
"@camstack/types": "1.2.
|
|
51
|
-
"@camstack/ui-library": "1.2.
|
|
49
|
+
"@camstack/system": "1.2.395",
|
|
50
|
+
"@camstack/types": "1.2.340",
|
|
51
|
+
"@camstack/ui-library": "1.2.260",
|
|
52
52
|
"@fastify/compress": "^9.0.0",
|
|
53
53
|
"@fastify/cookie": "^11.0.2",
|
|
54
54
|
"@fastify/cors": "^11.2.0",
|