borgmcp-server 0.1.8 → 0.1.9
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/README.md +57 -43
- package/SECURITY.md +12 -1
- package/dist/bootstrap.d.ts +8 -1
- package/dist/bootstrap.js +39 -6
- package/dist/bootstrap.js.map +1 -1
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +176 -1
- package/dist/cli.js.map +1 -1
- package/dist/credentials.d.ts +1 -0
- package/dist/credentials.js +7 -0
- package/dist/credentials.js.map +1 -1
- package/dist/debug-log.d.ts +1 -1
- package/dist/debug-log.js +1 -1
- package/dist/debug-log.js.map +1 -1
- package/dist/https-server.d.ts +3 -0
- package/dist/https-server.js +25 -7
- package/dist/https-server.js.map +1 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -1
- package/dist/managed-service.d.ts +20 -0
- package/dist/managed-service.js +80 -0
- package/dist/managed-service.js.map +1 -0
- package/dist/portable-credential-store.d.ts +16 -0
- package/dist/portable-credential-store.js +305 -0
- package/dist/portable-credential-store.js.map +1 -0
- package/dist/registry-artifact.d.ts +11 -0
- package/dist/registry-artifact.js +99 -0
- package/dist/registry-artifact.js.map +1 -0
- package/dist/runtime-identity.d.ts +19 -0
- package/dist/runtime-identity.js +61 -0
- package/dist/runtime-identity.js.map +1 -0
- package/dist/runtime-lifecycle.d.ts +56 -0
- package/dist/runtime-lifecycle.js +486 -0
- package/dist/runtime-lifecycle.js.map +1 -0
- package/dist/runtime-operator.d.ts +24 -0
- package/dist/runtime-operator.js +95 -0
- package/dist/runtime-operator.js.map +1 -0
- package/dist/service.d.ts +53 -5
- package/dist/service.js +326 -15
- package/dist/service.js.map +1 -1
- package/dist/store.d.ts +1 -0
- package/dist/store.js +8 -0
- package/dist/store.js.map +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
- package/src/bootstrap.ts +46 -5
- package/src/cli.ts +171 -1
- package/src/credentials.ts +7 -0
- package/src/debug-log.ts +2 -1
- package/src/https-server.ts +27 -7
- package/src/index.ts +46 -1
- package/src/main.ts +1 -0
- package/src/managed-service.ts +107 -0
- package/src/portable-credential-store.ts +306 -0
- package/src/registry-artifact.ts +111 -0
- package/src/runtime-identity.ts +82 -0
- package/src/runtime-lifecycle.ts +567 -0
- package/src/runtime-operator.ts +124 -0
- package/src/service.ts +401 -20
- package/src/store.ts +10 -0
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { spawn } from "node:child_process";
|
|
3
|
+
import { chmod, lstat, mkdir, mkdtemp, readFile, readdir, realpath, rename, rm, symlink, writeFile, } from "node:fs/promises";
|
|
4
|
+
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
|
+
const exactVersion = /^[0-9]+\.[0-9]+\.[0-9]+(?:-[0-9A-Za-z.-]+)?$/u;
|
|
6
|
+
const sha512Integrity = /^sha512-[A-Za-z0-9+/]{86}==$/u;
|
|
7
|
+
const sourceSha = /^[0-9a-f]{40}$/u;
|
|
8
|
+
export class RuntimeActivationError extends Error {
|
|
9
|
+
recovery;
|
|
10
|
+
constructor(recovery) {
|
|
11
|
+
super("Runtime activation did not complete.");
|
|
12
|
+
this.name = "RuntimeActivationError";
|
|
13
|
+
this.recovery = recovery;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export function createRuntimeLifecycle(dependencies) {
|
|
17
|
+
return {
|
|
18
|
+
stage: (input) => stageRuntimeArtifact(input, dependencies.unpack),
|
|
19
|
+
prepare: async (input) => {
|
|
20
|
+
const root = await prepareRuntimeRoot(input.runtimeRoot);
|
|
21
|
+
const artifact = await revalidateArtifact(root, input.artifact);
|
|
22
|
+
await switchCurrent(root, artifact.artifactDirectory);
|
|
23
|
+
return artifact;
|
|
24
|
+
},
|
|
25
|
+
activate: (input) => activateRuntimeArtifact(input, dependencies),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export async function inspectActiveRuntimeArtifact(runtimeRoot) {
|
|
29
|
+
if (!isAbsolute(runtimeRoot))
|
|
30
|
+
throw new Error("Runtime root must be absolute.");
|
|
31
|
+
let root;
|
|
32
|
+
try {
|
|
33
|
+
root = await realpath(runtimeRoot);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
if (error.code === "ENOENT")
|
|
37
|
+
return null;
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
const target = await readCurrentTarget(join(root, "current"), root);
|
|
41
|
+
return target === null ? null : readArtifactDescriptor(target);
|
|
42
|
+
}
|
|
43
|
+
async function stageRuntimeArtifact(input, unpack) {
|
|
44
|
+
validateStageInput(input);
|
|
45
|
+
const root = await prepareRuntimeRoot(input.runtimeRoot);
|
|
46
|
+
const archive = await readRegularFile(input.tarballPath, 2 * 1024 * 1024);
|
|
47
|
+
const actualIntegrity = `sha512-${createHash("sha512").update(archive).digest("base64")}`;
|
|
48
|
+
if (actualIntegrity !== input.expectedIntegrity)
|
|
49
|
+
throw new Error("Runtime artifact integrity does not match.");
|
|
50
|
+
const artifactId = createHash("sha256").update(archive).digest("hex");
|
|
51
|
+
const artifactsDirectory = join(root, "artifacts");
|
|
52
|
+
await mkdir(artifactsDirectory, { recursive: true, mode: 0o700 });
|
|
53
|
+
const target = join(artifactsDirectory, artifactId);
|
|
54
|
+
const existing = await existingArtifact(target, input);
|
|
55
|
+
if (existing !== null)
|
|
56
|
+
return existing;
|
|
57
|
+
const staging = await mkdtemp(join(root, ".staging-"));
|
|
58
|
+
try {
|
|
59
|
+
await withDeadline(input.timeoutMs, (signal) => unpack(archive, staging, signal));
|
|
60
|
+
const packageDirectory = await validateUnpackedPackage(staging, input.expectedVersion);
|
|
61
|
+
await makeTreeReadOnly(packageDirectory);
|
|
62
|
+
const treeSha256 = await hashArtifactTree(packageDirectory);
|
|
63
|
+
const manifest = Object.freeze({
|
|
64
|
+
version: input.expectedVersion,
|
|
65
|
+
integrity: input.expectedIntegrity,
|
|
66
|
+
source_sha: input.sourceSha ?? null,
|
|
67
|
+
tree_sha256: treeSha256,
|
|
68
|
+
});
|
|
69
|
+
await writeFile(join(staging, "artifact.json"), `${JSON.stringify(manifest)}\n`, {
|
|
70
|
+
flag: "wx",
|
|
71
|
+
mode: 0o600,
|
|
72
|
+
});
|
|
73
|
+
await chmod(join(staging, "artifact.json"), 0o400);
|
|
74
|
+
await rename(staging, target);
|
|
75
|
+
await chmod(target, 0o500);
|
|
76
|
+
return Object.freeze({
|
|
77
|
+
artifactDirectory: target,
|
|
78
|
+
packageDirectory: join(target, basename(packageDirectory)),
|
|
79
|
+
version: input.expectedVersion,
|
|
80
|
+
integrity: input.expectedIntegrity,
|
|
81
|
+
sourceSha: input.sourceSha ?? null,
|
|
82
|
+
treeSha256,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
await removeOwnedStaging(staging);
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
async function activateRuntimeArtifact(input, dependencies) {
|
|
91
|
+
if (!Number.isSafeInteger(input.timeoutMs) || input.timeoutMs < 100 || input.timeoutMs > 120_000) {
|
|
92
|
+
throw new Error("Runtime lifecycle timeout is invalid.");
|
|
93
|
+
}
|
|
94
|
+
const root = await prepareRuntimeRoot(input.runtimeRoot);
|
|
95
|
+
const artifact = await revalidateArtifact(root, input.artifact);
|
|
96
|
+
const current = join(root, "current");
|
|
97
|
+
const previousTarget = await readCurrentTarget(current, root);
|
|
98
|
+
await switchCurrent(root, artifact.artifactDirectory);
|
|
99
|
+
try {
|
|
100
|
+
await withDeadline(input.timeoutMs, dependencies.restart);
|
|
101
|
+
const identity = await withDeadline(input.timeoutMs, dependencies.probe);
|
|
102
|
+
assertIdentity(identity, artifact);
|
|
103
|
+
return identity;
|
|
104
|
+
}
|
|
105
|
+
catch (activationError) {
|
|
106
|
+
if (previousTarget === null) {
|
|
107
|
+
await rm(current, { force: true });
|
|
108
|
+
try {
|
|
109
|
+
await withDeadline(input.timeoutMs, dependencies.stop);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
throw new RuntimeActivationError("failed");
|
|
113
|
+
}
|
|
114
|
+
throw new RuntimeActivationError("stopped");
|
|
115
|
+
}
|
|
116
|
+
await switchCurrent(root, previousTarget);
|
|
117
|
+
try {
|
|
118
|
+
await withDeadline(input.timeoutMs, dependencies.restart);
|
|
119
|
+
const restored = await withDeadline(input.timeoutMs, dependencies.probe);
|
|
120
|
+
const previous = await readArtifactDescriptor(previousTarget);
|
|
121
|
+
assertIdentity(restored, previous);
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
throw new RuntimeActivationError("failed");
|
|
125
|
+
}
|
|
126
|
+
throw new RuntimeActivationError("restored");
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function validateStageInput(input) {
|
|
130
|
+
if (!exactVersion.test(input.expectedVersion))
|
|
131
|
+
throw new Error("Runtime artifact version is invalid.");
|
|
132
|
+
if (!sha512Integrity.test(input.expectedIntegrity))
|
|
133
|
+
throw new Error("Runtime artifact integrity is invalid.");
|
|
134
|
+
if (input.sourceSha !== undefined && !sourceSha.test(input.sourceSha)) {
|
|
135
|
+
throw new Error("Runtime artifact source identity is invalid.");
|
|
136
|
+
}
|
|
137
|
+
if (!isAbsolute(input.runtimeRoot) || !isAbsolute(input.tarballPath)) {
|
|
138
|
+
throw new Error("Runtime lifecycle paths must be absolute.");
|
|
139
|
+
}
|
|
140
|
+
if (!Number.isSafeInteger(input.timeoutMs) || input.timeoutMs < 100 || input.timeoutMs > 300_000) {
|
|
141
|
+
throw new Error("Runtime staging timeout is invalid.");
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
export function createUnixNpmArtifactUnpacker(options = {}) {
|
|
145
|
+
const tarExecutable = options.tarExecutable ?? "tar";
|
|
146
|
+
const npmExecutable = options.npmExecutable ?? "npm";
|
|
147
|
+
const run = options.run ?? runRuntimeCommand;
|
|
148
|
+
return async (archive, stagingDirectory, signal) => {
|
|
149
|
+
const listing = await run(tarExecutable, ["-tzf", "-"], { signal, stdin: archive });
|
|
150
|
+
const entries = listing.stdout.trim().split("\n").filter(Boolean);
|
|
151
|
+
if (entries.length === 0 || entries.length > 544 || entries.some((entry) => {
|
|
152
|
+
const segments = entry.split("/");
|
|
153
|
+
return !entry.startsWith("package/") || entry.startsWith("/") || entry.includes("\\") ||
|
|
154
|
+
segments.includes("..") || segments.includes(".") || entry.length > 512;
|
|
155
|
+
})) {
|
|
156
|
+
throw new Error("Runtime artifact archive entries are invalid.");
|
|
157
|
+
}
|
|
158
|
+
await run(tarExecutable, ["-xzf", "-", "-C", stagingDirectory], {
|
|
159
|
+
signal,
|
|
160
|
+
stdin: archive,
|
|
161
|
+
});
|
|
162
|
+
await hashArtifactTree(join(stagingDirectory, "package"));
|
|
163
|
+
await run(npmExecutable, [
|
|
164
|
+
"ci",
|
|
165
|
+
"--omit=dev",
|
|
166
|
+
"--ignore-scripts",
|
|
167
|
+
"--no-audit",
|
|
168
|
+
"--no-fund",
|
|
169
|
+
], { cwd: join(stagingDirectory, "package"), signal });
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
async function runRuntimeCommand(executable, args, options) {
|
|
173
|
+
return new Promise((resolve, reject) => {
|
|
174
|
+
const child = spawn(executable, args, {
|
|
175
|
+
...(options.cwd === undefined ? {} : { cwd: options.cwd }),
|
|
176
|
+
detached: process.platform !== "win32",
|
|
177
|
+
shell: false,
|
|
178
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
179
|
+
});
|
|
180
|
+
const stdout = [];
|
|
181
|
+
const stderr = [];
|
|
182
|
+
let bytes = 0;
|
|
183
|
+
let settled = false;
|
|
184
|
+
let killTimer;
|
|
185
|
+
const kill = (signal) => {
|
|
186
|
+
if (child.pid === undefined)
|
|
187
|
+
return;
|
|
188
|
+
try {
|
|
189
|
+
if (process.platform === "win32")
|
|
190
|
+
child.kill(signal);
|
|
191
|
+
else
|
|
192
|
+
process.kill(-child.pid, signal);
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
if (error.code !== "ESRCH")
|
|
196
|
+
child.kill(signal);
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
const abort = () => {
|
|
200
|
+
kill("SIGTERM");
|
|
201
|
+
killTimer = setTimeout(() => kill("SIGKILL"), 500);
|
|
202
|
+
killTimer.unref();
|
|
203
|
+
};
|
|
204
|
+
if (options.signal.aborted)
|
|
205
|
+
abort();
|
|
206
|
+
else
|
|
207
|
+
options.signal.addEventListener("abort", abort, { once: true });
|
|
208
|
+
const cleanup = () => {
|
|
209
|
+
options.signal.removeEventListener("abort", abort);
|
|
210
|
+
if (killTimer !== undefined)
|
|
211
|
+
clearTimeout(killTimer);
|
|
212
|
+
};
|
|
213
|
+
const capture = (target, chunk) => {
|
|
214
|
+
bytes += chunk.length;
|
|
215
|
+
if (bytes > 1024 * 1024) {
|
|
216
|
+
kill("SIGKILL");
|
|
217
|
+
if (!settled) {
|
|
218
|
+
settled = true;
|
|
219
|
+
cleanup();
|
|
220
|
+
reject(new Error("Runtime artifact command output exceeded its bound."));
|
|
221
|
+
}
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
target.push(chunk);
|
|
225
|
+
};
|
|
226
|
+
child.stdout.on("data", (chunk) => capture(stdout, chunk));
|
|
227
|
+
child.stderr.on("data", (chunk) => capture(stderr, chunk));
|
|
228
|
+
child.stdin.end(options.stdin);
|
|
229
|
+
child.once("error", (error) => {
|
|
230
|
+
if (!settled) {
|
|
231
|
+
settled = true;
|
|
232
|
+
cleanup();
|
|
233
|
+
reject(error);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
child.once("close", (code, signal) => {
|
|
237
|
+
if (settled)
|
|
238
|
+
return;
|
|
239
|
+
settled = true;
|
|
240
|
+
cleanup();
|
|
241
|
+
if (code !== 0) {
|
|
242
|
+
reject(new Error(`Runtime artifact command failed (${code ?? signal ?? "unknown"}).`));
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
resolve({
|
|
246
|
+
stdout: Buffer.concat(stdout).toString("utf8"),
|
|
247
|
+
stderr: Buffer.concat(stderr).toString("utf8"),
|
|
248
|
+
});
|
|
249
|
+
});
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
async function prepareRuntimeRoot(value) {
|
|
253
|
+
if (!isAbsolute(value))
|
|
254
|
+
throw new Error("Runtime root must be absolute.");
|
|
255
|
+
try {
|
|
256
|
+
const existing = await lstat(value);
|
|
257
|
+
if (!existing.isDirectory() || existing.isSymbolicLink()) {
|
|
258
|
+
throw new Error("Runtime root must be a private directory.");
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
catch (error) {
|
|
262
|
+
if (error.code !== "ENOENT")
|
|
263
|
+
throw error;
|
|
264
|
+
await mkdir(value, { recursive: true, mode: 0o700 });
|
|
265
|
+
}
|
|
266
|
+
const root = await realpath(value);
|
|
267
|
+
const metadata = await lstat(root);
|
|
268
|
+
if (!metadata.isDirectory() || metadata.isSymbolicLink() || (metadata.mode & 0o077) !== 0) {
|
|
269
|
+
throw new Error("Runtime root must be a private directory.");
|
|
270
|
+
}
|
|
271
|
+
return root;
|
|
272
|
+
}
|
|
273
|
+
async function readRegularFile(path, limit) {
|
|
274
|
+
const metadata = await lstat(path);
|
|
275
|
+
if (!metadata.isFile() || metadata.isSymbolicLink() || metadata.size > limit) {
|
|
276
|
+
throw new Error("Runtime artifact must be a bounded regular file.");
|
|
277
|
+
}
|
|
278
|
+
return readFile(path);
|
|
279
|
+
}
|
|
280
|
+
async function validateUnpackedPackage(staging, version) {
|
|
281
|
+
const packageDirectory = join(staging, "package");
|
|
282
|
+
const canonical = await realpath(packageDirectory);
|
|
283
|
+
if (dirname(canonical) !== staging)
|
|
284
|
+
throw new Error("Runtime artifact package escaped staging.");
|
|
285
|
+
const manifest = JSON.parse((await readRegularFile(join(canonical, "package.json"), 64 * 1024))
|
|
286
|
+
.toString("utf8"));
|
|
287
|
+
if (manifest.name !== "borgmcp-server" || manifest.version !== version ||
|
|
288
|
+
JSON.stringify(manifest.bin) !== JSON.stringify({ "borg-mcp-server": "./dist/main.js" })) {
|
|
289
|
+
throw new Error("Runtime artifact package identity does not match.");
|
|
290
|
+
}
|
|
291
|
+
const entrypoint = await realpath(join(canonical, "dist", "main.js"));
|
|
292
|
+
if (!inside(canonical, entrypoint) || !(await lstat(entrypoint)).isFile()) {
|
|
293
|
+
throw new Error("Runtime artifact entrypoint is invalid.");
|
|
294
|
+
}
|
|
295
|
+
return canonical;
|
|
296
|
+
}
|
|
297
|
+
async function makeTreeReadOnly(directory) {
|
|
298
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
299
|
+
for (const entry of entries) {
|
|
300
|
+
const path = join(directory, entry.name);
|
|
301
|
+
const metadata = await lstat(path);
|
|
302
|
+
if (metadata.isSymbolicLink())
|
|
303
|
+
throw new Error("Runtime artifact contains a symbolic link.");
|
|
304
|
+
if (metadata.isDirectory()) {
|
|
305
|
+
await makeTreeReadOnly(path);
|
|
306
|
+
await chmod(path, 0o500);
|
|
307
|
+
}
|
|
308
|
+
else if (metadata.isFile())
|
|
309
|
+
await chmod(path, 0o400);
|
|
310
|
+
else
|
|
311
|
+
throw new Error("Runtime artifact contains an unsupported file.");
|
|
312
|
+
}
|
|
313
|
+
await chmod(directory, 0o500);
|
|
314
|
+
}
|
|
315
|
+
async function existingArtifact(target, input) {
|
|
316
|
+
try {
|
|
317
|
+
const artifact = await readArtifactDescriptor(target);
|
|
318
|
+
if (artifact.version !== input.expectedVersion || artifact.integrity !== input.expectedIntegrity ||
|
|
319
|
+
artifact.sourceSha !== (input.sourceSha ?? null)) {
|
|
320
|
+
throw new Error("Existing runtime artifact descriptor does not match.");
|
|
321
|
+
}
|
|
322
|
+
await validateUnpackedPackage(target, input.expectedVersion);
|
|
323
|
+
return artifact;
|
|
324
|
+
}
|
|
325
|
+
catch (error) {
|
|
326
|
+
if (error.code === "ENOENT")
|
|
327
|
+
return null;
|
|
328
|
+
throw error;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
async function readArtifactDescriptor(directory) {
|
|
332
|
+
const canonical = await realpath(directory);
|
|
333
|
+
const value = JSON.parse((await readRegularFile(join(canonical, "artifact.json"), 4 * 1024))
|
|
334
|
+
.toString("utf8"));
|
|
335
|
+
if (typeof value.version !== "string" || !exactVersion.test(value.version) ||
|
|
336
|
+
typeof value.integrity !== "string" || !sha512Integrity.test(value.integrity) ||
|
|
337
|
+
(value.source_sha !== null &&
|
|
338
|
+
(typeof value.source_sha !== "string" || !sourceSha.test(value.source_sha))) ||
|
|
339
|
+
typeof value.tree_sha256 !== "string" || !/^[0-9a-f]{64}$/u.test(value.tree_sha256)) {
|
|
340
|
+
throw new Error("Runtime artifact descriptor is invalid.");
|
|
341
|
+
}
|
|
342
|
+
const packageDirectory = join(canonical, "package");
|
|
343
|
+
if (await hashArtifactTree(packageDirectory) !== value.tree_sha256) {
|
|
344
|
+
throw new Error("Runtime artifact content changed.");
|
|
345
|
+
}
|
|
346
|
+
return Object.freeze({
|
|
347
|
+
artifactDirectory: canonical,
|
|
348
|
+
packageDirectory,
|
|
349
|
+
version: value.version,
|
|
350
|
+
integrity: value.integrity,
|
|
351
|
+
sourceSha: value.source_sha,
|
|
352
|
+
treeSha256: value.tree_sha256,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
async function hashArtifactTree(root) {
|
|
356
|
+
const hash = createHash("sha256");
|
|
357
|
+
let entries = 0;
|
|
358
|
+
let bytes = 0;
|
|
359
|
+
const walk = async (directory) => {
|
|
360
|
+
const children = await readdir(directory, { withFileTypes: true });
|
|
361
|
+
children.sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);
|
|
362
|
+
for (const child of children) {
|
|
363
|
+
entries += 1;
|
|
364
|
+
if (entries > 50_000 || child.name.includes("\0")) {
|
|
365
|
+
throw new Error("Runtime artifact tree exceeded its bound.");
|
|
366
|
+
}
|
|
367
|
+
const path = join(directory, child.name);
|
|
368
|
+
const metadata = await lstat(path);
|
|
369
|
+
const name = relative(root, path);
|
|
370
|
+
if (metadata.isSymbolicLink())
|
|
371
|
+
throw new Error("Runtime artifact contains a symbolic link.");
|
|
372
|
+
if (metadata.isDirectory()) {
|
|
373
|
+
hash.update(`D\0${name}\0${metadata.mode & 0o777}\0`);
|
|
374
|
+
await walk(path);
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
377
|
+
if (!metadata.isFile() || metadata.size > 32 * 1024 * 1024) {
|
|
378
|
+
throw new Error("Runtime artifact contains an unsupported file.");
|
|
379
|
+
}
|
|
380
|
+
bytes += metadata.size;
|
|
381
|
+
if (bytes > 256 * 1024 * 1024)
|
|
382
|
+
throw new Error("Runtime artifact tree exceeded its bound.");
|
|
383
|
+
const content = await readFile(path);
|
|
384
|
+
hash.update(`F\0${name}\0${metadata.mode & 0o777}\0${content.length}\0`);
|
|
385
|
+
hash.update(content);
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
await walk(root);
|
|
389
|
+
return hash.digest("hex");
|
|
390
|
+
}
|
|
391
|
+
async function removeOwnedStaging(path) {
|
|
392
|
+
try {
|
|
393
|
+
const metadata = await lstat(path);
|
|
394
|
+
if (metadata.isSymbolicLink()) {
|
|
395
|
+
await rm(path, { force: true });
|
|
396
|
+
return;
|
|
397
|
+
}
|
|
398
|
+
if (metadata.isDirectory()) {
|
|
399
|
+
await chmod(path, 0o700);
|
|
400
|
+
for (const entry of await readdir(path))
|
|
401
|
+
await removeOwnedStaging(join(path, entry));
|
|
402
|
+
}
|
|
403
|
+
else if (metadata.isFile())
|
|
404
|
+
await chmod(path, 0o600);
|
|
405
|
+
await rm(path, { recursive: metadata.isDirectory(), force: true });
|
|
406
|
+
}
|
|
407
|
+
catch (error) {
|
|
408
|
+
if (error.code !== "ENOENT")
|
|
409
|
+
throw error;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
async function revalidateArtifact(root, artifact) {
|
|
413
|
+
const canonical = await realpath(artifact.artifactDirectory);
|
|
414
|
+
if (!inside(join(root, "artifacts"), canonical))
|
|
415
|
+
throw new Error("Runtime artifact is outside the runtime root.");
|
|
416
|
+
const actual = await readArtifactDescriptor(canonical);
|
|
417
|
+
if (actual.version !== artifact.version || actual.integrity !== artifact.integrity ||
|
|
418
|
+
actual.sourceSha !== artifact.sourceSha || actual.treeSha256 !== artifact.treeSha256) {
|
|
419
|
+
throw new Error("Runtime artifact descriptor changed.");
|
|
420
|
+
}
|
|
421
|
+
await validateUnpackedPackage(canonical, artifact.version);
|
|
422
|
+
return actual;
|
|
423
|
+
}
|
|
424
|
+
async function switchCurrent(root, target) {
|
|
425
|
+
if (!inside(join(root, "artifacts"), target))
|
|
426
|
+
throw new Error("Runtime activation target is invalid.");
|
|
427
|
+
const temporary = join(root, `.current-${process.pid}-${Date.now()}`);
|
|
428
|
+
await symlink(relative(root, target), temporary, "dir");
|
|
429
|
+
await rename(temporary, join(root, "current"));
|
|
430
|
+
}
|
|
431
|
+
async function readCurrentTarget(current, root) {
|
|
432
|
+
try {
|
|
433
|
+
const target = await realpath(current);
|
|
434
|
+
if (!inside(join(root, "artifacts"), target))
|
|
435
|
+
throw new Error("Active runtime target is invalid.");
|
|
436
|
+
return target;
|
|
437
|
+
}
|
|
438
|
+
catch (error) {
|
|
439
|
+
if (error.code === "ENOENT")
|
|
440
|
+
return null;
|
|
441
|
+
throw error;
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
function assertIdentity(identity, artifact) {
|
|
445
|
+
if (identity.package_version !== artifact.version ||
|
|
446
|
+
identity.artifact_integrity !== artifact.integrity ||
|
|
447
|
+
identity.source_sha !== artifact.sourceSha) {
|
|
448
|
+
throw new Error("Running server identity does not match the active artifact.");
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
async function withDeadline(timeoutMs, operation) {
|
|
452
|
+
const controller = new AbortController();
|
|
453
|
+
let timer;
|
|
454
|
+
let timedOut = false;
|
|
455
|
+
const pending = operation(controller.signal);
|
|
456
|
+
try {
|
|
457
|
+
return await Promise.race([
|
|
458
|
+
pending,
|
|
459
|
+
new Promise((_resolve, reject) => {
|
|
460
|
+
timer = setTimeout(() => {
|
|
461
|
+
timedOut = true;
|
|
462
|
+
reject(new Error("Runtime lifecycle operation timed out."));
|
|
463
|
+
controller.abort();
|
|
464
|
+
}, timeoutMs);
|
|
465
|
+
}),
|
|
466
|
+
]);
|
|
467
|
+
}
|
|
468
|
+
catch (error) {
|
|
469
|
+
if (timedOut) {
|
|
470
|
+
await Promise.race([
|
|
471
|
+
pending.then(() => undefined, () => undefined),
|
|
472
|
+
new Promise((resolve) => setTimeout(resolve, 1_000)),
|
|
473
|
+
]);
|
|
474
|
+
}
|
|
475
|
+
throw error;
|
|
476
|
+
}
|
|
477
|
+
finally {
|
|
478
|
+
if (timer !== undefined)
|
|
479
|
+
clearTimeout(timer);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
function inside(root, candidate) {
|
|
483
|
+
const path = relative(resolve(root), resolve(candidate));
|
|
484
|
+
return path !== "" && path !== ".." && !path.startsWith(`..${sep}`) && !isAbsolute(path);
|
|
485
|
+
}
|
|
486
|
+
//# sourceMappingURL=runtime-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-lifecycle.js","sourceRoot":"","sources":["../src/runtime-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { RegistryArtifactSource } from "./registry-artifact.js";
|
|
2
|
+
import { type RuntimeLifecycle, type RuntimeRecoveryState, type VerifiedRuntimeArtifact } from "./runtime-lifecycle.js";
|
|
3
|
+
import type { RuntimeBuildIdentity } from "./runtime-identity.js";
|
|
4
|
+
export interface RuntimeOperator {
|
|
5
|
+
readonly prepareLatest: (timeoutMs: number) => Promise<VerifiedRuntimeArtifact>;
|
|
6
|
+
readonly updateLatest: (timeoutMs: number) => Promise<RuntimeUpdateResult>;
|
|
7
|
+
}
|
|
8
|
+
export interface RuntimeUpdateResult {
|
|
9
|
+
readonly outcome: "prepared" | "updated";
|
|
10
|
+
readonly artifact: VerifiedRuntimeArtifact;
|
|
11
|
+
readonly runningIdentity: RuntimeBuildIdentity | null;
|
|
12
|
+
readonly dataIdentity: "preserved";
|
|
13
|
+
}
|
|
14
|
+
export declare class RuntimeUpdateFailure extends Error {
|
|
15
|
+
readonly code: "ARTIFACT_VERIFICATION_FAILED" | "ACTIVATION_FAILED";
|
|
16
|
+
readonly recovery: RuntimeRecoveryState | null;
|
|
17
|
+
constructor(code: "ARTIFACT_VERIFICATION_FAILED" | "ACTIVATION_FAILED", recovery?: RuntimeRecoveryState | null);
|
|
18
|
+
}
|
|
19
|
+
export declare function createRuntimeOperator(options: {
|
|
20
|
+
readonly runtimeRoot: string;
|
|
21
|
+
readonly artifacts: RegistryArtifactSource;
|
|
22
|
+
readonly lifecycle: RuntimeLifecycle;
|
|
23
|
+
readonly isRunning: () => Promise<boolean>;
|
|
24
|
+
}): RuntimeOperator;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { RuntimeActivationError, } from "./runtime-lifecycle.js";
|
|
2
|
+
export class RuntimeUpdateFailure extends Error {
|
|
3
|
+
code;
|
|
4
|
+
recovery;
|
|
5
|
+
constructor(code, recovery = null) {
|
|
6
|
+
super("Runtime update did not complete.");
|
|
7
|
+
this.name = "RuntimeUpdateFailure";
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.recovery = recovery;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export function createRuntimeOperator(options) {
|
|
13
|
+
const stageLatest = async (timeoutMs) => {
|
|
14
|
+
validateTimeout(timeoutMs);
|
|
15
|
+
const controller = new AbortController();
|
|
16
|
+
let timer;
|
|
17
|
+
let downloaded;
|
|
18
|
+
const download = options.artifacts.latest(options.runtimeRoot, controller.signal);
|
|
19
|
+
try {
|
|
20
|
+
downloaded = await Promise.race([
|
|
21
|
+
download,
|
|
22
|
+
new Promise((_resolve, reject) => {
|
|
23
|
+
timer = setTimeout(() => {
|
|
24
|
+
controller.abort();
|
|
25
|
+
reject(new Error("Runtime artifact download timed out."));
|
|
26
|
+
}, timeoutMs);
|
|
27
|
+
}),
|
|
28
|
+
]);
|
|
29
|
+
return await options.lifecycle.stage({
|
|
30
|
+
runtimeRoot: options.runtimeRoot,
|
|
31
|
+
tarballPath: downloaded.tarballPath,
|
|
32
|
+
expectedIntegrity: downloaded.integrity,
|
|
33
|
+
expectedVersion: downloaded.version,
|
|
34
|
+
...(downloaded.sourceSha === null ? {} : { sourceSha: downloaded.sourceSha }),
|
|
35
|
+
timeoutMs,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
if (timer !== undefined)
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
if (downloaded === undefined) {
|
|
42
|
+
void download.then((late) => late.cleanup()).catch(() => undefined);
|
|
43
|
+
}
|
|
44
|
+
await downloaded?.cleanup();
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
return {
|
|
48
|
+
async prepareLatest(timeoutMs) {
|
|
49
|
+
const artifact = await stageLatest(timeoutMs);
|
|
50
|
+
return options.lifecycle.prepare({ runtimeRoot: options.runtimeRoot, artifact });
|
|
51
|
+
},
|
|
52
|
+
async updateLatest(timeoutMs) {
|
|
53
|
+
await options.isRunning();
|
|
54
|
+
let artifact;
|
|
55
|
+
try {
|
|
56
|
+
artifact = await stageLatest(timeoutMs);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
throw new RuntimeUpdateFailure("ARTIFACT_VERIFICATION_FAILED");
|
|
60
|
+
}
|
|
61
|
+
if (!await options.isRunning()) {
|
|
62
|
+
await options.lifecycle.prepare({ runtimeRoot: options.runtimeRoot, artifact });
|
|
63
|
+
return Object.freeze({
|
|
64
|
+
outcome: "prepared",
|
|
65
|
+
artifact,
|
|
66
|
+
runningIdentity: null,
|
|
67
|
+
dataIdentity: "preserved",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
let runningIdentity;
|
|
71
|
+
try {
|
|
72
|
+
runningIdentity = await options.lifecycle.activate({
|
|
73
|
+
runtimeRoot: options.runtimeRoot,
|
|
74
|
+
artifact,
|
|
75
|
+
timeoutMs,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
throw new RuntimeUpdateFailure("ACTIVATION_FAILED", error instanceof RuntimeActivationError ? error.recovery : "failed");
|
|
80
|
+
}
|
|
81
|
+
return Object.freeze({
|
|
82
|
+
outcome: "updated",
|
|
83
|
+
artifact,
|
|
84
|
+
runningIdentity,
|
|
85
|
+
dataIdentity: "preserved",
|
|
86
|
+
});
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function validateTimeout(value) {
|
|
91
|
+
if (!Number.isSafeInteger(value) || value < 100 || value > 300_000) {
|
|
92
|
+
throw new Error("Runtime operator timeout is invalid.");
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=runtime-operator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime-operator.js","sourceRoot":"","sources":["../src/runtime-operator.ts"],"names":[],"mappings":"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"}
|