@impz/testing 4.2.5 → 6.0.0
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 +4 -1
- package/dist/index.js +1327 -1273
- package/package.json +44 -22
package/dist/index.js
CHANGED
|
@@ -18990,7 +18990,7 @@ import invariant6 from "tiny-invariant";
|
|
|
18990
18990
|
|
|
18991
18991
|
// packages/daemon/src/config.ts
|
|
18992
18992
|
import { join as join4 } from "path";
|
|
18993
|
-
import * as
|
|
18993
|
+
import * as z53 from "zod";
|
|
18994
18994
|
// packages/shared/src/format-bytes.ts
|
|
18995
18995
|
var UNITS = ["B", "KiB", "MiB", "GiB", "TiB"];
|
|
18996
18996
|
function formatBytes(bytes) {
|
|
@@ -19425,7 +19425,7 @@ function buildRangeMatcher(ranges) {
|
|
|
19425
19425
|
}
|
|
19426
19426
|
|
|
19427
19427
|
// packages/daemon/src/identity/auth/parse-tailnet-rules.ts
|
|
19428
|
-
import * as
|
|
19428
|
+
import * as z48 from "zod";
|
|
19429
19429
|
// packages/api/src/schemas/lease-schema.ts
|
|
19430
19430
|
import * as z2 from "zod";
|
|
19431
19431
|
|
|
@@ -19923,11 +19923,14 @@ var BrokerRuleSchema = z15.object({
|
|
|
19923
19923
|
user: BasicUserSchema.optional(),
|
|
19924
19924
|
upstream: BrokerUpstreamSchema.optional()
|
|
19925
19925
|
});
|
|
19926
|
-
var
|
|
19926
|
+
var SecretPresetSchema = z15.enum(["github", "anthropic", "npm"]);
|
|
19927
|
+
var SecretKindSchema = z15.enum(["static", "oauth"]);
|
|
19927
19928
|
var OAuthConfigSchema = z15.object({
|
|
19928
19929
|
tokenUrl: z15.url({ protocol: /^https$/u }).max(2048),
|
|
19929
19930
|
clientId: PrintableSchema.min(1).max(256),
|
|
19930
19931
|
tokenFormat: z15.enum(["json", "form"]).default("form")
|
|
19932
|
+
}, {
|
|
19933
|
+
error: (issue) => issue.input === undefined ? "needs a token URL and a client id" : undefined
|
|
19931
19934
|
});
|
|
19932
19935
|
var OAuthStateSchema = OAuthConfigSchema.extend({
|
|
19933
19936
|
status: z15.enum(["pending", "ready", "needs_login"]),
|
|
@@ -19936,10 +19939,24 @@ var OAuthStateSchema = OAuthConfigSchema.extend({
|
|
|
19936
19939
|
error: z15.string().nullable(),
|
|
19937
19940
|
idClaims: z15.record(z15.string(), z15.unknown()).readonly().nullable()
|
|
19938
19941
|
});
|
|
19942
|
+
var BROKER_ENV_NAMES = [
|
|
19943
|
+
"HTTPS_PROXY",
|
|
19944
|
+
"https_proxy",
|
|
19945
|
+
"NO_PROXY",
|
|
19946
|
+
"no_proxy",
|
|
19947
|
+
"NODE_USE_ENV_PROXY",
|
|
19948
|
+
"SSL_CERT_FILE",
|
|
19949
|
+
"NODE_EXTRA_CA_CERTS",
|
|
19950
|
+
"GIT_SSL_CAINFO",
|
|
19951
|
+
"REQUESTS_CA_BUNDLE",
|
|
19952
|
+
"CURL_CA_BUNDLE"
|
|
19953
|
+
];
|
|
19954
|
+
var SecretEnvSchema = z15.array(z15.string().regex(/^[A-Z_][A-Z0-9_]{0,63}$/u, "must be an upper-case variable name").refine((name) => !BROKER_ENV_NAMES.includes(name), "must not be a variable the broker sets")).max(16).readonly();
|
|
19939
19955
|
var SecretSchema = z15.object({
|
|
19940
19956
|
name: SecretNameSchema,
|
|
19941
19957
|
kind: SecretKindSchema,
|
|
19942
19958
|
rules: z15.array(BrokerRuleSchema).readonly(),
|
|
19959
|
+
env: SecretEnvSchema,
|
|
19943
19960
|
imps: z15.array(NameSchema).readonly(),
|
|
19944
19961
|
createdAt: z15.date(),
|
|
19945
19962
|
oauth: OAuthStateSchema.optional()
|
|
@@ -20200,7 +20217,7 @@ var REFERENCE = new RegExp(String.raw`^(?:${DOMAIN}/)?${PATH_COMPONENT}(?:/${PAT
|
|
|
20200
20217
|
var ImageRefSchema = z19.string().max(255).regex(REFERENCE, "must be an image reference such as ubuntu:24.04 or ghcr.io/org/app@sha256:\u2026");
|
|
20201
20218
|
// packages/api/src/contract/caller-contract.ts
|
|
20202
20219
|
import { eventIterator } from "@orpc/contract";
|
|
20203
|
-
import * as
|
|
20220
|
+
import * as z42 from "zod";
|
|
20204
20221
|
|
|
20205
20222
|
// packages/api/src/schemas/backup-schema.ts
|
|
20206
20223
|
import * as z20 from "zod";
|
|
@@ -20370,83 +20387,140 @@ function isAllowedRedirectUri(text) {
|
|
|
20370
20387
|
return url.protocol === "http:" && ["127.0.0.1", "[::1]", "localhost"].includes(url.hostname);
|
|
20371
20388
|
}
|
|
20372
20389
|
|
|
20373
|
-
// packages/api/src/schemas/
|
|
20390
|
+
// packages/api/src/schemas/secret-add-schema.ts
|
|
20374
20391
|
import * as z29 from "zod";
|
|
20392
|
+
var SecretRulesSchema = z29.array(BrokerRuleSchema, {
|
|
20393
|
+
error: (issue) => issue.input === undefined ? "needs at least one host" : undefined
|
|
20394
|
+
}).min(1, "needs at least one host").max(16).superRefine((rules, context) => {
|
|
20395
|
+
const hosts = rules.map((rule) => rule.host);
|
|
20396
|
+
const repeated = hosts.find((host, index) => hosts.indexOf(host) !== index);
|
|
20397
|
+
if (repeated !== undefined) {
|
|
20398
|
+
context.addIssue({ code: "custom", message: `${repeated} has more than one rule` });
|
|
20399
|
+
}
|
|
20400
|
+
}).readonly();
|
|
20401
|
+
var StaticBindingSchema = z29.strictObject({
|
|
20402
|
+
kind: z29.literal("static"),
|
|
20403
|
+
rules: SecretRulesSchema,
|
|
20404
|
+
env: SecretEnvSchema.optional()
|
|
20405
|
+
});
|
|
20406
|
+
var OAuthBindingSchema = z29.strictObject({
|
|
20407
|
+
kind: z29.literal("oauth"),
|
|
20408
|
+
rules: SecretRulesSchema.refine((rules) => rules.every((rule) => rule.upstream === undefined), "an oauth secret cannot have an upstream; it is for kind static"),
|
|
20409
|
+
env: SecretEnvSchema.optional(),
|
|
20410
|
+
oauth: OAuthConfigSchema
|
|
20411
|
+
});
|
|
20412
|
+
var OldPresetBindingSchema = z29.strictObject({ kind: SecretPresetSchema });
|
|
20413
|
+
var SecretAddKindSchema = z29.enum([
|
|
20414
|
+
...SecretKindSchema.options,
|
|
20415
|
+
...SecretPresetSchema.options,
|
|
20416
|
+
"custom"
|
|
20417
|
+
]);
|
|
20418
|
+
var OldCustomBindingSchema = z29.strictObject({
|
|
20419
|
+
kind: z29.literal("custom"),
|
|
20420
|
+
rules: SecretRulesSchema
|
|
20421
|
+
});
|
|
20422
|
+
var PresetBindingSchema = z29.strictObject({
|
|
20423
|
+
kind: z29.undefined().optional(),
|
|
20424
|
+
preset: SecretPresetSchema
|
|
20425
|
+
});
|
|
20426
|
+
var SecretBindingSchema = z29.discriminatedUnion("kind", [
|
|
20427
|
+
StaticBindingSchema,
|
|
20428
|
+
OAuthBindingSchema,
|
|
20429
|
+
PresetBindingSchema,
|
|
20430
|
+
OldPresetBindingSchema,
|
|
20431
|
+
OldCustomBindingSchema
|
|
20432
|
+
]);
|
|
20433
|
+
var AddFields = {
|
|
20434
|
+
name: SecretNameSchema,
|
|
20435
|
+
value: SecretValueSchema,
|
|
20436
|
+
replace: z29.boolean().optional(),
|
|
20437
|
+
rebind: z29.boolean().optional()
|
|
20438
|
+
};
|
|
20439
|
+
var SecretAddSchema = z29.discriminatedUnion("kind", [
|
|
20440
|
+
StaticBindingSchema.extend(AddFields),
|
|
20441
|
+
OAuthBindingSchema.extend(AddFields),
|
|
20442
|
+
PresetBindingSchema.extend(AddFields),
|
|
20443
|
+
OldPresetBindingSchema.extend(AddFields),
|
|
20444
|
+
OldCustomBindingSchema.extend(AddFields)
|
|
20445
|
+
]);
|
|
20446
|
+
|
|
20447
|
+
// packages/api/src/schemas/service-schema.ts
|
|
20448
|
+
import * as z30 from "zod";
|
|
20375
20449
|
var SERVICE_NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,62}$/u;
|
|
20376
|
-
var ServiceNameSchema =
|
|
20450
|
+
var ServiceNameSchema = z30.string().regex(SERVICE_NAME_PATTERN, "must be a lowercase letter or digit followed by up to 62 lowercase letters, digits or -");
|
|
20377
20451
|
var SERVICE_LOG_MAX_LINES = 1e5;
|
|
20378
|
-
var ServiceRestartSchema =
|
|
20379
|
-
var EnvEntrySchema =
|
|
20380
|
-
var ServiceDefSchema =
|
|
20452
|
+
var ServiceRestartSchema = z30.enum(["always", "on-failure", "never"]);
|
|
20453
|
+
var EnvEntrySchema = z30.string().regex(/^[A-Za-z_][A-Za-z0-9_]*=/u, "must be KEY=VALUE");
|
|
20454
|
+
var ServiceDefSchema = z30.object({
|
|
20381
20455
|
name: ServiceNameSchema,
|
|
20382
|
-
argv:
|
|
20383
|
-
env:
|
|
20384
|
-
cwd:
|
|
20385
|
-
user:
|
|
20456
|
+
argv: z30.array(z30.string().min(1)).min(1).max(256).readonly(),
|
|
20457
|
+
env: z30.array(EnvEntrySchema).max(256).readonly().optional(),
|
|
20458
|
+
cwd: z30.string().min(1).optional(),
|
|
20459
|
+
user: z30.string().min(1).optional(),
|
|
20386
20460
|
restart: ServiceRestartSchema.optional()
|
|
20387
20461
|
});
|
|
20388
|
-
var ServiceStateSchema =
|
|
20389
|
-
var ServiceSchema =
|
|
20390
|
-
name:
|
|
20462
|
+
var ServiceStateSchema = z30.enum(["starting", "running", "backoff", "stopped", "exited"]);
|
|
20463
|
+
var ServiceSchema = z30.object({
|
|
20464
|
+
name: z30.string(),
|
|
20391
20465
|
state: ServiceStateSchema,
|
|
20392
|
-
pid:
|
|
20393
|
-
restarts:
|
|
20394
|
-
lastExit:
|
|
20395
|
-
argv:
|
|
20396
|
-
envKeys:
|
|
20397
|
-
cwd:
|
|
20398
|
-
user:
|
|
20466
|
+
pid: z30.int().positive().nullable(),
|
|
20467
|
+
restarts: z30.int().nonnegative(),
|
|
20468
|
+
lastExit: z30.object({ code: z30.int(), signal: z30.string().nullable() }).nullable(),
|
|
20469
|
+
argv: z30.array(z30.string()).readonly(),
|
|
20470
|
+
envKeys: z30.array(z30.string()).readonly(),
|
|
20471
|
+
cwd: z30.string().nullable(),
|
|
20472
|
+
user: z30.string().nullable(),
|
|
20399
20473
|
restart: ServiceRestartSchema,
|
|
20400
|
-
source:
|
|
20401
|
-
root:
|
|
20474
|
+
source: z30.enum(["image", "api"]),
|
|
20475
|
+
root: z30.boolean()
|
|
20402
20476
|
});
|
|
20403
|
-
var ServiceLogSchema =
|
|
20404
|
-
|
|
20405
|
-
|
|
20406
|
-
|
|
20407
|
-
|
|
20477
|
+
var ServiceLogSchema = z30.discriminatedUnion("type", [
|
|
20478
|
+
z30.object({ type: z30.literal("log"), service: z30.string(), text: z30.string() }),
|
|
20479
|
+
z30.object({ type: z30.literal("sleeping"), state: ImpStateSchema }),
|
|
20480
|
+
z30.object({ type: z30.literal("awake") }),
|
|
20481
|
+
z30.object({ type: z30.literal("restarting") })
|
|
20408
20482
|
]);
|
|
20409
|
-
var ServiceListSchema =
|
|
20410
|
-
services:
|
|
20411
|
-
recorded:
|
|
20483
|
+
var ServiceListSchema = z30.object({
|
|
20484
|
+
services: z30.array(ServiceSchema).readonly(),
|
|
20485
|
+
recorded: z30.boolean()
|
|
20412
20486
|
});
|
|
20413
20487
|
|
|
20414
20488
|
// packages/api/src/schemas/session-log-schema.ts
|
|
20415
|
-
import * as
|
|
20489
|
+
import * as z31 from "zod";
|
|
20416
20490
|
var SESSION_LOG_READ_MAX_BYTES = 1048576;
|
|
20417
|
-
var SessionLogSchema =
|
|
20491
|
+
var SessionLogSchema = z31.object({
|
|
20418
20492
|
session: SessionNameSchema,
|
|
20419
20493
|
executionGeneration: ExecutionGenerationSchema,
|
|
20420
|
-
bootId:
|
|
20421
|
-
state:
|
|
20494
|
+
bootId: z31.string(),
|
|
20495
|
+
state: z31.enum(["live", "ended"]),
|
|
20422
20496
|
logStart: OffsetSchema,
|
|
20423
20497
|
logEnd: OffsetSchema,
|
|
20424
20498
|
bytes: OffsetSchema,
|
|
20425
20499
|
end: OffsetSchema.optional(),
|
|
20426
|
-
exitCode:
|
|
20427
|
-
complete:
|
|
20428
|
-
stopped:
|
|
20429
|
-
startedAt:
|
|
20430
|
-
endedAt:
|
|
20500
|
+
exitCode: z31.int().nullable().optional(),
|
|
20501
|
+
complete: z31.boolean(),
|
|
20502
|
+
stopped: z31.enum(["disk_full", "imp_limit"]).optional(),
|
|
20503
|
+
startedAt: z31.date(),
|
|
20504
|
+
endedAt: z31.date().optional()
|
|
20431
20505
|
}).readonly();
|
|
20432
|
-
var SessionLogListInputSchema =
|
|
20506
|
+
var SessionLogListInputSchema = z31.object({
|
|
20433
20507
|
name: NameSchema,
|
|
20434
20508
|
session: SessionNameSchema.optional()
|
|
20435
20509
|
});
|
|
20436
|
-
var SessionLogReadInputSchema =
|
|
20510
|
+
var SessionLogReadInputSchema = z31.object({
|
|
20437
20511
|
name: NameSchema,
|
|
20438
20512
|
session: SessionNameSchema,
|
|
20439
20513
|
executionGeneration: ExecutionGenerationSchema,
|
|
20440
20514
|
from: OffsetSchema,
|
|
20441
|
-
limit:
|
|
20515
|
+
limit: z31.int().min(1).max(SESSION_LOG_READ_MAX_BYTES).optional()
|
|
20442
20516
|
});
|
|
20443
|
-
var SessionLogReadSchema =
|
|
20517
|
+
var SessionLogReadSchema = z31.object({
|
|
20444
20518
|
offset: OffsetSchema,
|
|
20445
|
-
gap:
|
|
20446
|
-
data:
|
|
20519
|
+
gap: z31.object({ from: OffsetSchema, to: OffsetSchema }).readonly().optional(),
|
|
20520
|
+
data: z31.instanceof(Blob),
|
|
20447
20521
|
log: SessionLogSchema
|
|
20448
20522
|
}).readonly();
|
|
20449
|
-
var SessionLogDeleteInputSchema =
|
|
20523
|
+
var SessionLogDeleteInputSchema = z31.object({
|
|
20450
20524
|
name: NameSchema,
|
|
20451
20525
|
session: SessionNameSchema.optional(),
|
|
20452
20526
|
executionGeneration: ExecutionGenerationSchema.optional()
|
|
@@ -20456,144 +20530,145 @@ var SessionLogDeleteInputSchema = z30.object({
|
|
|
20456
20530
|
});
|
|
20457
20531
|
|
|
20458
20532
|
// packages/api/src/schemas/storage-schema.ts
|
|
20459
|
-
import * as
|
|
20460
|
-
var DroppedStorageSchema =
|
|
20461
|
-
kind:
|
|
20462
|
-
id:
|
|
20533
|
+
import * as z32 from "zod";
|
|
20534
|
+
var DroppedStorageSchema = z32.object({
|
|
20535
|
+
kind: z32.enum(["imp", "checkpoint", "image", "snapshot", "memory", "secrets"]),
|
|
20536
|
+
id: z32.string()
|
|
20463
20537
|
}).readonly();
|
|
20464
|
-
var OrphanStorageSchema =
|
|
20465
|
-
kind:
|
|
20466
|
-
id:
|
|
20467
|
-
location:
|
|
20468
|
-
bytes:
|
|
20469
|
-
createdAt:
|
|
20470
|
-
snapshots:
|
|
20471
|
-
files:
|
|
20538
|
+
var OrphanStorageSchema = z32.object({
|
|
20539
|
+
kind: z32.enum(["imp", "image", "memory", "checkpoint", "secrets"]),
|
|
20540
|
+
id: z32.string(),
|
|
20541
|
+
location: z32.string(),
|
|
20542
|
+
bytes: z32.int().nonnegative(),
|
|
20543
|
+
createdAt: z32.date().nullable(),
|
|
20544
|
+
snapshots: z32.array(z32.string()).readonly(),
|
|
20545
|
+
files: z32.array(z32.string()).readonly().optional()
|
|
20472
20546
|
}).readonly();
|
|
20473
|
-
var StorageGcSchema =
|
|
20474
|
-
dryRun:
|
|
20475
|
-
dropped:
|
|
20476
|
-
kept:
|
|
20547
|
+
var StorageGcSchema = z32.object({
|
|
20548
|
+
dryRun: z32.boolean(),
|
|
20549
|
+
dropped: z32.array(DroppedStorageSchema).readonly(),
|
|
20550
|
+
kept: z32.array(OrphanStorageSchema).readonly().optional()
|
|
20477
20551
|
}).readonly();
|
|
20478
|
-
var DatabaseCopySchema =
|
|
20479
|
-
path:
|
|
20480
|
-
sizeBytes:
|
|
20481
|
-
lastMigration:
|
|
20482
|
-
impVersion:
|
|
20483
|
-
createdAt:
|
|
20484
|
-
integrity:
|
|
20552
|
+
var DatabaseCopySchema = z32.object({
|
|
20553
|
+
path: z32.string(),
|
|
20554
|
+
sizeBytes: z32.int().nonnegative(),
|
|
20555
|
+
lastMigration: z32.string(),
|
|
20556
|
+
impVersion: z32.string(),
|
|
20557
|
+
createdAt: z32.date(),
|
|
20558
|
+
integrity: z32.string()
|
|
20485
20559
|
});
|
|
20486
20560
|
|
|
20487
20561
|
// packages/api/src/schemas/system-info-schema.ts
|
|
20488
|
-
import * as
|
|
20489
|
-
var CountSchema =
|
|
20490
|
-
var NameFailureSchema =
|
|
20491
|
-
var TailnetNamesSchema =
|
|
20562
|
+
import * as z33 from "zod";
|
|
20563
|
+
var CountSchema = z33.int().nonnegative();
|
|
20564
|
+
var NameFailureSchema = z33.object({ name: NameSchema, error: z33.string() });
|
|
20565
|
+
var TailnetNamesSchema = z33.object({
|
|
20492
20566
|
live: CountSchema,
|
|
20493
|
-
failed:
|
|
20567
|
+
failed: z33.array(NameFailureSchema).readonly()
|
|
20494
20568
|
});
|
|
20495
|
-
var BootStatusSchema =
|
|
20569
|
+
var BootStatusSchema = z33.object({
|
|
20496
20570
|
coldBoots: CountSchema,
|
|
20497
|
-
outdated:
|
|
20571
|
+
outdated: z33.object({
|
|
20498
20572
|
firecracker: CountSchema,
|
|
20499
20573
|
kernel: CountSchema,
|
|
20500
20574
|
agent: CountSchema,
|
|
20501
20575
|
ipv6: CountSchema.optional()
|
|
20502
20576
|
})
|
|
20503
20577
|
});
|
|
20504
|
-
var PassStatusSchema =
|
|
20505
|
-
isOk:
|
|
20506
|
-
error:
|
|
20507
|
-
at:
|
|
20578
|
+
var PassStatusSchema = z33.object({
|
|
20579
|
+
isOk: z33.boolean(),
|
|
20580
|
+
error: z33.string().nullable(),
|
|
20581
|
+
at: z33.date()
|
|
20508
20582
|
});
|
|
20509
|
-
var HttpsInfoSchema =
|
|
20510
|
-
domain:
|
|
20583
|
+
var HttpsInfoSchema = z33.object({
|
|
20584
|
+
domain: z33.string(),
|
|
20511
20585
|
dnsToken: PassStatusSchema.nullable()
|
|
20512
20586
|
});
|
|
20513
|
-
var PublicInfoSchema =
|
|
20514
|
-
ip:
|
|
20587
|
+
var PublicInfoSchema = z33.object({
|
|
20588
|
+
ip: z33.ipv4(),
|
|
20515
20589
|
imps: CountSchema,
|
|
20516
20590
|
records: PassStatusSchema.nullable()
|
|
20517
20591
|
});
|
|
20518
|
-
var SystemFeaturesSchema =
|
|
20519
|
-
sessionOffsets:
|
|
20520
|
-
leases:
|
|
20521
|
-
grantableTokens:
|
|
20522
|
-
secretRebind:
|
|
20523
|
-
tokenUpdate:
|
|
20524
|
-
tokenImageAdd:
|
|
20525
|
-
databaseCopy:
|
|
20526
|
-
imageOpStream:
|
|
20527
|
-
imageBuilds:
|
|
20528
|
-
execRequire:
|
|
20529
|
-
oauthGrants:
|
|
20530
|
-
secretFilesGc:
|
|
20531
|
-
sessionLog:
|
|
20532
|
-
publicEgress:
|
|
20533
|
-
oauthSecrets:
|
|
20534
|
-
secretUpstream:
|
|
20535
|
-
|
|
20536
|
-
|
|
20537
|
-
|
|
20538
|
-
|
|
20539
|
-
|
|
20540
|
-
|
|
20541
|
-
|
|
20542
|
-
|
|
20592
|
+
var SystemFeaturesSchema = z33.object({
|
|
20593
|
+
sessionOffsets: z33.boolean(),
|
|
20594
|
+
leases: z33.boolean(),
|
|
20595
|
+
grantableTokens: z33.boolean().optional(),
|
|
20596
|
+
secretRebind: z33.boolean().optional(),
|
|
20597
|
+
tokenUpdate: z33.boolean().optional(),
|
|
20598
|
+
tokenImageAdd: z33.boolean().optional(),
|
|
20599
|
+
databaseCopy: z33.boolean().optional(),
|
|
20600
|
+
imageOpStream: z33.boolean().optional(),
|
|
20601
|
+
imageBuilds: z33.boolean().optional(),
|
|
20602
|
+
execRequire: z33.boolean().optional(),
|
|
20603
|
+
oauthGrants: z33.boolean().optional(),
|
|
20604
|
+
secretFilesGc: z33.boolean().optional(),
|
|
20605
|
+
sessionLog: z33.boolean().optional(),
|
|
20606
|
+
publicEgress: z33.boolean().optional(),
|
|
20607
|
+
oauthSecrets: z33.boolean().optional(),
|
|
20608
|
+
secretUpstream: z33.boolean().optional(),
|
|
20609
|
+
secretPresets: z33.boolean().optional(),
|
|
20610
|
+
backupOptOut: z33.boolean().optional(),
|
|
20611
|
+
brokerRefusals: z33.boolean().optional(),
|
|
20612
|
+
grantFilters: z33.boolean().optional(),
|
|
20613
|
+
readOnlyFiles: z33.boolean().optional(),
|
|
20614
|
+
execDropSysAdmin: z33.boolean().optional(),
|
|
20615
|
+
guestScratch: z33.boolean().optional(),
|
|
20616
|
+
imagePins: z33.boolean().optional(),
|
|
20617
|
+
buildContextUpload: z33.boolean().optional()
|
|
20543
20618
|
});
|
|
20544
|
-
var GuestInfoSchema =
|
|
20545
|
-
scratchDir:
|
|
20546
|
-
isClearedOnBoot:
|
|
20619
|
+
var GuestInfoSchema = z33.object({
|
|
20620
|
+
scratchDir: z33.string(),
|
|
20621
|
+
isClearedOnBoot: z33.boolean()
|
|
20547
20622
|
});
|
|
20548
|
-
var SystemInfoSchema =
|
|
20549
|
-
version:
|
|
20550
|
-
ramBudgetMib:
|
|
20551
|
-
ramUsedMib:
|
|
20552
|
-
ramReservedMib:
|
|
20553
|
-
ramCommittedMib:
|
|
20554
|
-
ramSleepingMib:
|
|
20555
|
-
awakeCount:
|
|
20556
|
-
impCount:
|
|
20557
|
-
sessionCount:
|
|
20623
|
+
var SystemInfoSchema = z33.object({
|
|
20624
|
+
version: z33.string(),
|
|
20625
|
+
ramBudgetMib: z33.int().nonnegative(),
|
|
20626
|
+
ramUsedMib: z33.int().nonnegative(),
|
|
20627
|
+
ramReservedMib: z33.int().nonnegative(),
|
|
20628
|
+
ramCommittedMib: z33.int().nonnegative(),
|
|
20629
|
+
ramSleepingMib: z33.int().nonnegative().optional(),
|
|
20630
|
+
awakeCount: z33.int().nonnegative(),
|
|
20631
|
+
impCount: z33.int().nonnegative(),
|
|
20632
|
+
sessionCount: z33.int().nonnegative(),
|
|
20558
20633
|
bootStatus: BootStatusSchema,
|
|
20559
|
-
firecrackerVersion:
|
|
20560
|
-
guestKernel:
|
|
20561
|
-
systemDrive:
|
|
20634
|
+
firecrackerVersion: z33.string().nullable(),
|
|
20635
|
+
guestKernel: z33.object({ version: z33.string().nullable(), sha256: z33.string() }),
|
|
20636
|
+
systemDrive: z33.object({ sha256: z33.string() }),
|
|
20562
20637
|
guest: GuestInfoSchema.optional(),
|
|
20563
|
-
storage:
|
|
20564
|
-
backend:
|
|
20565
|
-
usedBytes:
|
|
20566
|
-
availableBytes:
|
|
20567
|
-
reserveBytes:
|
|
20568
|
-
pendingBytes:
|
|
20569
|
-
isLow:
|
|
20570
|
-
impDiskBytes:
|
|
20638
|
+
storage: z33.object({
|
|
20639
|
+
backend: z33.enum(["xfs", "zfs"]),
|
|
20640
|
+
usedBytes: z33.int().nonnegative(),
|
|
20641
|
+
availableBytes: z33.int().nonnegative(),
|
|
20642
|
+
reserveBytes: z33.int().nonnegative(),
|
|
20643
|
+
pendingBytes: z33.int().nonnegative(),
|
|
20644
|
+
isLow: z33.boolean(),
|
|
20645
|
+
impDiskBytes: z33.int().nonnegative()
|
|
20571
20646
|
}),
|
|
20572
|
-
tailscale:
|
|
20573
|
-
enabled:
|
|
20574
|
-
state:
|
|
20575
|
-
hostname:
|
|
20576
|
-
ip:
|
|
20647
|
+
tailscale: z33.object({
|
|
20648
|
+
enabled: z33.boolean(),
|
|
20649
|
+
state: z33.string().nullable(),
|
|
20650
|
+
hostname: z33.string().nullable(),
|
|
20651
|
+
ip: z33.string().nullable(),
|
|
20577
20652
|
names: TailnetNamesSchema.nullable()
|
|
20578
20653
|
}),
|
|
20579
|
-
ksm:
|
|
20580
|
-
running:
|
|
20654
|
+
ksm: z33.object({
|
|
20655
|
+
running: z33.boolean(),
|
|
20581
20656
|
sharedMib: CountSchema,
|
|
20582
|
-
profitMib:
|
|
20657
|
+
profitMib: z33.int(),
|
|
20583
20658
|
zeroMib: CountSchema,
|
|
20584
20659
|
headroomMib: CountSchema,
|
|
20585
20660
|
unmergeable: CountSchema
|
|
20586
20661
|
}).nullable().optional(),
|
|
20587
|
-
rebootReason:
|
|
20588
|
-
cpu:
|
|
20589
|
-
defaults:
|
|
20590
|
-
egress:
|
|
20662
|
+
rebootReason: z33.string().nullable().optional(),
|
|
20663
|
+
cpu: z33.object({ hostCpus: z33.int().positive(), limitsEnforced: z33.boolean() }).optional(),
|
|
20664
|
+
defaults: z33.object({ memoryMib: z33.int().positive(), image: z33.string().nullable() }).optional(),
|
|
20665
|
+
egress: z33.object({ isEnforced: z33.boolean() }).optional(),
|
|
20591
20666
|
public: PublicInfoSchema.nullable().optional(),
|
|
20592
20667
|
https: HttpsInfoSchema.nullable().optional(),
|
|
20593
20668
|
features: SystemFeaturesSchema.optional()
|
|
20594
20669
|
});
|
|
20595
|
-
var SystemFeaturesInfoSchema =
|
|
20596
|
-
version:
|
|
20670
|
+
var SystemFeaturesInfoSchema = z33.object({
|
|
20671
|
+
version: z33.string(),
|
|
20597
20672
|
features: SystemFeaturesSchema
|
|
20598
20673
|
});
|
|
20599
20674
|
var SYSTEM_FEATURES = SystemFeaturesSchema.required().parse(Object.fromEntries(SystemFeaturesSchema.keyof().options.map((name) => [name, true])));
|
|
@@ -20618,7 +20693,7 @@ var ACCESS = {
|
|
|
20618
20693
|
import { oc } from "@orpc/contract";
|
|
20619
20694
|
|
|
20620
20695
|
// packages/api/src/contract/imp-errors.ts
|
|
20621
|
-
import * as
|
|
20696
|
+
import * as z34 from "zod";
|
|
20622
20697
|
|
|
20623
20698
|
// packages/api/src/contract/define-errors.ts
|
|
20624
20699
|
function defineErrors(errors) {
|
|
@@ -20626,7 +20701,7 @@ function defineErrors(errors) {
|
|
|
20626
20701
|
}
|
|
20627
20702
|
|
|
20628
20703
|
// packages/api/src/contract/imp-errors.ts
|
|
20629
|
-
var ResourceKindSchema =
|
|
20704
|
+
var ResourceKindSchema = z34.enum([
|
|
20630
20705
|
"imp",
|
|
20631
20706
|
"image",
|
|
20632
20707
|
"checkpoint",
|
|
@@ -20643,22 +20718,22 @@ var ResourceKindSchema = z33.enum([
|
|
|
20643
20718
|
"oauth-approval",
|
|
20644
20719
|
"database-copy"
|
|
20645
20720
|
]);
|
|
20646
|
-
var ResourceDataSchema =
|
|
20721
|
+
var ResourceDataSchema = z34.object({
|
|
20647
20722
|
kind: ResourceKindSchema,
|
|
20648
|
-
name:
|
|
20649
|
-
reason:
|
|
20723
|
+
name: z34.string(),
|
|
20724
|
+
reason: z34.enum(["binding_changed"]).optional()
|
|
20650
20725
|
});
|
|
20651
|
-
var ForbiddenReasonSchema =
|
|
20652
|
-
var ForbiddenDataSchema =
|
|
20653
|
-
var PreconditionDataSchema =
|
|
20654
|
-
reason:
|
|
20655
|
-
detail:
|
|
20726
|
+
var ForbiddenReasonSchema = z34.enum(["imp_out_of_scope", "not_grantable", "scope"]);
|
|
20727
|
+
var ForbiddenDataSchema = z34.object({ reason: ForbiddenReasonSchema });
|
|
20728
|
+
var PreconditionDataSchema = z34.object({
|
|
20729
|
+
reason: z34.enum(["broker_not_ready", "impd_outdated"]),
|
|
20730
|
+
detail: z34.string()
|
|
20656
20731
|
});
|
|
20657
|
-
var ProtectedImpSchema =
|
|
20732
|
+
var ProtectedImpSchema = z34.object({
|
|
20658
20733
|
name: NameSchema,
|
|
20659
|
-
ramMib:
|
|
20660
|
-
leased:
|
|
20661
|
-
busy:
|
|
20734
|
+
ramMib: z34.int().nonnegative(),
|
|
20735
|
+
leased: z34.boolean(),
|
|
20736
|
+
busy: z34.boolean()
|
|
20662
20737
|
});
|
|
20663
20738
|
var IMP_ERRORS = defineErrors({
|
|
20664
20739
|
NOT_FOUND: { message: "Not found", data: ResourceDataSchema },
|
|
@@ -20671,22 +20746,22 @@ var IMP_ERRORS = defineErrors({
|
|
|
20671
20746
|
RAM_BUDGET_EXCEEDED: {
|
|
20672
20747
|
message: "Not enough RAM budget, even after sleeping idle imps",
|
|
20673
20748
|
status: 503,
|
|
20674
|
-
data:
|
|
20675
|
-
budgetMib:
|
|
20676
|
-
usedMib:
|
|
20677
|
-
requestedMib:
|
|
20678
|
-
neededMib:
|
|
20679
|
-
protected:
|
|
20680
|
-
protectedHidden:
|
|
20749
|
+
data: z34.object({
|
|
20750
|
+
budgetMib: z34.int().nonnegative(),
|
|
20751
|
+
usedMib: z34.int().nonnegative(),
|
|
20752
|
+
requestedMib: z34.int().nonnegative(),
|
|
20753
|
+
neededMib: z34.int().nonnegative().optional(),
|
|
20754
|
+
protected: z34.array(ProtectedImpSchema).readonly().optional(),
|
|
20755
|
+
protectedHidden: z34.int().nonnegative().optional()
|
|
20681
20756
|
})
|
|
20682
20757
|
},
|
|
20683
20758
|
SERVICE_UNAVAILABLE: { message: "impd is stopping" },
|
|
20684
20759
|
INVALID_STATE: {
|
|
20685
20760
|
message: "The imp is not in a state that allows this",
|
|
20686
20761
|
status: 409,
|
|
20687
|
-
data:
|
|
20762
|
+
data: z34.object({
|
|
20688
20763
|
state: ImpStateSchema,
|
|
20689
|
-
allowed:
|
|
20764
|
+
allowed: z34.array(ImpStateSchema),
|
|
20690
20765
|
coldBoots: ColdBootsSchema.optional()
|
|
20691
20766
|
})
|
|
20692
20767
|
},
|
|
@@ -20698,10 +20773,10 @@ var IMP_ERRORS = defineErrors({
|
|
|
20698
20773
|
DISK_FULL: {
|
|
20699
20774
|
message: "Not enough free disk on the host",
|
|
20700
20775
|
status: 507,
|
|
20701
|
-
data:
|
|
20702
|
-
availableBytes:
|
|
20703
|
-
reserveBytes:
|
|
20704
|
-
requestedBytes:
|
|
20776
|
+
data: z34.object({
|
|
20777
|
+
availableBytes: z34.int().nonnegative(),
|
|
20778
|
+
reserveBytes: z34.int().nonnegative(),
|
|
20779
|
+
requestedBytes: z34.int().nonnegative()
|
|
20705
20780
|
})
|
|
20706
20781
|
},
|
|
20707
20782
|
LEASED: {
|
|
@@ -20714,7 +20789,7 @@ var IMP_ERRORS = defineErrors({
|
|
|
20714
20789
|
MOVING: {
|
|
20715
20790
|
message: "The imp is moving between hosts",
|
|
20716
20791
|
status: 409,
|
|
20717
|
-
data:
|
|
20792
|
+
data: z34.object({ retryAfterS: z34.int().positive() })
|
|
20718
20793
|
}
|
|
20719
20794
|
});
|
|
20720
20795
|
|
|
@@ -20722,73 +20797,73 @@ var IMP_ERRORS = defineErrors({
|
|
|
20722
20797
|
var contractBase = oc.$meta({}).errors(IMP_ERRORS);
|
|
20723
20798
|
|
|
20724
20799
|
// packages/api/src/contract/imps-contract.ts
|
|
20725
|
-
import * as
|
|
20800
|
+
import * as z40 from "zod";
|
|
20726
20801
|
|
|
20727
20802
|
// packages/api/src/schemas/cpu-limit-schema.ts
|
|
20728
|
-
import * as
|
|
20729
|
-
var CpuLimitSchema =
|
|
20803
|
+
import * as z35 from "zod";
|
|
20804
|
+
var CpuLimitSchema = z35.number().min(0.1);
|
|
20730
20805
|
|
|
20731
20806
|
// packages/api/src/schemas/cpu-weight-schema.ts
|
|
20732
|
-
import * as
|
|
20733
|
-
var CpuWeightSchema =
|
|
20807
|
+
import * as z36 from "zod";
|
|
20808
|
+
var CpuWeightSchema = z36.int().min(1).max(1e4);
|
|
20734
20809
|
|
|
20735
20810
|
// packages/api/src/schemas/imp-create-input-schema.ts
|
|
20736
|
-
import * as
|
|
20811
|
+
import * as z39 from "zod";
|
|
20737
20812
|
|
|
20738
20813
|
// packages/api/src/schemas/port-schema.ts
|
|
20739
|
-
import * as
|
|
20740
|
-
var PortSchema =
|
|
20814
|
+
import * as z37 from "zod";
|
|
20815
|
+
var PortSchema = z37.int().min(1).max(65535);
|
|
20741
20816
|
|
|
20742
20817
|
// packages/api/src/schemas/vcpus-schema.ts
|
|
20743
|
-
import * as
|
|
20744
|
-
var VcpusSchema =
|
|
20818
|
+
import * as z38 from "zod";
|
|
20819
|
+
var VcpusSchema = z38.int().min(1).max(32);
|
|
20745
20820
|
|
|
20746
20821
|
// packages/api/src/schemas/imp-create-input-schema.ts
|
|
20747
|
-
var ImpCreateInputSchema =
|
|
20822
|
+
var ImpCreateInputSchema = z39.object({
|
|
20748
20823
|
name: NameSchema.optional(),
|
|
20749
20824
|
image: NameSchema.optional(),
|
|
20750
20825
|
vcpus: VcpusSchema.optional(),
|
|
20751
|
-
memoryMib:
|
|
20752
|
-
maxMemoryMib:
|
|
20753
|
-
diskMib:
|
|
20826
|
+
memoryMib: z39.int().min(128).optional(),
|
|
20827
|
+
maxMemoryMib: z39.int().min(128).optional(),
|
|
20828
|
+
diskMib: z39.int().min(1024).optional(),
|
|
20754
20829
|
httpPort: PortSchema.optional(),
|
|
20755
20830
|
policy: EgressPolicySchema.optional(),
|
|
20756
20831
|
cpuLimit: CpuLimitSchema.nullable().optional(),
|
|
20757
20832
|
cpuWeight: CpuWeightSchema.optional(),
|
|
20758
|
-
networks:
|
|
20759
|
-
backup:
|
|
20833
|
+
networks: z39.array(NameSchema).max(MAX_CREATE_NETWORKS).optional(),
|
|
20834
|
+
backup: z39.boolean().optional()
|
|
20760
20835
|
});
|
|
20761
20836
|
|
|
20762
20837
|
// packages/api/src/contract/imps-contract.ts
|
|
20763
|
-
var ForceInputSchema =
|
|
20838
|
+
var ForceInputSchema = z40.object({ name: NameSchema, force: z40.boolean().optional() });
|
|
20764
20839
|
var impsContract = {
|
|
20765
20840
|
create: contractBase.meta(ACCESS.manageImp).input(ImpCreateInputSchema).output(ImpSchema),
|
|
20766
|
-
list: contractBase.meta(ACCESS.readAny).input(
|
|
20841
|
+
list: contractBase.meta(ACCESS.readAny).input(z40.object({ builders: z40.boolean().optional() }).optional()).output(z40.array(ImpSchema)),
|
|
20767
20842
|
get: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(ImpSchema),
|
|
20768
20843
|
destroy: contractBase.meta(ACCESS.manageImp).input(NameInputSchema).output(EmptySchema),
|
|
20769
20844
|
start: contractBase.meta(ACCESS.execImp).input(NameInputSchema).output(ImpSchema),
|
|
20770
20845
|
stop: contractBase.meta(ACCESS.execImp).input(ForceInputSchema).output(ImpSchema),
|
|
20771
20846
|
sleep: contractBase.meta(ACCESS.execImp).input(ForceInputSchema).output(ImpSchema),
|
|
20772
|
-
wake: contractBase.meta(ACCESS.execImp).input(
|
|
20773
|
-
hold: contractBase.meta(ACCESS.execImp).input(
|
|
20774
|
-
resizeDisk: contractBase.meta(ACCESS.manageImp).input(
|
|
20775
|
-
url: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(
|
|
20776
|
-
local:
|
|
20777
|
-
https:
|
|
20778
|
-
public:
|
|
20779
|
-
service:
|
|
20780
|
-
tailnet:
|
|
20847
|
+
wake: contractBase.meta(ACCESS.execImp).input(z40.object({ name: NameSchema, restartError: z40.boolean().optional() })).output(ImpSchema),
|
|
20848
|
+
hold: contractBase.meta(ACCESS.execImp).input(z40.object({ name: NameSchema, seconds: z40.int().nonnegative() })).output(ImpSchema),
|
|
20849
|
+
resizeDisk: contractBase.meta(ACCESS.manageImp).input(z40.object({ name: NameSchema, diskMib: z40.int().min(1024) })).output(ImpSchema),
|
|
20850
|
+
url: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(z40.object({
|
|
20851
|
+
local: z40.url(),
|
|
20852
|
+
https: z40.url().nullable(),
|
|
20853
|
+
public: z40.url().nullable(),
|
|
20854
|
+
service: z40.url().nullable(),
|
|
20855
|
+
tailnet: z40.url().nullable()
|
|
20781
20856
|
})),
|
|
20782
20857
|
policy: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(EgressPolicySchema),
|
|
20783
|
-
setPolicy: contractBase.meta(ACCESS.manageImp).input(
|
|
20858
|
+
setPolicy: contractBase.meta(ACCESS.manageImp).input(z40.object({ name: NameSchema, policy: EgressPolicySchema })).output(EgressPolicySchema),
|
|
20784
20859
|
expose: contractBase.meta(ACCESS.manageHost).input(ExposeInputSchema).output(ExposeResultSchema),
|
|
20785
20860
|
unexpose: contractBase.meta(ACCESS.manageHost).input(NameInputSchema).output(ImpSchema),
|
|
20786
|
-
fork: contractBase.meta({ access: { scope: "manage", on: "imp", fields: ["source", "name"], noGrantable: true } }).input(
|
|
20861
|
+
fork: contractBase.meta({ access: { scope: "manage", on: "imp", fields: ["source", "name"], noGrantable: true } }).input(z40.object({
|
|
20787
20862
|
source: NameSchema,
|
|
20788
20863
|
name: NameSchema,
|
|
20789
20864
|
checkpoint: CheckpointRefSchema.optional()
|
|
20790
20865
|
})).output(ForkResultSchema),
|
|
20791
|
-
update: contractBase.meta(ACCESS.manageImp).input(
|
|
20866
|
+
update: contractBase.meta(ACCESS.manageImp).input(z40.object({
|
|
20792
20867
|
name: NameSchema,
|
|
20793
20868
|
cpuLimit: CpuLimitSchema.nullable().optional(),
|
|
20794
20869
|
cpuWeight: CpuWeightSchema.optional(),
|
|
@@ -20798,184 +20873,176 @@ var impsContract = {
|
|
|
20798
20873
|
};
|
|
20799
20874
|
|
|
20800
20875
|
// packages/api/src/contract/tokens-contract.ts
|
|
20801
|
-
import * as
|
|
20876
|
+
import * as z41 from "zod";
|
|
20802
20877
|
var tokensContract = {
|
|
20803
|
-
list: contractBase.meta(ACCESS.manageHost).output(
|
|
20804
|
-
create: contractBase.meta(ACCESS.manageHost).input(
|
|
20878
|
+
list: contractBase.meta(ACCESS.manageHost).output(z41.array(TokenSchema)),
|
|
20879
|
+
create: contractBase.meta(ACCESS.manageHost).input(z41.object({
|
|
20805
20880
|
name: NameSchema,
|
|
20806
20881
|
scope: ScopeSchema,
|
|
20807
|
-
imps:
|
|
20808
|
-
sshKeys:
|
|
20882
|
+
imps: z41.array(ImpPatternSchema).min(1).max(32).optional(),
|
|
20883
|
+
sshKeys: z41.array(SshPublicKeySchema).min(1).max(MAX_SSH_KEYS).optional(),
|
|
20809
20884
|
grantable: GrantableSchema.optional(),
|
|
20810
20885
|
imageRefPrefix: ImageRefPrefixSchema.optional()
|
|
20811
|
-
})).output(
|
|
20812
|
-
update: contractBase.meta(ACCESS.manageHost).input(
|
|
20886
|
+
})).output(z41.object({ token: TokenSchema, secret: z41.string() })),
|
|
20887
|
+
update: contractBase.meta(ACCESS.manageHost).input(z41.object({
|
|
20813
20888
|
name: NameSchema,
|
|
20814
20889
|
grantable: GrantableUpdateSchema.optional(),
|
|
20815
20890
|
imageRefPrefix: ImageRefPrefixSchema.nullable().optional()
|
|
20816
20891
|
}).refine((input) => input.grantable !== undefined || input.imageRefPrefix !== undefined, "must set grantable, imageRefPrefix or both")).output(TokenSchema),
|
|
20817
20892
|
delete: contractBase.meta(ACCESS.manageHost).input(NameInputSchema).output(EmptySchema),
|
|
20818
|
-
addKey: contractBase.meta(ACCESS.manageHost).input(
|
|
20819
|
-
removeKey: contractBase.meta(ACCESS.manageHost).input(
|
|
20893
|
+
addKey: contractBase.meta(ACCESS.manageHost).input(z41.object({ name: NameSchema, key: SshPublicKeySchema })).output(SshKeySchema),
|
|
20894
|
+
removeKey: contractBase.meta(ACCESS.manageHost).input(z41.object({ name: NameSchema, fingerprint: z41.string() })).output(EmptySchema),
|
|
20820
20895
|
whoami: contractBase.meta(ACCESS.readAny).output(IdentitySchema)
|
|
20821
20896
|
};
|
|
20822
20897
|
|
|
20823
20898
|
// packages/api/src/contract/caller-contract.ts
|
|
20824
|
-
var LeaseInputSchema =
|
|
20899
|
+
var LeaseInputSchema = z42.object({
|
|
20825
20900
|
name: NameSchema,
|
|
20826
20901
|
label: LeaseLabelSchema.refine((label) => label !== "hold", "hold is the label imps.hold writes"),
|
|
20827
20902
|
ttlSeconds: LeaseTtlSchema
|
|
20828
20903
|
});
|
|
20829
|
-
var ImageAddInputSchema =
|
|
20830
|
-
|
|
20831
|
-
|
|
20904
|
+
var ImageAddInputSchema = z42.union([
|
|
20905
|
+
z42.object({ ref: ImageRefSchema, name: NameSchema.optional() }),
|
|
20906
|
+
z42.object({ imp: NameSchema, name: NameSchema })
|
|
20832
20907
|
]);
|
|
20833
|
-
var ImageBuildInputSchema =
|
|
20834
|
-
contextDir:
|
|
20908
|
+
var ImageBuildInputSchema = z42.object({
|
|
20909
|
+
contextDir: z42.string().startsWith("/"),
|
|
20835
20910
|
name: NameSchema,
|
|
20836
20911
|
dockerfile: DockerfilePathSchema.optional(),
|
|
20837
|
-
logs:
|
|
20912
|
+
logs: z42.boolean().optional()
|
|
20838
20913
|
});
|
|
20839
|
-
var ImageBuildStreamInputSchema =
|
|
20914
|
+
var ImageBuildStreamInputSchema = z42.union([
|
|
20840
20915
|
ImageBuildInputSchema,
|
|
20841
|
-
|
|
20916
|
+
z42.object({ upload: z42.string().min(1), logs: z42.boolean().optional() })
|
|
20842
20917
|
]);
|
|
20843
|
-
var CheckpointCreateInputSchema =
|
|
20918
|
+
var CheckpointCreateInputSchema = z42.object({
|
|
20844
20919
|
name: NameSchema,
|
|
20845
|
-
label:
|
|
20920
|
+
label: z42.string().min(1).max(64).optional()
|
|
20846
20921
|
});
|
|
20847
20922
|
var callerContract = {
|
|
20848
20923
|
imps: impsContract,
|
|
20849
20924
|
leases: {
|
|
20850
20925
|
acquire: contractBase.meta(ACCESS.execImp).input(LeaseInputSchema).output(LeaseSchema),
|
|
20851
20926
|
renew: contractBase.meta(ACCESS.execImp).input(LeaseInputSchema).output(LeaseSchema),
|
|
20852
|
-
release: contractBase.meta(ACCESS.execImp).input(
|
|
20853
|
-
list: contractBase.meta({ access: { scope: "exec", on: "any", audit: false } }).input(
|
|
20927
|
+
release: contractBase.meta(ACCESS.execImp).input(z42.object({ name: NameSchema, label: LeaseLabelSchema })).output(z42.object({ released: z42.boolean() })),
|
|
20928
|
+
list: contractBase.meta({ access: { scope: "exec", on: "any", audit: false } }).input(z42.object({ name: NameSchema.optional(), label: LeaseLabelSchema.optional() })).output(z42.array(LeaseSchema))
|
|
20854
20929
|
},
|
|
20855
20930
|
moves: {
|
|
20856
|
-
prepare: contractBase.meta(ACCESS.manageImpNoGrantable).input(
|
|
20931
|
+
prepare: contractBase.meta(ACCESS.manageImpNoGrantable).input(z42.object({
|
|
20857
20932
|
name: NameSchema,
|
|
20858
|
-
stop:
|
|
20859
|
-
force:
|
|
20860
|
-
targetStorage:
|
|
20933
|
+
stop: z42.boolean().optional(),
|
|
20934
|
+
force: z42.boolean().optional(),
|
|
20935
|
+
targetStorage: z42.enum(["xfs", "zfs"]).optional(),
|
|
20861
20936
|
target: WarmHostSchema.optional()
|
|
20862
20937
|
})).output(MovePlanSchema),
|
|
20863
20938
|
facts: contractBase.meta(ACCESS.manageHost).output(WarmHostSchema),
|
|
20864
|
-
receive: contractBase.meta(ACCESS.manageHost).input(
|
|
20939
|
+
receive: contractBase.meta(ACCESS.manageHost).input(z42.object({
|
|
20865
20940
|
name: NameSchema,
|
|
20866
|
-
bytes:
|
|
20941
|
+
bytes: z42.int().nonnegative(),
|
|
20867
20942
|
warm: WarmMoveSchema.optional()
|
|
20868
20943
|
})).output(MoveTicketSchema),
|
|
20869
|
-
send: contractBase.meta(ACCESS.manageImpNoGrantable).input(
|
|
20870
|
-
status: contractBase.meta(ACCESS.readImp).input(
|
|
20871
|
-
reissue: contractBase.meta(ACCESS.manageHost).input(
|
|
20872
|
-
resume: contractBase.meta(ACCESS.manageImpNoGrantable).input(
|
|
20873
|
-
abort: contractBase.meta(ACCESS.manageImp).input(
|
|
20944
|
+
send: contractBase.meta(ACCESS.manageImpNoGrantable).input(z42.object({ name: NameSchema, to: PeerUrlSchema, ticket: z42.string() })).output(MoveStatusSchema),
|
|
20945
|
+
status: contractBase.meta(ACCESS.readImp).input(z42.object({ name: NameSchema })).output(MoveStatusSchema),
|
|
20946
|
+
reissue: contractBase.meta(ACCESS.manageHost).input(z42.object({ name: NameSchema })).output(MoveTicketSchema),
|
|
20947
|
+
resume: contractBase.meta(ACCESS.manageImpNoGrantable).input(z42.object({ name: NameSchema, ticket: z42.string().optional() })).output(MoveStatusSchema),
|
|
20948
|
+
abort: contractBase.meta(ACCESS.manageImp).input(z42.object({ name: NameSchema })).output(MoveStatusSchema)
|
|
20874
20949
|
},
|
|
20875
20950
|
checkpoints: {
|
|
20876
20951
|
create: contractBase.meta(ACCESS.manageImp).input(CheckpointCreateInputSchema).output(CheckpointSchema),
|
|
20877
|
-
list: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(
|
|
20878
|
-
restore: contractBase.meta(ACCESS.manageImp).input(
|
|
20879
|
-
delete: contractBase.meta(ACCESS.manageImp).input(
|
|
20952
|
+
list: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(z42.array(CheckpointSchema)),
|
|
20953
|
+
restore: contractBase.meta(ACCESS.manageImp).input(z42.object({ name: NameSchema, checkpoint: CheckpointRefSchema })).output(ImpSchema),
|
|
20954
|
+
delete: contractBase.meta(ACCESS.manageImp).input(z42.object({ name: NameSchema, checkpoint: CheckpointRefSchema })).output(EmptySchema)
|
|
20880
20955
|
},
|
|
20881
20956
|
backups: {
|
|
20882
20957
|
run: contractBase.meta(ACCESS.manageHost).output(BackupRunSchema),
|
|
20883
20958
|
list: contractBase.meta(ACCESS.readHost).output(BackupStatusSchema),
|
|
20884
|
-
restore: contractBase.meta(ACCESS.manageHost).input(
|
|
20959
|
+
restore: contractBase.meta(ACCESS.manageHost).input(z42.object({
|
|
20885
20960
|
name: NameSchema.optional(),
|
|
20886
|
-
all:
|
|
20887
|
-
at:
|
|
20961
|
+
all: z42.boolean().optional(),
|
|
20962
|
+
at: z42.date().optional(),
|
|
20888
20963
|
as: NameSchema.optional(),
|
|
20889
|
-
merge:
|
|
20964
|
+
merge: z42.boolean().optional()
|
|
20890
20965
|
})).output(BackupRestoreSchema),
|
|
20891
|
-
check: contractBase.meta(ACCESS.manageHost).input(
|
|
20966
|
+
check: contractBase.meta(ACCESS.manageHost).input(z42.object({ subset: BackupCheckSubsetSchema.optional() })).output(EmptySchema)
|
|
20892
20967
|
},
|
|
20893
20968
|
images: {
|
|
20894
|
-
list: contractBase.meta(ACCESS.readAny).output(
|
|
20969
|
+
list: contractBase.meta(ACCESS.readAny).output(z42.array(ImageSchema)),
|
|
20895
20970
|
add: contractBase.meta(ACCESS.manageImage).input(ImageAddInputSchema).output(ImageSchema),
|
|
20896
20971
|
build: contractBase.meta(ACCESS.manageHost).input(ImageBuildInputSchema).output(ImageSchema),
|
|
20897
20972
|
addStream: contractBase.meta({ access: { scope: "manage", on: "image", audit: "refusals" } }).input(ImageAddInputSchema).output(eventIterator(ImageOpEventSchema)),
|
|
20898
20973
|
buildStream: contractBase.meta({ access: { scope: "manage", on: "host", audit: "refusals" } }).input(ImageBuildStreamInputSchema).output(eventIterator(ImageOpEventSchema)),
|
|
20899
|
-
builds: contractBase.meta(ACCESS.readHost).output(
|
|
20974
|
+
builds: contractBase.meta(ACCESS.readHost).output(z42.array(ImageBuildRunSchema)),
|
|
20900
20975
|
delete: contractBase.meta(ACCESS.manageHost).input(NameInputSchema).output(EmptySchema),
|
|
20901
20976
|
pin: contractBase.meta(ACCESS.manageHeldImage).input(NameInputSchema).output(ImageSchema),
|
|
20902
20977
|
unpin: contractBase.meta(ACCESS.manageHeldImage).input(NameInputSchema).output(ImageSchema)
|
|
20903
20978
|
},
|
|
20904
20979
|
exec: {
|
|
20905
|
-
ticket: contractBase.meta({ access: { scope: "exec", on: "imp", fields: ["name"], audit: false } }).input(NameInputSchema).output(
|
|
20980
|
+
ticket: contractBase.meta({ access: { scope: "exec", on: "imp", fields: ["name"], audit: false } }).input(NameInputSchema).output(z42.object({ ticket: z42.string(), expiresAt: z42.date() }))
|
|
20906
20981
|
},
|
|
20907
20982
|
sessions: {
|
|
20908
|
-
list: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(
|
|
20909
|
-
kill: contractBase.meta(ACCESS.execImp).input(
|
|
20910
|
-
logs: contractBase.meta(ACCESS.readImp).input(SessionLogListInputSchema).output(
|
|
20983
|
+
list: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(z42.array(SessionSchema)),
|
|
20984
|
+
kill: contractBase.meta(ACCESS.execImp).input(z42.object({ name: NameSchema, session: SessionNameSchema })).output(EmptySchema),
|
|
20985
|
+
logs: contractBase.meta(ACCESS.readImp).input(SessionLogListInputSchema).output(z42.array(SessionLogSchema)),
|
|
20911
20986
|
readLog: contractBase.meta(ACCESS.execImp).input(SessionLogReadInputSchema).output(SessionLogReadSchema),
|
|
20912
|
-
deleteLog: contractBase.meta(ACCESS.execImp).input(SessionLogDeleteInputSchema).output(
|
|
20987
|
+
deleteLog: contractBase.meta(ACCESS.execImp).input(SessionLogDeleteInputSchema).output(z42.object({ deleted: z42.int().nonnegative() }))
|
|
20913
20988
|
},
|
|
20914
20989
|
services: {
|
|
20915
20990
|
list: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(ServiceListSchema),
|
|
20916
|
-
add: contractBase.meta(ACCESS.execImp).input(
|
|
20991
|
+
add: contractBase.meta(ACCESS.execImp).input(z42.object({
|
|
20917
20992
|
name: NameSchema,
|
|
20918
20993
|
service: ServiceDefSchema,
|
|
20919
|
-
replace:
|
|
20994
|
+
replace: z42.boolean().optional()
|
|
20920
20995
|
})).output(EmptySchema),
|
|
20921
|
-
remove: contractBase.meta(ACCESS.execImp).input(
|
|
20922
|
-
restart: contractBase.meta(ACCESS.execImp).input(
|
|
20923
|
-
logs: contractBase.meta(ACCESS.execImp).input(
|
|
20996
|
+
remove: contractBase.meta(ACCESS.execImp).input(z42.object({ name: NameSchema, service: ServiceNameSchema })).output(EmptySchema),
|
|
20997
|
+
restart: contractBase.meta(ACCESS.execImp).input(z42.object({ name: NameSchema, service: ServiceNameSchema })).output(EmptySchema),
|
|
20998
|
+
logs: contractBase.meta(ACCESS.execImp).input(z42.object({
|
|
20924
20999
|
name: NameSchema,
|
|
20925
21000
|
service: ServiceNameSchema.optional(),
|
|
20926
|
-
lines:
|
|
20927
|
-
follow:
|
|
21001
|
+
lines: z42.int().min(0).max(SERVICE_LOG_MAX_LINES).optional(),
|
|
21002
|
+
follow: z42.boolean().optional()
|
|
20928
21003
|
})).output(eventIterator(ServiceLogSchema))
|
|
20929
21004
|
},
|
|
20930
21005
|
files: {
|
|
20931
|
-
write: contractBase.meta(ACCESS.execImp).input(
|
|
20932
|
-
remove: contractBase.meta(ACCESS.execImp).input(
|
|
21006
|
+
write: contractBase.meta(ACCESS.execImp).input(z42.object({ name: NameSchema, path: FilePathSchema, content: FileContentSchema })).output(z42.object({ path: z42.string() })),
|
|
21007
|
+
remove: contractBase.meta(ACCESS.execImp).input(z42.object({ name: NameSchema, path: FilePathSchema })).output(z42.object({ removed: z42.boolean() }))
|
|
20933
21008
|
},
|
|
20934
21009
|
secrets: {
|
|
20935
|
-
add: contractBase.meta(ACCESS.manageHost).input(
|
|
20936
|
-
|
|
20937
|
-
|
|
20938
|
-
|
|
20939
|
-
rules: z41.array(BrokerRuleSchema).min(1).max(16).optional(),
|
|
20940
|
-
oauth: OAuthConfigSchema.optional(),
|
|
20941
|
-
replace: z41.boolean().optional(),
|
|
20942
|
-
rebind: z41.boolean().optional()
|
|
20943
|
-
})).output(SecretAddedSchema),
|
|
20944
|
-
list: contractBase.meta(ACCESS.readAny).output(z41.array(SecretSchema)),
|
|
20945
|
-
refresh: contractBase.meta(ACCESS.manageHost).input(z41.object({ name: SecretNameSchema })).output(SecretSchema),
|
|
20946
|
-
delete: contractBase.meta(ACCESS.manageHost).input(z41.object({ name: SecretNameSchema })).output(EmptySchema)
|
|
21010
|
+
add: contractBase.meta(ACCESS.manageHost).input(SecretAddSchema).output(SecretAddedSchema),
|
|
21011
|
+
list: contractBase.meta(ACCESS.readAny).output(z42.array(SecretSchema)),
|
|
21012
|
+
refresh: contractBase.meta(ACCESS.manageHost).input(z42.object({ name: SecretNameSchema })).output(SecretSchema),
|
|
21013
|
+
delete: contractBase.meta(ACCESS.manageHost).input(z42.object({ name: SecretNameSchema })).output(EmptySchema)
|
|
20947
21014
|
},
|
|
20948
21015
|
networks: {
|
|
20949
|
-
list: contractBase.meta(ACCESS.readAny).output(
|
|
21016
|
+
list: contractBase.meta(ACCESS.readAny).output(z42.array(NetworkSchema)),
|
|
20950
21017
|
create: contractBase.meta(ACCESS.manageHost).input(NameInputSchema).output(NetworkSchema),
|
|
20951
21018
|
delete: contractBase.meta(ACCESS.manageHost).input(NameInputSchema).output(EmptySchema),
|
|
20952
|
-
join: contractBase.meta(ACCESS.manageHost).input(
|
|
20953
|
-
warnings: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(
|
|
20954
|
-
leave: contractBase.meta(ACCESS.manageHost).input(
|
|
21019
|
+
join: contractBase.meta(ACCESS.manageHost).input(z42.object({ network: NameSchema, name: NameSchema })).output(NetworkJoinSchema),
|
|
21020
|
+
warnings: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(z42.array(z42.string())),
|
|
21021
|
+
leave: contractBase.meta(ACCESS.manageHost).input(z42.object({ network: NameSchema, name: NameSchema })).output(NetworkSchema)
|
|
20955
21022
|
},
|
|
20956
21023
|
grants: {
|
|
20957
|
-
add: contractBase.meta(ACCESS.manageGrant).input(
|
|
21024
|
+
add: contractBase.meta(ACCESS.manageGrant).input(z42.object({
|
|
20958
21025
|
name: NameSchema,
|
|
20959
21026
|
secret: SecretNameSchema,
|
|
20960
21027
|
filter: GrantFilterSchema.optional()
|
|
20961
21028
|
})).output(EmptySchema),
|
|
20962
|
-
delete: contractBase.meta(ACCESS.manageGrant).input(
|
|
20963
|
-
list: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(
|
|
20964
|
-
details: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(
|
|
21029
|
+
delete: contractBase.meta(ACCESS.manageGrant).input(z42.object({ name: NameSchema, secret: SecretNameSchema })).output(EmptySchema),
|
|
21030
|
+
list: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(z42.array(SecretNameSchema)),
|
|
21031
|
+
details: contractBase.meta(ACCESS.readImp).input(NameInputSchema).output(z42.array(GrantSchema))
|
|
20965
21032
|
},
|
|
20966
21033
|
audit: {
|
|
20967
|
-
list: contractBase.meta(ACCESS.readAny).input(
|
|
21034
|
+
list: contractBase.meta(ACCESS.readAny).input(z42.object({
|
|
20968
21035
|
name: NameSchema.optional(),
|
|
20969
|
-
limit:
|
|
20970
|
-
})).output(
|
|
20971
|
-
refused: contractBase.meta(ACCESS.readAny).input(
|
|
21036
|
+
limit: z42.int().min(1).max(1000).optional()
|
|
21037
|
+
})).output(z42.array(AuditEntrySchema)),
|
|
21038
|
+
refused: contractBase.meta(ACCESS.readAny).input(z42.object({
|
|
20972
21039
|
name: NameSchema.optional(),
|
|
20973
|
-
limit:
|
|
20974
|
-
})).output(
|
|
20975
|
-
calls: contractBase.meta(ACCESS.readAny).input(
|
|
21040
|
+
limit: z42.int().min(1).max(1000).optional()
|
|
21041
|
+
})).output(z42.array(RefusedRequestSchema)),
|
|
21042
|
+
calls: contractBase.meta(ACCESS.readAny).input(z42.object({
|
|
20976
21043
|
name: NameSchema.optional(),
|
|
20977
|
-
limit:
|
|
20978
|
-
})).output(
|
|
21044
|
+
limit: z42.int().min(1).max(1000).optional()
|
|
21045
|
+
})).output(z42.array(ApiCallSchema))
|
|
20979
21046
|
},
|
|
20980
21047
|
events: {
|
|
20981
21048
|
stream: contractBase.meta(ACCESS.readAny).output(eventIterator(ImpEventSchema))
|
|
@@ -20983,40 +21050,40 @@ var callerContract = {
|
|
|
20983
21050
|
system: {
|
|
20984
21051
|
info: contractBase.meta(ACCESS.readAny).output(SystemInfoSchema),
|
|
20985
21052
|
features: contractBase.meta(ACCESS.readAny).output(SystemFeaturesInfoSchema),
|
|
20986
|
-
gc: contractBase.meta(ACCESS.manageHost).input(
|
|
20987
|
-
dryRun:
|
|
20988
|
-
orphans:
|
|
20989
|
-
secretFiles:
|
|
20990
|
-
removeSecretFiles:
|
|
21053
|
+
gc: contractBase.meta(ACCESS.manageHost).input(z42.object({
|
|
21054
|
+
dryRun: z42.boolean().optional(),
|
|
21055
|
+
orphans: z42.boolean().optional(),
|
|
21056
|
+
secretFiles: z42.boolean().optional(),
|
|
21057
|
+
removeSecretFiles: z42.boolean().optional()
|
|
20991
21058
|
})).output(StorageGcSchema),
|
|
20992
|
-
copyDatabase: contractBase.meta(ACCESS.manageHost).input(
|
|
21059
|
+
copyDatabase: contractBase.meta(ACCESS.manageHost).input(z42.object({ name: NameSchema.optional() })).output(DatabaseCopySchema)
|
|
20993
21060
|
},
|
|
20994
21061
|
oauth: {
|
|
20995
21062
|
clients: {
|
|
20996
|
-
list: contractBase.meta(ACCESS.manageHost).output(
|
|
20997
|
-
add: contractBase.meta(ACCESS.manageHost).input(
|
|
20998
|
-
update: contractBase.meta(ACCESS.manageHost).input(
|
|
21063
|
+
list: contractBase.meta(ACCESS.manageHost).output(z42.array(OAuthClientSchema)),
|
|
21064
|
+
add: contractBase.meta(ACCESS.manageHost).input(z42.object({ name: NameSchema, redirectUris: RedirectUrisSchema })).output(OAuthClientSchema),
|
|
21065
|
+
update: contractBase.meta(ACCESS.manageHost).input(z42.object({ name: NameSchema, redirectUris: RedirectUrisSchema })).output(OAuthClientSchema),
|
|
20999
21066
|
delete: contractBase.meta(ACCESS.manageHost).input(NameInputSchema).output(EmptySchema)
|
|
21000
21067
|
},
|
|
21001
21068
|
grants: {
|
|
21002
|
-
list: contractBase.meta(ACCESS.manageHost).output(
|
|
21003
|
-
delete: contractBase.meta(ACCESS.manageHost).input(
|
|
21069
|
+
list: contractBase.meta(ACCESS.manageHost).output(z42.array(OAuthGrantSchema)),
|
|
21070
|
+
delete: contractBase.meta(ACCESS.manageHost).input(z42.object({ id: z42.string().min(1).max(64) })).output(EmptySchema)
|
|
21004
21071
|
},
|
|
21005
21072
|
approvals: {
|
|
21006
|
-
get: contractBase.meta(ACCESS.readAny).input(
|
|
21007
|
-
approve: contractBase.meta(ACCESS.readAny).input(
|
|
21073
|
+
get: contractBase.meta(ACCESS.readAny).input(z42.object({ code: ApprovalCodeSchema })).output(OAuthApprovalSchema),
|
|
21074
|
+
approve: contractBase.meta(ACCESS.readAny).input(z42.object({
|
|
21008
21075
|
code: ApprovalCodeSchema,
|
|
21009
21076
|
scope: ScopeSchema,
|
|
21010
|
-
imps:
|
|
21077
|
+
imps: z42.array(GrantPatternSchema).min(1).max(32).optional()
|
|
21011
21078
|
})).output(EmptySchema)
|
|
21012
21079
|
}
|
|
21013
21080
|
},
|
|
21014
21081
|
tokens: tokensContract
|
|
21015
21082
|
};
|
|
21016
21083
|
// packages/api/src/contract/auth-contract.ts
|
|
21017
|
-
import * as
|
|
21084
|
+
import * as z43 from "zod";
|
|
21018
21085
|
var authContract = {
|
|
21019
|
-
login: contractBase.meta(ACCESS.noSession).errors({ UNAUTHORIZED: { message: "The token authenticates nobody" } }).input(
|
|
21086
|
+
login: contractBase.meta(ACCESS.noSession).errors({ UNAUTHORIZED: { message: "The token authenticates nobody" } }).input(z43.object({ token: z43.string() })).output(EmptySchema),
|
|
21020
21087
|
logout: contractBase.meta(ACCESS.noSession).output(EmptySchema)
|
|
21021
21088
|
};
|
|
21022
21089
|
|
|
@@ -21024,43 +21091,43 @@ var authContract = {
|
|
|
21024
21091
|
var sessionContract = { auth: authContract };
|
|
21025
21092
|
// packages/api/src/contract/collect-procedure-access.ts
|
|
21026
21093
|
import { isContractProcedure } from "@orpc/contract";
|
|
21027
|
-
import * as
|
|
21094
|
+
import * as z45 from "zod";
|
|
21028
21095
|
|
|
21029
21096
|
// packages/api/src/schemas/procedure-access-schema.ts
|
|
21030
|
-
import * as
|
|
21031
|
-
var FieldsSchema =
|
|
21032
|
-
var NoSessionAccessSchema =
|
|
21033
|
-
var HostAccessSchema =
|
|
21097
|
+
import * as z44 from "zod";
|
|
21098
|
+
var FieldsSchema = z44.array(z44.string()).readonly();
|
|
21099
|
+
var NoSessionAccessSchema = z44.object({ on: z44.literal("none") });
|
|
21100
|
+
var HostAccessSchema = z44.object({
|
|
21034
21101
|
scope: ScopeSchema,
|
|
21035
|
-
on:
|
|
21036
|
-
audit:
|
|
21102
|
+
on: z44.literal("host"),
|
|
21103
|
+
audit: z44.union([z44.literal(false), z44.literal("refusals")]).optional()
|
|
21037
21104
|
});
|
|
21038
|
-
var ImpAccessSchema =
|
|
21105
|
+
var ImpAccessSchema = z44.object({
|
|
21039
21106
|
scope: ScopeSchema,
|
|
21040
|
-
on:
|
|
21107
|
+
on: z44.literal("imp"),
|
|
21041
21108
|
fields: FieldsSchema,
|
|
21042
|
-
noGrantable:
|
|
21043
|
-
audit:
|
|
21109
|
+
noGrantable: z44.literal(true).optional(),
|
|
21110
|
+
audit: z44.literal(false).optional()
|
|
21044
21111
|
});
|
|
21045
|
-
var GrantAccessSchema =
|
|
21112
|
+
var GrantAccessSchema = z44.object({
|
|
21046
21113
|
scope: ScopeSchema,
|
|
21047
|
-
on:
|
|
21114
|
+
on: z44.literal("grant"),
|
|
21048
21115
|
fields: FieldsSchema,
|
|
21049
|
-
secretField:
|
|
21050
|
-
audit:
|
|
21116
|
+
secretField: z44.string(),
|
|
21117
|
+
audit: z44.literal(false).optional()
|
|
21051
21118
|
});
|
|
21052
|
-
var ImageAccessSchema =
|
|
21119
|
+
var ImageAccessSchema = z44.object({
|
|
21053
21120
|
scope: ScopeSchema,
|
|
21054
|
-
on:
|
|
21055
|
-
held:
|
|
21056
|
-
audit:
|
|
21121
|
+
on: z44.literal("image"),
|
|
21122
|
+
held: z44.literal(true).optional(),
|
|
21123
|
+
audit: z44.union([z44.literal(false), z44.literal("refusals")]).optional()
|
|
21057
21124
|
});
|
|
21058
|
-
var AnyAccessSchema =
|
|
21125
|
+
var AnyAccessSchema = z44.object({
|
|
21059
21126
|
scope: ScopeSchema,
|
|
21060
|
-
on:
|
|
21061
|
-
audit:
|
|
21127
|
+
on: z44.literal("any"),
|
|
21128
|
+
audit: z44.literal(false).optional()
|
|
21062
21129
|
});
|
|
21063
|
-
var ProcedureAccessSchema =
|
|
21130
|
+
var ProcedureAccessSchema = z44.discriminatedUnion("on", [
|
|
21064
21131
|
NoSessionAccessSchema,
|
|
21065
21132
|
HostAccessSchema,
|
|
21066
21133
|
ImpAccessSchema,
|
|
@@ -21070,7 +21137,7 @@ var ProcedureAccessSchema = z43.discriminatedUnion("on", [
|
|
|
21070
21137
|
]);
|
|
21071
21138
|
|
|
21072
21139
|
// packages/api/src/contract/collect-procedure-access.ts
|
|
21073
|
-
var MetaSchema =
|
|
21140
|
+
var MetaSchema = z45.object({ access: ProcedureAccessSchema });
|
|
21074
21141
|
function collectProcedureAccess(router, prefix = "") {
|
|
21075
21142
|
return Object.entries(router).flatMap(([key, value]) => {
|
|
21076
21143
|
const path = `${prefix}${key}`;
|
|
@@ -21128,23 +21195,23 @@ var MOVE_RECEIVE_PATH = "/move/receive";
|
|
|
21128
21195
|
import { oc as oc2 } from "@orpc/contract";
|
|
21129
21196
|
|
|
21130
21197
|
// packages/api/src/schemas/move-peer-schema.ts
|
|
21131
|
-
import * as
|
|
21132
|
-
var SystemDriveSchema =
|
|
21133
|
-
var MoveOfferSchema =
|
|
21134
|
-
imageDigest:
|
|
21135
|
-
receivedImageDigest:
|
|
21198
|
+
import * as z46 from "zod";
|
|
21199
|
+
var SystemDriveSchema = z46.string().regex(/^[\da-f]{64}$/v);
|
|
21200
|
+
var MoveOfferSchema = z46.object({
|
|
21201
|
+
imageDigest: z46.string(),
|
|
21202
|
+
receivedImageDigest: z46.string().nullable().default(null),
|
|
21136
21203
|
systemDrive: SystemDriveSchema.optional()
|
|
21137
21204
|
});
|
|
21138
|
-
var MoveOfferReplySchema =
|
|
21139
|
-
needsImage:
|
|
21140
|
-
needsSystemDrive:
|
|
21141
|
-
storage:
|
|
21142
|
-
keepsMaxMemory:
|
|
21143
|
-
keepsLeases:
|
|
21144
|
-
keepsPublicEgress:
|
|
21145
|
-
keepsBackupOff:
|
|
21205
|
+
var MoveOfferReplySchema = z46.object({
|
|
21206
|
+
needsImage: z46.boolean(),
|
|
21207
|
+
needsSystemDrive: z46.boolean().default(false),
|
|
21208
|
+
storage: z46.enum(["xfs", "zfs"]),
|
|
21209
|
+
keepsMaxMemory: z46.boolean().default(false),
|
|
21210
|
+
keepsLeases: z46.boolean().default(false),
|
|
21211
|
+
keepsPublicEgress: z46.boolean().default(false),
|
|
21212
|
+
keepsBackupOff: z46.boolean().default(false)
|
|
21146
21213
|
});
|
|
21147
|
-
var MoveCommitReplySchema =
|
|
21214
|
+
var MoveCommitReplySchema = z46.object({ isCommitted: z46.boolean() });
|
|
21148
21215
|
|
|
21149
21216
|
// packages/api/src/contract/move-peer-contract.ts
|
|
21150
21217
|
var movePeerContract = {
|
|
@@ -21152,6 +21219,28 @@ var movePeerContract = {
|
|
|
21152
21219
|
commit: oc2.route({ method: "POST", path: "/move/commit" }).output(MoveCommitReplySchema),
|
|
21153
21220
|
abort: oc2.route({ method: "POST", path: "/move/abort" }).output(MoveCommitReplySchema)
|
|
21154
21221
|
};
|
|
21222
|
+
// packages/api/src/schemas/secret-presets.ts
|
|
21223
|
+
var SECRET_PRESETS = {
|
|
21224
|
+
github: {
|
|
21225
|
+
kind: "static",
|
|
21226
|
+
rules: [
|
|
21227
|
+
{ host: "github.com", header: "authorization", scheme: "basic", user: "x-access-token" },
|
|
21228
|
+
{ host: "api.github.com", header: "authorization", scheme: "bearer" },
|
|
21229
|
+
{ host: "uploads.github.com", header: "authorization", scheme: "bearer" }
|
|
21230
|
+
],
|
|
21231
|
+
env: ["GH_TOKEN", "GITHUB_TOKEN"]
|
|
21232
|
+
},
|
|
21233
|
+
anthropic: {
|
|
21234
|
+
kind: "static",
|
|
21235
|
+
rules: [{ host: "api.anthropic.com", header: "x-api-key", scheme: "raw" }],
|
|
21236
|
+
env: ["ANTHROPIC_API_KEY"]
|
|
21237
|
+
},
|
|
21238
|
+
npm: {
|
|
21239
|
+
kind: "static",
|
|
21240
|
+
rules: [{ host: "registry.npmjs.org", header: "authorization", scheme: "bearer" }],
|
|
21241
|
+
env: ["NPM_TOKEN"]
|
|
21242
|
+
}
|
|
21243
|
+
};
|
|
21155
21244
|
// packages/api/src/rules/has-scope.ts
|
|
21156
21245
|
function hasScope(granted, needed) {
|
|
21157
21246
|
const grantedRank = ScopeSchema.options.indexOf(granted);
|
|
@@ -21159,7 +21248,7 @@ function hasScope(granted, needed) {
|
|
|
21159
21248
|
return grantedRank !== -1 && neededRank !== -1 && grantedRank >= neededRank;
|
|
21160
21249
|
}
|
|
21161
21250
|
// packages/daemon/src/identity/auth/tailnet-identity.ts
|
|
21162
|
-
import * as
|
|
21251
|
+
import * as z47 from "zod";
|
|
21163
21252
|
|
|
21164
21253
|
// packages/daemon/src/platform/process/ttl-cache.ts
|
|
21165
21254
|
import { LRUCache } from "lru-cache";
|
|
@@ -21173,16 +21262,16 @@ function createTtlCache(options) {
|
|
|
21173
21262
|
}
|
|
21174
21263
|
|
|
21175
21264
|
// packages/daemon/src/identity/auth/tailnet-identity.ts
|
|
21176
|
-
var TailnetRuleSchema =
|
|
21177
|
-
match:
|
|
21265
|
+
var TailnetRuleSchema = z47.object({
|
|
21266
|
+
match: z47.string().regex(/^(?:user:\S+|tag:[\w-]+|\*)$/u, "must be user:<login>, tag:<tag> or *"),
|
|
21178
21267
|
scope: ScopeSchema,
|
|
21179
|
-
imps:
|
|
21268
|
+
imps: z47.array(ImpPatternSchema).min(1).readonly().optional()
|
|
21180
21269
|
}).readonly();
|
|
21181
|
-
var TailnetRulesSchema =
|
|
21182
|
-
var TagsSchema =
|
|
21183
|
-
var WhoisSchema =
|
|
21184
|
-
Node:
|
|
21185
|
-
UserProfile:
|
|
21270
|
+
var TailnetRulesSchema = z47.array(TailnetRuleSchema).min(1).readonly();
|
|
21271
|
+
var TagsSchema = z47.array(z47.string()).nullable().optional();
|
|
21272
|
+
var WhoisSchema = z47.object({
|
|
21273
|
+
Node: z47.object({ Name: z47.string(), Tags: TagsSchema, StableID: z47.string().optional() }),
|
|
21274
|
+
UserProfile: z47.object({ LoginName: z47.string() })
|
|
21186
21275
|
});
|
|
21187
21276
|
var WHOIS_TTL_MS = 60000;
|
|
21188
21277
|
var MAX_CACHED = 256;
|
|
@@ -21305,16 +21394,16 @@ function parseTailnetRules(text) {
|
|
|
21305
21394
|
}
|
|
21306
21395
|
const rules = TailnetRulesSchema.safeParse(json);
|
|
21307
21396
|
if (!rules.success) {
|
|
21308
|
-
throw new Error(`IMP_TAILNET_IDENTITIES: ${
|
|
21397
|
+
throw new Error(`IMP_TAILNET_IDENTITIES: ${z48.prettifyError(rules.error)}`);
|
|
21309
21398
|
}
|
|
21310
21399
|
return rules.data;
|
|
21311
21400
|
}
|
|
21312
21401
|
|
|
21313
21402
|
// packages/daemon/src/identity/oauth/public-mcp-config.ts
|
|
21314
|
-
import * as
|
|
21315
|
-
var PublicMcpEnvSchema =
|
|
21316
|
-
IMP_MCP_PUBLIC_URL:
|
|
21317
|
-
IMP_MCP_PUBLIC_PORT:
|
|
21403
|
+
import * as z49 from "zod";
|
|
21404
|
+
var PublicMcpEnvSchema = z49.object({
|
|
21405
|
+
IMP_MCP_PUBLIC_URL: z49.string().optional(),
|
|
21406
|
+
IMP_MCP_PUBLIC_PORT: z49.coerce.number().pipe(z49.int().min(1).max(65535)).default(7071)
|
|
21318
21407
|
});
|
|
21319
21408
|
var LOOPBACK_HOSTS = new Set(["127.0.0.1", "localhost", "[::1]"]);
|
|
21320
21409
|
function parsePublicMcpConfig(env, others, slotPorts) {
|
|
@@ -21352,16 +21441,16 @@ function parseOrigin(text) {
|
|
|
21352
21441
|
}
|
|
21353
21442
|
|
|
21354
21443
|
// packages/daemon/src/imp-ops/backup/backup-config.ts
|
|
21355
|
-
import * as
|
|
21356
|
-
var CountSchema2 =
|
|
21444
|
+
import * as z50 from "zod";
|
|
21445
|
+
var CountSchema2 = z50.coerce.number().pipe(z50.int().positive());
|
|
21357
21446
|
var KEEP_BUCKETS = ["hourly", "daily", "weekly"];
|
|
21358
|
-
var BackupEnvSchema =
|
|
21359
|
-
IMP_BACKUP_REPOSITORY:
|
|
21360
|
-
IMP_BACKUP_PASSWORD_FILE:
|
|
21447
|
+
var BackupEnvSchema = z50.object({
|
|
21448
|
+
IMP_BACKUP_REPOSITORY: z50.string().optional(),
|
|
21449
|
+
IMP_BACKUP_PASSWORD_FILE: z50.string().optional(),
|
|
21361
21450
|
IMP_BACKUP_INTERVAL_S: CountSchema2.default(21600),
|
|
21362
|
-
IMP_BACKUP_KEEP:
|
|
21363
|
-
IMP_BACKUP_FORGET:
|
|
21364
|
-
IMP_BACKUP_DATABASE:
|
|
21451
|
+
IMP_BACKUP_KEEP: z50.string().default("hourly=24,daily=7,weekly=4"),
|
|
21452
|
+
IMP_BACKUP_FORGET: z50.enum(["true", "false"]).default("true"),
|
|
21453
|
+
IMP_BACKUP_DATABASE: z50.enum(["true", "false"]).default("false"),
|
|
21365
21454
|
IMP_BACKUP_CPUS: CountSchema2.default(2),
|
|
21366
21455
|
IMP_BACKUP_MEMORY_MIB: CountSchema2.default(512)
|
|
21367
21456
|
});
|
|
@@ -21442,26 +21531,26 @@ function checkPublicPorts(ports, others, slotPorts) {
|
|
|
21442
21531
|
|
|
21443
21532
|
// packages/daemon/src/network/https/https-config.ts
|
|
21444
21533
|
import { existsSync as existsSync3 } from "fs";
|
|
21445
|
-
import * as
|
|
21534
|
+
import * as z51 from "zod";
|
|
21446
21535
|
var LETS_ENCRYPT_DIRECTORY = "https://acme-v02.api.letsencrypt.org/directory";
|
|
21447
|
-
var DomainSchema =
|
|
21448
|
-
var PortSchema2 =
|
|
21536
|
+
var DomainSchema = z51.string().transform((value) => value.toLowerCase().replace(/\.$/u, "")).pipe(z51.string().regex(/^(?:[a-z\d](?:[a-z\d-]{0,61}[a-z\d])?\.)+[a-z\d](?:[a-z\d-]{0,61}[a-z\d])?$/u, "IMP_DOMAIN must be a domain name such as imp.example.com"));
|
|
21537
|
+
var PortSchema2 = z51.coerce.number().pipe(z51.int().min(1).max(65535));
|
|
21449
21538
|
var DNS_PROVIDERS = ["cloudflare", "challtestsrv"];
|
|
21450
|
-
var HttpsEnvSchema =
|
|
21539
|
+
var HttpsEnvSchema = z51.object({
|
|
21451
21540
|
IMP_DOMAIN: DomainSchema.optional(),
|
|
21452
21541
|
IMP_HTTPS_PORT: PortSchema2.default(443),
|
|
21453
21542
|
IMP_HTTP_PORT: PortSchema2.default(80),
|
|
21454
|
-
IMP_DNS_PROVIDER:
|
|
21455
|
-
IMP_DNS_API_TOKEN:
|
|
21456
|
-
IMP_DNS_API_TOKEN_FILE:
|
|
21457
|
-
IMP_DNS_API_URL:
|
|
21458
|
-
IMP_ACME_DIRECTORY:
|
|
21459
|
-
IMP_ACME_EMAIL:
|
|
21460
|
-
IMP_ACME_CA_FILE:
|
|
21461
|
-
IMP_PUBLIC_IP:
|
|
21543
|
+
IMP_DNS_PROVIDER: z51.enum(DNS_PROVIDERS).optional(),
|
|
21544
|
+
IMP_DNS_API_TOKEN: z51.string().optional(),
|
|
21545
|
+
IMP_DNS_API_TOKEN_FILE: z51.string().optional(),
|
|
21546
|
+
IMP_DNS_API_URL: z51.url().optional(),
|
|
21547
|
+
IMP_ACME_DIRECTORY: z51.url().default(LETS_ENCRYPT_DIRECTORY),
|
|
21548
|
+
IMP_ACME_EMAIL: z51.email().optional(),
|
|
21549
|
+
IMP_ACME_CA_FILE: z51.string().optional(),
|
|
21550
|
+
IMP_PUBLIC_IP: z51.ipv4().optional(),
|
|
21462
21551
|
IMP_PUBLIC_HTTPS_PORT: PortSchema2.default(7443),
|
|
21463
21552
|
IMP_PUBLIC_HTTP_PORT: PortSchema2.default(7480),
|
|
21464
|
-
IMP_E2E:
|
|
21553
|
+
IMP_E2E: z51.literal("1").optional()
|
|
21465
21554
|
});
|
|
21466
21555
|
function readHttpsConfig(env) {
|
|
21467
21556
|
if (env.IMP_DNS_API_TOKEN !== undefined && env.IMP_DNS_API_TOKEN_FILE !== undefined) {
|
|
@@ -21556,12 +21645,12 @@ function checkSecureUrl(url) {
|
|
|
21556
21645
|
|
|
21557
21646
|
// packages/daemon/src/network/tailnet-names/tailnet-names-config.ts
|
|
21558
21647
|
import { join as join3 } from "path";
|
|
21559
|
-
import * as
|
|
21560
|
-
var PrefixSchema =
|
|
21561
|
-
var TailnetNamesEnvSchema =
|
|
21562
|
-
IMP_TAILNET_NAMES:
|
|
21648
|
+
import * as z52 from "zod";
|
|
21649
|
+
var PrefixSchema = z52.string().regex(/^[a-z][a-z\d-]{0,20}$/u, "IMP_TAILNET_NAME_PREFIX must be a lowercase letter followed by up to 20 letters, digits or hyphens");
|
|
21650
|
+
var TailnetNamesEnvSchema = z52.object({
|
|
21651
|
+
IMP_TAILNET_NAMES: z52.literal("1").optional(),
|
|
21563
21652
|
IMP_TAILNET_NAME_PREFIX: PrefixSchema.optional(),
|
|
21564
|
-
IMP_TAILNET_OAUTH_FILE:
|
|
21653
|
+
IMP_TAILNET_OAUTH_FILE: z52.string().optional()
|
|
21565
21654
|
});
|
|
21566
21655
|
function parseTailnetNamesConfig(env, dataDir, isOnTailnet) {
|
|
21567
21656
|
if (env.IMP_TAILNET_NAMES === undefined) {
|
|
@@ -21577,33 +21666,33 @@ function parseTailnetNamesConfig(env, dataDir, isOnTailnet) {
|
|
|
21577
21666
|
}
|
|
21578
21667
|
|
|
21579
21668
|
// packages/daemon/src/config.ts
|
|
21580
|
-
var PortSchema3 =
|
|
21581
|
-
var CountSchema3 =
|
|
21582
|
-
var DnsServersSchema =
|
|
21583
|
-
var PercentSchema =
|
|
21584
|
-
var MarkSchema =
|
|
21585
|
-
var EnvSchema =
|
|
21586
|
-
IMP_DATA_DIR:
|
|
21669
|
+
var PortSchema3 = z53.coerce.number().pipe(z53.int().min(1).max(65535));
|
|
21670
|
+
var CountSchema3 = z53.coerce.number().pipe(z53.int().positive());
|
|
21671
|
+
var DnsServersSchema = z53.array(z53.ipv4()).min(1);
|
|
21672
|
+
var PercentSchema = z53.coerce.number().pipe(z53.int().min(0).max(100));
|
|
21673
|
+
var MarkSchema = z53.coerce.number().pipe(z53.int().min(1).max(99));
|
|
21674
|
+
var EnvSchema = z53.object({
|
|
21675
|
+
IMP_DATA_DIR: z53.string().default("/var/lib/imp"),
|
|
21587
21676
|
IMP_API_PORT: PortSchema3.default(7070),
|
|
21588
21677
|
IMP_PROXY_PORT: PortSchema3.default(7080),
|
|
21589
21678
|
IMP_PORT_BASE: PortSchema3.default(20000),
|
|
21590
|
-
IMP_SSH_PORT:
|
|
21591
|
-
IMP_SSH_AUTHORIZED_KEYS:
|
|
21679
|
+
IMP_SSH_PORT: z53.coerce.number().pipe(z53.int().min(0).max(65535)).default(22),
|
|
21680
|
+
IMP_SSH_AUTHORIZED_KEYS: z53.enum(["true", "false"]).default("true"),
|
|
21592
21681
|
IMP_BROKER_PORT: PortSchema3.default(7081),
|
|
21593
|
-
IMP_BROKER_TEST_UPSTREAMS:
|
|
21682
|
+
IMP_BROKER_TEST_UPSTREAMS: z53.string().optional(),
|
|
21594
21683
|
IMP_EGRESS_DNS_PORT: PortSchema3.default(7053),
|
|
21595
|
-
IMP_EGRESS_DENY:
|
|
21596
|
-
IMP_HOST_ADDRESSES:
|
|
21684
|
+
IMP_EGRESS_DENY: z53.string().default(""),
|
|
21685
|
+
IMP_HOST_ADDRESSES: z53.string().default(""),
|
|
21597
21686
|
IMP_RAM_BUDGET_MIB: CountSchema3.default(16384),
|
|
21598
21687
|
IMP_IDLE_TIMEOUT_S: CountSchema3.default(60),
|
|
21599
|
-
IMP_IDLE_CPU_PERCENT:
|
|
21688
|
+
IMP_IDLE_CPU_PERCENT: z53.coerce.number().nonnegative().default(10),
|
|
21600
21689
|
IMP_MEMORY_SHRINK_AFTER_S: CountSchema3.default(60),
|
|
21601
|
-
IMP_BOOT_RESERVE_PERCENT: CountSchema3.pipe(
|
|
21690
|
+
IMP_BOOT_RESERVE_PERCENT: CountSchema3.pipe(z53.int().max(100)).default(50),
|
|
21602
21691
|
IMP_WAKE_RESERVE_MIB: CountSchema3.default(256),
|
|
21603
|
-
IMP_SLEEP_MIN_GUEST_UPTIME_MS:
|
|
21604
|
-
IMP_BOOT_TEMPLATES:
|
|
21692
|
+
IMP_SLEEP_MIN_GUEST_UPTIME_MS: z53.coerce.number().pipe(z53.int().nonnegative()).default(1500),
|
|
21693
|
+
IMP_BOOT_TEMPLATES: z53.enum(["true", "false"]).default("true"),
|
|
21605
21694
|
IMP_WATCHDOG_TIMEOUT_S: CountSchema3.default(60),
|
|
21606
|
-
IMP_WATCHDOG_ACTION:
|
|
21695
|
+
IMP_WATCHDOG_ACTION: z53.enum(["report", "restart", "snapshot"]).default("report"),
|
|
21607
21696
|
IMP_DEFAULT_VCPUS: CountSchema3.default(2),
|
|
21608
21697
|
IMP_DEFAULT_MEMORY_MIB: CountSchema3.default(2048),
|
|
21609
21698
|
IMP_DEFAULT_DISK_GIB: CountSchema3.default(32),
|
|
@@ -21613,38 +21702,37 @@ var EnvSchema = z52.object({
|
|
|
21613
21702
|
IMP_BUILD_DISK_GIB: CountSchema3.default(20),
|
|
21614
21703
|
IMP_BUILD_IMAGE_MAX_MIB: CountSchema3.default(8192),
|
|
21615
21704
|
IMP_BUILD_IMAGE_MAX_FILES: CountSchema3.default(1e6),
|
|
21616
|
-
IMP_BUILD_IMAGE:
|
|
21617
|
-
IMP_BUILD_TEST_REGISTRY:
|
|
21618
|
-
IMP_BUILD_TEST_REGISTRY_CA:
|
|
21705
|
+
IMP_BUILD_IMAGE: z53.string().regex(BUILD_IMAGE_PATTERN, "must name an image by digest, <ref>@sha256:<hex>").default(DEFAULT_BUILD_IMAGE),
|
|
21706
|
+
IMP_BUILD_TEST_REGISTRY: z53.string().regex(/^[a-z0-9][a-z0-9.\-]*:\d+$/v, "must be <name>:<port>").optional(),
|
|
21707
|
+
IMP_BUILD_TEST_REGISTRY_CA: z53.string().optional(),
|
|
21619
21708
|
IMP_IMAGE_EVICT_HIGH_PERCENT: MarkSchema.optional(),
|
|
21620
21709
|
IMP_IMAGE_EVICT_LOW_PERCENT: MarkSchema.optional(),
|
|
21621
21710
|
IMP_SESSION_LOG_MAX_MIB: CountSchema3.default(16),
|
|
21622
21711
|
IMP_SESSION_LOG_IMP_MAX_MIB: CountSchema3.default(64),
|
|
21623
21712
|
IMP_SESSION_LOG_IMP_MAX_LIVE: CountSchema3.default(8),
|
|
21624
21713
|
IMP_SESSION_LOG_MAX_AGE_DAYS: CountSchema3.default(7),
|
|
21625
|
-
|
|
21626
|
-
|
|
21627
|
-
|
|
21628
|
-
|
|
21629
|
-
|
|
21630
|
-
|
|
21631
|
-
|
|
21632
|
-
|
|
21633
|
-
|
|
21634
|
-
|
|
21635
|
-
|
|
21636
|
-
|
|
21637
|
-
|
|
21638
|
-
|
|
21639
|
-
|
|
21640
|
-
|
|
21641
|
-
|
|
21642
|
-
|
|
21643
|
-
|
|
21644
|
-
|
|
21645
|
-
|
|
21646
|
-
|
|
21647
|
-
IMP_MOVE_TEST_CIDR: z52.cidrv4().optional(),
|
|
21714
|
+
IMP_KSM: z53.enum(["0", "1"]).default("0"),
|
|
21715
|
+
IMP_KSM_EXEC: z53.string().default("ksm-exec"),
|
|
21716
|
+
IMP_KSM_HEADROOM_PERCENT: z53.string().default("100"),
|
|
21717
|
+
IMP_DNS: z53.string().default("1.1.1.1,8.8.8.8").transform(splitList).pipe(DnsServersSchema),
|
|
21718
|
+
IMP_SUBNET: z53.cidrv4().default("10.66.0.0/16"),
|
|
21719
|
+
IMP_SUBNET6: z53.string().default("auto"),
|
|
21720
|
+
IMP_FIRECRACKER_BIN: z53.string().default("firecracker"),
|
|
21721
|
+
IMP_JAILER: z53.enum(["true", "false"]).default("true"),
|
|
21722
|
+
IMP_JAILER_BIN: z53.string().default("jailer"),
|
|
21723
|
+
IMP_KERNEL: z53.string().optional(),
|
|
21724
|
+
IMP_SYSTEM_DRIVE: z53.string().optional(),
|
|
21725
|
+
IMP_DEFAULT_IMAGE: z53.string().default("base"),
|
|
21726
|
+
IMP_STORAGE_BACKEND: z53.enum(["xfs", "zfs"]).default("xfs"),
|
|
21727
|
+
IMP_ZFS_ROOT: z53.string().optional(),
|
|
21728
|
+
IMP_ZFS_ALLOW_UIOMOVE_BUG: z53.enum(["0", "1"]).default("0"),
|
|
21729
|
+
TAILSCALE_AUTHKEY: z53.string().optional(),
|
|
21730
|
+
IMP_TAILSCALE_NODE: z53.literal("1").optional(),
|
|
21731
|
+
IMP_TAILSCALE_HOSTNAME: z53.string().default("imp"),
|
|
21732
|
+
IMP_DASHBOARD_DIR: z53.string().optional(),
|
|
21733
|
+
IMP_TAILNET_IDENTITIES: z53.string().optional(),
|
|
21734
|
+
IMP_PEER_URL: z53.url().optional(),
|
|
21735
|
+
IMP_MOVE_TEST_CIDR: z53.cidrv4().optional(),
|
|
21648
21736
|
...HttpsEnvSchema.shape,
|
|
21649
21737
|
...TailnetNamesEnvSchema.shape,
|
|
21650
21738
|
...PublicMcpEnvSchema.shape
|
|
@@ -21787,7 +21875,6 @@ function loadConfig(env) {
|
|
|
21787
21875
|
impMaxLive: parsed.IMP_SESSION_LOG_IMP_MAX_LIVE,
|
|
21788
21876
|
maxAgeMs: parsed.IMP_SESSION_LOG_MAX_AGE_DAYS * 86400000
|
|
21789
21877
|
},
|
|
21790
|
-
dockerHost: parsed.DOCKER_HOST ?? null,
|
|
21791
21878
|
dns: parsed.IMP_DNS,
|
|
21792
21879
|
subnet,
|
|
21793
21880
|
ipv6: parseIpv6Setting(parsed.IMP_SUBNET6),
|
|
@@ -21862,7 +21949,7 @@ import { join as join46 } from "path";
|
|
|
21862
21949
|
// packages/daemon/package.json
|
|
21863
21950
|
var package_default = {
|
|
21864
21951
|
name: "@impz/daemon",
|
|
21865
|
-
version: "
|
|
21952
|
+
version: "6.0.0",
|
|
21866
21953
|
private: true,
|
|
21867
21954
|
description: "impd: the imp host daemon",
|
|
21868
21955
|
type: "module",
|
|
@@ -21871,6 +21958,7 @@ var package_default = {
|
|
|
21871
21958
|
"./testing": "./testing/index.ts",
|
|
21872
21959
|
"./testing/build-stub-clock": "./testing/platform/build-stub-clock.ts",
|
|
21873
21960
|
"./testing/data-layout": "./src/vm/storage/data-layout.ts",
|
|
21961
|
+
"./testing/pebble-images": "./testing/network/pebble-images.ts",
|
|
21874
21962
|
"./testing/start-stub-agent": "./testing/vm/start-stub-agent.ts",
|
|
21875
21963
|
"./testing/start-test-impd": "./testing/start-test-impd.ts",
|
|
21876
21964
|
"./testing/test-token": "./testing/test-token.ts",
|
|
@@ -22605,10 +22693,10 @@ import { Database } from "bun:sqlite";
|
|
|
22605
22693
|
import { chmodSync, closeSync, mkdirSync as mkdirSync3, openSync, rmSync, statSync } from "fs";
|
|
22606
22694
|
import { join as join5 } from "path";
|
|
22607
22695
|
import { sql as sql2 } from "kysely";
|
|
22608
|
-
import * as
|
|
22609
|
-
var MigrationRowSchema =
|
|
22610
|
-
var IntegrityRowSchema =
|
|
22611
|
-
var SizeRowSchema =
|
|
22696
|
+
import * as z54 from "zod";
|
|
22697
|
+
var MigrationRowSchema = z54.object({ name: z54.string() });
|
|
22698
|
+
var IntegrityRowSchema = z54.object({ integrity_check: z54.string() });
|
|
22699
|
+
var SizeRowSchema = z54.object({ bytes: z54.int().nonnegative() });
|
|
22612
22700
|
async function writeConsistentCopy(db, path) {
|
|
22613
22701
|
await sql2`VACUUM INTO ${path}`.execute(db);
|
|
22614
22702
|
}
|
|
@@ -22901,17 +22989,17 @@ function readFileState(path, stamp) {
|
|
|
22901
22989
|
|
|
22902
22990
|
// packages/daemon/src/platform/db/secrets.ts
|
|
22903
22991
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
22904
|
-
import * as
|
|
22992
|
+
import * as z57 from "zod";
|
|
22905
22993
|
|
|
22906
22994
|
// packages/daemon/src/platform/db/tokens.ts
|
|
22907
|
-
import * as
|
|
22995
|
+
import * as z56 from "zod";
|
|
22908
22996
|
|
|
22909
22997
|
// packages/daemon/src/platform/db/imps-schema.ts
|
|
22910
|
-
import * as
|
|
22911
|
-
var ImpsSchema =
|
|
22998
|
+
import * as z55 from "zod";
|
|
22999
|
+
var ImpsSchema = z55.array(z55.string()).nullable();
|
|
22912
23000
|
|
|
22913
23001
|
// packages/daemon/src/platform/db/tokens.ts
|
|
22914
|
-
var GrantableSchema2 =
|
|
23002
|
+
var GrantableSchema2 = z56.array(z56.object({ name: z56.string(), generation: z56.string() }));
|
|
22915
23003
|
async function listTokenRecords(db) {
|
|
22916
23004
|
const rows = await db.selectFrom("tokens").selectAll().orderBy("name").execute();
|
|
22917
23005
|
return rows.map((row) => toTokenRecord(row));
|
|
@@ -23017,12 +23105,14 @@ function toTokenSshKeyRecord(row) {
|
|
|
23017
23105
|
}
|
|
23018
23106
|
|
|
23019
23107
|
// packages/daemon/src/platform/db/secrets.ts
|
|
23020
|
-
var RulesSchema =
|
|
23108
|
+
var RulesSchema = z57.array(BrokerRuleSchema);
|
|
23109
|
+
var EnvSchema2 = z57.array(z57.string());
|
|
23021
23110
|
async function createSecret(db, secret) {
|
|
23022
23111
|
const row = await db.insertInto("secrets").values({
|
|
23023
23112
|
name: secret.name,
|
|
23024
23113
|
kind: secret.kind,
|
|
23025
23114
|
rules: JSON.stringify(secret.rules),
|
|
23115
|
+
env: JSON.stringify(secret.env ?? []),
|
|
23026
23116
|
oauth: formatOAuthConfig(secret.oauth),
|
|
23027
23117
|
generation: createGeneration(),
|
|
23028
23118
|
value_file: secret.valueFile,
|
|
@@ -23051,6 +23141,7 @@ function upsertSecret(db, secret, rebind) {
|
|
|
23051
23141
|
const row = await trx.updateTable("secrets").set({
|
|
23052
23142
|
kind: secret.kind,
|
|
23053
23143
|
rules: JSON.stringify(secret.rules),
|
|
23144
|
+
env: JSON.stringify(secret.env ?? []),
|
|
23054
23145
|
oauth: formatOAuthConfig(secret.oauth),
|
|
23055
23146
|
value_file: secret.valueFile,
|
|
23056
23147
|
...!isRotation && { generation: createGeneration() }
|
|
@@ -23143,6 +23234,7 @@ async function listGrantedRules(db, impId) {
|
|
|
23143
23234
|
"secrets.name",
|
|
23144
23235
|
"secrets.kind",
|
|
23145
23236
|
"secrets.rules",
|
|
23237
|
+
"secrets.env",
|
|
23146
23238
|
"secrets.value_file",
|
|
23147
23239
|
"grants.filter"
|
|
23148
23240
|
]).where("grants.imp_id", "=", impId).orderBy("secrets.name").execute();
|
|
@@ -23150,6 +23242,7 @@ async function listGrantedRules(db, impId) {
|
|
|
23150
23242
|
secretName: row.name,
|
|
23151
23243
|
kind: parseKind(row.kind),
|
|
23152
23244
|
rule,
|
|
23245
|
+
env: parseEnv(row.env),
|
|
23153
23246
|
valueFile: row.value_file,
|
|
23154
23247
|
filter: parseFilter(row.filter)
|
|
23155
23248
|
})));
|
|
@@ -23222,6 +23315,7 @@ function toSecretRecord(row) {
|
|
|
23222
23315
|
name: row.name,
|
|
23223
23316
|
kind: parseKind(row.kind),
|
|
23224
23317
|
rules: parseRules(row.rules),
|
|
23318
|
+
env: parseEnv(row.env),
|
|
23225
23319
|
oauth: parseOAuth(row.oauth),
|
|
23226
23320
|
generation: row.generation,
|
|
23227
23321
|
valueFile: row.value_file,
|
|
@@ -23231,6 +23325,9 @@ function toSecretRecord(row) {
|
|
|
23231
23325
|
function parseRules(json) {
|
|
23232
23326
|
return RulesSchema.parse(JSON.parse(json));
|
|
23233
23327
|
}
|
|
23328
|
+
function parseEnv(json) {
|
|
23329
|
+
return EnvSchema2.parse(JSON.parse(json));
|
|
23330
|
+
}
|
|
23234
23331
|
function parseFilter(json) {
|
|
23235
23332
|
return json === null ? null : GrantFilterSchema.parse(JSON.parse(json));
|
|
23236
23333
|
}
|
|
@@ -23867,7 +23964,7 @@ function findBadFieldValue(field, value) {
|
|
|
23867
23964
|
return isGood ? undefined : name;
|
|
23868
23965
|
}
|
|
23869
23966
|
// packages/agent-protocol/src/frame-codec.ts
|
|
23870
|
-
import * as
|
|
23967
|
+
import * as z58 from "zod";
|
|
23871
23968
|
var FRAME_TYPES = {
|
|
23872
23969
|
request: 1,
|
|
23873
23970
|
response: 2,
|
|
@@ -23933,7 +24030,7 @@ function buildFrameDecoder() {
|
|
|
23933
24030
|
return { push: decodeChunk, end: checkEnded };
|
|
23934
24031
|
}
|
|
23935
24032
|
function decodeJsonPayload(frame) {
|
|
23936
|
-
return
|
|
24033
|
+
return z58.json().parse(JSON.parse(new TextDecoder().decode(frame.payload)));
|
|
23937
24034
|
}
|
|
23938
24035
|
function mergeBytes2(left, right) {
|
|
23939
24036
|
if (left.byteLength === 0) {
|
|
@@ -25315,7 +25412,7 @@ function toLeaseRecord(row) {
|
|
|
25315
25412
|
// packages/daemon/src/vm/sleep/snapshot-meta.ts
|
|
25316
25413
|
import { existsSync as existsSync4, rmSync as rmSync4 } from "fs";
|
|
25317
25414
|
import { toJson as toJson3 } from "@bufbuild/protobuf";
|
|
25318
|
-
import * as
|
|
25415
|
+
import * as z60 from "zod";
|
|
25319
25416
|
|
|
25320
25417
|
// packages/daemon/src/platform/process/write-file-durably.ts
|
|
25321
25418
|
import {
|
|
@@ -25406,11 +25503,11 @@ function writeToDisk(paths, sync = fsyncSync) {
|
|
|
25406
25503
|
import { isMessage } from "@bufbuild/protobuf";
|
|
25407
25504
|
|
|
25408
25505
|
// packages/daemon/src/vm/agent-client/agent-ids.ts
|
|
25409
|
-
import * as
|
|
25506
|
+
import * as z59 from "zod";
|
|
25410
25507
|
var AgentGenerationSchema = ExecutionGenerationSchema;
|
|
25411
25508
|
var AgentSessionNameSchema = SessionNameSchema;
|
|
25412
|
-
var AgentBootIdSchema =
|
|
25413
|
-
var AgentLogIdentitySchema =
|
|
25509
|
+
var AgentBootIdSchema = z59.string().regex(/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})?$/u);
|
|
25510
|
+
var AgentLogIdentitySchema = z59.object({
|
|
25414
25511
|
generation: AgentGenerationSchema,
|
|
25415
25512
|
session: AgentSessionNameSchema,
|
|
25416
25513
|
bootId: AgentBootIdSchema
|
|
@@ -25486,20 +25583,20 @@ function findCpuChange(snapshot, host) {
|
|
|
25486
25583
|
}
|
|
25487
25584
|
|
|
25488
25585
|
// packages/daemon/src/vm/sleep/snapshot-meta.ts
|
|
25489
|
-
var SnapshotIdentitySchema =
|
|
25490
|
-
firecrackerVersion:
|
|
25491
|
-
snapshotVersion:
|
|
25492
|
-
hostKernel:
|
|
25493
|
-
guestKernel:
|
|
25494
|
-
systemDrive:
|
|
25495
|
-
systemDrivePath:
|
|
25496
|
-
agentVersion:
|
|
25497
|
-
ipv6Prefix:
|
|
25498
|
-
cpuModel:
|
|
25499
|
-
cpuFlags:
|
|
25586
|
+
var SnapshotIdentitySchema = z60.object({
|
|
25587
|
+
firecrackerVersion: z60.string(),
|
|
25588
|
+
snapshotVersion: z60.string(),
|
|
25589
|
+
hostKernel: z60.string(),
|
|
25590
|
+
guestKernel: z60.string(),
|
|
25591
|
+
systemDrive: z60.string(),
|
|
25592
|
+
systemDrivePath: z60.string().optional(),
|
|
25593
|
+
agentVersion: z60.string().optional(),
|
|
25594
|
+
ipv6Prefix: z60.string().nullable().optional(),
|
|
25595
|
+
cpuModel: z60.string().optional(),
|
|
25596
|
+
cpuFlags: z60.string().optional()
|
|
25500
25597
|
});
|
|
25501
25598
|
var AGENT_RECORD_JSON = { useProtoFieldName: true, alwaysEmitImplicit: true };
|
|
25502
|
-
var SeenSessionJsonSchema =
|
|
25599
|
+
var SeenSessionJsonSchema = z60.json().transform((json, ctx) => {
|
|
25503
25600
|
try {
|
|
25504
25601
|
if (typeof json !== "object" || json === null || Array.isArray(json)) {
|
|
25505
25602
|
throw new Error("a session is a JSON object");
|
|
@@ -25512,23 +25609,23 @@ var SeenSessionJsonSchema = z59.json().transform((json, ctx) => {
|
|
|
25512
25609
|
return typeof observed === "number" ? { ...session, observedUnixMs: observed } : session;
|
|
25513
25610
|
} catch (error) {
|
|
25514
25611
|
ctx.addIssue({ code: "custom", message: String(error) });
|
|
25515
|
-
return
|
|
25612
|
+
return z60.NEVER;
|
|
25516
25613
|
}
|
|
25517
25614
|
});
|
|
25518
|
-
var ServicesListJsonSchema =
|
|
25615
|
+
var ServicesListJsonSchema = z60.json().transform((json, ctx) => {
|
|
25519
25616
|
try {
|
|
25520
25617
|
return decodeAgentMessage(ServicesListSchema, json);
|
|
25521
25618
|
} catch (error) {
|
|
25522
25619
|
ctx.addIssue({ code: "custom", message: String(error) });
|
|
25523
|
-
return
|
|
25620
|
+
return z60.NEVER;
|
|
25524
25621
|
}
|
|
25525
25622
|
});
|
|
25526
25623
|
var SnapshotMetaSchema = SnapshotIdentitySchema.extend({
|
|
25527
|
-
createdAt:
|
|
25528
|
-
memoryMib:
|
|
25529
|
-
ramMib:
|
|
25530
|
-
pluggedMib:
|
|
25531
|
-
sessions:
|
|
25624
|
+
createdAt: z60.int(),
|
|
25625
|
+
memoryMib: z60.int(),
|
|
25626
|
+
ramMib: z60.int().nonnegative(),
|
|
25627
|
+
pluggedMib: z60.int().nonnegative().optional(),
|
|
25628
|
+
sessions: z60.array(SeenSessionJsonSchema).readonly().optional(),
|
|
25532
25629
|
services: ServicesListJsonSchema.optional()
|
|
25533
25630
|
});
|
|
25534
25631
|
function buildSnapshotIdentity(vm, host) {
|
|
@@ -25655,19 +25752,19 @@ function countSessions(context, imp) {
|
|
|
25655
25752
|
// packages/daemon/src/vm/sleep/vm-identity.ts
|
|
25656
25753
|
import { existsSync as existsSync5, readFileSync as readFileSync6 } from "fs";
|
|
25657
25754
|
import { release } from "os";
|
|
25658
|
-
import * as
|
|
25659
|
-
var VmIdentitySchema =
|
|
25660
|
-
firecrackerVersion:
|
|
25661
|
-
snapshotVersion:
|
|
25662
|
-
hostKernel:
|
|
25663
|
-
guestKernel:
|
|
25664
|
-
systemDrive:
|
|
25665
|
-
systemDrivePath:
|
|
25666
|
-
agentVersion:
|
|
25667
|
-
bootReason:
|
|
25668
|
-
ipv6Prefix:
|
|
25669
|
-
cpuModel:
|
|
25670
|
-
cpuFlags:
|
|
25755
|
+
import * as z61 from "zod";
|
|
25756
|
+
var VmIdentitySchema = z61.object({
|
|
25757
|
+
firecrackerVersion: z61.string(),
|
|
25758
|
+
snapshotVersion: z61.string(),
|
|
25759
|
+
hostKernel: z61.string(),
|
|
25760
|
+
guestKernel: z61.string(),
|
|
25761
|
+
systemDrive: z61.string(),
|
|
25762
|
+
systemDrivePath: z61.string(),
|
|
25763
|
+
agentVersion: z61.string(),
|
|
25764
|
+
bootReason: z61.string().nullable(),
|
|
25765
|
+
ipv6Prefix: z61.string().nullable().optional(),
|
|
25766
|
+
cpuModel: z61.string().optional(),
|
|
25767
|
+
cpuFlags: z61.string().optional()
|
|
25671
25768
|
});
|
|
25672
25769
|
function readHostIdentity(firecrackerBin, systemFiles, ipv6Prefix = null) {
|
|
25673
25770
|
return {
|
|
@@ -25982,7 +26079,7 @@ import {
|
|
|
25982
26079
|
writeFileSync as writeFileSync2
|
|
25983
26080
|
} from "fs";
|
|
25984
26081
|
import { dirname as dirname6, join as join9 } from "path";
|
|
25985
|
-
import * as
|
|
26082
|
+
import * as z65 from "zod";
|
|
25986
26083
|
|
|
25987
26084
|
// packages/daemon/src/platform/process/require-within.ts
|
|
25988
26085
|
async function requireWithin(promise, durationMs, buildError, startTimer = startRealTimer) {
|
|
@@ -26294,43 +26391,43 @@ function buildKeyedMutex() {
|
|
|
26294
26391
|
import { Database as Database2 } from "bun:sqlite";
|
|
26295
26392
|
import { mkdirSync as mkdirSync4, rmSync as rmSync5 } from "fs";
|
|
26296
26393
|
import { dirname as dirname4 } from "path";
|
|
26297
|
-
import * as
|
|
26298
|
-
var CopyImpSchema =
|
|
26299
|
-
id:
|
|
26300
|
-
name:
|
|
26301
|
-
imageId:
|
|
26302
|
-
state:
|
|
26303
|
-
vcpus:
|
|
26304
|
-
memoryMib:
|
|
26305
|
-
maxMemoryMib:
|
|
26306
|
-
httpPort:
|
|
26307
|
-
egressPolicy:
|
|
26308
|
-
diskBytes:
|
|
26309
|
-
egressAllow:
|
|
26310
|
-
identityResetPending:
|
|
26311
|
-
backup:
|
|
26394
|
+
import * as z62 from "zod";
|
|
26395
|
+
var CopyImpSchema = z62.object({
|
|
26396
|
+
id: z62.string(),
|
|
26397
|
+
name: z62.string(),
|
|
26398
|
+
imageId: z62.string(),
|
|
26399
|
+
state: z62.string(),
|
|
26400
|
+
vcpus: z62.int(),
|
|
26401
|
+
memoryMib: z62.int(),
|
|
26402
|
+
maxMemoryMib: z62.int().nullable(),
|
|
26403
|
+
httpPort: z62.int(),
|
|
26404
|
+
egressPolicy: z62.string(),
|
|
26405
|
+
diskBytes: z62.int(),
|
|
26406
|
+
egressAllow: z62.string(),
|
|
26407
|
+
identityResetPending: z62.int(),
|
|
26408
|
+
backup: z62.int()
|
|
26312
26409
|
});
|
|
26313
|
-
var CopyGrantSchema =
|
|
26314
|
-
impId:
|
|
26315
|
-
secretName:
|
|
26316
|
-
filter:
|
|
26410
|
+
var CopyGrantSchema = z62.object({
|
|
26411
|
+
impId: z62.string(),
|
|
26412
|
+
secretName: z62.string(),
|
|
26413
|
+
filter: z62.string().nullable().transform((json) => json === null ? null : GrantFilterSchema.parse(JSON.parse(json)))
|
|
26317
26414
|
});
|
|
26318
|
-
var CopyMemberSchema =
|
|
26319
|
-
var CopyCheckpointSchema =
|
|
26320
|
-
id:
|
|
26321
|
-
impId:
|
|
26322
|
-
label:
|
|
26323
|
-
createdAt:
|
|
26324
|
-
diskBytes:
|
|
26415
|
+
var CopyMemberSchema = z62.object({ impId: z62.string(), network: z62.string() });
|
|
26416
|
+
var CopyCheckpointSchema = z62.object({
|
|
26417
|
+
id: z62.string(),
|
|
26418
|
+
impId: z62.string(),
|
|
26419
|
+
label: z62.string().nullable(),
|
|
26420
|
+
createdAt: z62.int(),
|
|
26421
|
+
diskBytes: z62.int()
|
|
26325
26422
|
});
|
|
26326
|
-
var CopyImageSchema =
|
|
26327
|
-
id:
|
|
26328
|
-
name:
|
|
26329
|
-
ref:
|
|
26330
|
-
digest:
|
|
26423
|
+
var CopyImageSchema = z62.object({
|
|
26424
|
+
id: z62.string(),
|
|
26425
|
+
name: z62.string(),
|
|
26426
|
+
ref: z62.string(),
|
|
26427
|
+
digest: z62.string(),
|
|
26331
26428
|
source: ImageSourceSchema,
|
|
26332
|
-
sourceImp:
|
|
26333
|
-
sizeBytes:
|
|
26429
|
+
sourceImp: z62.string().nullable(),
|
|
26430
|
+
sizeBytes: z62.int()
|
|
26334
26431
|
});
|
|
26335
26432
|
async function readDatabaseCopy(db, path) {
|
|
26336
26433
|
mkdirSync4(dirname4(path), { recursive: true });
|
|
@@ -26351,11 +26448,11 @@ async function readDatabaseCopy(db, path) {
|
|
|
26351
26448
|
const members = copy.query(`SELECT network_members.imp_id AS impId, networks.name AS network FROM network_members
|
|
26352
26449
|
JOIN networks ON networks.id = network_members.network_id ORDER BY networks.name`).all();
|
|
26353
26450
|
return {
|
|
26354
|
-
imps:
|
|
26355
|
-
grants:
|
|
26356
|
-
members:
|
|
26357
|
-
checkpoints:
|
|
26358
|
-
images:
|
|
26451
|
+
imps: z62.array(CopyImpSchema).parse(imps),
|
|
26452
|
+
grants: z62.array(CopyGrantSchema).parse(grants),
|
|
26453
|
+
members: z62.array(CopyMemberSchema).parse(members),
|
|
26454
|
+
checkpoints: z62.array(CopyCheckpointSchema).parse(checkpoints),
|
|
26455
|
+
images: z62.array(CopyImageSchema).parse(images)
|
|
26359
26456
|
};
|
|
26360
26457
|
} finally {
|
|
26361
26458
|
copy.close();
|
|
@@ -26363,7 +26460,7 @@ async function readDatabaseCopy(db, path) {
|
|
|
26363
26460
|
}
|
|
26364
26461
|
|
|
26365
26462
|
// packages/daemon/src/imp-ops/backup/restic.ts
|
|
26366
|
-
import * as
|
|
26463
|
+
import * as z63 from "zod";
|
|
26367
26464
|
var BACKUP_TAG = "imp-backup";
|
|
26368
26465
|
var RESTIC_HOST = "impd";
|
|
26369
26466
|
var NO_REPOSITORY_EXIT = 10;
|
|
@@ -26371,20 +26468,20 @@ var LOCKED_EXIT = 11;
|
|
|
26371
26468
|
var RETRY_LOCK = "2m";
|
|
26372
26469
|
var LOCK_HOLDER = /locked.* by PID /v;
|
|
26373
26470
|
var NO_SNAPSHOT = "no matching ID found";
|
|
26374
|
-
var SnapshotSchema =
|
|
26375
|
-
id:
|
|
26376
|
-
time:
|
|
26377
|
-
paths:
|
|
26378
|
-
tags:
|
|
26471
|
+
var SnapshotSchema = z63.object({
|
|
26472
|
+
id: z63.string(),
|
|
26473
|
+
time: z63.coerce.date(),
|
|
26474
|
+
paths: z63.array(z63.string()),
|
|
26475
|
+
tags: z63.array(z63.string()).nullish()
|
|
26379
26476
|
});
|
|
26380
|
-
var ExitErrorSchema =
|
|
26381
|
-
var SummarySchema =
|
|
26382
|
-
message_type:
|
|
26383
|
-
snapshot_id:
|
|
26384
|
-
files_new:
|
|
26385
|
-
files_changed:
|
|
26386
|
-
files_unmodified:
|
|
26387
|
-
data_added:
|
|
26477
|
+
var ExitErrorSchema = z63.object({ message_type: z63.literal("exit_error"), message: z63.string() });
|
|
26478
|
+
var SummarySchema = z63.object({
|
|
26479
|
+
message_type: z63.literal("summary"),
|
|
26480
|
+
snapshot_id: z63.string(),
|
|
26481
|
+
files_new: z63.number(),
|
|
26482
|
+
files_changed: z63.number(),
|
|
26483
|
+
files_unmodified: z63.number(),
|
|
26484
|
+
data_added: z63.number()
|
|
26388
26485
|
});
|
|
26389
26486
|
|
|
26390
26487
|
class ResticError extends Error {
|
|
@@ -26488,7 +26585,7 @@ function createRestic(deps) {
|
|
|
26488
26585
|
};
|
|
26489
26586
|
}
|
|
26490
26587
|
function parseSnapshots(stdout) {
|
|
26491
|
-
const parsed =
|
|
26588
|
+
const parsed = z63.array(SnapshotSchema).parse(JSON.parse(stdout || "[]"));
|
|
26492
26589
|
return parsed.map((snapshot) => ({
|
|
26493
26590
|
id: snapshot.id,
|
|
26494
26591
|
time: snapshot.time,
|
|
@@ -27847,61 +27944,61 @@ async function restoreGrants(deps, impName, imported) {
|
|
|
27847
27944
|
}
|
|
27848
27945
|
|
|
27849
27946
|
// packages/daemon/src/imp-ops/backup/backup-manifest.ts
|
|
27850
|
-
import * as
|
|
27947
|
+
import * as z64 from "zod";
|
|
27851
27948
|
|
|
27852
27949
|
// packages/daemon/src/platform/process/legacy-disk-bytes.ts
|
|
27853
27950
|
var LEGACY_DISK_BYTES = 32 * 1024 ** 3;
|
|
27854
27951
|
|
|
27855
27952
|
// packages/daemon/src/imp-ops/backup/backup-manifest.ts
|
|
27856
|
-
var ManifestCheckpointSchema =
|
|
27857
|
-
id:
|
|
27858
|
-
label:
|
|
27859
|
-
createdAt:
|
|
27860
|
-
disk:
|
|
27861
|
-
diskBytes:
|
|
27862
|
-
usedBytes:
|
|
27953
|
+
var ManifestCheckpointSchema = z64.object({
|
|
27954
|
+
id: z64.string(),
|
|
27955
|
+
label: z64.string().nullable(),
|
|
27956
|
+
createdAt: z64.coerce.date(),
|
|
27957
|
+
disk: z64.string(),
|
|
27958
|
+
diskBytes: z64.int().positive().default(LEGACY_DISK_BYTES),
|
|
27959
|
+
usedBytes: z64.int().nonnegative().optional()
|
|
27863
27960
|
}).readonly();
|
|
27864
|
-
var FilteredGrantSchema =
|
|
27865
|
-
var ManifestImpSchema =
|
|
27866
|
-
id:
|
|
27867
|
-
name:
|
|
27868
|
-
imageDigest:
|
|
27869
|
-
vcpus:
|
|
27870
|
-
memoryMib:
|
|
27871
|
-
maxMemoryMib:
|
|
27872
|
-
httpPort:
|
|
27873
|
-
state:
|
|
27874
|
-
synced:
|
|
27875
|
-
dir:
|
|
27876
|
-
disk:
|
|
27877
|
-
diskBytes:
|
|
27878
|
-
usedBytes:
|
|
27879
|
-
egressPolicy:
|
|
27880
|
-
egressAllow:
|
|
27881
|
-
grants:
|
|
27882
|
-
filteredGrants:
|
|
27883
|
-
identityResetPending:
|
|
27884
|
-
networks:
|
|
27885
|
-
checkpoints:
|
|
27961
|
+
var FilteredGrantSchema = z64.object({ secret: z64.string(), filter: GrantFilterSchema }).readonly();
|
|
27962
|
+
var ManifestImpSchema = z64.object({
|
|
27963
|
+
id: z64.string(),
|
|
27964
|
+
name: z64.string(),
|
|
27965
|
+
imageDigest: z64.string(),
|
|
27966
|
+
vcpus: z64.int(),
|
|
27967
|
+
memoryMib: z64.int(),
|
|
27968
|
+
maxMemoryMib: z64.int().nullable().optional(),
|
|
27969
|
+
httpPort: z64.int(),
|
|
27970
|
+
state: z64.string(),
|
|
27971
|
+
synced: z64.boolean(),
|
|
27972
|
+
dir: z64.string(),
|
|
27973
|
+
disk: z64.string(),
|
|
27974
|
+
diskBytes: z64.int().positive().default(LEGACY_DISK_BYTES),
|
|
27975
|
+
usedBytes: z64.int().nonnegative().optional(),
|
|
27976
|
+
egressPolicy: z64.string().default("open"),
|
|
27977
|
+
egressAllow: z64.array(z64.string()).readonly().default([]),
|
|
27978
|
+
grants: z64.array(z64.string()).readonly().default([]),
|
|
27979
|
+
filteredGrants: z64.array(FilteredGrantSchema).readonly().default([]),
|
|
27980
|
+
identityResetPending: z64.boolean().default(false),
|
|
27981
|
+
networks: z64.array(z64.string()).readonly().default([]),
|
|
27982
|
+
checkpoints: z64.array(ManifestCheckpointSchema).readonly()
|
|
27886
27983
|
}).readonly();
|
|
27887
|
-
var ManifestImageSchema =
|
|
27888
|
-
name:
|
|
27889
|
-
ref:
|
|
27890
|
-
digest:
|
|
27984
|
+
var ManifestImageSchema = z64.object({
|
|
27985
|
+
name: z64.string(),
|
|
27986
|
+
ref: z64.string(),
|
|
27987
|
+
digest: z64.string(),
|
|
27891
27988
|
source: ImageSourceSchema.default("oci"),
|
|
27892
|
-
sourceImp:
|
|
27893
|
-
sizeBytes:
|
|
27894
|
-
dir:
|
|
27989
|
+
sourceImp: z64.string().nullable().default(null),
|
|
27990
|
+
sizeBytes: z64.int(),
|
|
27991
|
+
dir: z64.string()
|
|
27895
27992
|
}).readonly();
|
|
27896
|
-
var ManifestExcludedSchema =
|
|
27897
|
-
var BackupManifestSchema =
|
|
27898
|
-
version:
|
|
27899
|
-
runId:
|
|
27900
|
-
createdAt:
|
|
27901
|
-
imps:
|
|
27902
|
-
excluded:
|
|
27903
|
-
images:
|
|
27904
|
-
database:
|
|
27993
|
+
var ManifestExcludedSchema = z64.object({ name: z64.string(), reason: z64.string() }).readonly();
|
|
27994
|
+
var BackupManifestSchema = z64.object({
|
|
27995
|
+
version: z64.literal(1),
|
|
27996
|
+
runId: z64.string(),
|
|
27997
|
+
createdAt: z64.coerce.date(),
|
|
27998
|
+
imps: z64.array(ManifestImpSchema).readonly(),
|
|
27999
|
+
excluded: z64.array(ManifestExcludedSchema).readonly().default([]),
|
|
28000
|
+
images: z64.array(ManifestImageSchema).readonly(),
|
|
28001
|
+
database: z64.object({ file: z64.string(), sizeBytes: z64.int().nonnegative() }).readonly().nullable().default(null)
|
|
27905
28002
|
}).readonly();
|
|
27906
28003
|
|
|
27907
28004
|
// packages/daemon/src/platform/db/create-restored-secrets.ts
|
|
@@ -28578,6 +28675,28 @@ var MIGRATION_041_ADD_MOVE_SEND_STEPS = {
|
|
|
28578
28675
|
}
|
|
28579
28676
|
};
|
|
28580
28677
|
|
|
28678
|
+
// packages/daemon/src/platform/db/migrations/migration-042-add-secret-env.ts
|
|
28679
|
+
var PRESET_ENV = {
|
|
28680
|
+
github: ["GH_TOKEN", "GITHUB_TOKEN"],
|
|
28681
|
+
anthropic: ["ANTHROPIC_API_KEY"],
|
|
28682
|
+
npm: ["NPM_TOKEN"]
|
|
28683
|
+
};
|
|
28684
|
+
var MIGRATION_042_ADD_SECRET_ENV = {
|
|
28685
|
+
async up(db) {
|
|
28686
|
+
await db.schema.alterTable("secrets").addColumn("env", "text", (column) => column.notNull().defaultTo("[]")).execute();
|
|
28687
|
+
for (const [kind, env] of Object.entries(PRESET_ENV)) {
|
|
28688
|
+
await db.updateTable("secrets").set({ env: JSON.stringify(env) }).where("kind", "=", kind).execute();
|
|
28689
|
+
}
|
|
28690
|
+
}
|
|
28691
|
+
};
|
|
28692
|
+
|
|
28693
|
+
// packages/daemon/src/platform/db/migrations/migration-043-merge-secret-kinds.ts
|
|
28694
|
+
var MIGRATION_043_MERGE_SECRET_KINDS = {
|
|
28695
|
+
async up(db) {
|
|
28696
|
+
await db.updateTable("secrets").set({ kind: "static" }).where("kind", "in", ["github", "anthropic", "npm", "custom"]).execute();
|
|
28697
|
+
}
|
|
28698
|
+
};
|
|
28699
|
+
|
|
28581
28700
|
// packages/daemon/src/platform/db/run-migrations.ts
|
|
28582
28701
|
var MIGRATIONS = {
|
|
28583
28702
|
"001_create_initial_schema": MIGRATION_001_CREATE_INITIAL_SCHEMA,
|
|
@@ -28620,7 +28739,9 @@ var MIGRATIONS = {
|
|
|
28620
28739
|
"038_add_image_removals": MIGRATION_038_ADD_IMAGE_REMOVALS,
|
|
28621
28740
|
"039_add_image_pins": MIGRATION_039_ADD_IMAGE_PINS,
|
|
28622
28741
|
"040_add_image_received_digests": MIGRATION_040_ADD_IMAGE_RECEIVED_DIGESTS,
|
|
28623
|
-
"041_add_move_send_steps": MIGRATION_041_ADD_MOVE_SEND_STEPS
|
|
28742
|
+
"041_add_move_send_steps": MIGRATION_041_ADD_MOVE_SEND_STEPS,
|
|
28743
|
+
"042_add_secret_env": MIGRATION_042_ADD_SECRET_ENV,
|
|
28744
|
+
"043_merge_secret_kinds": MIGRATION_043_MERGE_SECRET_KINDS
|
|
28624
28745
|
};
|
|
28625
28746
|
var PROVIDER = {
|
|
28626
28747
|
getMigrations: () => Promise.resolve(MIGRATIONS)
|
|
@@ -28925,11 +29046,11 @@ var CHECK_EVERY_MS = 7 * DAY_MS;
|
|
|
28925
29046
|
var CHECK_SUBSET = "5%";
|
|
28926
29047
|
var PRUNE_LOCK_TRIES = 6;
|
|
28927
29048
|
var RETRY_FIRST_MS = 5 * 60 * 1000;
|
|
28928
|
-
var BackupStateSchema =
|
|
28929
|
-
lastRunAt:
|
|
28930
|
-
lastPruneAt:
|
|
28931
|
-
lastCheckAt:
|
|
28932
|
-
lastCheckError:
|
|
29049
|
+
var BackupStateSchema = z65.object({
|
|
29050
|
+
lastRunAt: z65.coerce.date().nullable().default(null),
|
|
29051
|
+
lastPruneAt: z65.coerce.date().nullable().default(null),
|
|
29052
|
+
lastCheckAt: z65.coerce.date().nullable().default(null),
|
|
29053
|
+
lastCheckError: z65.string().nullable().default(null)
|
|
28933
29054
|
});
|
|
28934
29055
|
function buildBackupsOffError() {
|
|
28935
29056
|
return new ImpdError("PRECONDITION_FAILED", {
|
|
@@ -30027,6 +30148,7 @@ function createSecretRoutes(os, deps) {
|
|
|
30027
30148
|
name: secret.name,
|
|
30028
30149
|
kind: secret.kind,
|
|
30029
30150
|
rules: secret.rules,
|
|
30151
|
+
env: secret.env,
|
|
30030
30152
|
imps: secret.imps.filter((name) => isImpAllowed(patterns, name)),
|
|
30031
30153
|
createdAt: secret.createdAt,
|
|
30032
30154
|
oauth: secret.oauth
|
|
@@ -30873,11 +30995,11 @@ import {
|
|
|
30873
30995
|
import { INVALID_PARAMS, isJSONRPCRequest } from "@modelcontextprotocol/server";
|
|
30874
30996
|
|
|
30875
30997
|
// packages/mcp/src/tools/checkpoint-tools.ts
|
|
30876
|
-
import * as
|
|
30998
|
+
import * as z68 from "zod";
|
|
30877
30999
|
|
|
30878
31000
|
// packages/mcp/src/tools/define-tool.ts
|
|
30879
31001
|
import { ExecError, ORPCError as ORPCError4 } from "@impz/client";
|
|
30880
|
-
import * as
|
|
31002
|
+
import * as z66 from "zod";
|
|
30881
31003
|
|
|
30882
31004
|
// packages/mcp/src/imp-guard.ts
|
|
30883
31005
|
class GuardError extends Error {
|
|
@@ -30978,14 +31100,14 @@ function readPrefix(patterns) {
|
|
|
30978
31100
|
}
|
|
30979
31101
|
|
|
30980
31102
|
// packages/mcp/src/tools/define-tool.ts
|
|
30981
|
-
var JsonObjectSchema =
|
|
31103
|
+
var JsonObjectSchema = z66.record(z66.string(), z66.unknown());
|
|
30982
31104
|
function defineTool(spec) {
|
|
30983
31105
|
const definition = {
|
|
30984
31106
|
name: spec.name,
|
|
30985
31107
|
title: spec.annotations.title,
|
|
30986
31108
|
description: spec.description,
|
|
30987
31109
|
inputSchema: {
|
|
30988
|
-
...JsonObjectSchema.parse(
|
|
31110
|
+
...JsonObjectSchema.parse(z66.toJSONSchema(spec.input, { io: "input" })),
|
|
30989
31111
|
type: "object"
|
|
30990
31112
|
},
|
|
30991
31113
|
annotations: spec.annotations
|
|
@@ -31044,15 +31166,15 @@ function formatCoded(code, message) {
|
|
|
31044
31166
|
}
|
|
31045
31167
|
|
|
31046
31168
|
// packages/mcp/src/tools/imp-tools.ts
|
|
31047
|
-
import * as
|
|
31169
|
+
import * as z67 from "zod";
|
|
31048
31170
|
var ImpNameInput = NameSchema.describe("The imp name, from imp_list");
|
|
31049
|
-
var NameOnly =
|
|
31171
|
+
var NameOnly = z67.strictObject({ name: ImpNameInput });
|
|
31050
31172
|
var IMP_TOOLS = [
|
|
31051
31173
|
defineTool({
|
|
31052
31174
|
name: "imp_list",
|
|
31053
31175
|
scope: "read",
|
|
31054
31176
|
description: "List the imps this server may touch: name, state (running, sleeping, stopped, error), image, memory and URL. A sleeping or stopped imp wakes or boots by itself on the next exec, file or HTTP request.",
|
|
31055
|
-
input:
|
|
31177
|
+
input: z67.strictObject({}),
|
|
31056
31178
|
annotations: { title: "List imps", readOnlyHint: true, openWorldHint: false },
|
|
31057
31179
|
run: async (_input, context) => {
|
|
31058
31180
|
const imps = await context.client.imps.list();
|
|
@@ -31064,7 +31186,7 @@ var IMP_TOOLS = [
|
|
|
31064
31186
|
scope: "manage",
|
|
31065
31187
|
cancellable: false,
|
|
31066
31188
|
description: "Create an imp, a persistent Linux microVM, and boot it. Its disk survives sleeps and restarts until imp_destroy. Without a name, the server picks one inside its guard. Returns the imp. A cancel does not stop the create, and its result still comes back.",
|
|
31067
|
-
input:
|
|
31189
|
+
input: z67.strictObject({
|
|
31068
31190
|
name: ImpCreateInputSchema.shape.name.describe("The new imp's name: a lowercase letter, then up to 30 lowercase letters, digits or hyphens. Omit to have one picked."),
|
|
31069
31191
|
image: ImpCreateInputSchema.shape.image.describe("The image to boot, from imp_image_list; impd's default when omitted"),
|
|
31070
31192
|
vcpus: ImpCreateInputSchema.shape.vcpus.describe("Virtual CPUs; impd's default when omitted"),
|
|
@@ -31141,10 +31263,10 @@ var IMP_TOOLS = [
|
|
|
31141
31263
|
scope: "manage",
|
|
31142
31264
|
cancellable: false,
|
|
31143
31265
|
description: "Create a new imp from the disk of another, now or as it was at one of its checkpoints. The fork boots fresh: it has the disk, not the running processes. Use it to try two approaches side by side. A token limited to some imps gives the fork only the source's secret grants it could make itself; grantsNotCopied names each grant the fork did not get, and grantsError says why it got none. A cancel does not stop the fork, and its result still comes back.",
|
|
31144
|
-
input:
|
|
31266
|
+
input: z67.strictObject({
|
|
31145
31267
|
source: NameSchema.describe("The imp to fork, from imp_list"),
|
|
31146
31268
|
name: NameSchema.optional().describe("The fork's name; omit to have one picked"),
|
|
31147
|
-
checkpoint:
|
|
31269
|
+
checkpoint: z67.string().min(1).optional().describe("A checkpoint id or label of the source, from imp_checkpoint_list; the source's disk now when omitted")
|
|
31148
31270
|
}),
|
|
31149
31271
|
annotations: {
|
|
31150
31272
|
title: "Fork an imp",
|
|
@@ -31177,7 +31299,7 @@ var IMP_TOOLS = [
|
|
|
31177
31299
|
name: "imp_image_list",
|
|
31178
31300
|
scope: "read",
|
|
31179
31301
|
description: "List the images an imp can boot from, for imp_create.",
|
|
31180
|
-
input:
|
|
31302
|
+
input: z67.strictObject({}),
|
|
31181
31303
|
annotations: { title: "List images", readOnlyHint: true, openWorldHint: false },
|
|
31182
31304
|
run: async (_input, context) => {
|
|
31183
31305
|
const images = await context.client.images.list();
|
|
@@ -31187,13 +31309,13 @@ var IMP_TOOLS = [
|
|
|
31187
31309
|
];
|
|
31188
31310
|
|
|
31189
31311
|
// packages/mcp/src/tools/checkpoint-tools.ts
|
|
31190
|
-
var CheckpointRefInput =
|
|
31312
|
+
var CheckpointRefInput = z68.string().min(1).describe("A checkpoint id or label, from imp_checkpoint_list");
|
|
31191
31313
|
var CHECKPOINT_TOOLS = [
|
|
31192
31314
|
defineTool({
|
|
31193
31315
|
name: "imp_checkpoint",
|
|
31194
31316
|
scope: "manage",
|
|
31195
31317
|
description: "Save the imp's disk as a checkpoint, in about 100 ms, without stopping it. Take one before a risky change; imp_restore goes back to it and imp_fork starts a new imp from it.",
|
|
31196
|
-
input:
|
|
31318
|
+
input: z68.strictObject({
|
|
31197
31319
|
name: ImpNameInput,
|
|
31198
31320
|
label: CheckpointCreateInputSchema.shape.label.describe("A label to find the checkpoint by, such as before-migration")
|
|
31199
31321
|
}),
|
|
@@ -31216,7 +31338,7 @@ var CHECKPOINT_TOOLS = [
|
|
|
31216
31338
|
name: "imp_checkpoint_list",
|
|
31217
31339
|
scope: "read",
|
|
31218
31340
|
description: "List the imp's checkpoints: id, label, time and size.",
|
|
31219
|
-
input:
|
|
31341
|
+
input: z68.strictObject({ name: ImpNameInput }),
|
|
31220
31342
|
annotations: { title: "List checkpoints", readOnlyHint: true, openWorldHint: false },
|
|
31221
31343
|
run: async (input, context) => {
|
|
31222
31344
|
context.guard.require(input.name);
|
|
@@ -31229,7 +31351,7 @@ var CHECKPOINT_TOOLS = [
|
|
|
31229
31351
|
scope: "manage",
|
|
31230
31352
|
cancellable: false,
|
|
31231
31353
|
description: "Put the imp's disk back to a checkpoint. Everything written since the checkpoint is lost, and so is the memory: an awake imp boots fresh, a sleeping or stopped one boots on its next use. A cancel does not stop the restore, and its result still comes back.",
|
|
31232
|
-
input:
|
|
31354
|
+
input: z68.strictObject({ name: ImpNameInput, checkpoint: CheckpointRefInput }),
|
|
31233
31355
|
annotations: {
|
|
31234
31356
|
title: "Restore a checkpoint",
|
|
31235
31357
|
readOnlyHint: false,
|
|
@@ -31246,7 +31368,7 @@ var CHECKPOINT_TOOLS = [
|
|
|
31246
31368
|
name: "imp_checkpoint_delete",
|
|
31247
31369
|
scope: "manage",
|
|
31248
31370
|
description: "Delete one of the imp's checkpoints for good. The imp itself is not touched.",
|
|
31249
|
-
input:
|
|
31371
|
+
input: z68.strictObject({ name: ImpNameInput, checkpoint: CheckpointRefInput }),
|
|
31250
31372
|
annotations: {
|
|
31251
31373
|
title: "Delete a checkpoint",
|
|
31252
31374
|
readOnlyHint: false,
|
|
@@ -31262,7 +31384,7 @@ var CHECKPOINT_TOOLS = [
|
|
|
31262
31384
|
];
|
|
31263
31385
|
|
|
31264
31386
|
// packages/mcp/src/tools/exec-tool.ts
|
|
31265
|
-
import * as
|
|
31387
|
+
import * as z69 from "zod";
|
|
31266
31388
|
|
|
31267
31389
|
// packages/mcp/src/exec/output-cap.ts
|
|
31268
31390
|
function createOutputCollector(maxBytes, headBytes) {
|
|
@@ -31500,16 +31622,16 @@ var MAX_TIMEOUT_S = 1800;
|
|
|
31500
31622
|
var DEFAULT_OUTPUT_BYTES = 64 * 1024;
|
|
31501
31623
|
var MAX_OUTPUT_BYTES = 256 * 1024;
|
|
31502
31624
|
var HEAD_BYTES = 8 * 1024;
|
|
31503
|
-
var ExecInput =
|
|
31625
|
+
var ExecInput = z69.strictObject({
|
|
31504
31626
|
name: ImpNameInput,
|
|
31505
|
-
command:
|
|
31506
|
-
argv:
|
|
31507
|
-
stdin:
|
|
31508
|
-
cwd:
|
|
31509
|
-
env:
|
|
31510
|
-
require:
|
|
31511
|
-
timeoutSeconds:
|
|
31512
|
-
maxOutputBytes:
|
|
31627
|
+
command: z69.string().min(1).optional().describe("A shell command line, run as /bin/sh -c COMMAND. Give this or argv."),
|
|
31628
|
+
argv: z69.array(z69.string()).min(1).optional().describe("The program and its arguments, run as they are with no shell. Give this or command."),
|
|
31629
|
+
stdin: z69.string().optional().describe("Text for the command's stdin, which then closes; closed at once when omitted"),
|
|
31630
|
+
cwd: z69.string().optional().describe("The working directory; the image's workdir or HOME when omitted"),
|
|
31631
|
+
env: z69.record(z69.string(), z69.string()).optional().describe("Environment variables, added to the image's"),
|
|
31632
|
+
require: z69.array(z69.enum(EXEC_REQUIREMENTS)).optional().describe("What impd must ensure before the command starts, or the call fails with PRECONDITION_FAILED and nothing runs. broker: impd set the credential broker's proxy variables and CA bundle for this boot."),
|
|
31633
|
+
timeoutSeconds: z69.int().min(1).max(MAX_TIMEOUT_S).default(DEFAULT_TIMEOUT_S).describe(`How long the command may run, waking the imp included (default ${String(DEFAULT_TIMEOUT_S)})`),
|
|
31634
|
+
maxOutputBytes: z69.int().min(1024).max(MAX_OUTPUT_BYTES).default(DEFAULT_OUTPUT_BYTES).describe(`The most output kept per stream (default ${String(DEFAULT_OUTPUT_BYTES)}): the first ${String(HEAD_BYTES)} bytes and the last bytes, with a marker for the bytes dropped between`)
|
|
31513
31635
|
}).refine((input) => input.command === undefined !== (input.argv === undefined), {
|
|
31514
31636
|
message: "give either command or argv"
|
|
31515
31637
|
});
|
|
@@ -31559,7 +31681,7 @@ var EXEC_TOOL = defineTool({
|
|
|
31559
31681
|
});
|
|
31560
31682
|
|
|
31561
31683
|
// packages/mcp/src/tools/file-tools.ts
|
|
31562
|
-
import * as
|
|
31684
|
+
import * as z70 from "zod";
|
|
31563
31685
|
|
|
31564
31686
|
// packages/mcp/src/tools/write-script.ts
|
|
31565
31687
|
var WRITE_SCRIPT = [
|
|
@@ -31588,15 +31710,15 @@ var MAX_READ_BYTES = 1024 * 1024;
|
|
|
31588
31710
|
var MAX_WRITE_BYTES = 4 * 1024 * 1024;
|
|
31589
31711
|
var FILE_TIMEOUT_MS = 60000;
|
|
31590
31712
|
var STDERR_BYTES = 4096;
|
|
31591
|
-
var GuestPathInput =
|
|
31592
|
-
var MaxBytesInput =
|
|
31593
|
-
var EncodingInput =
|
|
31713
|
+
var GuestPathInput = z70.string().startsWith("/", "must be an absolute path").describe("An absolute path in the imp");
|
|
31714
|
+
var MaxBytesInput = z70.int().min(1).max(MAX_READ_BYTES).default(DEFAULT_READ_BYTES).describe(`The most bytes to read (default ${String(DEFAULT_READ_BYTES)}); a larger file fails, so read a part of it with imp_exec (head, tail, sed -n)`);
|
|
31715
|
+
var EncodingInput = z70.enum(["utf8", "base64"]).default("utf8").describe("utf8 for text, base64 for any bytes (default utf8)");
|
|
31594
31716
|
var FILE_TOOLS = [
|
|
31595
31717
|
defineTool({
|
|
31596
31718
|
name: "imp_read_file",
|
|
31597
31719
|
scope: "exec",
|
|
31598
31720
|
description: `Read a file in an imp, up to maxBytes. A sleeping imp wakes and a stopped one boots first. Text comes back as utf8; a file that is not valid UTF-8 fails, so read it again with encoding base64.`,
|
|
31599
|
-
input:
|
|
31721
|
+
input: z70.strictObject({
|
|
31600
31722
|
name: ImpNameInput,
|
|
31601
31723
|
path: GuestPathInput,
|
|
31602
31724
|
encoding: EncodingInput,
|
|
@@ -31636,10 +31758,10 @@ var FILE_TOOLS = [
|
|
|
31636
31758
|
name: "imp_write_file",
|
|
31637
31759
|
scope: "exec",
|
|
31638
31760
|
description: `Write a file in an imp, replacing it whole, and create its parent directories. The write goes to a temp file that is renamed over the path, so no reader sees half a file; an existing file keeps its mode, a symlink is written through, and a directory is refused. At most ${String(MAX_WRITE_BYTES)} bytes.`,
|
|
31639
|
-
input:
|
|
31761
|
+
input: z70.strictObject({
|
|
31640
31762
|
name: ImpNameInput,
|
|
31641
31763
|
path: GuestPathInput,
|
|
31642
|
-
content:
|
|
31764
|
+
content: z70.string().describe("The whole file, as text or as base64 (see encoding)"),
|
|
31643
31765
|
encoding: EncodingInput
|
|
31644
31766
|
}),
|
|
31645
31767
|
annotations: {
|
|
@@ -31872,11 +31994,7 @@ function createImpServer(options, caller, calls) {
|
|
|
31872
31994
|
const printError = options.printError ?? console.error;
|
|
31873
31995
|
const server = new McpServer({ name: "imp", title: "imp", version: options.version }, {
|
|
31874
31996
|
capabilities: { tools: { listChanged: false } },
|
|
31875
|
-
instructions:
|
|
31876
|
-
'imp runs persistent Linux microVMs ("imps") that sleep when idle and wake on use.',
|
|
31877
|
-
`This server may touch ${caller.guard.summary}.`,
|
|
31878
|
-
"Create an imp, run commands and read and write files in it, checkpoint before a risky change, fork to try two fixes, and destroy what you no longer need."
|
|
31879
|
-
].join(" "),
|
|
31997
|
+
instructions: buildInstructions(caller),
|
|
31880
31998
|
supportedProtocolVersions: [...PROTOCOL_VERSIONS, ...MODERN_PROTOCOL_VERSIONS]
|
|
31881
31999
|
});
|
|
31882
32000
|
server.server.fallbackRequestHandler = (request) => Promise.reject(new ProtocolError(ProtocolErrorCode.MethodNotFound, `unknown method: ${request.method}`));
|
|
@@ -31932,6 +32050,20 @@ function createImpServer(options, caller, calls) {
|
|
|
31932
32050
|
}
|
|
31933
32051
|
return server;
|
|
31934
32052
|
}
|
|
32053
|
+
var SCOPE_GUIDES = {
|
|
32054
|
+
read: "This caller has the read scope, so it can only look: list imps, their URLs, the images and the checkpoints. Running commands, reading or writing files, and creating, checkpointing, forking or destroying an imp need a wider grant: exec or manage.",
|
|
32055
|
+
exec: "This caller has the exec scope: list imps, their URLs, the images and the checkpoints, run commands and read and write files in an imp, and put one to sleep. Creating, checkpointing, restoring, forking or destroying an imp needs a manage grant.",
|
|
32056
|
+
manage: "Create an imp, run commands and read and write files in it, checkpoint before a risky change, fork to try two fixes, and destroy what you no longer need."
|
|
32057
|
+
};
|
|
32058
|
+
function buildInstructions(caller) {
|
|
32059
|
+
const names = TOOLS.filter((tool) => hasScope(caller.scope, tool.scope)).map((tool) => tool.definition.name);
|
|
32060
|
+
return [
|
|
32061
|
+
'imp runs persistent Linux microVMs ("imps") that sleep when idle and wake on use.',
|
|
32062
|
+
`This server may touch ${caller.guard.summary}.`,
|
|
32063
|
+
SCOPE_GUIDES[caller.scope],
|
|
32064
|
+
`Its tools: ${names.join(", ")}.`
|
|
32065
|
+
].join(" ");
|
|
32066
|
+
}
|
|
31935
32067
|
function startProgress(ctx, options) {
|
|
31936
32068
|
const token = ctx.mcpReq._meta?.progressToken;
|
|
31937
32069
|
if (token === undefined) {
|
|
@@ -32275,14 +32407,14 @@ function createMcpEndpoint(deps) {
|
|
|
32275
32407
|
}
|
|
32276
32408
|
|
|
32277
32409
|
// packages/daemon/src/surface/with-retry-after.ts
|
|
32278
|
-
import * as
|
|
32410
|
+
import * as z71 from "zod";
|
|
32279
32411
|
async function withRetryAfter(response) {
|
|
32280
32412
|
if (response.status !== 409) {
|
|
32281
32413
|
return response;
|
|
32282
32414
|
}
|
|
32283
32415
|
try {
|
|
32284
32416
|
const body = await response.clone().json();
|
|
32285
|
-
const MovingBodySchema =
|
|
32417
|
+
const MovingBodySchema = z71.object({ json: z71.object({ code: z71.literal("MOVING") }) });
|
|
32286
32418
|
if (!MovingBodySchema.safeParse(body).success) {
|
|
32287
32419
|
return response;
|
|
32288
32420
|
}
|
|
@@ -32738,7 +32870,7 @@ import { join as join16 } from "path";
|
|
|
32738
32870
|
// packages/daemon/src/create-upstream-resolver.ts
|
|
32739
32871
|
import { readFileSync as readFileSync13, statSync as statSync6 } from "fs";
|
|
32740
32872
|
import { rootCertificates } from "tls";
|
|
32741
|
-
import * as
|
|
32873
|
+
import * as z72 from "zod";
|
|
32742
32874
|
|
|
32743
32875
|
// packages/daemon/src/network/broker/tls/resolve-public-upstream.ts
|
|
32744
32876
|
function resolvePublicUpstream(host) {
|
|
@@ -32746,9 +32878,9 @@ function resolvePublicUpstream(host) {
|
|
|
32746
32878
|
}
|
|
32747
32879
|
|
|
32748
32880
|
// packages/daemon/src/create-upstream-resolver.ts
|
|
32749
|
-
var FileSchema =
|
|
32750
|
-
ca:
|
|
32751
|
-
upstreams:
|
|
32881
|
+
var FileSchema = z72.object({
|
|
32882
|
+
ca: z72.string().includes("-----BEGIN CERTIFICATE-----"),
|
|
32883
|
+
upstreams: z72.record(z72.string(), z72.url({ protocol: /^https$/u }))
|
|
32752
32884
|
});
|
|
32753
32885
|
function createUpstreamResolver(path) {
|
|
32754
32886
|
const cache = {
|
|
@@ -33012,7 +33144,7 @@ function buildHostReach(ranges, uplinks, hasIPv6) {
|
|
|
33012
33144
|
|
|
33013
33145
|
// packages/daemon/src/network/broker/broker-service.ts
|
|
33014
33146
|
import { join as join15 } from "path";
|
|
33015
|
-
import { match as
|
|
33147
|
+
import { match as match3 } from "ts-pattern";
|
|
33016
33148
|
|
|
33017
33149
|
// packages/daemon/src/platform/db/broker-audit.ts
|
|
33018
33150
|
var AUDIT_ROWS_PER_IMP = 1000;
|
|
@@ -33317,7 +33449,7 @@ input=$target.in
|
|
|
33317
33449
|
next=$target.tmp
|
|
33318
33450
|
|
|
33319
33451
|
mkdir -p "$(dirname "$target")"
|
|
33320
|
-
cat >"$input"
|
|
33452
|
+
cat > "$input"
|
|
33321
33453
|
|
|
33322
33454
|
# the first line that is the marker, matched whole and as a fixed string
|
|
33323
33455
|
split=$(grep -n -x -F -e "$marker" "$input" | head -n 1 | cut -d : -f 1)
|
|
@@ -33344,7 +33476,7 @@ done
|
|
|
33344
33476
|
fi
|
|
33345
33477
|
echo
|
|
33346
33478
|
head -n "$((split - 1))" "$input"
|
|
33347
|
-
} >"$next"
|
|
33479
|
+
} > "$next"
|
|
33348
33480
|
|
|
33349
33481
|
rm -f "$input"
|
|
33350
33482
|
|
|
@@ -33577,51 +33709,8 @@ async function readBrokerPeer(db, slot) {
|
|
|
33577
33709
|
|
|
33578
33710
|
// packages/daemon/src/network/broker/secrets/connector-kinds.ts
|
|
33579
33711
|
var PLACEHOLDER = "imp-broker-placeholder";
|
|
33580
|
-
|
|
33581
|
-
|
|
33582
|
-
rules: [
|
|
33583
|
-
{ host: "github.com", header: "authorization", scheme: "basic", user: "x-access-token" },
|
|
33584
|
-
{ host: "api.github.com", header: "authorization", scheme: "bearer" },
|
|
33585
|
-
{ host: "uploads.github.com", header: "authorization", scheme: "bearer" }
|
|
33586
|
-
],
|
|
33587
|
-
env: ["GH_TOKEN", "GITHUB_TOKEN"]
|
|
33588
|
-
},
|
|
33589
|
-
anthropic: {
|
|
33590
|
-
rules: [{ host: "api.anthropic.com", header: "x-api-key", scheme: "raw" }],
|
|
33591
|
-
env: ["ANTHROPIC_API_KEY"]
|
|
33592
|
-
},
|
|
33593
|
-
npm: {
|
|
33594
|
-
rules: [{ host: "registry.npmjs.org", header: "authorization", scheme: "bearer" }],
|
|
33595
|
-
env: ["NPM_TOKEN"]
|
|
33596
|
-
}
|
|
33597
|
-
};
|
|
33598
|
-
|
|
33599
|
-
class SecretRulesError extends Error {
|
|
33600
|
-
name = "SecretRulesError";
|
|
33601
|
-
}
|
|
33602
|
-
function resolveRules(kind, given) {
|
|
33603
|
-
if (kind !== "custom" && kind !== "oauth") {
|
|
33604
|
-
if (given !== undefined) {
|
|
33605
|
-
throw new SecretRulesError(`kind ${kind} has its own hosts; rules are for kinds custom and oauth`);
|
|
33606
|
-
}
|
|
33607
|
-
return PRESETS[kind].rules;
|
|
33608
|
-
}
|
|
33609
|
-
if (given === undefined || given.length === 0) {
|
|
33610
|
-
throw new SecretRulesError(`kind ${kind} needs at least one host`);
|
|
33611
|
-
}
|
|
33612
|
-
if (kind !== "custom" && given.some((rule) => rule.upstream !== undefined)) {
|
|
33613
|
-
throw new SecretRulesError(`kind ${kind} cannot have an upstream; it is for kind custom`);
|
|
33614
|
-
}
|
|
33615
|
-
const hosts = given.map((rule) => rule.host);
|
|
33616
|
-
const repeated = hosts.find((host, index) => hosts.indexOf(host) !== index);
|
|
33617
|
-
if (repeated !== undefined) {
|
|
33618
|
-
throw new SecretRulesError(`${repeated} has more than one rule`);
|
|
33619
|
-
}
|
|
33620
|
-
return given;
|
|
33621
|
-
}
|
|
33622
|
-
function listPlaceholderEnv(kinds) {
|
|
33623
|
-
const names = kinds.flatMap((kind) => kind === "custom" || kind === "oauth" ? [] : PRESETS[kind].env);
|
|
33624
|
-
return [...new Set(names)];
|
|
33712
|
+
function listPlaceholderEnv(envLists) {
|
|
33713
|
+
return [...new Set(envLists.flat())];
|
|
33625
33714
|
}
|
|
33626
33715
|
function renderCredential(rule, value) {
|
|
33627
33716
|
if (rule.scheme === "bearer") {
|
|
@@ -33634,17 +33723,17 @@ function renderCredential(rule, value) {
|
|
|
33634
33723
|
}
|
|
33635
33724
|
|
|
33636
33725
|
// packages/daemon/src/network/broker/secrets/oauth-state.ts
|
|
33637
|
-
import * as
|
|
33638
|
-
var TokenSchema2 =
|
|
33639
|
-
var StateSchema =
|
|
33640
|
-
v:
|
|
33726
|
+
import * as z73 from "zod";
|
|
33727
|
+
var TokenSchema2 = z73.string().min(1).max(16384);
|
|
33728
|
+
var StateSchema = z73.object({
|
|
33729
|
+
v: z73.literal(1),
|
|
33641
33730
|
refreshToken: TokenSchema2,
|
|
33642
33731
|
accessToken: TokenSchema2.nullable(),
|
|
33643
33732
|
idToken: TokenSchema2.nullable(),
|
|
33644
|
-
expiresAt:
|
|
33645
|
-
refreshedAt:
|
|
33646
|
-
status:
|
|
33647
|
-
error:
|
|
33733
|
+
expiresAt: z73.number().nullable(),
|
|
33734
|
+
refreshedAt: z73.number().nullable(),
|
|
33735
|
+
status: z73.enum(["pending", "ready", "needs_login"]),
|
|
33736
|
+
error: z73.string().max(200).nullable()
|
|
33648
33737
|
});
|
|
33649
33738
|
function buildPendingState(refreshToken) {
|
|
33650
33739
|
return {
|
|
@@ -33706,6 +33795,23 @@ function readJwtExpiry(token) {
|
|
|
33706
33795
|
return typeof exp === "number" && Number.isFinite(exp) && exp > 0 ? exp * 1000 : null;
|
|
33707
33796
|
}
|
|
33708
33797
|
|
|
33798
|
+
// packages/daemon/src/network/broker/secrets/secret-kinds.ts
|
|
33799
|
+
var SECRET_KINDS = {
|
|
33800
|
+
static: {
|
|
33801
|
+
formatValueFile: (value) => value,
|
|
33802
|
+
findCredential: (content) => ({ value: content, oauth: null }),
|
|
33803
|
+
isRefreshed: false
|
|
33804
|
+
},
|
|
33805
|
+
oauth: {
|
|
33806
|
+
formatValueFile: (refreshToken) => formatOAuthState(buildPendingState(refreshToken)),
|
|
33807
|
+
findCredential: (content) => {
|
|
33808
|
+
const state = parseOAuthState(content);
|
|
33809
|
+
return state === null || state.accessToken === null ? null : { value: state.accessToken, oauth: { refreshedAt: state.refreshedAt } };
|
|
33810
|
+
},
|
|
33811
|
+
isRefreshed: true
|
|
33812
|
+
}
|
|
33813
|
+
};
|
|
33814
|
+
|
|
33709
33815
|
// packages/daemon/src/platform/http/send-with-ca.ts
|
|
33710
33816
|
function sendWithCA(url, init) {
|
|
33711
33817
|
const tls = init.tls === undefined ? {} : { tls: { ca: [...init.tls.ca] } };
|
|
@@ -34451,18 +34557,17 @@ function createBrokerProxy(deps) {
|
|
|
34451
34557
|
const readCredential = async (impId, host) => {
|
|
34452
34558
|
const granted = await readRule(impId, host);
|
|
34453
34559
|
const stored = granted === undefined ? null : files.read(granted.valueFile);
|
|
34454
|
-
const
|
|
34455
|
-
|
|
34456
|
-
if (granted === undefined || value === null) {
|
|
34560
|
+
const credential = granted === undefined || stored === null ? null : SECRET_KINDS[granted.kind].findCredential(stored);
|
|
34561
|
+
if (granted === undefined || credential === null) {
|
|
34457
34562
|
return null;
|
|
34458
34563
|
}
|
|
34459
34564
|
return {
|
|
34460
34565
|
secretName: granted.secretName,
|
|
34461
34566
|
header: granted.rule.header,
|
|
34462
|
-
value: renderCredential(granted.rule, value),
|
|
34567
|
+
value: renderCredential(granted.rule, credential.value),
|
|
34463
34568
|
upstream: granted.rule.upstream ?? null,
|
|
34464
34569
|
filter: granted.filter,
|
|
34465
|
-
oauth: oauth
|
|
34570
|
+
oauth: credential.oauth
|
|
34466
34571
|
};
|
|
34467
34572
|
};
|
|
34468
34573
|
const writeAudit = async (entry) => {
|
|
@@ -34531,6 +34636,30 @@ function createBrokerProxy(deps) {
|
|
|
34531
34636
|
};
|
|
34532
34637
|
}
|
|
34533
34638
|
|
|
34639
|
+
// packages/daemon/src/network/broker/secrets/build-stored-binding.ts
|
|
34640
|
+
import { P, match as match2 } from "ts-pattern";
|
|
34641
|
+
function buildStoredBinding(input) {
|
|
34642
|
+
return match2(input).returnType().with({ kind: "static" }, (given) => ({
|
|
34643
|
+
kind: "static",
|
|
34644
|
+
rules: given.rules,
|
|
34645
|
+
env: given.env ?? [],
|
|
34646
|
+
oauth: null
|
|
34647
|
+
})).with({ kind: "oauth" }, (given) => ({
|
|
34648
|
+
kind: "oauth",
|
|
34649
|
+
rules: given.rules,
|
|
34650
|
+
env: given.env ?? [],
|
|
34651
|
+
oauth: given.oauth
|
|
34652
|
+
})).with({ preset: P.string }, (given) => buildPresetBinding(given.preset)).with({ kind: "custom" }, (given) => ({
|
|
34653
|
+
kind: "static",
|
|
34654
|
+
rules: given.rules,
|
|
34655
|
+
env: [],
|
|
34656
|
+
oauth: null
|
|
34657
|
+
})).with({ kind: P.union("github", "anthropic", "npm") }, (given) => buildPresetBinding(given.kind)).exhaustive();
|
|
34658
|
+
}
|
|
34659
|
+
function buildPresetBinding(preset) {
|
|
34660
|
+
return { ...SECRET_PRESETS[preset], oauth: null };
|
|
34661
|
+
}
|
|
34662
|
+
|
|
34534
34663
|
// packages/daemon/src/network/broker/secrets/secret-files.ts
|
|
34535
34664
|
import { randomBytes as randomBytes7 } from "crypto";
|
|
34536
34665
|
import {
|
|
@@ -34653,6 +34782,7 @@ function createSecretStore(deps) {
|
|
|
34653
34782
|
name: secret.name,
|
|
34654
34783
|
kind: secret.kind,
|
|
34655
34784
|
rules: secret.rules,
|
|
34785
|
+
env: secret.env,
|
|
34656
34786
|
imps,
|
|
34657
34787
|
createdAt: secret.createdAt
|
|
34658
34788
|
};
|
|
@@ -34704,38 +34834,19 @@ function createSecretStore(deps) {
|
|
|
34704
34834
|
};
|
|
34705
34835
|
return {
|
|
34706
34836
|
addSecret: async (input) => {
|
|
34707
|
-
|
|
34708
|
-
|
|
34709
|
-
rules = resolveRules(input.kind, input.rules);
|
|
34710
|
-
} catch (error) {
|
|
34711
|
-
if (error instanceof SecretRulesError) {
|
|
34712
|
-
throw new ImpdError("BAD_REQUEST", { message: error.message });
|
|
34713
|
-
}
|
|
34714
|
-
throw error;
|
|
34715
|
-
}
|
|
34716
|
-
if (input.kind === "oauth" && input.oauth === undefined) {
|
|
34717
|
-
throw new ImpdError("BAD_REQUEST", {
|
|
34718
|
-
message: "kind oauth needs a token URL and a client id"
|
|
34719
|
-
});
|
|
34720
|
-
}
|
|
34721
|
-
if (input.kind !== "oauth" && input.oauth !== undefined) {
|
|
34722
|
-
throw new ImpdError("BAD_REQUEST", {
|
|
34723
|
-
message: `kind ${input.kind} has no token URL or client id; they are for kind oauth`
|
|
34724
|
-
});
|
|
34725
|
-
}
|
|
34726
|
-
const oauth = input.kind === "oauth" ? input.oauth ?? null : null;
|
|
34837
|
+
const binding = buildStoredBinding(input);
|
|
34838
|
+
const kind = SECRET_KINDS[binding.kind];
|
|
34727
34839
|
const saved = await refresher.withLock(input.name, async () => {
|
|
34728
34840
|
const valueFile = buildValueFile(input.name);
|
|
34729
|
-
|
|
34730
|
-
|
|
34731
|
-
const written = await writeSecretRow({ name: input.name, kind: input.kind, rules, oauth, valueFile }, input);
|
|
34841
|
+
files.write(valueFile, kind.formatValueFile(input.value));
|
|
34842
|
+
const written = await writeSecretRow({ name: input.name, ...binding, valueFile }, input);
|
|
34732
34843
|
if (written.oldValueFile !== null) {
|
|
34733
34844
|
await removeDisplacedFile(written.oldValueFile);
|
|
34734
34845
|
await deps.applyGrants();
|
|
34735
34846
|
}
|
|
34736
34847
|
return written;
|
|
34737
34848
|
});
|
|
34738
|
-
if (
|
|
34849
|
+
if (kind.isRefreshed) {
|
|
34739
34850
|
await refresher.refresh(input.name, true);
|
|
34740
34851
|
}
|
|
34741
34852
|
const latest = await readSecret(db, input.name);
|
|
@@ -34751,7 +34862,7 @@ function createSecretStore(deps) {
|
|
|
34751
34862
|
if (secret === undefined) {
|
|
34752
34863
|
throw buildNotFoundError("secret", name);
|
|
34753
34864
|
}
|
|
34754
|
-
if (secret.kind
|
|
34865
|
+
if (!SECRET_KINDS[secret.kind].isRefreshed) {
|
|
34755
34866
|
throw new ImpdError("BAD_REQUEST", { message: `secret ${name} is not an oauth secret` });
|
|
34756
34867
|
}
|
|
34757
34868
|
await refresher.refresh(name, true);
|
|
@@ -34890,7 +35001,7 @@ function isDue(state, at) {
|
|
|
34890
35001
|
}
|
|
34891
35002
|
|
|
34892
35003
|
// packages/daemon/src/network/broker/secrets/parse-token-answer.ts
|
|
34893
|
-
import * as
|
|
35004
|
+
import * as z74 from "zod";
|
|
34894
35005
|
function parseTokenAnswer(status, text) {
|
|
34895
35006
|
let body = null;
|
|
34896
35007
|
try {
|
|
@@ -34916,8 +35027,8 @@ function parseTokenAnswer(status, text) {
|
|
|
34916
35027
|
}
|
|
34917
35028
|
return parseTokens(body);
|
|
34918
35029
|
}
|
|
34919
|
-
var ErrorObjectSchema =
|
|
34920
|
-
var ErrorAnswerSchema =
|
|
35030
|
+
var ErrorObjectSchema = z74.object({ code: z74.string().nullish(), error: z74.string().nullish() });
|
|
35031
|
+
var ErrorAnswerSchema = z74.object({ error: z74.union([z74.string(), ErrorObjectSchema]) });
|
|
34921
35032
|
function findErrorCode(body) {
|
|
34922
35033
|
const parsed = ErrorAnswerSchema.safeParse(body);
|
|
34923
35034
|
if (!parsed.success) {
|
|
@@ -34927,11 +35038,11 @@ function findErrorCode(body) {
|
|
|
34927
35038
|
const code = typeof error === "string" ? error : error.code ?? error.error;
|
|
34928
35039
|
return code !== null && code !== undefined && /^[A-Za-z0-9_.-]{1,64}$/u.test(code) ? code : null;
|
|
34929
35040
|
}
|
|
34930
|
-
var TokenAnswerSchema =
|
|
34931
|
-
access_token:
|
|
34932
|
-
refresh_token:
|
|
34933
|
-
id_token:
|
|
34934
|
-
expires_in:
|
|
35041
|
+
var TokenAnswerSchema = z74.object({
|
|
35042
|
+
access_token: z74.string().nullish(),
|
|
35043
|
+
refresh_token: z74.string().nullish(),
|
|
35044
|
+
id_token: z74.string().nullish(),
|
|
35045
|
+
expires_in: z74.number().nullish()
|
|
34935
35046
|
});
|
|
34936
35047
|
function parseTokens(body) {
|
|
34937
35048
|
const parsed = TokenAnswerSchema.safeParse(body);
|
|
@@ -35457,7 +35568,7 @@ ${key.host}`));
|
|
|
35457
35568
|
if (outcome.kind === "granted") {
|
|
35458
35569
|
return;
|
|
35459
35570
|
}
|
|
35460
|
-
throw
|
|
35571
|
+
throw match3(outcome).with({ kind: "no-secret" }, () => buildNotFoundError("secret", secretName)).with({ kind: "no-token" }, () => buildTokenGoneError()).with({ kind: "not-grantable" }, () => buildStaleError(secretName)).with({ kind: "clash" }, (refused) => buildClashError(impName, secretName, refused.clash)).exhaustive();
|
|
35461
35572
|
},
|
|
35462
35573
|
removeGrant: async (impName, secretName, authority = null) => {
|
|
35463
35574
|
const imp = await requireImp(impName);
|
|
@@ -35533,7 +35644,7 @@ ${key.host}`));
|
|
|
35533
35644
|
}).hostIp;
|
|
35534
35645
|
const env = buildBrokerEnv({
|
|
35535
35646
|
proxyUrl: `http://${gateway}:${String(proxy.getPort())}`,
|
|
35536
|
-
placeholders: listPlaceholderEnv(granted.map((entry) => entry.
|
|
35647
|
+
placeholders: listPlaceholderEnv(granted.map((entry) => entry.env)),
|
|
35537
35648
|
placeholder: PLACEHOLDER
|
|
35538
35649
|
});
|
|
35539
35650
|
return { kind: "ready", env };
|
|
@@ -37552,7 +37663,7 @@ function createImpWatchdog(context, lock, ops) {
|
|
|
37552
37663
|
}
|
|
37553
37664
|
|
|
37554
37665
|
// packages/daemon/src/platform/events/imp-event-publisher.ts
|
|
37555
|
-
import { P, match as
|
|
37666
|
+
import { P as P2, match as match4 } from "ts-pattern";
|
|
37556
37667
|
function startImpEventPublisher(deps) {
|
|
37557
37668
|
const pending = [];
|
|
37558
37669
|
const state = { draining: false };
|
|
@@ -37579,7 +37690,7 @@ function startImpEventPublisher(deps) {
|
|
|
37579
37690
|
}
|
|
37580
37691
|
function readEvent(deps, write) {
|
|
37581
37692
|
const envelope = { v: EVENT_VERSION, at: new Date(deps.now()) };
|
|
37582
|
-
return
|
|
37693
|
+
return match4(write).returnType().with({ kind: "added" }, async (added) => ({
|
|
37583
37694
|
...envelope,
|
|
37584
37695
|
ev: "ImpAdded",
|
|
37585
37696
|
reason: "created",
|
|
@@ -37594,7 +37705,7 @@ function readEvent(deps, write) {
|
|
|
37594
37705
|
...envelope,
|
|
37595
37706
|
ev: "ImpRemoved",
|
|
37596
37707
|
imp: await deps.toApi(removed.imp)
|
|
37597
|
-
})).with({ kind:
|
|
37708
|
+
})).with({ kind: P2.union("checkpointAdded", "checkpointRemoved") }, async (checkpointWrite) => {
|
|
37598
37709
|
const imp = await readImpById(deps.db, checkpointWrite.checkpoint.impId);
|
|
37599
37710
|
if (imp === undefined) {
|
|
37600
37711
|
return null;
|
|
@@ -38783,7 +38894,7 @@ import {
|
|
|
38783
38894
|
} from "fs";
|
|
38784
38895
|
import { join as join18 } from "path";
|
|
38785
38896
|
import { withContext as withContext2 } from "@logtape/logtape";
|
|
38786
|
-
import * as
|
|
38897
|
+
import * as z75 from "zod";
|
|
38787
38898
|
|
|
38788
38899
|
// packages/daemon/src/vm/vmm/configure-vm.ts
|
|
38789
38900
|
function createMarks() {
|
|
@@ -38860,11 +38971,11 @@ var MAX_TEMPLATES = 4;
|
|
|
38860
38971
|
var MAX_BUILD_FAILURES = 3;
|
|
38861
38972
|
var MAX_RESTORE_FAILURES = 3;
|
|
38862
38973
|
var BUILD_RETRY_MS = 60000;
|
|
38863
|
-
var TemplateMetaSchema =
|
|
38864
|
-
buildId:
|
|
38865
|
-
vcpus:
|
|
38866
|
-
memoryMib:
|
|
38867
|
-
systemDrivePath:
|
|
38974
|
+
var TemplateMetaSchema = z75.object({
|
|
38975
|
+
buildId: z75.string(),
|
|
38976
|
+
vcpus: z75.int().positive(),
|
|
38977
|
+
memoryMib: z75.int().positive(),
|
|
38978
|
+
systemDrivePath: z75.string()
|
|
38868
38979
|
});
|
|
38869
38980
|
|
|
38870
38981
|
class BuildRefusedError extends Error {
|
|
@@ -39261,7 +39372,7 @@ function readThreadIds(pid, procRoot = "/proc") {
|
|
|
39261
39372
|
}
|
|
39262
39373
|
|
|
39263
39374
|
// packages/daemon/src/imps/session-logs/session-log-service.ts
|
|
39264
|
-
import * as
|
|
39375
|
+
import * as z77 from "zod";
|
|
39265
39376
|
|
|
39266
39377
|
// packages/daemon/src/imps/session-logs/build-log-key.ts
|
|
39267
39378
|
function buildLogKey(impId, generation) {
|
|
@@ -39280,7 +39391,7 @@ import { basename as basename2, dirname as dirname8, join as join20, resolve as
|
|
|
39280
39391
|
import { existsSync as existsSync10, readFileSync as readFileSync20, readdirSync as readdirSync5, rmSync as rmSync16 } from "fs";
|
|
39281
39392
|
import { mkdir, open as open4, stat, truncate, unlink } from "fs/promises";
|
|
39282
39393
|
import { join as join19 } from "path";
|
|
39283
|
-
import * as
|
|
39394
|
+
import * as z76 from "zod";
|
|
39284
39395
|
|
|
39285
39396
|
// packages/daemon/src/imps/session-logs/plan-log-read.ts
|
|
39286
39397
|
function getLogBounds(segments, origin) {
|
|
@@ -39325,20 +39436,20 @@ function planLogRead(segments, origin, from, limit) {
|
|
|
39325
39436
|
var META_FILE = "meta.json";
|
|
39326
39437
|
var SEGMENT_SUFFIX = ".seg";
|
|
39327
39438
|
var COMMIT_DELAY_MS = 1000;
|
|
39328
|
-
var OffsetSchema2 =
|
|
39329
|
-
var GenerationMetaSchema =
|
|
39330
|
-
version:
|
|
39439
|
+
var OffsetSchema2 = z76.int().nonnegative();
|
|
39440
|
+
var GenerationMetaSchema = z76.object({
|
|
39441
|
+
version: z76.literal(1),
|
|
39331
39442
|
session: AgentSessionNameSchema,
|
|
39332
39443
|
executionGeneration: AgentGenerationSchema,
|
|
39333
39444
|
bootId: AgentBootIdSchema,
|
|
39334
|
-
startedAt:
|
|
39445
|
+
startedAt: z76.int(),
|
|
39335
39446
|
origin: OffsetSchema2,
|
|
39336
|
-
segments:
|
|
39337
|
-
state:
|
|
39338
|
-
endedAt:
|
|
39447
|
+
segments: z76.array(z76.object({ start: OffsetSchema2, length: OffsetSchema2 })),
|
|
39448
|
+
state: z76.enum(["live", "ended"]),
|
|
39449
|
+
endedAt: z76.int().optional(),
|
|
39339
39450
|
end: OffsetSchema2.optional(),
|
|
39340
|
-
exitCode:
|
|
39341
|
-
stopped:
|
|
39451
|
+
exitCode: z76.int().nullable().optional(),
|
|
39452
|
+
stopped: z76.enum(["disk_full", "imp_limit"]).optional()
|
|
39342
39453
|
});
|
|
39343
39454
|
function getSegmentPath(directory, start) {
|
|
39344
39455
|
return join19(directory, `${String(start)}${SEGMENT_SUFFIX}`);
|
|
@@ -40118,7 +40229,7 @@ function toExitCode(code, signal) {
|
|
|
40118
40229
|
}
|
|
40119
40230
|
|
|
40120
40231
|
// packages/daemon/src/imps/session-logs/session-log-service.ts
|
|
40121
|
-
var NoSessionPreviousSchema =
|
|
40232
|
+
var NoSessionPreviousSchema = z77.object({ previous: PreviousGenerationSchema.optional() });
|
|
40122
40233
|
function createSessionLogs(deps) {
|
|
40123
40234
|
const openTap = deps.openTap ?? openTapStream;
|
|
40124
40235
|
const createLog = deps.createLog ?? createGenerationLog;
|
|
@@ -42190,9 +42301,9 @@ async function waitForAgent(vsockPath, options) {
|
|
|
42190
42301
|
}
|
|
42191
42302
|
|
|
42192
42303
|
// packages/daemon/src/vm/vmm/firecracker-client.ts
|
|
42193
|
-
import * as
|
|
42194
|
-
var InstanceInfoSchema =
|
|
42195
|
-
var MachineConfigSchema =
|
|
42304
|
+
import * as z78 from "zod";
|
|
42305
|
+
var InstanceInfoSchema = z78.object({ state: z78.enum(["Not started", "Running", "Paused"]) });
|
|
42306
|
+
var MachineConfigSchema = z78.object({ track_dirty_pages: z78.boolean().optional() });
|
|
42196
42307
|
var DEFAULT_TIMEOUTS = { requestMs: 1e4, snapshotMs: 120000 };
|
|
42197
42308
|
|
|
42198
42309
|
class FirecrackerApiError extends Error {
|
|
@@ -44310,78 +44421,78 @@ function buildOfferedDigests(digest, receivedDigest) {
|
|
|
44310
44421
|
var COMMIT_WINDOW_MS = 24 * 60 * 60 * 1000;
|
|
44311
44422
|
|
|
44312
44423
|
// packages/daemon/src/imp-ops/moves/move-header.ts
|
|
44313
|
-
import * as
|
|
44314
|
-
var CpuSchema =
|
|
44315
|
-
var EgressSchema =
|
|
44316
|
-
var CheckpointSchema3 =
|
|
44317
|
-
label:
|
|
44318
|
-
createdAt:
|
|
44319
|
-
diskBytes:
|
|
44424
|
+
import * as z79 from "zod";
|
|
44425
|
+
var CpuSchema = z79.object({ limit: z79.number().positive().nullable(), weight: z79.int() }).readonly();
|
|
44426
|
+
var EgressSchema = z79.object({ mode: z79.string(), allow: z79.array(z79.string()).readonly() }).readonly();
|
|
44427
|
+
var CheckpointSchema3 = z79.object({
|
|
44428
|
+
label: z79.string().nullable(),
|
|
44429
|
+
createdAt: z79.coerce.date(),
|
|
44430
|
+
diskBytes: z79.int().positive()
|
|
44320
44431
|
}).readonly();
|
|
44321
|
-
var MovedBootSchema =
|
|
44432
|
+
var MovedBootSchema = z79.object({ bootId: z79.uuid(), cause: ColdBootCauseSchema, at: z79.iso.datetime() }).readonly();
|
|
44322
44433
|
var MAX_MOVED_LEASES = 1024;
|
|
44323
44434
|
var MAX_LEASE_REMAINING_MS = 100 * 365 * 24 * 60 * 60 * 1000;
|
|
44324
|
-
var LeaseOwnerTextSchema =
|
|
44325
|
-
var MovedLeaseOwnerSchema =
|
|
44435
|
+
var LeaseOwnerTextSchema = z79.string().min(1).max(256);
|
|
44436
|
+
var MovedLeaseOwnerSchema = z79.object({
|
|
44326
44437
|
principal: LeaseOwnerTextSchema,
|
|
44327
44438
|
label: LeaseLabelSchema,
|
|
44328
44439
|
display: LeaseOwnerTextSchema
|
|
44329
44440
|
});
|
|
44330
44441
|
var MovedLeaseSchema = MovedLeaseOwnerSchema.extend({
|
|
44331
|
-
remainingMs:
|
|
44332
|
-
createdAt:
|
|
44442
|
+
remainingMs: z79.int().nonnegative().max(MAX_LEASE_REMAINING_MS).nullable(),
|
|
44443
|
+
createdAt: z79.coerce.date()
|
|
44333
44444
|
}).readonly();
|
|
44334
|
-
var FilteredGrantSchema2 =
|
|
44335
|
-
var ImpSchema2 =
|
|
44336
|
-
id:
|
|
44337
|
-
name:
|
|
44338
|
-
vcpus:
|
|
44339
|
-
memoryMib:
|
|
44340
|
-
maxMemoryMib:
|
|
44341
|
-
httpPort:
|
|
44342
|
-
diskBytes:
|
|
44445
|
+
var FilteredGrantSchema2 = z79.object({ secret: z79.string(), filter: GrantFilterSchema }).readonly();
|
|
44446
|
+
var ImpSchema2 = z79.object({
|
|
44447
|
+
id: z79.uuid(),
|
|
44448
|
+
name: z79.string(),
|
|
44449
|
+
vcpus: z79.int().positive(),
|
|
44450
|
+
memoryMib: z79.int().positive(),
|
|
44451
|
+
maxMemoryMib: z79.int().positive().optional(),
|
|
44452
|
+
httpPort: z79.int().positive(),
|
|
44453
|
+
diskBytes: z79.int().positive(),
|
|
44343
44454
|
cpu: CpuSchema,
|
|
44344
44455
|
egress: EgressSchema,
|
|
44345
|
-
grants:
|
|
44346
|
-
filteredGrants:
|
|
44347
|
-
isIdentityResetPending:
|
|
44348
|
-
isDiskGrowPending:
|
|
44349
|
-
isBackedUp:
|
|
44350
|
-
coldBoots:
|
|
44351
|
-
leases:
|
|
44456
|
+
grants: z79.array(z79.string()).readonly(),
|
|
44457
|
+
filteredGrants: z79.array(FilteredGrantSchema2).readonly().default([]),
|
|
44458
|
+
isIdentityResetPending: z79.boolean(),
|
|
44459
|
+
isDiskGrowPending: z79.boolean().default(false),
|
|
44460
|
+
isBackedUp: z79.boolean().default(true),
|
|
44461
|
+
coldBoots: z79.array(MovedBootSchema).max(4).readonly().default([]),
|
|
44462
|
+
leases: z79.array(MovedLeaseSchema).max(MAX_MOVED_LEASES).readonly().optional()
|
|
44352
44463
|
}).readonly();
|
|
44353
|
-
var StreamStepSchema =
|
|
44354
|
-
checkpoint:
|
|
44355
|
-
dataset:
|
|
44356
|
-
base:
|
|
44464
|
+
var StreamStepSchema = z79.object({
|
|
44465
|
+
checkpoint: z79.int().nonnegative().nullable(),
|
|
44466
|
+
dataset: z79.int().nonnegative(),
|
|
44467
|
+
base: z79.int().nonnegative().nullable()
|
|
44357
44468
|
}).readonly();
|
|
44358
|
-
var HeldAnswerSchema =
|
|
44359
|
-
names:
|
|
44360
|
-
address:
|
|
44361
|
-
ttlS:
|
|
44469
|
+
var HeldAnswerSchema = z79.object({
|
|
44470
|
+
names: z79.array(z79.string()).readonly(),
|
|
44471
|
+
address: z79.string(),
|
|
44472
|
+
ttlS: z79.int().positive()
|
|
44362
44473
|
}).readonly();
|
|
44363
|
-
var WarmSchema =
|
|
44474
|
+
var WarmSchema = z79.object({
|
|
44364
44475
|
move: WarmMoveSchema,
|
|
44365
44476
|
meta: SnapshotMetaSchema.extend({ systemDrive: SystemDriveSchema }),
|
|
44366
44477
|
vm: VmIdentitySchema.nullable(),
|
|
44367
|
-
isDriveIncluded:
|
|
44368
|
-
answers:
|
|
44478
|
+
isDriveIncluded: z79.boolean(),
|
|
44479
|
+
answers: z79.array(HeldAnswerSchema).readonly()
|
|
44369
44480
|
}).readonly();
|
|
44370
|
-
var MoveHeaderSchema =
|
|
44371
|
-
version:
|
|
44481
|
+
var MoveHeaderSchema = z79.object({
|
|
44482
|
+
version: z79.literal(1),
|
|
44372
44483
|
imp: ImpSchema2,
|
|
44373
|
-
image:
|
|
44374
|
-
name:
|
|
44375
|
-
ref:
|
|
44376
|
-
digest:
|
|
44377
|
-
receivedDigest:
|
|
44378
|
-
sizeBytes:
|
|
44484
|
+
image: z79.object({
|
|
44485
|
+
name: z79.string(),
|
|
44486
|
+
ref: z79.string(),
|
|
44487
|
+
digest: z79.string(),
|
|
44488
|
+
receivedDigest: z79.string().nullable().default(null),
|
|
44489
|
+
sizeBytes: z79.int().nonnegative(),
|
|
44379
44490
|
source: ImageSourceSchema,
|
|
44380
|
-
sourceImp:
|
|
44381
|
-
isIncluded:
|
|
44491
|
+
sourceImp: z79.string().nullable(),
|
|
44492
|
+
isIncluded: z79.boolean()
|
|
44382
44493
|
}),
|
|
44383
|
-
checkpoints:
|
|
44384
|
-
streams:
|
|
44494
|
+
checkpoints: z79.array(CheckpointSchema3).readonly(),
|
|
44495
|
+
streams: z79.array(StreamStepSchema).readonly().nullable(),
|
|
44385
44496
|
warm: WarmSchema.nullable().default(null)
|
|
44386
44497
|
}).readonly();
|
|
44387
44498
|
var MOVE_PART_HEADER = "x-imp-move-part";
|
|
@@ -44543,7 +44654,7 @@ class MoveRequestError extends ImpdError {
|
|
|
44543
44654
|
}
|
|
44544
44655
|
|
|
44545
44656
|
// packages/daemon/src/imp-ops/moves/move-tickets.ts
|
|
44546
|
-
import * as
|
|
44657
|
+
import * as z80 from "zod";
|
|
44547
44658
|
var MOVE_AUTH_SCHEME = "ImpMove";
|
|
44548
44659
|
var MOVE_TICKET_PREFIX = "";
|
|
44549
44660
|
function isSameHash(leftItem, rightItem) {
|
|
@@ -44557,19 +44668,19 @@ function readTicketHeader(request) {
|
|
|
44557
44668
|
function buildTicketHeader(ticket) {
|
|
44558
44669
|
return { authorization: `${MOVE_AUTH_SCHEME} ${ticket}` };
|
|
44559
44670
|
}
|
|
44560
|
-
var ReceiptFileSchema =
|
|
44561
|
-
kind:
|
|
44562
|
-
index:
|
|
44563
|
-
sha256:
|
|
44564
|
-
bytes:
|
|
44671
|
+
var ReceiptFileSchema = z80.object({
|
|
44672
|
+
kind: z80.string(),
|
|
44673
|
+
index: z80.int().nonnegative().optional(),
|
|
44674
|
+
sha256: z80.string(),
|
|
44675
|
+
bytes: z80.int().nonnegative()
|
|
44565
44676
|
});
|
|
44566
|
-
var ReceiptBodySchema =
|
|
44567
|
-
ticketId:
|
|
44568
|
-
name:
|
|
44569
|
-
impId:
|
|
44570
|
-
files:
|
|
44677
|
+
var ReceiptBodySchema = z80.object({
|
|
44678
|
+
ticketId: z80.string(),
|
|
44679
|
+
name: z80.string(),
|
|
44680
|
+
impId: z80.string(),
|
|
44681
|
+
files: z80.array(ReceiptFileSchema)
|
|
44571
44682
|
});
|
|
44572
|
-
var ReceiptSchema =
|
|
44683
|
+
var ReceiptSchema = z80.object({ body: z80.string(), mac: z80.string() });
|
|
44573
44684
|
function buildReceipt(body, secret) {
|
|
44574
44685
|
const text = JSON.stringify(body);
|
|
44575
44686
|
return { body: text, mac: sign(secret, text).toString("hex") };
|
|
@@ -44794,7 +44905,7 @@ function createByteCounter(limit) {
|
|
|
44794
44905
|
// packages/daemon/src/imp-ops/moves/move-frames.ts
|
|
44795
44906
|
import { createHash as createHash8 } from "crypto";
|
|
44796
44907
|
import { open as open6 } from "fs/promises";
|
|
44797
|
-
import * as
|
|
44908
|
+
import * as z81 from "zod";
|
|
44798
44909
|
|
|
44799
44910
|
// packages/daemon/src/imp-ops/moves/create-content-hash.ts
|
|
44800
44911
|
import { createHash as createHash7 } from "crypto";
|
|
@@ -44832,8 +44943,8 @@ var MOVE_BLOCK_BYTES = 1024 * 1024;
|
|
|
44832
44943
|
var OFFSET_BYTES = 8;
|
|
44833
44944
|
var HEADER_BYTES3 = 5;
|
|
44834
44945
|
var MAX_PAYLOAD_BYTES = MOVE_BLOCK_BYTES + OFFSET_BYTES;
|
|
44835
|
-
var MoveFileSchema =
|
|
44836
|
-
kind:
|
|
44946
|
+
var MoveFileSchema = z81.object({
|
|
44947
|
+
kind: z81.enum([
|
|
44837
44948
|
"image-rootfs",
|
|
44838
44949
|
"image-config",
|
|
44839
44950
|
"checkpoint",
|
|
@@ -44843,13 +44954,13 @@ var MoveFileSchema = z80.object({
|
|
|
44843
44954
|
"vmstate",
|
|
44844
44955
|
"mem"
|
|
44845
44956
|
]),
|
|
44846
|
-
index:
|
|
44847
|
-
sizeBytes:
|
|
44957
|
+
index: z81.int().nonnegative().optional(),
|
|
44958
|
+
sizeBytes: z81.int().nonnegative()
|
|
44848
44959
|
});
|
|
44849
44960
|
function createFileContentHash(file) {
|
|
44850
44961
|
return file.kind === "image-rootfs" || file.kind === "image-config" ? createContentHash(file.sizeBytes) : null;
|
|
44851
44962
|
}
|
|
44852
|
-
var FileEndSchema =
|
|
44963
|
+
var FileEndSchema = z81.object({ sha256: z81.string() });
|
|
44853
44964
|
function encodeFrame2(type, payload) {
|
|
44854
44965
|
const frame = new Uint8Array(HEADER_BYTES3 + payload.length);
|
|
44855
44966
|
const view = new DataView(frame.buffer);
|
|
@@ -45685,7 +45796,7 @@ function readSettled2(row, imp) {
|
|
|
45685
45796
|
|
|
45686
45797
|
// packages/daemon/src/imp-ops/moves/move-sender.ts
|
|
45687
45798
|
import invariant4 from "tiny-invariant";
|
|
45688
|
-
import { match as
|
|
45799
|
+
import { match as match5 } from "ts-pattern";
|
|
45689
45800
|
|
|
45690
45801
|
// packages/daemon/src/platform/db/move-send-steps.ts
|
|
45691
45802
|
var MOVE_SEND_STEPS = [
|
|
@@ -46247,7 +46358,7 @@ function createMoveSender(deps) {
|
|
|
46247
46358
|
};
|
|
46248
46359
|
const recoverSend = async (imp, row) => {
|
|
46249
46360
|
const log = getImpdLogger("move").with({ imp: imp.name });
|
|
46250
|
-
await
|
|
46361
|
+
await match5(pickSendRecovery(imp.moveState, row?.step)).with("unmark", () => removeMark(imp)).with("wait", () => {
|
|
46251
46362
|
log.info("a prepared send waits for its send after a restart");
|
|
46252
46363
|
}).with("abort", async () => {
|
|
46253
46364
|
const isUndone = await resetSend(imp, row?.peer_url ?? null, row?.ticket ?? null);
|
|
@@ -46369,7 +46480,7 @@ function buildPublicError(name) {
|
|
|
46369
46480
|
}
|
|
46370
46481
|
function pickSendRecovery(moveState, step) {
|
|
46371
46482
|
if (moveState === "sending") {
|
|
46372
|
-
return
|
|
46483
|
+
return match5(step).with(undefined, () => "unmark").with("prepared", () => "wait").with("streaming", () => "abort").with("sent", () => "commit").exhaustive();
|
|
46373
46484
|
}
|
|
46374
46485
|
return moveState === "moved" && step === "sent" ? "commit" : "none";
|
|
46375
46486
|
}
|
|
@@ -46421,7 +46532,7 @@ function createMoveService(deps) {
|
|
|
46421
46532
|
// packages/daemon/src/surface/moves/create-move-peer-handler.ts
|
|
46422
46533
|
import { OpenAPIHandler } from "@orpc/openapi/fetch";
|
|
46423
46534
|
import { ORPCError as ORPCError7, implement as implement3, onError as onError3 } from "@orpc/server";
|
|
46424
|
-
import { match as
|
|
46535
|
+
import { match as match6 } from "ts-pattern";
|
|
46425
46536
|
function createMovePeerHandler(deps) {
|
|
46426
46537
|
const withTicket = async (step, context, call) => {
|
|
46427
46538
|
const startedAt = deps.now();
|
|
@@ -46472,7 +46583,7 @@ function createMovePeerHandler(deps) {
|
|
|
46472
46583
|
const respondReceive = async (context) => {
|
|
46473
46584
|
try {
|
|
46474
46585
|
const received = await withTicket("receive", context, (checked) => deps.calls.receive(checked, context.request));
|
|
46475
|
-
return
|
|
46586
|
+
return match6(received).with({ kind: "part" }, (sent) => Response.json({ part: sent.part }, { status: 202 })).with({ kind: "receipt" }, (sent) => Response.json(sent.receipt)).exhaustive();
|
|
46476
46587
|
} catch (error) {
|
|
46477
46588
|
const failure = toPeerError(error);
|
|
46478
46589
|
return Response.json(encodePeerError(failure), { status: failure.status });
|
|
@@ -46516,7 +46627,7 @@ import {
|
|
|
46516
46627
|
} from "@orpc/client";
|
|
46517
46628
|
import { ResponseValidationPlugin } from "@orpc/contract/plugins";
|
|
46518
46629
|
import { OpenAPILink } from "@orpc/openapi-client/fetch";
|
|
46519
|
-
import * as
|
|
46630
|
+
import * as z82 from "zod";
|
|
46520
46631
|
function makeConnectMovePeer(deps) {
|
|
46521
46632
|
return (target) => {
|
|
46522
46633
|
const sendLinkRequest = async (request) => {
|
|
@@ -46562,7 +46673,7 @@ function makeConnectMovePeer(deps) {
|
|
|
46562
46673
|
};
|
|
46563
46674
|
};
|
|
46564
46675
|
}
|
|
46565
|
-
var PeerErrorBodySchema =
|
|
46676
|
+
var PeerErrorBodySchema = z82.looseObject({ error: z82.string().optional() });
|
|
46566
46677
|
function decodePeerError(body, response) {
|
|
46567
46678
|
const parsed = PeerErrorBodySchema.safeParse(body);
|
|
46568
46679
|
if (!parsed.success) {
|
|
@@ -47318,11 +47429,11 @@ function createImpdServices(config, deps, parts) {
|
|
|
47318
47429
|
|
|
47319
47430
|
// packages/daemon/src/imps/images/build/create-image-builds.ts
|
|
47320
47431
|
import { existsSync as existsSync18, mkdirSync as mkdirSync20, rmSync as rmSync24, statSync as statSync12 } from "fs";
|
|
47321
|
-
import { join as
|
|
47432
|
+
import { join as join28, posix as posix3 } from "path";
|
|
47322
47433
|
|
|
47323
47434
|
// packages/local-tar/src/extract-local.ts
|
|
47324
47435
|
import tar from "tar-stream";
|
|
47325
|
-
import * as
|
|
47436
|
+
import * as z83 from "zod";
|
|
47326
47437
|
// packages/local-tar/src/pack-build-context.ts
|
|
47327
47438
|
import { existsSync as existsSync17 } from "fs";
|
|
47328
47439
|
import { lstat, readFile as readFile4, readdir } from "fs/promises";
|
|
@@ -47783,6 +47894,9 @@ function formatFamiliarRepository(reference) {
|
|
|
47783
47894
|
}
|
|
47784
47895
|
|
|
47785
47896
|
// packages/daemon/src/imps/docker-contract/check-registry.ts
|
|
47897
|
+
function checkReferenceRegistry(reference) {
|
|
47898
|
+
return checkRegistry(parseImageReference(reference).registry);
|
|
47899
|
+
}
|
|
47786
47900
|
function checkRegistry(registry) {
|
|
47787
47901
|
const host = readRegistryHost(registry).toLowerCase();
|
|
47788
47902
|
if (host === "localhost" || host.endsWith(".localhost")) {
|
|
@@ -47793,9 +47907,6 @@ function checkRegistry(registry) {
|
|
|
47793
47907
|
}
|
|
47794
47908
|
return null;
|
|
47795
47909
|
}
|
|
47796
|
-
function checkReferenceRegistry(reference) {
|
|
47797
|
-
return checkRegistry(parseImageReference(reference).registry);
|
|
47798
|
-
}
|
|
47799
47910
|
function readRegistryHost(registry) {
|
|
47800
47911
|
if (registry.startsWith("[")) {
|
|
47801
47912
|
return registry.slice(1, registry.indexOf("]"));
|
|
@@ -48452,14 +48563,14 @@ function renderPinnedDockerfile(dockerfile, pins, platform) {
|
|
|
48452
48563
|
}
|
|
48453
48564
|
|
|
48454
48565
|
// packages/daemon/src/imps/images/pull/image-pin.ts
|
|
48455
|
-
import * as
|
|
48566
|
+
import * as z84 from "zod";
|
|
48456
48567
|
var PIN_INSPECT_FORMAT = '{"Id":{{json .Id}},"RepoDigests":{{json .RepoDigests}},"Os":{{json .Os}},"Architecture":{{json .Architecture}},"Config":{{json .Config}}}';
|
|
48457
|
-
var ConfigSchema =
|
|
48458
|
-
var PinInspectSchema =
|
|
48459
|
-
Id:
|
|
48460
|
-
RepoDigests:
|
|
48461
|
-
Os:
|
|
48462
|
-
Architecture:
|
|
48568
|
+
var ConfigSchema = z84.object({ OnBuild: z84.array(z84.unknown()).readonly().nullish() }).nullable();
|
|
48569
|
+
var PinInspectSchema = z84.object({
|
|
48570
|
+
Id: z84.string(),
|
|
48571
|
+
RepoDigests: z84.array(z84.string()).readonly().nullable(),
|
|
48572
|
+
Os: z84.string(),
|
|
48573
|
+
Architecture: z84.string(),
|
|
48463
48574
|
Config: ConfigSchema
|
|
48464
48575
|
}).transform((inspect) => ({
|
|
48465
48576
|
Id: inspect.Id,
|
|
@@ -48521,7 +48632,7 @@ impd pinned ${pinned}. On the containerd image store a retag of a multi-platform
|
|
|
48521
48632
|
}
|
|
48522
48633
|
|
|
48523
48634
|
// packages/daemon/src/imps/images/build/build-engine.ts
|
|
48524
|
-
import * as
|
|
48635
|
+
import * as z85 from "zod";
|
|
48525
48636
|
|
|
48526
48637
|
// packages/daemon/src/imps/docker-contract/dockerfile-frontend.ts
|
|
48527
48638
|
var DOCKERFILE_FRONTEND = "docker/dockerfile:1.28@sha256:bb22d9815c728170f72750f4e5b0d672e06176142e1d602c7e66c050100b7e5b";
|
|
@@ -48555,7 +48666,7 @@ function createBuildEngine(run) {
|
|
|
48555
48666
|
if (version.exitCode !== 0) {
|
|
48556
48667
|
throw new Error(`docker version: ${version.stderr.trim()}`);
|
|
48557
48668
|
}
|
|
48558
|
-
const [os, arch] =
|
|
48669
|
+
const [os, arch] = z85.tuple([z85.string(), z85.string()]).parse(version.stdout.trim().split(" ").map((part) => JSON.parse(part)));
|
|
48559
48670
|
return normalizePlatform(os, arch);
|
|
48560
48671
|
},
|
|
48561
48672
|
loadImage: async (image, signal) => {
|
|
@@ -48657,56 +48768,14 @@ class DockerBuildError extends Error {
|
|
|
48657
48768
|
}
|
|
48658
48769
|
|
|
48659
48770
|
// packages/daemon/src/imps/images/build/guest-build.ts
|
|
48660
|
-
import * as
|
|
48771
|
+
import * as z86 from "zod";
|
|
48661
48772
|
|
|
48662
|
-
// packages/daemon/src/
|
|
48663
|
-
|
|
48664
|
-
|
|
48665
|
-
|
|
48666
|
-
|
|
48667
|
-
|
|
48668
|
-
const dirs = [root];
|
|
48669
|
-
for (let directory = dirs.pop();directory !== undefined; directory = dirs.pop()) {
|
|
48670
|
-
const entries = await readEntries2(readDir, directory);
|
|
48671
|
-
for (const entry of entries) {
|
|
48672
|
-
if (entry.isDirectory()) {
|
|
48673
|
-
dirs.push(join28(directory, entry.name));
|
|
48674
|
-
}
|
|
48675
|
-
}
|
|
48676
|
-
const files = entries.filter((entry) => entry.isFile());
|
|
48677
|
-
const stats = await Promise.all(files.map((entry) => readFileStats(join28(directory, entry.name))));
|
|
48678
|
-
for (const stat of stats) {
|
|
48679
|
-
if (stat !== undefined) {
|
|
48680
|
-
inodes.set(`${String(stat.dev)}:${String(stat.ino)}`, Math.max(0, stat.blocks - 1) * 512);
|
|
48681
|
-
}
|
|
48682
|
-
}
|
|
48683
|
-
}
|
|
48684
|
-
return [...inodes.values()].reduce((sum, bytes) => sum + bytes, 0);
|
|
48685
|
-
}
|
|
48686
|
-
function readDirEntries(directory) {
|
|
48687
|
-
return readdir3(directory, { withFileTypes: true });
|
|
48688
|
-
}
|
|
48689
|
-
async function readEntries2(readDir, directory) {
|
|
48690
|
-
try {
|
|
48691
|
-
return await readDir(directory);
|
|
48692
|
-
} catch (error) {
|
|
48693
|
-
if (isMissing(error)) {
|
|
48694
|
-
return [];
|
|
48695
|
-
}
|
|
48696
|
-
throw error;
|
|
48697
|
-
}
|
|
48698
|
-
}
|
|
48699
|
-
function isMissing(error) {
|
|
48700
|
-
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
48701
|
-
}
|
|
48702
|
-
async function readFileStats(path) {
|
|
48703
|
-
try {
|
|
48704
|
-
return await lstat3(path);
|
|
48705
|
-
} catch (error) {
|
|
48706
|
-
if (isMissing(error)) {
|
|
48707
|
-
return;
|
|
48708
|
-
}
|
|
48709
|
-
throw error;
|
|
48773
|
+
// packages/daemon/src/imps/images/build/image-limit-error.ts
|
|
48774
|
+
class ImageLimitError extends ImpdError {
|
|
48775
|
+
name = "ImageLimitError";
|
|
48776
|
+
constructor(limit, max) {
|
|
48777
|
+
const over = limit === "bytes" ? `over ${String(Math.floor(max / 1024 ** 2))} MiB (IMP_BUILD_IMAGE_MAX_MIB)` : `over ${String(max)} files (IMP_BUILD_IMAGE_MAX_FILES)`;
|
|
48778
|
+
super("BAD_REQUEST", { message: `the built image's filesystem is ${over}` });
|
|
48710
48779
|
}
|
|
48711
48780
|
}
|
|
48712
48781
|
|
|
@@ -48742,73 +48811,9 @@ var UNPACK_TAR_ARGS = [
|
|
|
48742
48811
|
"-xpf",
|
|
48743
48812
|
"-"
|
|
48744
48813
|
];
|
|
48745
|
-
async function writeExportedTree(containerId, root) {
|
|
48746
|
-
const exporter = Bun.spawn(["docker", "export", containerId], {
|
|
48747
|
-
stdin: "ignore",
|
|
48748
|
-
stdout: "pipe",
|
|
48749
|
-
stderr: "pipe",
|
|
48750
|
-
env: process.env
|
|
48751
|
-
});
|
|
48752
|
-
const tar = await spawnTar(root, exporter);
|
|
48753
|
-
const state = { hasExportEnded: false, isTarFirst: false, isExportStopped: false };
|
|
48754
|
-
const waitForExport = async () => {
|
|
48755
|
-
await exporter.exited;
|
|
48756
|
-
state.hasExportEnded = true;
|
|
48757
|
-
};
|
|
48758
|
-
const waitForTar = async () => {
|
|
48759
|
-
const code = await tar.exited;
|
|
48760
|
-
if (code !== 0 && !state.hasExportEnded) {
|
|
48761
|
-
state.isTarFirst = true;
|
|
48762
|
-
state.isExportStopped = true;
|
|
48763
|
-
exporter.kill();
|
|
48764
|
-
}
|
|
48765
|
-
};
|
|
48766
|
-
waitForExport();
|
|
48767
|
-
waitForTar();
|
|
48768
|
-
const [exportCode, exportStderr, tarCode, tarStderr] = await Promise.all([
|
|
48769
|
-
exporter.exited,
|
|
48770
|
-
new Response(exporter.stderr).text(),
|
|
48771
|
-
tar.exited,
|
|
48772
|
-
new Response(tar.stderr).text()
|
|
48773
|
-
]);
|
|
48774
|
-
const failure = findUnpackFailure({
|
|
48775
|
-
containerId,
|
|
48776
|
-
exported: { exitCode: exportCode, stdout: "", stderr: exportStderr },
|
|
48777
|
-
unpacked: { exitCode: tarCode, stdout: "", stderr: tarStderr },
|
|
48778
|
-
isTarFirst: state.isTarFirst,
|
|
48779
|
-
isExportStopped: state.isExportStopped && exporter.signalCode !== null
|
|
48780
|
-
});
|
|
48781
|
-
if (failure !== null) {
|
|
48782
|
-
throw failure;
|
|
48783
|
-
}
|
|
48784
|
-
assertUnpacked({ exitCode: tarCode, stdout: "", stderr: tarStderr });
|
|
48785
|
-
}
|
|
48786
|
-
async function spawnTar(root, exporter) {
|
|
48787
|
-
try {
|
|
48788
|
-
return Bun.spawn([...UNPACK_TAR_ARGS, "-C", root], {
|
|
48789
|
-
stdin: exporter.stdout,
|
|
48790
|
-
stdout: "ignore",
|
|
48791
|
-
stderr: "pipe",
|
|
48792
|
-
env: { ...process.env, LC_ALL: "C" }
|
|
48793
|
-
});
|
|
48794
|
-
} catch (error) {
|
|
48795
|
-
exporter.kill();
|
|
48796
|
-
await exporter.exited;
|
|
48797
|
-
throw error;
|
|
48798
|
-
}
|
|
48799
|
-
}
|
|
48800
|
-
function findUnpackFailure(outcome) {
|
|
48801
|
-
const exportFailure = outcome.exported.exitCode === 0 || outcome.isExportStopped ? null : buildExitError(["docker", "export", outcome.containerId], outcome.exported);
|
|
48802
|
-
const tarFailure = outcome.unpacked.exitCode === 0 ? null : buildExitError(["tar"], outcome.unpacked);
|
|
48803
|
-
if (exportFailure === null || tarFailure === null) {
|
|
48804
|
-
return exportFailure ?? tarFailure;
|
|
48805
|
-
}
|
|
48806
|
-
const [first, second] = outcome.isTarFirst ? [tarFailure, exportFailure] : [exportFailure, tarFailure];
|
|
48807
|
-
return new Error(`${first.message}; ${second.message}`);
|
|
48808
|
-
}
|
|
48809
48814
|
function assertUnpacked(result) {
|
|
48810
48815
|
if (result.exitCode !== 0) {
|
|
48811
|
-
throw buildExitError(["
|
|
48816
|
+
throw buildExitError(["tar"], result);
|
|
48812
48817
|
}
|
|
48813
48818
|
const failure = findXattrFailure(result.stderr);
|
|
48814
48819
|
if (failure?.missingSetfcap === true) {
|
|
@@ -48844,6 +48849,122 @@ function readSetfcapWarning(status = readFileSync23("/proc/self/status", "utf8")
|
|
|
48844
48849
|
return `no CAP_SETFCAP, so an image add or build fails on an image with a file capability; ${SETFCAP_HELP}`;
|
|
48845
48850
|
}
|
|
48846
48851
|
|
|
48852
|
+
// packages/daemon/src/imps/images/rootfs/write-streamed-tree.ts
|
|
48853
|
+
var EXPORT_IDLE_MS = 120000;
|
|
48854
|
+
var GROW_STEP_BYTES = 256 * 1024 ** 2;
|
|
48855
|
+
var TAR_STOPPED = new Error("tar stopped before the export ended");
|
|
48856
|
+
async function writeStreamedTree(options) {
|
|
48857
|
+
const root = options.root;
|
|
48858
|
+
const limits = options.limits;
|
|
48859
|
+
const grow = options.grow ?? (() => Promise.resolve());
|
|
48860
|
+
const startTimer = options.startTimer;
|
|
48861
|
+
const maxBytes = limits.maxBytes;
|
|
48862
|
+
const tar = options.startTar([...UNPACK_TAR_ARGS, "-vv", "--quoting-style=escape", "-C", root]);
|
|
48863
|
+
const sent = { bytes: 0 };
|
|
48864
|
+
const unpacked = {};
|
|
48865
|
+
const stopExport = new AbortController;
|
|
48866
|
+
const readMax = (limit) => limit === "bytes" ? maxBytes : limits.maxFiles;
|
|
48867
|
+
const listed = { bytes: 0 };
|
|
48868
|
+
const held = { bytes: 0 };
|
|
48869
|
+
const growHold = async () => {
|
|
48870
|
+
const tree = Math.max(sent.bytes, listed.bytes);
|
|
48871
|
+
const needed = 2 * tree + planRootfsOverhead(tree);
|
|
48872
|
+
if (needed > held.bytes) {
|
|
48873
|
+
held.bytes = (Math.floor(needed / GROW_STEP_BYTES) + 1) * GROW_STEP_BYTES;
|
|
48874
|
+
const writtenBytes = await options.countTreeBytes(root);
|
|
48875
|
+
await grow(held.bytes, writtenBytes);
|
|
48876
|
+
}
|
|
48877
|
+
};
|
|
48878
|
+
const onCounted = (bytes) => {
|
|
48879
|
+
listed.bytes = bytes;
|
|
48880
|
+
};
|
|
48881
|
+
const counting = countUnpacked(tar.stdout, limits, onCounted, (limit) => {
|
|
48882
|
+
unpacked.over = limit;
|
|
48883
|
+
const max = readMax(limit);
|
|
48884
|
+
tar.kill();
|
|
48885
|
+
stopExport.abort(new ImageLimitError(limit, max));
|
|
48886
|
+
});
|
|
48887
|
+
const waitForTar = async () => {
|
|
48888
|
+
const code = await tar.exited;
|
|
48889
|
+
if (code !== 0 && unpacked.ended !== true) {
|
|
48890
|
+
stopExport.abort(TAR_STOPPED);
|
|
48891
|
+
}
|
|
48892
|
+
};
|
|
48893
|
+
waitForTar();
|
|
48894
|
+
const assertWithinLimits = () => {
|
|
48895
|
+
const over = unpacked.over;
|
|
48896
|
+
if (over !== undefined) {
|
|
48897
|
+
throw new ImageLimitError(over, readMax(over));
|
|
48898
|
+
}
|
|
48899
|
+
};
|
|
48900
|
+
const stopIdle = () => {
|
|
48901
|
+
stopExport.abort(new Error(`${options.source} sent nothing in ${String(EXPORT_IDLE_MS / 1000)} s`));
|
|
48902
|
+
};
|
|
48903
|
+
const idle = { cancel: startTimer(stopIdle, EXPORT_IDLE_MS) };
|
|
48904
|
+
const stderrText = new Response(tar.stderr).text();
|
|
48905
|
+
try {
|
|
48906
|
+
const exported = await options.runExport(async (chunk) => {
|
|
48907
|
+
idle.cancel();
|
|
48908
|
+
idle.cancel = startTimer(stopIdle, EXPORT_IDLE_MS);
|
|
48909
|
+
sent.bytes += chunk.byteLength;
|
|
48910
|
+
if (sent.bytes > maxBytes) {
|
|
48911
|
+
throw new ImageLimitError("bytes", maxBytes);
|
|
48912
|
+
}
|
|
48913
|
+
assertWithinLimits();
|
|
48914
|
+
await growHold();
|
|
48915
|
+
await tar.stdin.write(chunk);
|
|
48916
|
+
await tar.stdin.flush();
|
|
48917
|
+
}, AbortSignal.any([options.signal, stopExport.signal]));
|
|
48918
|
+
if (exported.exitCode !== 0) {
|
|
48919
|
+
throw new Error(`${options.source}: ${exported.stderr.trim()}`);
|
|
48920
|
+
}
|
|
48921
|
+
unpacked.ended = true;
|
|
48922
|
+
await tar.stdin.end();
|
|
48923
|
+
const [exitCode, stderr] = await Promise.all([tar.exited, stderrText, counting]);
|
|
48924
|
+
assertWithinLimits();
|
|
48925
|
+
assertUnpacked({ exitCode, stdout: "", stderr });
|
|
48926
|
+
await growHold();
|
|
48927
|
+
} catch (error) {
|
|
48928
|
+
tar.kill();
|
|
48929
|
+
assertWithinLimits();
|
|
48930
|
+
if (stopExport.signal.reason === TAR_STOPPED) {
|
|
48931
|
+
const [exitCode, stderr] = await Promise.all([tar.exited, stderrText]);
|
|
48932
|
+
assertUnpacked({ exitCode, stdout: "", stderr });
|
|
48933
|
+
}
|
|
48934
|
+
throw error;
|
|
48935
|
+
} finally {
|
|
48936
|
+
idle.cancel();
|
|
48937
|
+
}
|
|
48938
|
+
}
|
|
48939
|
+
async function countUnpacked(stdout, limits, onCounted, onOver) {
|
|
48940
|
+
const decoder = new TextDecoder;
|
|
48941
|
+
const counted = { lines: 0, bytes: 0, rest: "" };
|
|
48942
|
+
for await (const chunk of stdout) {
|
|
48943
|
+
const lines = `${counted.rest}${decoder.decode(chunk, { stream: true })}`.split(`
|
|
48944
|
+
`);
|
|
48945
|
+
counted.rest = lines.pop() ?? "";
|
|
48946
|
+
for (const line of lines) {
|
|
48947
|
+
counted.lines += 1;
|
|
48948
|
+
counted.bytes += readAllocatedBytes(line);
|
|
48949
|
+
}
|
|
48950
|
+
onCounted(counted.bytes);
|
|
48951
|
+
if (counted.bytes > limits.maxBytes) {
|
|
48952
|
+
onOver("bytes");
|
|
48953
|
+
return;
|
|
48954
|
+
}
|
|
48955
|
+
if (counted.lines > limits.maxFiles) {
|
|
48956
|
+
onOver("files");
|
|
48957
|
+
return;
|
|
48958
|
+
}
|
|
48959
|
+
}
|
|
48960
|
+
}
|
|
48961
|
+
var BLOCK_BYTES = 4096;
|
|
48962
|
+
function readAllocatedBytes(line) {
|
|
48963
|
+
const size = line.trim().split(/\s+/v)[2] ?? "";
|
|
48964
|
+
const bytes = /^\d+$/v.test(size) ? Number(size) : 0;
|
|
48965
|
+
return Math.max(1, Math.ceil(bytes / BLOCK_BYTES)) * BLOCK_BYTES;
|
|
48966
|
+
}
|
|
48967
|
+
|
|
48847
48968
|
// packages/daemon/src/imps/images/build/create-build-steps.ts
|
|
48848
48969
|
var STEP_PATTERN = /^\[(?:\S+ )?\d+\/\d+\] /v;
|
|
48849
48970
|
function createBuildSteps(setStep) {
|
|
@@ -48916,20 +49037,11 @@ function createPlainLines(output) {
|
|
|
48916
49037
|
};
|
|
48917
49038
|
}
|
|
48918
49039
|
|
|
48919
|
-
// packages/daemon/src/imps/images/build/image-limit-error.ts
|
|
48920
|
-
class ImageLimitError extends ImpdError {
|
|
48921
|
-
name = "ImageLimitError";
|
|
48922
|
-
constructor(limit, max) {
|
|
48923
|
-
const over = limit === "bytes" ? `over ${String(Math.floor(max / 1024 ** 2))} MiB (IMP_BUILD_IMAGE_MAX_MIB)` : `over ${String(max)} files (IMP_BUILD_IMAGE_MAX_FILES)`;
|
|
48924
|
-
super("BAD_REQUEST", { message: `the built image's filesystem is ${over}` });
|
|
48925
|
-
}
|
|
48926
|
-
}
|
|
48927
|
-
|
|
48928
49040
|
// packages/daemon/src/imps/images/build/guest-build.ts
|
|
48929
49041
|
var GUEST_BUILD_TAG = "imp-build:latest";
|
|
48930
49042
|
var LOG_MAX_CHARS = 8000;
|
|
48931
|
-
var ContainerIdSchema =
|
|
48932
|
-
var OciConfigSchema =
|
|
49043
|
+
var ContainerIdSchema = z86.string().regex(/^[a-f0-9]{64}$/v);
|
|
49044
|
+
var OciConfigSchema = z86.record(z86.string(), z86.unknown()).nullable();
|
|
48933
49045
|
async function runGuestBuild(exec, options) {
|
|
48934
49046
|
const lines = options.output === undefined ? null : createPlainLines(options.output);
|
|
48935
49047
|
const result = await exec([
|
|
@@ -48980,55 +49092,9 @@ async function loadGuestImage(exec, options) {
|
|
|
48980
49092
|
var DIGEST_PREFIX = "imp-build-";
|
|
48981
49093
|
var DIGEST_DOMAIN = `imp build image v1
|
|
48982
49094
|
`;
|
|
48983
|
-
var EXPORT_IDLE_MS = 120000;
|
|
48984
|
-
var GROW_STEP_BYTES = 256 * 1024 ** 2;
|
|
48985
|
-
var TAR_STOPPED = new Error("tar stopped before the export ended");
|
|
48986
|
-
function createImageHash(configText) {
|
|
48987
|
-
const config = new TextEncoder().encode(configText);
|
|
48988
|
-
const length = new Uint8Array(8);
|
|
48989
|
-
new DataView(length.buffer).setBigUint64(0, BigInt(config.byteLength));
|
|
48990
|
-
const hash = new Bun.CryptoHasher("sha256");
|
|
48991
|
-
hash.update(DIGEST_DOMAIN);
|
|
48992
|
-
hash.update(length);
|
|
48993
|
-
hash.update(config);
|
|
48994
|
-
return hash;
|
|
48995
|
-
}
|
|
48996
|
-
var BLOCK_BYTES = 4096;
|
|
48997
|
-
function readAllocatedBytes(line) {
|
|
48998
|
-
const size = line.trim().split(/\s+/v)[2] ?? "";
|
|
48999
|
-
const bytes = /^\d+$/v.test(size) ? Number(size) : 0;
|
|
49000
|
-
return Math.max(1, Math.ceil(bytes / BLOCK_BYTES)) * BLOCK_BYTES;
|
|
49001
|
-
}
|
|
49002
|
-
async function countUnpacked(stdout, limits, onCounted, onOver) {
|
|
49003
|
-
const decoder = new TextDecoder;
|
|
49004
|
-
const counted = { lines: 0, bytes: 0, rest: "" };
|
|
49005
|
-
for await (const chunk of stdout) {
|
|
49006
|
-
const lines = `${counted.rest}${decoder.decode(chunk, { stream: true })}`.split(`
|
|
49007
|
-
`);
|
|
49008
|
-
counted.rest = lines.pop() ?? "";
|
|
49009
|
-
for (const line of lines) {
|
|
49010
|
-
counted.lines += 1;
|
|
49011
|
-
counted.bytes += readAllocatedBytes(line);
|
|
49012
|
-
}
|
|
49013
|
-
onCounted(counted.bytes);
|
|
49014
|
-
if (counted.bytes > limits.maxBytes) {
|
|
49015
|
-
onOver("bytes");
|
|
49016
|
-
return;
|
|
49017
|
-
}
|
|
49018
|
-
if (counted.lines > limits.maxFiles) {
|
|
49019
|
-
onOver("files");
|
|
49020
|
-
return;
|
|
49021
|
-
}
|
|
49022
|
-
}
|
|
49023
|
-
}
|
|
49024
49095
|
async function writeGuestTree(options) {
|
|
49025
49096
|
const exec = options.exec;
|
|
49026
|
-
const root = options.root;
|
|
49027
|
-
const limits = options.limits;
|
|
49028
49097
|
const signal = options.signal;
|
|
49029
|
-
const grow = options.grow ?? (() => Promise.resolve());
|
|
49030
|
-
const startTimer = options.startTimer ?? startRealTimer;
|
|
49031
|
-
const maxBytes = limits.maxBytes;
|
|
49032
49098
|
const inspected = await exec(["docker", "image", "inspect", "--format", "{{json .Config}}", GUEST_BUILD_TAG], { signal });
|
|
49033
49099
|
if (inspected.exitCode !== 0) {
|
|
49034
49100
|
throw new Error(`docker image inspect in the builder: ${inspected.stderr.trim()}`);
|
|
@@ -49040,94 +49106,36 @@ async function writeGuestTree(options) {
|
|
|
49040
49106
|
throw new Error(`docker create in the builder: ${created.stderr.trim()}`);
|
|
49041
49107
|
}
|
|
49042
49108
|
const containerId = ContainerIdSchema.parse(created.stdout.trim());
|
|
49043
|
-
const tar = Bun.spawn([...UNPACK_TAR_ARGS, "-vv", "--quoting-style=escape", "-C", root], {
|
|
49044
|
-
stdin: "pipe",
|
|
49045
|
-
stdout: "pipe",
|
|
49046
|
-
stderr: "pipe",
|
|
49047
|
-
env: { ...process.env, LC_ALL: "C" }
|
|
49048
|
-
});
|
|
49049
49109
|
const hash = createImageHash(configText);
|
|
49050
|
-
|
|
49051
|
-
|
|
49052
|
-
|
|
49053
|
-
|
|
49054
|
-
|
|
49055
|
-
|
|
49056
|
-
|
|
49057
|
-
|
|
49058
|
-
|
|
49059
|
-
|
|
49060
|
-
|
|
49061
|
-
const writtenBytes = await countTreeBytes(root);
|
|
49062
|
-
await grow(held.bytes, writtenBytes);
|
|
49063
|
-
}
|
|
49064
|
-
};
|
|
49065
|
-
const onCounted = (bytes) => {
|
|
49066
|
-
listed.bytes = bytes;
|
|
49067
|
-
};
|
|
49068
|
-
const counting = countUnpacked(tar.stdout, limits, onCounted, (limit) => {
|
|
49069
|
-
unpacked.over = limit;
|
|
49070
|
-
const max = readMax(limit);
|
|
49071
|
-
tar.kill();
|
|
49072
|
-
stopExport.abort(new ImageLimitError(limit, max));
|
|
49073
|
-
});
|
|
49074
|
-
const waitForTar = async () => {
|
|
49075
|
-
const code = await tar.exited;
|
|
49076
|
-
if (code !== 0 && unpacked.ended !== true) {
|
|
49077
|
-
stopExport.abort(TAR_STOPPED);
|
|
49078
|
-
}
|
|
49079
|
-
};
|
|
49080
|
-
waitForTar();
|
|
49081
|
-
const assertWithinLimits = () => {
|
|
49082
|
-
const over = unpacked.over;
|
|
49083
|
-
if (over !== undefined) {
|
|
49084
|
-
throw new ImageLimitError(over, readMax(over));
|
|
49085
|
-
}
|
|
49086
|
-
};
|
|
49087
|
-
const stopIdle = () => {
|
|
49088
|
-
stopExport.abort(new Error(`docker export in the builder sent nothing in ${String(EXPORT_IDLE_MS / 1000)} s`));
|
|
49089
|
-
};
|
|
49090
|
-
const idle = { cancel: startTimer(stopIdle, EXPORT_IDLE_MS) };
|
|
49091
|
-
const stderrText = new Response(tar.stderr).text();
|
|
49092
|
-
try {
|
|
49093
|
-
const exported = await exec(["docker", "export", containerId], {
|
|
49094
|
-
signal: AbortSignal.any([signal, stopExport.signal]),
|
|
49110
|
+
await writeStreamedTree({
|
|
49111
|
+
root: options.root,
|
|
49112
|
+
limits: options.limits,
|
|
49113
|
+
signal,
|
|
49114
|
+
source: "docker export in the builder",
|
|
49115
|
+
grow: options.grow,
|
|
49116
|
+
startTimer: options.startTimer,
|
|
49117
|
+
startTar: options.startTar,
|
|
49118
|
+
countTreeBytes: options.countTreeBytes,
|
|
49119
|
+
runExport: (onStdout, exportSignal) => exec(["docker", "export", containerId], {
|
|
49120
|
+
signal: exportSignal,
|
|
49095
49121
|
onStdout: async (chunk) => {
|
|
49096
|
-
|
|
49097
|
-
idle.cancel = startTimer(stopIdle, EXPORT_IDLE_MS);
|
|
49098
|
-
sent.bytes += chunk.byteLength;
|
|
49099
|
-
if (sent.bytes > maxBytes) {
|
|
49100
|
-
throw new ImageLimitError("bytes", maxBytes);
|
|
49101
|
-
}
|
|
49102
|
-
assertWithinLimits();
|
|
49103
|
-
await growHold();
|
|
49122
|
+
await onStdout(chunk);
|
|
49104
49123
|
hash.update(chunk);
|
|
49105
|
-
await tar.stdin.write(chunk);
|
|
49106
|
-
await tar.stdin.flush();
|
|
49107
49124
|
}
|
|
49108
|
-
})
|
|
49109
|
-
|
|
49110
|
-
throw new Error(`docker export in the builder: ${exported.stderr.trim()}`);
|
|
49111
|
-
}
|
|
49112
|
-
unpacked.ended = true;
|
|
49113
|
-
await tar.stdin.end();
|
|
49114
|
-
const [exitCode, stderr] = await Promise.all([tar.exited, stderrText, counting]);
|
|
49115
|
-
assertWithinLimits();
|
|
49116
|
-
assertUnpacked({ exitCode, stdout: "", stderr });
|
|
49117
|
-
await growHold();
|
|
49118
|
-
} catch (error) {
|
|
49119
|
-
tar.kill();
|
|
49120
|
-
assertWithinLimits();
|
|
49121
|
-
if (stopExport.signal.reason === TAR_STOPPED) {
|
|
49122
|
-
const [exitCode, stderr] = await Promise.all([tar.exited, stderrText]);
|
|
49123
|
-
assertUnpacked({ exitCode, stdout: "", stderr });
|
|
49124
|
-
}
|
|
49125
|
-
throw error;
|
|
49126
|
-
} finally {
|
|
49127
|
-
idle.cancel();
|
|
49128
|
-
}
|
|
49125
|
+
})
|
|
49126
|
+
});
|
|
49129
49127
|
return { digest: `${DIGEST_PREFIX}${hash.digest("hex")}`, config };
|
|
49130
49128
|
}
|
|
49129
|
+
function createImageHash(configText) {
|
|
49130
|
+
const config = new TextEncoder().encode(configText);
|
|
49131
|
+
const length = new Uint8Array(8);
|
|
49132
|
+
new DataView(length.buffer).setBigUint64(0, BigInt(config.byteLength));
|
|
49133
|
+
const hash = new Bun.CryptoHasher("sha256");
|
|
49134
|
+
hash.update(DIGEST_DOMAIN);
|
|
49135
|
+
hash.update(length);
|
|
49136
|
+
hash.update(config);
|
|
49137
|
+
return hash;
|
|
49138
|
+
}
|
|
49131
49139
|
|
|
49132
49140
|
// packages/daemon/src/imps/images/build/write-context-tar.ts
|
|
49133
49141
|
import { open as open9 } from "fs/promises";
|
|
@@ -49295,7 +49303,7 @@ function createImageBuilds(deps, writer) {
|
|
|
49295
49303
|
});
|
|
49296
49304
|
}
|
|
49297
49305
|
const uploadsDir = buildUploadsDir(deps.config.dataDir);
|
|
49298
|
-
const tarPath =
|
|
49306
|
+
const tarPath = join28(uploadsDir, `${Bun.randomUUIDv7()}.tar`);
|
|
49299
49307
|
mkdirSync20(uploadsDir, { recursive: true, mode: 448 });
|
|
49300
49308
|
return deps.diskBudget.withRoom(tarBytes, async () => {
|
|
49301
49309
|
try {
|
|
@@ -49388,7 +49396,7 @@ function normalizeDockerfilePath(path) {
|
|
|
49388
49396
|
}
|
|
49389
49397
|
|
|
49390
49398
|
// packages/daemon/src/imps/images/image-naming.ts
|
|
49391
|
-
import * as
|
|
49399
|
+
import * as z87 from "zod";
|
|
49392
49400
|
var MAX_NAME_LENGTH2 = 31;
|
|
49393
49401
|
function deriveImageName(ref) {
|
|
49394
49402
|
const lastSegment = parseImageReference(ref).path.split("/").at(-1) ?? "";
|
|
@@ -49398,10 +49406,10 @@ function deriveImageName(ref) {
|
|
|
49398
49406
|
}
|
|
49399
49407
|
return name;
|
|
49400
49408
|
}
|
|
49401
|
-
var OciConfigSchema2 =
|
|
49402
|
-
Env:
|
|
49403
|
-
WorkingDir:
|
|
49404
|
-
User:
|
|
49409
|
+
var OciConfigSchema2 = z87.object({
|
|
49410
|
+
Env: z87.array(z87.string()).nullish(),
|
|
49411
|
+
WorkingDir: z87.string().nullish(),
|
|
49412
|
+
User: z87.string().nullish()
|
|
49405
49413
|
}).nullish();
|
|
49406
49414
|
function buildImageRuntimeConfig(ociConfig) {
|
|
49407
49415
|
const parsed = OciConfigSchema2.parse(ociConfig);
|
|
@@ -49414,96 +49422,33 @@ function buildImageRuntimeConfig(ociConfig) {
|
|
|
49414
49422
|
|
|
49415
49423
|
// packages/daemon/src/imps/images/rootfs/create-image-writer.ts
|
|
49416
49424
|
import { existsSync as existsSync19, mkdirSync as mkdirSync22, rmSync as rmSync26, statSync as statSync13, writeFileSync as writeFileSync8 } from "fs";
|
|
49417
|
-
import { join as
|
|
49418
|
-
import * as z88 from "zod";
|
|
49419
|
-
|
|
49420
|
-
// packages/daemon/src/imps/docker-contract/refusal.ts
|
|
49421
|
-
import { z as z87 } from "zod";
|
|
49422
|
-
var PROXY_PREFIX = "imp-docker-proxy: ";
|
|
49423
|
-
var ENGINE_FAILURE_PREFIX = `${PROXY_PREFIX}the engine call failed: `;
|
|
49424
|
-
var REFUSAL_MAX_CHARS = 1000;
|
|
49425
|
-
var DAEMON_ERROR_PREFIX = "Error response from daemon: ";
|
|
49426
|
-
var UNABLE_TO_FIND_LINE = /^Unable to find image '[^'\n]+' locally$/u;
|
|
49427
|
-
var RefusalBodySchema = z87.strictObject({ message: z87.string() });
|
|
49428
|
-
function readProxyRefusal(text) {
|
|
49429
|
-
const body = readJsonMessage(text.trim());
|
|
49430
|
-
if (body !== null) {
|
|
49431
|
-
return toRefusal(body);
|
|
49432
|
-
}
|
|
49433
|
-
const errorLine = readErrorLine(text.trimEnd().split(`
|
|
49434
|
-
`));
|
|
49435
|
-
if (!errorLine.startsWith(DAEMON_ERROR_PREFIX)) {
|
|
49436
|
-
return null;
|
|
49437
|
-
}
|
|
49438
|
-
const answer = errorLine.slice(DAEMON_ERROR_PREFIX.length);
|
|
49439
|
-
return toRefusal(readJsonMessage(answer) ?? answer);
|
|
49440
|
-
}
|
|
49441
|
-
function readErrorLine(lines) {
|
|
49442
|
-
const [first = "", second = ""] = lines;
|
|
49443
|
-
if (lines.length === 1) {
|
|
49444
|
-
return first;
|
|
49445
|
-
}
|
|
49446
|
-
return lines.length === 2 && UNABLE_TO_FIND_LINE.test(first) ? second : "";
|
|
49447
|
-
}
|
|
49448
|
-
function toRefusal(message) {
|
|
49449
|
-
if (!message.startsWith(PROXY_PREFIX) || message.startsWith(ENGINE_FAILURE_PREFIX)) {
|
|
49450
|
-
return null;
|
|
49451
|
-
}
|
|
49452
|
-
const firstLine = message.split(`
|
|
49453
|
-
`, 1)[0] ?? "";
|
|
49454
|
-
return firstLine.trim().slice(0, REFUSAL_MAX_CHARS);
|
|
49455
|
-
}
|
|
49456
|
-
function readJsonMessage(text) {
|
|
49457
|
-
if (!text.startsWith("{")) {
|
|
49458
|
-
return null;
|
|
49459
|
-
}
|
|
49460
|
-
try {
|
|
49461
|
-
const body = RefusalBodySchema.safeParse(JSON.parse(text));
|
|
49462
|
-
return body.success ? body.data.message : null;
|
|
49463
|
-
} catch {
|
|
49464
|
-
return null;
|
|
49465
|
-
}
|
|
49466
|
-
}
|
|
49425
|
+
import { join as join30 } from "path";
|
|
49467
49426
|
|
|
49468
|
-
// packages/daemon/src/imps/images/rootfs/
|
|
49469
|
-
|
|
49470
|
-
|
|
49471
|
-
|
|
49472
|
-
|
|
49473
|
-
|
|
49427
|
+
// packages/daemon/src/imps/images/rootfs/read-oci-config.ts
|
|
49428
|
+
import * as z88 from "zod";
|
|
49429
|
+
var OciConfigSchema3 = z88.object({
|
|
49430
|
+
digest: z88.string().regex(/^sha256:[a-f0-9]{64}$/v),
|
|
49431
|
+
config: z88.record(z88.string(), z88.unknown()).nullable()
|
|
49432
|
+
});
|
|
49433
|
+
async function readOciConfig(ref, signal, run) {
|
|
49434
|
+
const argv = ["oci-fetch", "config", ref];
|
|
49435
|
+
const result = await run(argv, { signal });
|
|
49436
|
+
signal.throwIfAborted();
|
|
49474
49437
|
if (result.exitCode !== 0) {
|
|
49475
|
-
|
|
49476
|
-
if (refused !== null) {
|
|
49477
|
-
throw refused;
|
|
49478
|
-
}
|
|
49479
|
-
}
|
|
49480
|
-
return result;
|
|
49481
|
-
}
|
|
49482
|
-
function readRefusalError(call, output) {
|
|
49483
|
-
const refusal = readProxyRefusal(output);
|
|
49484
|
-
if (refusal === null) {
|
|
49485
|
-
return null;
|
|
49438
|
+
throw buildExitError(argv, result);
|
|
49486
49439
|
}
|
|
49487
|
-
|
|
49488
|
-
return new ImpdError("BAD_REQUEST", { message: refusal });
|
|
49489
|
-
}
|
|
49490
|
-
async function runDockerChecked(argv, options = {}) {
|
|
49491
|
-
const result = await runDocker(argv, options);
|
|
49492
|
-
if (result.exitCode !== 0) {
|
|
49493
|
-
throw buildExitError(["docker", ...argv], result);
|
|
49494
|
-
}
|
|
49495
|
-
return result.stdout;
|
|
49440
|
+
return OciConfigSchema3.parse(JSON.parse(result.stdout));
|
|
49496
49441
|
}
|
|
49497
49442
|
|
|
49498
49443
|
// packages/daemon/src/imps/images/rootfs/write-image-config.ts
|
|
49499
49444
|
import { closeSync as closeSync9, constants as constants5, lstatSync as lstatSync5, mkdirSync as mkdirSync21, openSync as openSync7, rmSync as rmSync25, writeSync as writeSync3 } from "fs";
|
|
49500
|
-
import { join as
|
|
49445
|
+
import { join as join29 } from "path";
|
|
49501
49446
|
function writeImageConfig(root, contents) {
|
|
49502
|
-
const etc =
|
|
49503
|
-
const directory =
|
|
49447
|
+
const etc = join29(root, "etc");
|
|
49448
|
+
const directory = join29(etc, "imp");
|
|
49504
49449
|
createDirectory(etc, "/etc");
|
|
49505
49450
|
createDirectory(directory, "/etc/imp");
|
|
49506
|
-
const file =
|
|
49451
|
+
const file = join29(directory, "image.json");
|
|
49507
49452
|
rmSync25(file, { recursive: true, force: true });
|
|
49508
49453
|
const fd = openSync7(file, constants5.O_WRONLY | constants5.O_CREAT | constants5.O_EXCL | constants5.O_NOFOLLOW, 420);
|
|
49509
49454
|
try {
|
|
@@ -49525,14 +49470,22 @@ function createDirectory(path, name) {
|
|
|
49525
49470
|
}
|
|
49526
49471
|
}
|
|
49527
49472
|
|
|
49473
|
+
// packages/daemon/src/imps/images/rootfs/write-oci-tree.ts
|
|
49474
|
+
function writeOciTree(options) {
|
|
49475
|
+
return writeStreamedTree({
|
|
49476
|
+
root: options.root,
|
|
49477
|
+
limits: options.limits,
|
|
49478
|
+
signal: options.signal,
|
|
49479
|
+
source: `oci-fetch export ${options.ref}`,
|
|
49480
|
+
grow: options.grow,
|
|
49481
|
+
startTimer: options.startTimer,
|
|
49482
|
+
startTar: options.startTar,
|
|
49483
|
+
countTreeBytes: options.countTreeBytes,
|
|
49484
|
+
runExport: (onStdout, signal) => options.runStreamed(["oci-fetch", "export", options.ref], onStdout, signal)
|
|
49485
|
+
});
|
|
49486
|
+
}
|
|
49487
|
+
|
|
49528
49488
|
// packages/daemon/src/imps/images/rootfs/create-image-writer.ts
|
|
49529
|
-
var InspectSchema = z88.tuple([
|
|
49530
|
-
z88.object({
|
|
49531
|
-
Id: z88.string(),
|
|
49532
|
-
Config: z88.unknown(),
|
|
49533
|
-
Size: z88.number().optional()
|
|
49534
|
-
})
|
|
49535
|
-
]);
|
|
49536
49489
|
function createImageWriter(deps) {
|
|
49537
49490
|
const storageGate = deps.storageGate;
|
|
49538
49491
|
const logger = getImpdLogger("image");
|
|
@@ -49540,22 +49493,10 @@ function createImageWriter(deps) {
|
|
|
49540
49493
|
const publishers = new Map;
|
|
49541
49494
|
const freshRootfs = new Set;
|
|
49542
49495
|
const guestRootfsLock = buildKeyedMutex();
|
|
49543
|
-
const docker = { env: deps.dockerEnv };
|
|
49544
|
-
const readInspect = async (ref, signal) => {
|
|
49545
|
-
const options = { ...docker, signal };
|
|
49546
|
-
const first = await runDocker(["image", "inspect", ref], options);
|
|
49547
|
-
if (first.exitCode === 0) {
|
|
49548
|
-
return InspectSchema.parse(JSON.parse(first.stdout))[0];
|
|
49549
|
-
}
|
|
49550
|
-
await runDockerChecked(["pull", "--quiet", ref], options);
|
|
49551
|
-
signal.throwIfAborted();
|
|
49552
|
-
const stdout = await runDockerChecked(["image", "inspect", ref], options);
|
|
49553
|
-
return InspectSchema.parse(JSON.parse(stdout))[0];
|
|
49554
|
-
};
|
|
49555
49496
|
const makeWorkDir = () => {
|
|
49556
49497
|
const images = buildImagesDir(deps.config.dataDir);
|
|
49557
|
-
const work =
|
|
49558
|
-
const root =
|
|
49498
|
+
const work = join30(images, `.build-${Bun.randomUUIDv7()}`);
|
|
49499
|
+
const root = join30(work, "root");
|
|
49559
49500
|
mkdirSync22(images, { recursive: true });
|
|
49560
49501
|
mkdirSync22(work, { mode: 448 });
|
|
49561
49502
|
mkdirSync22(root, { mode: 493 });
|
|
@@ -49566,7 +49507,7 @@ function createImageWriter(deps) {
|
|
|
49566
49507
|
const usage = await readTreeUsage(root);
|
|
49567
49508
|
const plan = planRootfs(usage);
|
|
49568
49509
|
await deps.storage.createImage(digest, async (directory) => {
|
|
49569
|
-
const image =
|
|
49510
|
+
const image = join30(directory, "rootfs.ext4");
|
|
49570
49511
|
await runChecked(["truncate", "-s", String(plan.bytes), image]);
|
|
49571
49512
|
await runChecked([
|
|
49572
49513
|
"mkfs.ext4",
|
|
@@ -49579,29 +49520,10 @@ function createImageWriter(deps) {
|
|
|
49579
49520
|
root,
|
|
49580
49521
|
image
|
|
49581
49522
|
]);
|
|
49582
|
-
writeFileSync8(
|
|
49523
|
+
writeFileSync8(join30(directory, "config.json"), JSON.stringify(ociConfig ?? {}, null, 2));
|
|
49583
49524
|
});
|
|
49584
49525
|
return readDiskUsage(buildImagePaths(deps.config.dataDir, digest).rootfs);
|
|
49585
49526
|
};
|
|
49586
|
-
const createRootfs = async (ref, digest, ociConfig) => {
|
|
49587
|
-
const paths = buildImagePaths(deps.config.dataDir, digest);
|
|
49588
|
-
if (existsSync19(paths.rootfs)) {
|
|
49589
|
-
return readDiskUsage(paths.rootfs);
|
|
49590
|
-
}
|
|
49591
|
-
const created = await runDockerChecked(["create", ref, "/bin/true"], docker);
|
|
49592
|
-
const containerId = created.trim();
|
|
49593
|
-
try {
|
|
49594
|
-
const workDir = makeWorkDir();
|
|
49595
|
-
try {
|
|
49596
|
-
await writeExportedTree(containerId, workDir.root);
|
|
49597
|
-
return await writeRootfs(workDir.root, digest, ociConfig);
|
|
49598
|
-
} finally {
|
|
49599
|
-
rmSync26(workDir.work, { recursive: true, force: true });
|
|
49600
|
-
}
|
|
49601
|
-
} finally {
|
|
49602
|
-
await runCommand(["docker", "rm", "-f", containerId]);
|
|
49603
|
-
}
|
|
49604
|
-
};
|
|
49605
49527
|
const createRootfsOnce = (digest, create) => building.run(digest, create);
|
|
49606
49528
|
const writeDockerImageRow = async (imageName, ref, digest, sizeBytes) => {
|
|
49607
49529
|
const at = deps.clock.now();
|
|
@@ -49655,22 +49577,6 @@ function createImageWriter(deps) {
|
|
|
49655
49577
|
});
|
|
49656
49578
|
}
|
|
49657
49579
|
});
|
|
49658
|
-
const createImageOnHost = async (ref, imageName, options) => {
|
|
49659
|
-
const inspect = await readInspect(ref, options.signal);
|
|
49660
|
-
options.onPulled();
|
|
49661
|
-
const treeBytes = inspect.Size ?? 0;
|
|
49662
|
-
const buildBytes = 2 * treeBytes + planRootfsOverhead(treeBytes);
|
|
49663
|
-
const withRoom = deps.diskBudget.withRoom;
|
|
49664
|
-
return withRoom(buildBytes, () => storageGate.join(async () => {
|
|
49665
|
-
await holdPublisher(inspect.Id);
|
|
49666
|
-
try {
|
|
49667
|
-
const sizeBytes = await createRootfsOnce(inspect.Id, () => createRootfs(ref, inspect.Id, inspect.Config));
|
|
49668
|
-
return await writeDockerImageRow(imageName, ref, inspect.Id, sizeBytes);
|
|
49669
|
-
} finally {
|
|
49670
|
-
await releasePublisher(inspect.Id, imageName);
|
|
49671
|
-
}
|
|
49672
|
-
}));
|
|
49673
|
-
};
|
|
49674
49580
|
const writeGuestRootfsAndRow = async (guest) => {
|
|
49675
49581
|
const digest = guest.digest;
|
|
49676
49582
|
const rootfs = buildImagePaths(deps.config.dataDir, digest).rootfs;
|
|
@@ -49701,7 +49607,10 @@ function createImageWriter(deps) {
|
|
|
49701
49607
|
root,
|
|
49702
49608
|
limits: { maxBytes, maxFiles: deps.config.build.imageMaxFiles },
|
|
49703
49609
|
signal,
|
|
49704
|
-
grow
|
|
49610
|
+
grow,
|
|
49611
|
+
startTar: deps.startTar,
|
|
49612
|
+
countTreeBytes: deps.countTreeBytes,
|
|
49613
|
+
startTimer: deps.startTimer
|
|
49705
49614
|
});
|
|
49706
49615
|
return await writeGuestRootfsAndRow({
|
|
49707
49616
|
root,
|
|
@@ -49716,6 +49625,41 @@ function createImageWriter(deps) {
|
|
|
49716
49625
|
}
|
|
49717
49626
|
}));
|
|
49718
49627
|
};
|
|
49628
|
+
const createBuilderImage = async (imageName, options) => {
|
|
49629
|
+
const ref = deps.config.build.image;
|
|
49630
|
+
const signal = options.signal;
|
|
49631
|
+
const build = deps.config.build;
|
|
49632
|
+
const limits = { maxBytes: build.imageMaxBytes, maxFiles: build.imageMaxFiles };
|
|
49633
|
+
const image = await readOciConfig(ref, signal, deps.runCommand);
|
|
49634
|
+
return deps.diskBudget.withGrowingRoom((grow) => storageGate.join(async () => {
|
|
49635
|
+
const workDir = makeWorkDir();
|
|
49636
|
+
const root = workDir.root;
|
|
49637
|
+
try {
|
|
49638
|
+
await writeOciTree({
|
|
49639
|
+
ref,
|
|
49640
|
+
root,
|
|
49641
|
+
limits,
|
|
49642
|
+
signal,
|
|
49643
|
+
grow,
|
|
49644
|
+
runStreamed: deps.runStreamed,
|
|
49645
|
+
startTar: deps.startTar,
|
|
49646
|
+
countTreeBytes: deps.countTreeBytes,
|
|
49647
|
+
startTimer: deps.startTimer
|
|
49648
|
+
});
|
|
49649
|
+
options.onFetched();
|
|
49650
|
+
return await writeGuestRootfsAndRow({
|
|
49651
|
+
root,
|
|
49652
|
+
digest: image.digest,
|
|
49653
|
+
config: image.config,
|
|
49654
|
+
imageName,
|
|
49655
|
+
ref,
|
|
49656
|
+
signal: new AbortController().signal
|
|
49657
|
+
});
|
|
49658
|
+
} finally {
|
|
49659
|
+
rmSync26(workDir.work, { recursive: true, force: true });
|
|
49660
|
+
}
|
|
49661
|
+
}));
|
|
49662
|
+
};
|
|
49719
49663
|
const withPublisher = async (digest, imageName, publish) => {
|
|
49720
49664
|
await holdPublisher(digest);
|
|
49721
49665
|
try {
|
|
@@ -49724,7 +49668,7 @@ function createImageWriter(deps) {
|
|
|
49724
49668
|
await releasePublisher(digest, imageName);
|
|
49725
49669
|
}
|
|
49726
49670
|
};
|
|
49727
|
-
return {
|
|
49671
|
+
return { createBuilderImage, writeGuestImage, removeIdleRootfs, removeIdleImage, withPublisher };
|
|
49728
49672
|
}
|
|
49729
49673
|
function requireDockerImage(existing) {
|
|
49730
49674
|
if (existing?.source === "imp") {
|
|
@@ -49798,18 +49742,18 @@ function createImageAdds(deps, writer) {
|
|
|
49798
49742
|
const createBuilderImage = async (ref) => {
|
|
49799
49743
|
const pullMs = deps.builderImagePullMs ?? BUILDER_IMAGE_PULL_MS;
|
|
49800
49744
|
const timeout = deps.startPullLimit?.(pullMs) ?? AbortSignal.timeout(pullMs);
|
|
49801
|
-
const step = {
|
|
49745
|
+
const step = { fetched: false };
|
|
49802
49746
|
try {
|
|
49803
|
-
return await writer.
|
|
49747
|
+
return await writer.createBuilderImage(BUILDER_IMAGE, {
|
|
49804
49748
|
signal: timeout,
|
|
49805
|
-
|
|
49806
|
-
step.
|
|
49749
|
+
onFetched: () => {
|
|
49750
|
+
step.fetched = true;
|
|
49807
49751
|
}
|
|
49808
49752
|
});
|
|
49809
49753
|
} catch (error) {
|
|
49810
|
-
const reason = timeout.aborted && !step.
|
|
49754
|
+
const reason = timeout.aborted && !step.fetched ? `the fetch did not finish in ${formatPullLimit(pullMs)}` : getErrorMessage(error);
|
|
49811
49755
|
throw new ImpdError("SERVICE_UNAVAILABLE", {
|
|
49812
|
-
message: `impd cannot add its builder image ${ref} (IMP_BUILD_IMAGE) from
|
|
49756
|
+
message: `impd cannot add its builder image ${ref} (IMP_BUILD_IMAGE) from its registry, so no image add or build can run: ${reason}`
|
|
49813
49757
|
});
|
|
49814
49758
|
}
|
|
49815
49759
|
};
|
|
@@ -50001,7 +49945,10 @@ function createImageEviction(deps) {
|
|
|
50001
49945
|
// packages/daemon/src/imps/images/image-service.ts
|
|
50002
49946
|
function createImageService(deps) {
|
|
50003
49947
|
const clock = deps.clock ?? REAL_CLOCK;
|
|
50004
|
-
const writer = createImageWriter({
|
|
49948
|
+
const writer = createImageWriter({
|
|
49949
|
+
...deps,
|
|
49950
|
+
clock
|
|
49951
|
+
});
|
|
50005
49952
|
const builds = createImageBuilds({ ...deps, clock }, writer);
|
|
50006
49953
|
const adds = createImageAdds({ ...deps, clock }, writer);
|
|
50007
49954
|
const eviction = createImageEviction({
|
|
@@ -50088,6 +50035,91 @@ function createImageService(deps) {
|
|
|
50088
50035
|
};
|
|
50089
50036
|
}
|
|
50090
50037
|
|
|
50038
|
+
// packages/daemon/src/imps/images/rootfs/start-tar-process.ts
|
|
50039
|
+
function startTarProcess(argv) {
|
|
50040
|
+
return Bun.spawn([...argv], {
|
|
50041
|
+
stdin: "pipe",
|
|
50042
|
+
stdout: "pipe",
|
|
50043
|
+
stderr: "pipe",
|
|
50044
|
+
env: { ...process.env, LC_ALL: "C" }
|
|
50045
|
+
});
|
|
50046
|
+
}
|
|
50047
|
+
|
|
50048
|
+
// packages/daemon/src/platform/process/run-streamed.ts
|
|
50049
|
+
async function runStreamed(argv, onStdout, signal) {
|
|
50050
|
+
const child = Bun.spawn([...argv], {
|
|
50051
|
+
stdin: "ignore",
|
|
50052
|
+
stdout: "pipe",
|
|
50053
|
+
stderr: "pipe",
|
|
50054
|
+
env: process.env,
|
|
50055
|
+
signal
|
|
50056
|
+
});
|
|
50057
|
+
const stderr = new Response(child.stderr).text();
|
|
50058
|
+
try {
|
|
50059
|
+
for await (const chunk of child.stdout) {
|
|
50060
|
+
await onStdout(chunk);
|
|
50061
|
+
}
|
|
50062
|
+
} catch (error) {
|
|
50063
|
+
child.kill();
|
|
50064
|
+
await child.exited;
|
|
50065
|
+
throw error;
|
|
50066
|
+
}
|
|
50067
|
+
const exitCode = await child.exited;
|
|
50068
|
+
signal.throwIfAborted();
|
|
50069
|
+
return { exitCode, stdout: "", stderr: await stderr };
|
|
50070
|
+
}
|
|
50071
|
+
|
|
50072
|
+
// packages/daemon/src/vm/storage/count-tree-bytes.ts
|
|
50073
|
+
import { lstat as lstat3, readdir as readdir3 } from "fs/promises";
|
|
50074
|
+
import { join as join31 } from "path";
|
|
50075
|
+
async function countTreeBytes(root, deps = {}) {
|
|
50076
|
+
const readDir = deps.readDir ?? readDirEntries;
|
|
50077
|
+
const inodes = new Map;
|
|
50078
|
+
const dirs = [root];
|
|
50079
|
+
for (let directory = dirs.pop();directory !== undefined; directory = dirs.pop()) {
|
|
50080
|
+
const entries = await readEntries2(readDir, directory);
|
|
50081
|
+
for (const entry of entries) {
|
|
50082
|
+
if (entry.isDirectory()) {
|
|
50083
|
+
dirs.push(join31(directory, entry.name));
|
|
50084
|
+
}
|
|
50085
|
+
}
|
|
50086
|
+
const files = entries.filter((entry) => entry.isFile());
|
|
50087
|
+
const stats = await Promise.all(files.map((entry) => readFileStats(join31(directory, entry.name))));
|
|
50088
|
+
for (const stat of stats) {
|
|
50089
|
+
if (stat !== undefined) {
|
|
50090
|
+
inodes.set(`${String(stat.dev)}:${String(stat.ino)}`, Math.max(0, stat.blocks - 1) * 512);
|
|
50091
|
+
}
|
|
50092
|
+
}
|
|
50093
|
+
}
|
|
50094
|
+
return [...inodes.values()].reduce((sum, bytes) => sum + bytes, 0);
|
|
50095
|
+
}
|
|
50096
|
+
function readDirEntries(directory) {
|
|
50097
|
+
return readdir3(directory, { withFileTypes: true });
|
|
50098
|
+
}
|
|
50099
|
+
async function readEntries2(readDir, directory) {
|
|
50100
|
+
try {
|
|
50101
|
+
return await readDir(directory);
|
|
50102
|
+
} catch (error) {
|
|
50103
|
+
if (isMissing(error)) {
|
|
50104
|
+
return [];
|
|
50105
|
+
}
|
|
50106
|
+
throw error;
|
|
50107
|
+
}
|
|
50108
|
+
}
|
|
50109
|
+
function isMissing(error) {
|
|
50110
|
+
return error instanceof Error && "code" in error && error.code === "ENOENT";
|
|
50111
|
+
}
|
|
50112
|
+
async function readFileStats(path) {
|
|
50113
|
+
try {
|
|
50114
|
+
return await lstat3(path);
|
|
50115
|
+
} catch (error) {
|
|
50116
|
+
if (isMissing(error)) {
|
|
50117
|
+
return;
|
|
50118
|
+
}
|
|
50119
|
+
throw error;
|
|
50120
|
+
}
|
|
50121
|
+
}
|
|
50122
|
+
|
|
50091
50123
|
// packages/daemon/src/vm/storage/disk-usage-cache.ts
|
|
50092
50124
|
var REFRESH_DELAY_MS = 1e4;
|
|
50093
50125
|
var CHANGES_USAGE = new Set([
|
|
@@ -50199,6 +50231,11 @@ function createImpdStorage(config, deps) {
|
|
|
50199
50231
|
storageGate,
|
|
50200
50232
|
diskBudget,
|
|
50201
50233
|
readBuilders: () => buildersHolder.builders,
|
|
50234
|
+
runCommand,
|
|
50235
|
+
runStreamed,
|
|
50236
|
+
startTar: startTarProcess,
|
|
50237
|
+
countTreeBytes,
|
|
50238
|
+
startTimer: startRealTimer,
|
|
50202
50239
|
...deps.now !== undefined && { clock: { now: deps.now } },
|
|
50203
50240
|
...deps.images
|
|
50204
50241
|
});
|
|
@@ -50806,14 +50843,14 @@ function expandScopes(asked) {
|
|
|
50806
50843
|
}
|
|
50807
50844
|
|
|
50808
50845
|
// packages/daemon/src/platform/http/render-html.ts
|
|
50809
|
-
import { P as
|
|
50846
|
+
import { P as P3, match as match7 } from "ts-pattern";
|
|
50810
50847
|
var MARKUP = Symbol("markup");
|
|
50811
50848
|
function renderHTML(strings, ...parts) {
|
|
50812
50849
|
const html = parts.reduce((text, part, index) => `${text}${toHTML(part)}${strings[index + 1] ?? ""}`, strings[0] ?? "");
|
|
50813
50850
|
return { [MARKUP]: true, html };
|
|
50814
50851
|
}
|
|
50815
50852
|
function toHTML(part) {
|
|
50816
|
-
return
|
|
50853
|
+
return match7(part).with(P3.string, (text) => escapeHTML(text)).with(P3.array(), (list) => list.map((each) => each.html).join("")).with({ html: P3.string }, (markup) => markup.html).exhaustive();
|
|
50817
50854
|
}
|
|
50818
50855
|
function escapeHTML(text) {
|
|
50819
50856
|
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
@@ -52084,7 +52121,6 @@ async function listPublicImpNames(db) {
|
|
|
52084
52121
|
|
|
52085
52122
|
// packages/daemon/src/network/https/acme/acme-issuer.ts
|
|
52086
52123
|
import { Agent } from "https";
|
|
52087
|
-
import * as acme from "acme-client";
|
|
52088
52124
|
|
|
52089
52125
|
// packages/daemon/src/network/https/acme/renewal-policy.ts
|
|
52090
52126
|
var FIRST_BACKOFF_MS2 = 15 * 60000;
|
|
@@ -52126,10 +52162,12 @@ function findRenewalReason(info, domain, now) {
|
|
|
52126
52162
|
|
|
52127
52163
|
// packages/daemon/src/network/https/acme/acme-issuer.ts
|
|
52128
52164
|
function createAcmeIssuer(options) {
|
|
52129
|
-
|
|
52130
|
-
|
|
52131
|
-
|
|
52132
|
-
|
|
52165
|
+
const loading = { promise: null };
|
|
52166
|
+
const loadAcme = () => {
|
|
52167
|
+
loading.promise ??= readAcmeClient(options.caPem);
|
|
52168
|
+
return loading.promise;
|
|
52169
|
+
};
|
|
52170
|
+
const openClient = async (acme) => {
|
|
52133
52171
|
const stored = options.store.readAccount(options.directoryUrl);
|
|
52134
52172
|
if (stored !== null) {
|
|
52135
52173
|
return new acme.Client({
|
|
@@ -52159,7 +52197,8 @@ function createAcmeIssuer(options) {
|
|
|
52159
52197
|
};
|
|
52160
52198
|
const runOrder = async (domain) => {
|
|
52161
52199
|
await checkDirectory2(options.directoryUrl, options.caPem);
|
|
52162
|
-
const
|
|
52200
|
+
const acme = await loadAcme();
|
|
52201
|
+
const client = await openClient(acme);
|
|
52163
52202
|
const names = listCertificateNames(domain);
|
|
52164
52203
|
const order = await client.createOrder({
|
|
52165
52204
|
identifiers: names.map((name) => ({ type: "dns", value: name }))
|
|
@@ -52208,24 +52247,12 @@ function createAcmeIssuer(options) {
|
|
|
52208
52247
|
}
|
|
52209
52248
|
};
|
|
52210
52249
|
}
|
|
52211
|
-
function
|
|
52212
|
-
const
|
|
52213
|
-
|
|
52214
|
-
|
|
52215
|
-
return { notBefore: info.notBefore, notAfter: info.notAfter, names: [...names] };
|
|
52216
|
-
}
|
|
52217
|
-
async function removeRecords(options, records) {
|
|
52218
|
-
for (const record of records) {
|
|
52219
|
-
try {
|
|
52220
|
-
await options.dns.removeTxt(record);
|
|
52221
|
-
} catch (error) {
|
|
52222
|
-
const reason = getErrorMessage(error);
|
|
52223
|
-
getImpdLogger("https").warning("could not remove the TXT record {fqdn}: {reason}", {
|
|
52224
|
-
fqdn: record.fqdn,
|
|
52225
|
-
reason
|
|
52226
|
-
});
|
|
52227
|
-
}
|
|
52250
|
+
async function readAcmeClient(caPem) {
|
|
52251
|
+
const acme = await import("acme-client");
|
|
52252
|
+
if (caPem !== null) {
|
|
52253
|
+
acme.axios.defaults.httpsAgent = new Agent({ ca: caPem });
|
|
52228
52254
|
}
|
|
52255
|
+
return acme;
|
|
52229
52256
|
}
|
|
52230
52257
|
async function checkDirectory2(directoryUrl, caPem) {
|
|
52231
52258
|
try {
|
|
@@ -52242,6 +52269,19 @@ async function checkDirectory2(directoryUrl, caPem) {
|
|
|
52242
52269
|
});
|
|
52243
52270
|
}
|
|
52244
52271
|
}
|
|
52272
|
+
async function removeRecords(options, records) {
|
|
52273
|
+
for (const record of records) {
|
|
52274
|
+
try {
|
|
52275
|
+
await options.dns.removeTxt(record);
|
|
52276
|
+
} catch (error) {
|
|
52277
|
+
const reason = getErrorMessage(error);
|
|
52278
|
+
getImpdLogger("https").warning("could not remove the TXT record {fqdn}: {reason}", {
|
|
52279
|
+
fqdn: record.fqdn,
|
|
52280
|
+
reason
|
|
52281
|
+
});
|
|
52282
|
+
}
|
|
52283
|
+
}
|
|
52284
|
+
}
|
|
52245
52285
|
function formatAcmeError(error) {
|
|
52246
52286
|
const message = getErrorMessage(error);
|
|
52247
52287
|
if (error instanceof TypeError && message.includes("response.config")) {
|
|
@@ -52649,6 +52689,20 @@ function createDnsProvider(config, token) {
|
|
|
52649
52689
|
});
|
|
52650
52690
|
}
|
|
52651
52691
|
|
|
52692
|
+
// packages/daemon/src/network/https/acme/read-certificate-info.ts
|
|
52693
|
+
import"reflect-metadata";
|
|
52694
|
+
import * as x5092 from "@peculiar/x509";
|
|
52695
|
+
function readCertificateInfo(chainPem) {
|
|
52696
|
+
const certificate = new x5092.X509Certificate(x5092.PemConverter.decodeFirst(chainPem));
|
|
52697
|
+
const altNames = certificate.getExtension(x5092.SubjectAlternativeNameExtension);
|
|
52698
|
+
const names = new Set([
|
|
52699
|
+
...certificate.subjectName.getField("CN"),
|
|
52700
|
+
...altNames?.names.items.map((name) => name.value) ?? []
|
|
52701
|
+
]);
|
|
52702
|
+
names.delete("");
|
|
52703
|
+
return { notBefore: certificate.notBefore, notAfter: certificate.notAfter, names: [...names] };
|
|
52704
|
+
}
|
|
52705
|
+
|
|
52652
52706
|
// packages/daemon/src/network/https/acme/cert-manager.ts
|
|
52653
52707
|
function createCertManager(options) {
|
|
52654
52708
|
const domain = options.domain;
|