@forgezero/agent 0.1.116 → 0.1.118
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 +8 -4
- package/dist/agent-heartbeat.js +1 -1
- package/dist/bootstrap.d.ts +1 -2
- package/dist/bootstrap.js +4 -27
- package/dist/deploy-compiler.d.ts +10 -1
- package/dist/deploy-compiler.js +32 -4
- package/dist/deploy-plan-runner.js +19 -2
- package/dist/deploy-plan.js +19 -2
- package/dist/deploy.d.ts +10 -1
- package/dist/deployment.d.ts +10 -1
- package/dist/fz-agent.js +20 -3
- package/dist/fz.js +84 -53
- package/dist/metal-bootstrap.js +1 -1
- package/dist/metal-provision.d.ts +1 -1
- package/dist/operator-bootstrap.js +4 -27
- package/dist/platform-bootstrap-runtime.d.ts +1 -11
- package/dist/platform-bootstrap-runtime.js +0 -5
- package/dist/platform-fleet-verification.js +1 -6
- package/dist/platform-launch-env.d.ts +0 -1
- package/dist/platform-launch-profile.d.ts +0 -4
- package/dist/provision.js +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -99,8 +99,12 @@ export default defineDeployment({
|
|
|
99
99
|
resources: { cpuCores: input.ref('cpuCores'), memoryMiB: input.ref('memoryMiB'), storageGiB: input.ref('storageGiB') },
|
|
100
100
|
os: 'ubuntu-24.04', runtime: 'oci-runc', sharing: 'shared', reuse: 'prefer',
|
|
101
101
|
provisioning: {
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
regionKey: 'default', imageKey: 'ubuntu-24.04-x64', environmentKey: 'production', ownership: 'platform',
|
|
103
|
+
resources: {
|
|
104
|
+
physicalCores: 1, vcpu: 2, memoryGib: 2, diskGib: 16,
|
|
105
|
+
egressGuaranteedMbps: 100, egressBurstMbps: 200, confidential: false
|
|
106
|
+
},
|
|
107
|
+
monthlyAmountCents: '1200', maxMonthlySpendMinor: '25000'
|
|
104
108
|
},
|
|
105
109
|
connectivity: {
|
|
106
110
|
private: { mode: 'private-lan' },
|
|
@@ -229,8 +233,8 @@ import {
|
|
|
229
233
|
ForgeZero,
|
|
230
234
|
} from '@forgezero/vault';
|
|
231
235
|
|
|
232
|
-
const fz = new ForgeZero({ project: '
|
|
233
|
-
await fz.get('
|
|
236
|
+
const fz = new ForgeZero({ project: 'payments-api', environment: 'production' });
|
|
237
|
+
await fz.get('PAYMENT_PROVIDER');
|
|
234
238
|
```
|
|
235
239
|
|
|
236
240
|
## A local copy, not a cache
|
package/dist/agent-heartbeat.js
CHANGED
package/dist/bootstrap.d.ts
CHANGED
|
@@ -89,7 +89,7 @@ export interface EnrolledComputeActivationConfig {
|
|
|
89
89
|
profile?: string;
|
|
90
90
|
deployRoot?: string;
|
|
91
91
|
software?: SoftwareRequirement[];
|
|
92
|
-
/** Compatibility-only per-node SSH deploy key
|
|
92
|
+
/** Compatibility-only per-node SSH deploy key for non-provider sources. */
|
|
93
93
|
gitDeployKey?: boolean;
|
|
94
94
|
installCloudflared?: boolean;
|
|
95
95
|
installWarp?: boolean;
|
|
@@ -115,7 +115,6 @@ export interface PlatformBootstrapSecrets {
|
|
|
115
115
|
backupS3Secret?: string;
|
|
116
116
|
cloudflareTunnelToken?: string;
|
|
117
117
|
cloudflareApiToken?: string;
|
|
118
|
-
githubOAuthClientSecret: string;
|
|
119
118
|
}
|
|
120
119
|
export interface EnrolledComputeBootstrapSecrets {
|
|
121
120
|
enrolmentToken: string;
|
package/dist/bootstrap.js
CHANGED
|
@@ -1460,7 +1460,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
|
|
|
1460
1460
|
var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
|
|
1461
1461
|
|
|
1462
1462
|
// src/version.ts
|
|
1463
|
-
var VERSION = "0.1.
|
|
1463
|
+
var VERSION = "0.1.118";
|
|
1464
1464
|
|
|
1465
1465
|
// src/software.ts
|
|
1466
1466
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -3272,9 +3272,6 @@ function validatePlatformSharedEnvironment(input) {
|
|
|
3272
3272
|
} else if (input.email !== undefined) {
|
|
3273
3273
|
throw new Error("Bootstrap email provider must be smtp or jetemail.");
|
|
3274
3274
|
}
|
|
3275
|
-
if (!input.githubOAuth || !/^(?:Iv1\.[A-Fa-f0-9]{16}|Ov23li[A-Za-z0-9]{14,})$/.test(input.githubOAuth.clientId)) {
|
|
3276
|
-
throw new Error("GitHub OAuth client id is malformed.");
|
|
3277
|
-
}
|
|
3278
3275
|
boundedInteger("publicApiPort", input.publicApiPort, 1024, 65533);
|
|
3279
3276
|
if (!Array.isArray(input.seedSyncMembers) || input.seedSyncMembers.length < 3 || input.seedSyncMembers.length > 64 || new Set(input.seedSyncMembers).size !== input.seedSyncMembers.length) {
|
|
3280
3277
|
throw new Error("seedSyncMembers must contain 3 to 64 unique physical host identities.");
|
|
@@ -3405,7 +3402,6 @@ function renderPlatformSharedEnvironment(input) {
|
|
|
3405
3402
|
FZ_REALTIME_WORKER_SCRIPT: value.realtime?.workerScriptName ?? "",
|
|
3406
3403
|
FZ_REALTIME_ENDPOINT: value.realtime?.endpoint ?? "",
|
|
3407
3404
|
FZ_REALTIME_PRODUCER: value.realtime?.producer ?? "",
|
|
3408
|
-
FZ_GITHUB_OAUTH_CLIENT_ID: value.githubOAuth.clientId,
|
|
3409
3405
|
FZ_PLATFORM_INITIAL_INVENTORY: value.initialInventory ? JSON.stringify(value.initialInventory) : ""
|
|
3410
3406
|
};
|
|
3411
3407
|
return `# Generated by fz bootstrap platform. Non-secret coordinates only.
|
|
@@ -3417,7 +3413,6 @@ function platformApiCredentialSpecs(options) {
|
|
|
3417
3413
|
const optional = [
|
|
3418
3414
|
["fz_smtp.password", options.emailProvider === "smtp"],
|
|
3419
3415
|
["fz_jetemail.apiKey", options.emailProvider === "jetemail"],
|
|
3420
|
-
["fz_oauth.github.clientSecret", options.githubOAuth],
|
|
3421
3416
|
["CF_API_TOKEN", options.cloudflareKv],
|
|
3422
3417
|
["CF_TUNNEL_TOKEN", options.cloudflareKv],
|
|
3423
3418
|
["REALTIME_PUBLISH_SECRET", options.realtime],
|
|
@@ -3814,15 +3809,7 @@ function validatePlatformBootstrapSecrets(config, input) {
|
|
|
3814
3809
|
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
3815
3810
|
throw new Error("bootstrap credential input must be an object");
|
|
3816
3811
|
const source = input;
|
|
3817
|
-
const allowed = [
|
|
3818
|
-
"clusterBootstrapCode",
|
|
3819
|
-
"emailSecret",
|
|
3820
|
-
"enrolmentToken",
|
|
3821
|
-
"backupS3Secret",
|
|
3822
|
-
"cloudflareTunnelToken",
|
|
3823
|
-
"cloudflareApiToken",
|
|
3824
|
-
"githubOAuthClientSecret"
|
|
3825
|
-
];
|
|
3812
|
+
const allowed = ["clusterBootstrapCode", "emailSecret", "enrolmentToken", "backupS3Secret", "cloudflareTunnelToken", "cloudflareApiToken"];
|
|
3826
3813
|
const unknown = Object.keys(source).filter((key) => !allowed.includes(key));
|
|
3827
3814
|
if (unknown.length)
|
|
3828
3815
|
throw new Error(`bootstrap credential input contains unsupported field ${unknown[0]}`);
|
|
@@ -3832,7 +3819,6 @@ function validatePlatformBootstrapSecrets(config, input) {
|
|
|
3832
3819
|
const backupS3Secret = typeof source.backupS3Secret === "string" ? source.backupS3Secret.trim() : undefined;
|
|
3833
3820
|
const cloudflareTunnelToken = typeof source.cloudflareTunnelToken === "string" ? source.cloudflareTunnelToken.trim() : undefined;
|
|
3834
3821
|
const cloudflareApiToken = typeof source.cloudflareApiToken === "string" ? source.cloudflareApiToken.trim() : undefined;
|
|
3835
|
-
const githubOAuthClientSecret = typeof source.githubOAuthClientSecret === "string" ? source.githubOAuthClientSecret.trim() : "";
|
|
3836
3822
|
if (!/^[a-f0-9]{64}$/i.test(clusterBootstrapCode))
|
|
3837
3823
|
throw new Error("cluster bootstrap code must contain exactly 64 hexadecimal characters");
|
|
3838
3824
|
if (!emailSecret || emailSecret.length > 16384 || /[\r\n\0]/.test(emailSecret))
|
|
@@ -3852,16 +3838,12 @@ function validatePlatformBootstrapSecrets(config, input) {
|
|
|
3852
3838
|
}
|
|
3853
3839
|
if (cloudflareTunnelToken)
|
|
3854
3840
|
validateCloudflareBootstrapSecretPair({ cloudflareTunnelToken, cloudflareApiToken });
|
|
3855
|
-
if (githubOAuthClientSecret.length < 20 || githubOAuthClientSecret.length > 512 || /[\r\n\0]/.test(githubOAuthClientSecret)) {
|
|
3856
|
-
throw new Error("GitHub OAuth client secret is malformed");
|
|
3857
|
-
}
|
|
3858
3841
|
return {
|
|
3859
3842
|
clusterBootstrapCode,
|
|
3860
3843
|
emailSecret,
|
|
3861
3844
|
...enrolmentToken ? { enrolmentToken } : {},
|
|
3862
3845
|
...backupS3Secret ? { backupS3Secret } : {},
|
|
3863
|
-
...cloudflareTunnelToken ? { cloudflareTunnelToken, cloudflareApiToken } : {}
|
|
3864
|
-
githubOAuthClientSecret
|
|
3846
|
+
...cloudflareTunnelToken ? { cloudflareTunnelToken, cloudflareApiToken } : {}
|
|
3865
3847
|
};
|
|
3866
3848
|
}
|
|
3867
3849
|
var platformBootstrapRunner = (config) => config.kind === "platform" && config.database.role === "master";
|
|
@@ -4784,8 +4766,7 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4784
4766
|
enrolmentToken: checked4.enrolmentToken,
|
|
4785
4767
|
backup: checked4.backupS3Secret,
|
|
4786
4768
|
cloudflareTunnelToken: checked4.cloudflareTunnelToken,
|
|
4787
|
-
cloudflareApiToken: checked4.cloudflareApiToken
|
|
4788
|
-
githubOAuthClientSecret: checked4.githubOAuthClientSecret
|
|
4769
|
+
cloudflareApiToken: checked4.cloudflareApiToken
|
|
4789
4770
|
};
|
|
4790
4771
|
})() : undefined;
|
|
4791
4772
|
const enrolledPrivate = config.kind === "enrolled-compute" ? validateEnrolledComputeBootstrapSecrets(config, secrets) : undefined;
|
|
@@ -4886,7 +4867,6 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4886
4867
|
const emailCredentialName = config.runtime.environment.email?.provider === "smtp" ? "fz_smtp.password" : config.runtime.environment.email?.provider === "jetemail" ? "fz_jetemail.apiKey" : undefined;
|
|
4887
4868
|
for (const [name, source] of Object.entries({
|
|
4888
4869
|
...emailCredentialName ? { [emailCredentialName]: platformPrivate.email } : {},
|
|
4889
|
-
"fz_oauth.github.clientSecret": platformPrivate.githubOAuthClientSecret,
|
|
4890
4870
|
"backup.s3.secretAccessKey": platformPrivate.backup
|
|
4891
4871
|
})) {
|
|
4892
4872
|
if (source) {
|
|
@@ -4903,7 +4883,6 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4903
4883
|
const credentials = platformApiCredentialSpecs({
|
|
4904
4884
|
emailProvider: runtime.environment.email?.provider,
|
|
4905
4885
|
cloudflareKv: cloudflareConfigured,
|
|
4906
|
-
githubOAuth: true,
|
|
4907
4886
|
realtime: Boolean(runtime.environment.realtime)
|
|
4908
4887
|
});
|
|
4909
4888
|
const units = renderPlatformApiUnits({
|
|
@@ -5151,7 +5130,6 @@ function strictBootstrapDocument(value) {
|
|
|
5151
5130
|
"agentOtlpEndpoint",
|
|
5152
5131
|
"custodianEmail",
|
|
5153
5132
|
"email",
|
|
5154
|
-
"githubOAuth",
|
|
5155
5133
|
"deployProfile",
|
|
5156
5134
|
"otlpFlushIntervalMs",
|
|
5157
5135
|
"otlpTraceSampleRatio",
|
|
@@ -5162,7 +5140,6 @@ function strictBootstrapDocument(value) {
|
|
|
5162
5140
|
"databaseReadPreferredCoordinators"
|
|
5163
5141
|
], "runtime environment");
|
|
5164
5142
|
const environment = runtime.environment;
|
|
5165
|
-
exactKeys(environment.githubOAuth, ["clientId"], "GitHub OAuth config");
|
|
5166
5143
|
if (environment.initialInventory !== undefined) {
|
|
5167
5144
|
const inventory = exactKeys(environment.initialInventory, ["metalHostname", "metalIdentity", "region", "computes", "attestation", "deployment"], "initial inventory");
|
|
5168
5145
|
if (inventory.metalIdentity !== undefined) {
|
|
@@ -10,12 +10,21 @@ export interface DeploymentCompilation {
|
|
|
10
10
|
}
|
|
11
11
|
export type DeploymentInitRuntime = 'native' | 'containerd' | 'kata-snp';
|
|
12
12
|
export interface DeploymentInitProvisioning {
|
|
13
|
-
planKey: string;
|
|
14
13
|
regionKey: string;
|
|
15
14
|
imageKey: string;
|
|
16
15
|
environmentKey: string;
|
|
17
16
|
ownership: 'platform' | 'tenant-metal';
|
|
18
17
|
metalHostname?: string;
|
|
18
|
+
resources: {
|
|
19
|
+
physicalCores: number;
|
|
20
|
+
vcpu: number;
|
|
21
|
+
memoryGib: number;
|
|
22
|
+
diskGib: number;
|
|
23
|
+
egressGuaranteedMbps: number;
|
|
24
|
+
egressBurstMbps: number;
|
|
25
|
+
confidential: boolean;
|
|
26
|
+
};
|
|
27
|
+
monthlyAmountCents: string;
|
|
19
28
|
maxMonthlySpendMinor: string;
|
|
20
29
|
}
|
|
21
30
|
export interface DeploymentInitOptions {
|
package/dist/deploy-compiler.js
CHANGED
|
@@ -910,13 +910,30 @@ function compileDeployment(sourceValue) {
|
|
|
910
910
|
fail(`deployment.spec.targets.${targetName}.allocation.execution`, "cannot satisfy required confidential compute.");
|
|
911
911
|
if (target.provisioning !== undefined) {
|
|
912
912
|
const provisioning = object(target.provisioning, `deployment.spec.targets.${targetName}.provisioning`);
|
|
913
|
-
exact3(provisioning, ["
|
|
914
|
-
for (const key of ["
|
|
913
|
+
exact3(provisioning, ["regionKey", "imageKey", "environmentKey", "ownership", "metalHostname", "resources", "monthlyAmountCents", "maxMonthlySpendMinor"], `deployment.spec.targets.${targetName}.provisioning`);
|
|
914
|
+
for (const key of ["regionKey", "imageKey", "environmentKey"])
|
|
915
915
|
named(provisioning[key], `deployment.spec.targets.${targetName}.provisioning.${key}`);
|
|
916
916
|
if (!["platform", "tenant-metal"].includes(String(provisioning.ownership)) || provisioning.ownership === "tenant-metal" !== Boolean(provisioning.metalHostname))
|
|
917
917
|
fail(`deployment.spec.targets.${targetName}.provisioning.ownership`, "must bind platform capacity or one tenant metal hostname.");
|
|
918
918
|
if (provisioning.metalHostname !== undefined && !/^(?=.{1,253}$)[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/.test(String(provisioning.metalHostname)))
|
|
919
919
|
fail(`deployment.spec.targets.${targetName}.provisioning.metalHostname`, "is invalid.");
|
|
920
|
+
const provisionedResources = object(provisioning.resources, `deployment.spec.targets.${targetName}.provisioning.resources`);
|
|
921
|
+
exact3(provisionedResources, ["physicalCores", "vcpu", "memoryGib", "diskGib", "egressGuaranteedMbps", "egressBurstMbps", "confidential"], `deployment.spec.targets.${targetName}.provisioning.resources`);
|
|
922
|
+
integer(provisionedResources.physicalCores, `deployment.spec.targets.${targetName}.provisioning.resources.physicalCores`, 1, 1024);
|
|
923
|
+
integer(provisionedResources.vcpu, `deployment.spec.targets.${targetName}.provisioning.resources.vcpu`, 1, 4096);
|
|
924
|
+
integer(provisionedResources.memoryGib, `deployment.spec.targets.${targetName}.provisioning.resources.memoryGib`, 1, 4194304);
|
|
925
|
+
integer(provisionedResources.diskGib, `deployment.spec.targets.${targetName}.provisioning.resources.diskGib`, 1, 1048576);
|
|
926
|
+
integer(provisionedResources.egressGuaranteedMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressGuaranteedMbps`, 0, 1e7);
|
|
927
|
+
integer(provisionedResources.egressBurstMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressBurstMbps`, Number(provisionedResources.egressGuaranteedMbps), 1e7);
|
|
928
|
+
if (typeof provisionedResources.confidential !== "boolean")
|
|
929
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources.confidential`, "must be boolean.");
|
|
930
|
+
if (typeof capacity.cpuCores === "number" && Number(provisionedResources.vcpu) < capacity.cpuCores || typeof capacity.memoryMiB === "number" && Number(provisionedResources.memoryGib) * 1024 < capacity.memoryMiB || typeof capacity.storageGiB === "number" && Number(provisionedResources.diskGib) < capacity.storageGiB) {
|
|
931
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources`, "must satisfy the per-slot allocation minimum.");
|
|
932
|
+
}
|
|
933
|
+
if ((selector.confidentialCompute === "required" || allocation.execution === "oci-kata-qemu-snp") && provisionedResources.confidential !== true)
|
|
934
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources.confidential`, "must be true for confidential execution.");
|
|
935
|
+
if (typeof provisioning.monthlyAmountCents !== "string" || !/^\d{1,18}$/.test(provisioning.monthlyAmountCents))
|
|
936
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.monthlyAmountCents`, "must be a bounded USD-cent amount.");
|
|
920
937
|
if (typeof provisioning.maxMonthlySpendMinor !== "string" || !/^\d{1,18}$/.test(provisioning.maxMonthlySpendMinor))
|
|
921
938
|
fail(`deployment.spec.targets.${targetName}.provisioning.maxMonthlySpendMinor`, "must be a bounded decimal minor-unit amount.");
|
|
922
939
|
}
|
|
@@ -1266,13 +1283,24 @@ function initCoordinates(options) {
|
|
|
1266
1283
|
throw new Error("reuse require cannot include provisioning coordinates");
|
|
1267
1284
|
if (options.provisioning !== undefined) {
|
|
1268
1285
|
for (const [label, value] of Object.entries({
|
|
1269
|
-
plan: options.provisioning.planKey,
|
|
1270
1286
|
region: options.provisioning.regionKey,
|
|
1271
1287
|
image: options.provisioning.imageKey,
|
|
1272
1288
|
environment: options.provisioning.environmentKey
|
|
1273
1289
|
}))
|
|
1274
1290
|
if (!/^[a-z][a-z0-9-]{0,62}$/.test(value))
|
|
1275
1291
|
throw new Error(`deployment provisioning ${label} must be a lowercase typed name`);
|
|
1292
|
+
const resources = options.provisioning.resources;
|
|
1293
|
+
for (const [label, value] of Object.entries(resources).filter(([key]) => key !== "confidential")) {
|
|
1294
|
+
if (!Number.isSafeInteger(value) || Number(value) < 0)
|
|
1295
|
+
throw new Error(`deployment provisioning ${label} must be a non-negative integer`);
|
|
1296
|
+
}
|
|
1297
|
+
if (resources.physicalCores < 1 || resources.vcpu < result.cpuCores || resources.memoryGib * 1024 < result.memoryMiB || resources.diskGib < result.storageGiB || resources.egressBurstMbps < resources.egressGuaranteedMbps) {
|
|
1298
|
+
throw new Error("deployment provisioning resources must satisfy the target allocation and bandwidth bounds");
|
|
1299
|
+
}
|
|
1300
|
+
if (result.isolation === "sev-snp" && !resources.confidential)
|
|
1301
|
+
throw new Error("deployment provisioning must provide confidential capacity for sev-snp");
|
|
1302
|
+
if (!/^\d{1,18}$/.test(options.provisioning.monthlyAmountCents))
|
|
1303
|
+
throw new Error("deployment provisioning monthly amount must be a bounded USD-cent amount");
|
|
1276
1304
|
if (!/^\d{1,18}$/.test(options.provisioning.maxMonthlySpendMinor))
|
|
1277
1305
|
throw new Error("deployment provisioning monthly spend must be a bounded decimal minor-unit amount");
|
|
1278
1306
|
if (options.provisioning.ownership === "tenant-metal" && !options.provisioning.metalHostname)
|
|
@@ -1289,7 +1317,7 @@ function defaultTypeScriptDeployment(name, options = {}) {
|
|
|
1289
1317
|
const execution = selected.runtime === "native" ? "native" : selected.runtime === "containerd" ? "oci-runc" : "oci-kata-qemu-snp";
|
|
1290
1318
|
const hostPackageVersion = selected.operatingSystem === "ubuntu-24.04" ? "ubuntu-24.04" : "ubuntu-26.04";
|
|
1291
1319
|
const provisioningBlock = selected.provisioning === undefined ? "" : `,
|
|
1292
|
-
provisioning: {
|
|
1320
|
+
provisioning: { regionKey: '${selected.provisioning.regionKey}', imageKey: '${selected.provisioning.imageKey}', environmentKey: '${selected.provisioning.environmentKey}', ownership: '${selected.provisioning.ownership}',${selected.provisioning.metalHostname ? ` metalHostname: '${selected.provisioning.metalHostname}',` : ""} resources: ${JSON.stringify(selected.provisioning.resources)}, monthlyAmountCents: '${selected.provisioning.monthlyAmountCents}', maxMonthlySpendMinor: '${selected.provisioning.maxMonthlySpendMinor}' }`;
|
|
1293
1321
|
const requirementBlock = selected.runtime === "native" ? `bun: providers.bun.require()` : selected.runtime === "containerd" ? `containerd: providers.containerd.require({ version: '${hostPackageVersion}' }),
|
|
1294
1322
|
nginx: providers.nginx.require({ version: '${hostPackageVersion}' })` : `containerd: providers.containerd.require(),
|
|
1295
1323
|
kata: providers.kata.require(),
|
|
@@ -910,13 +910,30 @@ function compileDeployment(sourceValue) {
|
|
|
910
910
|
fail(`deployment.spec.targets.${targetName}.allocation.execution`, "cannot satisfy required confidential compute.");
|
|
911
911
|
if (target.provisioning !== undefined) {
|
|
912
912
|
const provisioning = object(target.provisioning, `deployment.spec.targets.${targetName}.provisioning`);
|
|
913
|
-
exact3(provisioning, ["
|
|
914
|
-
for (const key of ["
|
|
913
|
+
exact3(provisioning, ["regionKey", "imageKey", "environmentKey", "ownership", "metalHostname", "resources", "monthlyAmountCents", "maxMonthlySpendMinor"], `deployment.spec.targets.${targetName}.provisioning`);
|
|
914
|
+
for (const key of ["regionKey", "imageKey", "environmentKey"])
|
|
915
915
|
named(provisioning[key], `deployment.spec.targets.${targetName}.provisioning.${key}`);
|
|
916
916
|
if (!["platform", "tenant-metal"].includes(String(provisioning.ownership)) || provisioning.ownership === "tenant-metal" !== Boolean(provisioning.metalHostname))
|
|
917
917
|
fail(`deployment.spec.targets.${targetName}.provisioning.ownership`, "must bind platform capacity or one tenant metal hostname.");
|
|
918
918
|
if (provisioning.metalHostname !== undefined && !/^(?=.{1,253}$)[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/.test(String(provisioning.metalHostname)))
|
|
919
919
|
fail(`deployment.spec.targets.${targetName}.provisioning.metalHostname`, "is invalid.");
|
|
920
|
+
const provisionedResources = object(provisioning.resources, `deployment.spec.targets.${targetName}.provisioning.resources`);
|
|
921
|
+
exact3(provisionedResources, ["physicalCores", "vcpu", "memoryGib", "diskGib", "egressGuaranteedMbps", "egressBurstMbps", "confidential"], `deployment.spec.targets.${targetName}.provisioning.resources`);
|
|
922
|
+
integer(provisionedResources.physicalCores, `deployment.spec.targets.${targetName}.provisioning.resources.physicalCores`, 1, 1024);
|
|
923
|
+
integer(provisionedResources.vcpu, `deployment.spec.targets.${targetName}.provisioning.resources.vcpu`, 1, 4096);
|
|
924
|
+
integer(provisionedResources.memoryGib, `deployment.spec.targets.${targetName}.provisioning.resources.memoryGib`, 1, 4194304);
|
|
925
|
+
integer(provisionedResources.diskGib, `deployment.spec.targets.${targetName}.provisioning.resources.diskGib`, 1, 1048576);
|
|
926
|
+
integer(provisionedResources.egressGuaranteedMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressGuaranteedMbps`, 0, 1e7);
|
|
927
|
+
integer(provisionedResources.egressBurstMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressBurstMbps`, Number(provisionedResources.egressGuaranteedMbps), 1e7);
|
|
928
|
+
if (typeof provisionedResources.confidential !== "boolean")
|
|
929
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources.confidential`, "must be boolean.");
|
|
930
|
+
if (typeof capacity.cpuCores === "number" && Number(provisionedResources.vcpu) < capacity.cpuCores || typeof capacity.memoryMiB === "number" && Number(provisionedResources.memoryGib) * 1024 < capacity.memoryMiB || typeof capacity.storageGiB === "number" && Number(provisionedResources.diskGib) < capacity.storageGiB) {
|
|
931
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources`, "must satisfy the per-slot allocation minimum.");
|
|
932
|
+
}
|
|
933
|
+
if ((selector.confidentialCompute === "required" || allocation.execution === "oci-kata-qemu-snp") && provisionedResources.confidential !== true)
|
|
934
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources.confidential`, "must be true for confidential execution.");
|
|
935
|
+
if (typeof provisioning.monthlyAmountCents !== "string" || !/^\d{1,18}$/.test(provisioning.monthlyAmountCents))
|
|
936
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.monthlyAmountCents`, "must be a bounded USD-cent amount.");
|
|
920
937
|
if (typeof provisioning.maxMonthlySpendMinor !== "string" || !/^\d{1,18}$/.test(provisioning.maxMonthlySpendMinor))
|
|
921
938
|
fail(`deployment.spec.targets.${targetName}.provisioning.maxMonthlySpendMinor`, "must be a bounded decimal minor-unit amount.");
|
|
922
939
|
}
|
package/dist/deploy-plan.js
CHANGED
|
@@ -910,13 +910,30 @@ function compileDeployment(sourceValue) {
|
|
|
910
910
|
fail(`deployment.spec.targets.${targetName}.allocation.execution`, "cannot satisfy required confidential compute.");
|
|
911
911
|
if (target.provisioning !== undefined) {
|
|
912
912
|
const provisioning = object(target.provisioning, `deployment.spec.targets.${targetName}.provisioning`);
|
|
913
|
-
exact3(provisioning, ["
|
|
914
|
-
for (const key of ["
|
|
913
|
+
exact3(provisioning, ["regionKey", "imageKey", "environmentKey", "ownership", "metalHostname", "resources", "monthlyAmountCents", "maxMonthlySpendMinor"], `deployment.spec.targets.${targetName}.provisioning`);
|
|
914
|
+
for (const key of ["regionKey", "imageKey", "environmentKey"])
|
|
915
915
|
named(provisioning[key], `deployment.spec.targets.${targetName}.provisioning.${key}`);
|
|
916
916
|
if (!["platform", "tenant-metal"].includes(String(provisioning.ownership)) || provisioning.ownership === "tenant-metal" !== Boolean(provisioning.metalHostname))
|
|
917
917
|
fail(`deployment.spec.targets.${targetName}.provisioning.ownership`, "must bind platform capacity or one tenant metal hostname.");
|
|
918
918
|
if (provisioning.metalHostname !== undefined && !/^(?=.{1,253}$)[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/.test(String(provisioning.metalHostname)))
|
|
919
919
|
fail(`deployment.spec.targets.${targetName}.provisioning.metalHostname`, "is invalid.");
|
|
920
|
+
const provisionedResources = object(provisioning.resources, `deployment.spec.targets.${targetName}.provisioning.resources`);
|
|
921
|
+
exact3(provisionedResources, ["physicalCores", "vcpu", "memoryGib", "diskGib", "egressGuaranteedMbps", "egressBurstMbps", "confidential"], `deployment.spec.targets.${targetName}.provisioning.resources`);
|
|
922
|
+
integer(provisionedResources.physicalCores, `deployment.spec.targets.${targetName}.provisioning.resources.physicalCores`, 1, 1024);
|
|
923
|
+
integer(provisionedResources.vcpu, `deployment.spec.targets.${targetName}.provisioning.resources.vcpu`, 1, 4096);
|
|
924
|
+
integer(provisionedResources.memoryGib, `deployment.spec.targets.${targetName}.provisioning.resources.memoryGib`, 1, 4194304);
|
|
925
|
+
integer(provisionedResources.diskGib, `deployment.spec.targets.${targetName}.provisioning.resources.diskGib`, 1, 1048576);
|
|
926
|
+
integer(provisionedResources.egressGuaranteedMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressGuaranteedMbps`, 0, 1e7);
|
|
927
|
+
integer(provisionedResources.egressBurstMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressBurstMbps`, Number(provisionedResources.egressGuaranteedMbps), 1e7);
|
|
928
|
+
if (typeof provisionedResources.confidential !== "boolean")
|
|
929
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources.confidential`, "must be boolean.");
|
|
930
|
+
if (typeof capacity.cpuCores === "number" && Number(provisionedResources.vcpu) < capacity.cpuCores || typeof capacity.memoryMiB === "number" && Number(provisionedResources.memoryGib) * 1024 < capacity.memoryMiB || typeof capacity.storageGiB === "number" && Number(provisionedResources.diskGib) < capacity.storageGiB) {
|
|
931
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources`, "must satisfy the per-slot allocation minimum.");
|
|
932
|
+
}
|
|
933
|
+
if ((selector.confidentialCompute === "required" || allocation.execution === "oci-kata-qemu-snp") && provisionedResources.confidential !== true)
|
|
934
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources.confidential`, "must be true for confidential execution.");
|
|
935
|
+
if (typeof provisioning.monthlyAmountCents !== "string" || !/^\d{1,18}$/.test(provisioning.monthlyAmountCents))
|
|
936
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.monthlyAmountCents`, "must be a bounded USD-cent amount.");
|
|
920
937
|
if (typeof provisioning.maxMonthlySpendMinor !== "string" || !/^\d{1,18}$/.test(provisioning.maxMonthlySpendMinor))
|
|
921
938
|
fail(`deployment.spec.targets.${targetName}.provisioning.maxMonthlySpendMinor`, "must be a bounded decimal minor-unit amount.");
|
|
922
939
|
}
|
package/dist/deploy.d.ts
CHANGED
|
@@ -185,12 +185,21 @@ export interface TargetDefinition {
|
|
|
185
185
|
};
|
|
186
186
|
/** Required only when the control plane may create capacity after reuse is exhausted. */
|
|
187
187
|
provisioning?: {
|
|
188
|
-
planKey: string;
|
|
189
188
|
regionKey: string;
|
|
190
189
|
imageKey: string;
|
|
191
190
|
environmentKey: string;
|
|
192
191
|
ownership: 'platform' | 'tenant-metal';
|
|
193
192
|
metalHostname?: string;
|
|
193
|
+
resources: {
|
|
194
|
+
physicalCores: number;
|
|
195
|
+
vcpu: number;
|
|
196
|
+
memoryGib: number;
|
|
197
|
+
diskGib: number;
|
|
198
|
+
egressGuaranteedMbps: number;
|
|
199
|
+
egressBurstMbps: number;
|
|
200
|
+
confidential: boolean;
|
|
201
|
+
};
|
|
202
|
+
monthlyAmountCents: string;
|
|
194
203
|
maxMonthlySpendMinor: string;
|
|
195
204
|
};
|
|
196
205
|
/** Per-slot connectivity intent. Credential names resolve through the scoped Vault, never to plan values. */
|
package/dist/deployment.d.ts
CHANGED
|
@@ -123,12 +123,21 @@ export interface ResolvedDeploymentTarget {
|
|
|
123
123
|
existing: 'prefer' | 'require';
|
|
124
124
|
};
|
|
125
125
|
provisioning?: {
|
|
126
|
-
planKey: string;
|
|
127
126
|
regionKey: string;
|
|
128
127
|
imageKey: string;
|
|
129
128
|
environmentKey: string;
|
|
130
129
|
ownership: 'platform' | 'tenant-metal';
|
|
131
130
|
metalHostname?: string;
|
|
131
|
+
resources: {
|
|
132
|
+
physicalCores: number;
|
|
133
|
+
vcpu: number;
|
|
134
|
+
memoryGib: number;
|
|
135
|
+
diskGib: number;
|
|
136
|
+
egressGuaranteedMbps: number;
|
|
137
|
+
egressBurstMbps: number;
|
|
138
|
+
confidential: boolean;
|
|
139
|
+
};
|
|
140
|
+
monthlyAmountCents: string;
|
|
132
141
|
maxMonthlySpendMinor: string;
|
|
133
142
|
};
|
|
134
143
|
connectivity?: {
|
package/dist/fz-agent.js
CHANGED
|
@@ -7160,13 +7160,30 @@ function compileDeployment(sourceValue) {
|
|
|
7160
7160
|
fail(`deployment.spec.targets.${targetName}.allocation.execution`, "cannot satisfy required confidential compute.");
|
|
7161
7161
|
if (target.provisioning !== undefined) {
|
|
7162
7162
|
const provisioning = object(target.provisioning, `deployment.spec.targets.${targetName}.provisioning`);
|
|
7163
|
-
exact3(provisioning, ["
|
|
7164
|
-
for (const key of ["
|
|
7163
|
+
exact3(provisioning, ["regionKey", "imageKey", "environmentKey", "ownership", "metalHostname", "resources", "monthlyAmountCents", "maxMonthlySpendMinor"], `deployment.spec.targets.${targetName}.provisioning`);
|
|
7164
|
+
for (const key of ["regionKey", "imageKey", "environmentKey"])
|
|
7165
7165
|
named(provisioning[key], `deployment.spec.targets.${targetName}.provisioning.${key}`);
|
|
7166
7166
|
if (!["platform", "tenant-metal"].includes(String(provisioning.ownership)) || provisioning.ownership === "tenant-metal" !== Boolean(provisioning.metalHostname))
|
|
7167
7167
|
fail(`deployment.spec.targets.${targetName}.provisioning.ownership`, "must bind platform capacity or one tenant metal hostname.");
|
|
7168
7168
|
if (provisioning.metalHostname !== undefined && !/^(?=.{1,253}$)[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/.test(String(provisioning.metalHostname)))
|
|
7169
7169
|
fail(`deployment.spec.targets.${targetName}.provisioning.metalHostname`, "is invalid.");
|
|
7170
|
+
const provisionedResources = object(provisioning.resources, `deployment.spec.targets.${targetName}.provisioning.resources`);
|
|
7171
|
+
exact3(provisionedResources, ["physicalCores", "vcpu", "memoryGib", "diskGib", "egressGuaranteedMbps", "egressBurstMbps", "confidential"], `deployment.spec.targets.${targetName}.provisioning.resources`);
|
|
7172
|
+
integer(provisionedResources.physicalCores, `deployment.spec.targets.${targetName}.provisioning.resources.physicalCores`, 1, 1024);
|
|
7173
|
+
integer(provisionedResources.vcpu, `deployment.spec.targets.${targetName}.provisioning.resources.vcpu`, 1, 4096);
|
|
7174
|
+
integer(provisionedResources.memoryGib, `deployment.spec.targets.${targetName}.provisioning.resources.memoryGib`, 1, 4194304);
|
|
7175
|
+
integer(provisionedResources.diskGib, `deployment.spec.targets.${targetName}.provisioning.resources.diskGib`, 1, 1048576);
|
|
7176
|
+
integer(provisionedResources.egressGuaranteedMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressGuaranteedMbps`, 0, 1e7);
|
|
7177
|
+
integer(provisionedResources.egressBurstMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressBurstMbps`, Number(provisionedResources.egressGuaranteedMbps), 1e7);
|
|
7178
|
+
if (typeof provisionedResources.confidential !== "boolean")
|
|
7179
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources.confidential`, "must be boolean.");
|
|
7180
|
+
if (typeof capacity.cpuCores === "number" && Number(provisionedResources.vcpu) < capacity.cpuCores || typeof capacity.memoryMiB === "number" && Number(provisionedResources.memoryGib) * 1024 < capacity.memoryMiB || typeof capacity.storageGiB === "number" && Number(provisionedResources.diskGib) < capacity.storageGiB) {
|
|
7181
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources`, "must satisfy the per-slot allocation minimum.");
|
|
7182
|
+
}
|
|
7183
|
+
if ((selector.confidentialCompute === "required" || allocation.execution === "oci-kata-qemu-snp") && provisionedResources.confidential !== true)
|
|
7184
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.resources.confidential`, "must be true for confidential execution.");
|
|
7185
|
+
if (typeof provisioning.monthlyAmountCents !== "string" || !/^\d{1,18}$/.test(provisioning.monthlyAmountCents))
|
|
7186
|
+
fail(`deployment.spec.targets.${targetName}.provisioning.monthlyAmountCents`, "must be a bounded USD-cent amount.");
|
|
7170
7187
|
if (typeof provisioning.maxMonthlySpendMinor !== "string" || !/^\d{1,18}$/.test(provisioning.maxMonthlySpendMinor))
|
|
7171
7188
|
fail(`deployment.spec.targets.${targetName}.provisioning.maxMonthlySpendMinor`, "must be a bounded decimal minor-unit amount.");
|
|
7172
7189
|
}
|
|
@@ -9601,7 +9618,7 @@ async function writeAndCloseProcessInput(input, value) {
|
|
|
9601
9618
|
}
|
|
9602
9619
|
|
|
9603
9620
|
// src/version.ts
|
|
9604
|
-
var VERSION2 = "0.1.
|
|
9621
|
+
var VERSION2 = "0.1.118";
|
|
9605
9622
|
|
|
9606
9623
|
// src/ssh-bootstrap.ts
|
|
9607
9624
|
class SshBootstrapError extends Error {
|
package/dist/fz.js
CHANGED
|
@@ -4634,7 +4634,7 @@ var VaultError, runtimeEnvironment = () => typeof process !== "undefined" && pro
|
|
|
4634
4634
|
} catch {
|
|
4635
4635
|
return;
|
|
4636
4636
|
}
|
|
4637
|
-
}, VERSION = "0.1.
|
|
4637
|
+
}, VERSION = "0.1.21";
|
|
4638
4638
|
var init_dist = __esm(() => {
|
|
4639
4639
|
init_identity();
|
|
4640
4640
|
VaultError = class VaultError extends Error {
|
|
@@ -4841,7 +4841,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
|
|
|
4841
4841
|
var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
|
|
4842
4842
|
|
|
4843
4843
|
// src/version.ts
|
|
4844
|
-
var VERSION2 = "0.1.
|
|
4844
|
+
var VERSION2 = "0.1.118";
|
|
4845
4845
|
|
|
4846
4846
|
// src/software.ts
|
|
4847
4847
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -11349,13 +11349,30 @@ function compileDeployment(sourceValue) {
|
|
|
11349
11349
|
fail2(`deployment.spec.targets.${targetName}.allocation.execution`, "cannot satisfy required confidential compute.");
|
|
11350
11350
|
if (target.provisioning !== undefined) {
|
|
11351
11351
|
const provisioning = object(target.provisioning, `deployment.spec.targets.${targetName}.provisioning`);
|
|
11352
|
-
exact3(provisioning, ["
|
|
11353
|
-
for (const key of ["
|
|
11352
|
+
exact3(provisioning, ["regionKey", "imageKey", "environmentKey", "ownership", "metalHostname", "resources", "monthlyAmountCents", "maxMonthlySpendMinor"], `deployment.spec.targets.${targetName}.provisioning`);
|
|
11353
|
+
for (const key of ["regionKey", "imageKey", "environmentKey"])
|
|
11354
11354
|
named(provisioning[key], `deployment.spec.targets.${targetName}.provisioning.${key}`);
|
|
11355
11355
|
if (!["platform", "tenant-metal"].includes(String(provisioning.ownership)) || provisioning.ownership === "tenant-metal" !== Boolean(provisioning.metalHostname))
|
|
11356
11356
|
fail2(`deployment.spec.targets.${targetName}.provisioning.ownership`, "must bind platform capacity or one tenant metal hostname.");
|
|
11357
11357
|
if (provisioning.metalHostname !== undefined && !/^(?=.{1,253}$)[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/.test(String(provisioning.metalHostname)))
|
|
11358
11358
|
fail2(`deployment.spec.targets.${targetName}.provisioning.metalHostname`, "is invalid.");
|
|
11359
|
+
const provisionedResources = object(provisioning.resources, `deployment.spec.targets.${targetName}.provisioning.resources`);
|
|
11360
|
+
exact3(provisionedResources, ["physicalCores", "vcpu", "memoryGib", "diskGib", "egressGuaranteedMbps", "egressBurstMbps", "confidential"], `deployment.spec.targets.${targetName}.provisioning.resources`);
|
|
11361
|
+
integer(provisionedResources.physicalCores, `deployment.spec.targets.${targetName}.provisioning.resources.physicalCores`, 1, 1024);
|
|
11362
|
+
integer(provisionedResources.vcpu, `deployment.spec.targets.${targetName}.provisioning.resources.vcpu`, 1, 4096);
|
|
11363
|
+
integer(provisionedResources.memoryGib, `deployment.spec.targets.${targetName}.provisioning.resources.memoryGib`, 1, 4194304);
|
|
11364
|
+
integer(provisionedResources.diskGib, `deployment.spec.targets.${targetName}.provisioning.resources.diskGib`, 1, 1048576);
|
|
11365
|
+
integer(provisionedResources.egressGuaranteedMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressGuaranteedMbps`, 0, 1e7);
|
|
11366
|
+
integer(provisionedResources.egressBurstMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressBurstMbps`, Number(provisionedResources.egressGuaranteedMbps), 1e7);
|
|
11367
|
+
if (typeof provisionedResources.confidential !== "boolean")
|
|
11368
|
+
fail2(`deployment.spec.targets.${targetName}.provisioning.resources.confidential`, "must be boolean.");
|
|
11369
|
+
if (typeof capacity.cpuCores === "number" && Number(provisionedResources.vcpu) < capacity.cpuCores || typeof capacity.memoryMiB === "number" && Number(provisionedResources.memoryGib) * 1024 < capacity.memoryMiB || typeof capacity.storageGiB === "number" && Number(provisionedResources.diskGib) < capacity.storageGiB) {
|
|
11370
|
+
fail2(`deployment.spec.targets.${targetName}.provisioning.resources`, "must satisfy the per-slot allocation minimum.");
|
|
11371
|
+
}
|
|
11372
|
+
if ((selector.confidentialCompute === "required" || allocation.execution === "oci-kata-qemu-snp") && provisionedResources.confidential !== true)
|
|
11373
|
+
fail2(`deployment.spec.targets.${targetName}.provisioning.resources.confidential`, "must be true for confidential execution.");
|
|
11374
|
+
if (typeof provisioning.monthlyAmountCents !== "string" || !/^\d{1,18}$/.test(provisioning.monthlyAmountCents))
|
|
11375
|
+
fail2(`deployment.spec.targets.${targetName}.provisioning.monthlyAmountCents`, "must be a bounded USD-cent amount.");
|
|
11359
11376
|
if (typeof provisioning.maxMonthlySpendMinor !== "string" || !/^\d{1,18}$/.test(provisioning.maxMonthlySpendMinor))
|
|
11360
11377
|
fail2(`deployment.spec.targets.${targetName}.provisioning.maxMonthlySpendMinor`, "must be a bounded decimal minor-unit amount.");
|
|
11361
11378
|
}
|
|
@@ -11701,13 +11718,24 @@ function initCoordinates(options) {
|
|
|
11701
11718
|
throw new Error("reuse require cannot include provisioning coordinates");
|
|
11702
11719
|
if (options.provisioning !== undefined) {
|
|
11703
11720
|
for (const [label, value] of Object.entries({
|
|
11704
|
-
plan: options.provisioning.planKey,
|
|
11705
11721
|
region: options.provisioning.regionKey,
|
|
11706
11722
|
image: options.provisioning.imageKey,
|
|
11707
11723
|
environment: options.provisioning.environmentKey
|
|
11708
11724
|
}))
|
|
11709
11725
|
if (!/^[a-z][a-z0-9-]{0,62}$/.test(value))
|
|
11710
11726
|
throw new Error(`deployment provisioning ${label} must be a lowercase typed name`);
|
|
11727
|
+
const resources = options.provisioning.resources;
|
|
11728
|
+
for (const [label, value] of Object.entries(resources).filter(([key]) => key !== "confidential")) {
|
|
11729
|
+
if (!Number.isSafeInteger(value) || Number(value) < 0)
|
|
11730
|
+
throw new Error(`deployment provisioning ${label} must be a non-negative integer`);
|
|
11731
|
+
}
|
|
11732
|
+
if (resources.physicalCores < 1 || resources.vcpu < result.cpuCores || resources.memoryGib * 1024 < result.memoryMiB || resources.diskGib < result.storageGiB || resources.egressBurstMbps < resources.egressGuaranteedMbps) {
|
|
11733
|
+
throw new Error("deployment provisioning resources must satisfy the target allocation and bandwidth bounds");
|
|
11734
|
+
}
|
|
11735
|
+
if (result.isolation === "sev-snp" && !resources.confidential)
|
|
11736
|
+
throw new Error("deployment provisioning must provide confidential capacity for sev-snp");
|
|
11737
|
+
if (!/^\d{1,18}$/.test(options.provisioning.monthlyAmountCents))
|
|
11738
|
+
throw new Error("deployment provisioning monthly amount must be a bounded USD-cent amount");
|
|
11711
11739
|
if (!/^\d{1,18}$/.test(options.provisioning.maxMonthlySpendMinor))
|
|
11712
11740
|
throw new Error("deployment provisioning monthly spend must be a bounded decimal minor-unit amount");
|
|
11713
11741
|
if (options.provisioning.ownership === "tenant-metal" && !options.provisioning.metalHostname)
|
|
@@ -11724,7 +11752,7 @@ function defaultTypeScriptDeployment(name, options = {}) {
|
|
|
11724
11752
|
const execution = selected.runtime === "native" ? "native" : selected.runtime === "containerd" ? "oci-runc" : "oci-kata-qemu-snp";
|
|
11725
11753
|
const hostPackageVersion = selected.operatingSystem === "ubuntu-24.04" ? "ubuntu-24.04" : "ubuntu-26.04";
|
|
11726
11754
|
const provisioningBlock = selected.provisioning === undefined ? "" : `,
|
|
11727
|
-
provisioning: {
|
|
11755
|
+
provisioning: { regionKey: '${selected.provisioning.regionKey}', imageKey: '${selected.provisioning.imageKey}', environmentKey: '${selected.provisioning.environmentKey}', ownership: '${selected.provisioning.ownership}',${selected.provisioning.metalHostname ? ` metalHostname: '${selected.provisioning.metalHostname}',` : ""} resources: ${JSON.stringify(selected.provisioning.resources)}, monthlyAmountCents: '${selected.provisioning.monthlyAmountCents}', maxMonthlySpendMinor: '${selected.provisioning.maxMonthlySpendMinor}' }`;
|
|
11728
11756
|
const requirementBlock = selected.runtime === "native" ? `bun: providers.bun.require()` : selected.runtime === "containerd" ? `containerd: providers.containerd.require({ version: '${hostPackageVersion}' }),
|
|
11729
11757
|
nginx: providers.nginx.require({ version: '${hostPackageVersion}' })` : `containerd: providers.containerd.require(),
|
|
11730
11758
|
kata: providers.kata.require(),
|
|
@@ -12383,9 +12411,6 @@ function validatePlatformSharedEnvironment(input) {
|
|
|
12383
12411
|
} else if (input.email !== undefined) {
|
|
12384
12412
|
throw new Error("Bootstrap email provider must be smtp or jetemail.");
|
|
12385
12413
|
}
|
|
12386
|
-
if (!input.githubOAuth || !/^(?:Iv1\.[A-Fa-f0-9]{16}|Ov23li[A-Za-z0-9]{14,})$/.test(input.githubOAuth.clientId)) {
|
|
12387
|
-
throw new Error("GitHub OAuth client id is malformed.");
|
|
12388
|
-
}
|
|
12389
12414
|
boundedInteger("publicApiPort", input.publicApiPort, 1024, 65533);
|
|
12390
12415
|
if (!Array.isArray(input.seedSyncMembers) || input.seedSyncMembers.length < 3 || input.seedSyncMembers.length > 64 || new Set(input.seedSyncMembers).size !== input.seedSyncMembers.length) {
|
|
12391
12416
|
throw new Error("seedSyncMembers must contain 3 to 64 unique physical host identities.");
|
|
@@ -12516,7 +12541,6 @@ function renderPlatformSharedEnvironment(input) {
|
|
|
12516
12541
|
FZ_REALTIME_WORKER_SCRIPT: value.realtime?.workerScriptName ?? "",
|
|
12517
12542
|
FZ_REALTIME_ENDPOINT: value.realtime?.endpoint ?? "",
|
|
12518
12543
|
FZ_REALTIME_PRODUCER: value.realtime?.producer ?? "",
|
|
12519
|
-
FZ_GITHUB_OAUTH_CLIENT_ID: value.githubOAuth.clientId,
|
|
12520
12544
|
FZ_PLATFORM_INITIAL_INVENTORY: value.initialInventory ? JSON.stringify(value.initialInventory) : ""
|
|
12521
12545
|
};
|
|
12522
12546
|
return `# Generated by fz bootstrap platform. Non-secret coordinates only.
|
|
@@ -12528,7 +12552,6 @@ function platformApiCredentialSpecs(options) {
|
|
|
12528
12552
|
const optional = [
|
|
12529
12553
|
["fz_smtp.password", options.emailProvider === "smtp"],
|
|
12530
12554
|
["fz_jetemail.apiKey", options.emailProvider === "jetemail"],
|
|
12531
|
-
["fz_oauth.github.clientSecret", options.githubOAuth],
|
|
12532
12555
|
["CF_API_TOKEN", options.cloudflareKv],
|
|
12533
12556
|
["CF_TUNNEL_TOKEN", options.cloudflareKv],
|
|
12534
12557
|
["REALTIME_PUBLISH_SECRET", options.realtime],
|
|
@@ -14201,15 +14224,7 @@ function validatePlatformBootstrapSecrets(config, input) {
|
|
|
14201
14224
|
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
14202
14225
|
throw new Error("bootstrap credential input must be an object");
|
|
14203
14226
|
const source = input;
|
|
14204
|
-
const allowed = [
|
|
14205
|
-
"clusterBootstrapCode",
|
|
14206
|
-
"emailSecret",
|
|
14207
|
-
"enrolmentToken",
|
|
14208
|
-
"backupS3Secret",
|
|
14209
|
-
"cloudflareTunnelToken",
|
|
14210
|
-
"cloudflareApiToken",
|
|
14211
|
-
"githubOAuthClientSecret"
|
|
14212
|
-
];
|
|
14227
|
+
const allowed = ["clusterBootstrapCode", "emailSecret", "enrolmentToken", "backupS3Secret", "cloudflareTunnelToken", "cloudflareApiToken"];
|
|
14213
14228
|
const unknown = Object.keys(source).filter((key) => !allowed.includes(key));
|
|
14214
14229
|
if (unknown.length)
|
|
14215
14230
|
throw new Error(`bootstrap credential input contains unsupported field ${unknown[0]}`);
|
|
@@ -14219,7 +14234,6 @@ function validatePlatformBootstrapSecrets(config, input) {
|
|
|
14219
14234
|
const backupS3Secret = typeof source.backupS3Secret === "string" ? source.backupS3Secret.trim() : undefined;
|
|
14220
14235
|
const cloudflareTunnelToken = typeof source.cloudflareTunnelToken === "string" ? source.cloudflareTunnelToken.trim() : undefined;
|
|
14221
14236
|
const cloudflareApiToken = typeof source.cloudflareApiToken === "string" ? source.cloudflareApiToken.trim() : undefined;
|
|
14222
|
-
const githubOAuthClientSecret = typeof source.githubOAuthClientSecret === "string" ? source.githubOAuthClientSecret.trim() : "";
|
|
14223
14237
|
if (!/^[a-f0-9]{64}$/i.test(clusterBootstrapCode))
|
|
14224
14238
|
throw new Error("cluster bootstrap code must contain exactly 64 hexadecimal characters");
|
|
14225
14239
|
if (!emailSecret || emailSecret.length > 16384 || /[\r\n\0]/.test(emailSecret))
|
|
@@ -14239,16 +14253,12 @@ function validatePlatformBootstrapSecrets(config, input) {
|
|
|
14239
14253
|
}
|
|
14240
14254
|
if (cloudflareTunnelToken)
|
|
14241
14255
|
validateCloudflareBootstrapSecretPair({ cloudflareTunnelToken, cloudflareApiToken });
|
|
14242
|
-
if (githubOAuthClientSecret.length < 20 || githubOAuthClientSecret.length > 512 || /[\r\n\0]/.test(githubOAuthClientSecret)) {
|
|
14243
|
-
throw new Error("GitHub OAuth client secret is malformed");
|
|
14244
|
-
}
|
|
14245
14256
|
return {
|
|
14246
14257
|
clusterBootstrapCode,
|
|
14247
14258
|
emailSecret,
|
|
14248
14259
|
...enrolmentToken ? { enrolmentToken } : {},
|
|
14249
14260
|
...backupS3Secret ? { backupS3Secret } : {},
|
|
14250
|
-
...cloudflareTunnelToken ? { cloudflareTunnelToken, cloudflareApiToken } : {}
|
|
14251
|
-
githubOAuthClientSecret
|
|
14261
|
+
...cloudflareTunnelToken ? { cloudflareTunnelToken, cloudflareApiToken } : {}
|
|
14252
14262
|
};
|
|
14253
14263
|
}
|
|
14254
14264
|
var platformBootstrapRunner = (config) => config.kind === "platform" && config.database.role === "master";
|
|
@@ -15171,8 +15181,7 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
15171
15181
|
enrolmentToken: checked4.enrolmentToken,
|
|
15172
15182
|
backup: checked4.backupS3Secret,
|
|
15173
15183
|
cloudflareTunnelToken: checked4.cloudflareTunnelToken,
|
|
15174
|
-
cloudflareApiToken: checked4.cloudflareApiToken
|
|
15175
|
-
githubOAuthClientSecret: checked4.githubOAuthClientSecret
|
|
15184
|
+
cloudflareApiToken: checked4.cloudflareApiToken
|
|
15176
15185
|
};
|
|
15177
15186
|
})() : undefined;
|
|
15178
15187
|
const enrolledPrivate = config.kind === "enrolled-compute" ? validateEnrolledComputeBootstrapSecrets(config, secrets) : undefined;
|
|
@@ -15273,7 +15282,6 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
15273
15282
|
const emailCredentialName = config.runtime.environment.email?.provider === "smtp" ? "fz_smtp.password" : config.runtime.environment.email?.provider === "jetemail" ? "fz_jetemail.apiKey" : undefined;
|
|
15274
15283
|
for (const [name, source] of Object.entries({
|
|
15275
15284
|
...emailCredentialName ? { [emailCredentialName]: platformPrivate.email } : {},
|
|
15276
|
-
"fz_oauth.github.clientSecret": platformPrivate.githubOAuthClientSecret,
|
|
15277
15285
|
"backup.s3.secretAccessKey": platformPrivate.backup
|
|
15278
15286
|
})) {
|
|
15279
15287
|
if (source) {
|
|
@@ -15290,7 +15298,6 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
15290
15298
|
const credentials = platformApiCredentialSpecs({
|
|
15291
15299
|
emailProvider: runtime.environment.email?.provider,
|
|
15292
15300
|
cloudflareKv: cloudflareConfigured,
|
|
15293
|
-
githubOAuth: true,
|
|
15294
15301
|
realtime: Boolean(runtime.environment.realtime)
|
|
15295
15302
|
});
|
|
15296
15303
|
const units = renderPlatformApiUnits({
|
|
@@ -15538,7 +15545,6 @@ function strictBootstrapDocument(value) {
|
|
|
15538
15545
|
"agentOtlpEndpoint",
|
|
15539
15546
|
"custodianEmail",
|
|
15540
15547
|
"email",
|
|
15541
|
-
"githubOAuth",
|
|
15542
15548
|
"deployProfile",
|
|
15543
15549
|
"otlpFlushIntervalMs",
|
|
15544
15550
|
"otlpTraceSampleRatio",
|
|
@@ -15549,7 +15555,6 @@ function strictBootstrapDocument(value) {
|
|
|
15549
15555
|
"databaseReadPreferredCoordinators"
|
|
15550
15556
|
], "runtime environment");
|
|
15551
15557
|
const environment = runtime.environment;
|
|
15552
|
-
exactKeys2(environment.githubOAuth, ["clientId"], "GitHub OAuth config");
|
|
15553
15558
|
if (environment.initialInventory !== undefined) {
|
|
15554
15559
|
const inventory = exactKeys2(environment.initialInventory, ["metalHostname", "metalIdentity", "region", "computes", "attestation", "deployment"], "initial inventory");
|
|
15555
15560
|
if (inventory.metalIdentity !== undefined) {
|
|
@@ -18263,7 +18268,6 @@ function forgeZeroLaunchTemplate(profile, guests, bundle, owner) {
|
|
|
18263
18268
|
otlpTraceSampleRatio: 0.1,
|
|
18264
18269
|
custodianEmail: owner.custodianEmail,
|
|
18265
18270
|
email: owner.email,
|
|
18266
|
-
githubOAuth: owner.githubOAuth,
|
|
18267
18271
|
deployProfile: profile.environment
|
|
18268
18272
|
},
|
|
18269
18273
|
serviceUser: "forgezero-api",
|
|
@@ -18651,18 +18655,15 @@ function readPlatformLaunchEnvironment(path) {
|
|
|
18651
18655
|
throw new Error(`bootstrap secret environment is missing ${name}`);
|
|
18652
18656
|
return value;
|
|
18653
18657
|
};
|
|
18654
|
-
const githubOAuth = { clientId: requiredValue("FZ_GITHUB_OAUTH_CLIENT_ID") };
|
|
18655
18658
|
const owner = {
|
|
18656
18659
|
custodianEmail: "info@axxra.in",
|
|
18657
|
-
email: { provider: "jetemail", from: "noreply@forgezero.net", eu: false }
|
|
18658
|
-
githubOAuth
|
|
18660
|
+
email: { provider: "jetemail", from: "noreply@forgezero.net", eu: false }
|
|
18659
18661
|
};
|
|
18660
18662
|
return {
|
|
18661
18663
|
owner,
|
|
18662
18664
|
emailSecret: requiredValue("FZ_JETEMAIL_API_KEY"),
|
|
18663
18665
|
cloudflareTunnelToken: requiredValue("CF_TUNNEL_TOKEN"),
|
|
18664
|
-
cloudflareApiToken: requiredValue("CF_API_TOKEN")
|
|
18665
|
-
githubOAuthClientSecret: requiredValue("FZ_GITHUB_OAUTH_CLIENT_SECRET")
|
|
18666
|
+
cloudflareApiToken: requiredValue("CF_API_TOKEN")
|
|
18666
18667
|
};
|
|
18667
18668
|
}
|
|
18668
18669
|
|
|
@@ -18798,9 +18799,6 @@ function parseOptions(argv2) {
|
|
|
18798
18799
|
options.deployReuse = value;
|
|
18799
18800
|
else
|
|
18800
18801
|
options.optionError = "--reuse must be require or prefer.";
|
|
18801
|
-
} else if (token === "--provision-plan") {
|
|
18802
|
-
options.deployProvisionPlan = argv2[++index];
|
|
18803
|
-
options.deployInitCustomized = true;
|
|
18804
18802
|
} else if (token === "--provision-region") {
|
|
18805
18803
|
options.deployProvisionRegion = argv2[++index];
|
|
18806
18804
|
options.deployInitCustomized = true;
|
|
@@ -18820,6 +18818,26 @@ function parseOptions(argv2) {
|
|
|
18820
18818
|
} else if (token === "--provision-metal") {
|
|
18821
18819
|
options.deployProvisionMetal = argv2[++index];
|
|
18822
18820
|
options.deployInitCustomized = true;
|
|
18821
|
+
} else if (["--provision-physical-cores", "--provision-vcpu", "--provision-memory-gib", "--provision-disk-gib", "--provision-guaranteed-mbps", "--provision-burst-mbps"].includes(token)) {
|
|
18822
|
+
const value = Number(argv2[++index] ?? "");
|
|
18823
|
+
options.deployInitCustomized = true;
|
|
18824
|
+
if (!Number.isSafeInteger(value) || value < 0)
|
|
18825
|
+
options.optionError = `${token} must be a non-negative integer.`;
|
|
18826
|
+
else if (token === "--provision-physical-cores")
|
|
18827
|
+
options.deployProvisionPhysicalCores = value;
|
|
18828
|
+
else if (token === "--provision-vcpu")
|
|
18829
|
+
options.deployProvisionVcpu = value;
|
|
18830
|
+
else if (token === "--provision-memory-gib")
|
|
18831
|
+
options.deployProvisionMemoryGib = value;
|
|
18832
|
+
else if (token === "--provision-disk-gib")
|
|
18833
|
+
options.deployProvisionDiskGib = value;
|
|
18834
|
+
else if (token === "--provision-guaranteed-mbps")
|
|
18835
|
+
options.deployProvisionGuaranteedMbps = value;
|
|
18836
|
+
else
|
|
18837
|
+
options.deployProvisionBurstMbps = value;
|
|
18838
|
+
} else if (token === "--provision-monthly-amount-cents") {
|
|
18839
|
+
options.deployProvisionMonthlyAmountCents = argv2[++index];
|
|
18840
|
+
options.deployInitCustomized = true;
|
|
18823
18841
|
} else if (token === "--max-monthly-spend-minor") {
|
|
18824
18842
|
options.deployMaxMonthlySpendMinor = argv2[++index];
|
|
18825
18843
|
options.deployInitCustomized = true;
|
|
@@ -19488,8 +19506,7 @@ async function promptPlatformBootstrapSecrets(config, generatedClusterBootstrapC
|
|
|
19488
19506
|
...config.cloudflareHandoff || config.runtime.environment.cloudflare ? {
|
|
19489
19507
|
cloudflareTunnelToken: await bootstrapSecret("CF_TUNNEL_TOKEN"),
|
|
19490
19508
|
cloudflareApiToken: await bootstrapSecret("CF_API_TOKEN")
|
|
19491
|
-
} : {}
|
|
19492
|
-
githubOAuthClientSecret: await bootstrapSecret("GitHub OAuth client secret")
|
|
19509
|
+
} : {}
|
|
19493
19510
|
});
|
|
19494
19511
|
}
|
|
19495
19512
|
var bootstrapList = (question, fallback) => bootstrapAnswer(question, fallback).split(",").map((value) => value.trim()).filter(Boolean);
|
|
@@ -19787,11 +19804,9 @@ function selectedForgeZeroLaunchEnvironment(value) {
|
|
|
19787
19804
|
return value;
|
|
19788
19805
|
}
|
|
19789
19806
|
function forgeZeroLaunchOwnerInput() {
|
|
19790
|
-
const githubOAuth = { clientId: bootstrapAnswer("GitHub OAuth client ID") };
|
|
19791
19807
|
return {
|
|
19792
19808
|
custodianEmail: "info@axxra.in",
|
|
19793
|
-
email: { provider: "jetemail", from: "noreply@forgezero.net", eu: false }
|
|
19794
|
-
githubOAuth
|
|
19809
|
+
email: { provider: "jetemail", from: "noreply@forgezero.net", eu: false }
|
|
19795
19810
|
};
|
|
19796
19811
|
}
|
|
19797
19812
|
async function prepareForgeZeroPlatformLaunch(environment, outputDirectory, projectRoot, owner) {
|
|
@@ -19860,7 +19875,6 @@ function interactiveBootstrap(kind, genesisGuests, genesisCloudflareCheckpoint)
|
|
|
19860
19875
|
const backupRegion = backupEndpoint ? bootstrapAnswer("Backup S3 region") : undefined;
|
|
19861
19876
|
const backupBucket = backupEndpoint ? bootstrapAnswer("Backup S3 bucket") : undefined;
|
|
19862
19877
|
const backupAccessKeyId = backupEndpoint ? bootstrapAnswer("Backup S3 access-key id") : undefined;
|
|
19863
|
-
const githubOAuthClientId = bootstrapAnswer("GitHub OAuth client ID");
|
|
19864
19878
|
const cloudflareHandoffFile = genesis ? cloudflareHostHandoffPath(genesisCloudflareCheckpoint, computeReference) : bootstrapAnswer("Node-specific Cloudflare host handoff (blank for no public edge)", "");
|
|
19865
19879
|
const cloudflareNodeName = cloudflareHandoffFile ? genesis ? computeReference : bootstrapAnswer("Cloudflare handoff node name", computeReference) : undefined;
|
|
19866
19880
|
const databaseNetworkMode = "private-lan";
|
|
@@ -19915,7 +19929,6 @@ function interactiveBootstrap(kind, genesisGuests, genesisCloudflareCheckpoint)
|
|
|
19915
19929
|
otlpTraceSampleRatio: 0.1,
|
|
19916
19930
|
custodianEmail: role === "master" ? bootstrapAnswer("First custodian email") : undefined,
|
|
19917
19931
|
email: emailProvider === "smtp" ? { provider: "smtp", host: smtpHost, port: smtpPort, user: smtpUser, from: emailFrom } : { provider: "jetemail", from: emailFrom, eu: jetemailEu },
|
|
19918
|
-
githubOAuth: { clientId: githubOAuthClientId },
|
|
19919
19932
|
...backupEndpoint && backupRegion && backupBucket && backupAccessKeyId ? {
|
|
19920
19933
|
backup: { endpoint: backupEndpoint, region: backupRegion, bucket: backupBucket, accessKeyId: backupAccessKeyId }
|
|
19921
19934
|
} : {},
|
|
@@ -19975,8 +19988,7 @@ async function runAttendedPlatformFleet(fleet, apply, generatedClusterBootstrapC
|
|
|
19975
19988
|
clusterBootstrapCode: generatedClusterBootstrapCode,
|
|
19976
19989
|
emailSecret: environmentInput.emailSecret,
|
|
19977
19990
|
cloudflareTunnelToken: environmentInput.cloudflareTunnelToken,
|
|
19978
|
-
cloudflareApiToken: environmentInput.cloudflareApiToken
|
|
19979
|
-
githubOAuthClientSecret: environmentInput.githubOAuthClientSecret
|
|
19991
|
+
cloudflareApiToken: environmentInput.cloudflareApiToken
|
|
19980
19992
|
}) : await promptPlatformBootstrapSecrets(firstConfig, generatedClusterBootstrapCode);
|
|
19981
19993
|
const cloudflare = await resolveCloudflareBootstrapCommandConfig(fleet.cloudflareConfigFile, {
|
|
19982
19994
|
tunnelToken: secrets.cloudflareTunnelToken,
|
|
@@ -20614,20 +20626,35 @@ async function cmdDeploy(options, args) {
|
|
|
20614
20626
|
reuse: options.deployReuse,
|
|
20615
20627
|
profile: options.deployProfile,
|
|
20616
20628
|
...[
|
|
20617
|
-
options.deployProvisionPlan,
|
|
20618
20629
|
options.deployProvisionRegion,
|
|
20619
20630
|
options.deployProvisionImage,
|
|
20620
20631
|
options.deployProvisionEnvironment,
|
|
20621
20632
|
options.deployProvisionOwnership,
|
|
20633
|
+
options.deployProvisionPhysicalCores,
|
|
20634
|
+
options.deployProvisionVcpu,
|
|
20635
|
+
options.deployProvisionMemoryGib,
|
|
20636
|
+
options.deployProvisionDiskGib,
|
|
20637
|
+
options.deployProvisionGuaranteedMbps,
|
|
20638
|
+
options.deployProvisionBurstMbps,
|
|
20639
|
+
options.deployProvisionMonthlyAmountCents,
|
|
20622
20640
|
options.deployMaxMonthlySpendMinor
|
|
20623
20641
|
].some((value) => value !== undefined) ? {
|
|
20624
20642
|
provisioning: {
|
|
20625
|
-
planKey: options.deployProvisionPlan ?? "",
|
|
20626
20643
|
regionKey: options.deployProvisionRegion ?? "",
|
|
20627
20644
|
imageKey: options.deployProvisionImage ?? "",
|
|
20628
20645
|
environmentKey: options.deployProvisionEnvironment ?? "",
|
|
20629
20646
|
ownership: options.deployProvisionOwnership ?? "platform",
|
|
20630
20647
|
...options.deployProvisionMetal ? { metalHostname: options.deployProvisionMetal } : {},
|
|
20648
|
+
resources: {
|
|
20649
|
+
physicalCores: options.deployProvisionPhysicalCores ?? 0,
|
|
20650
|
+
vcpu: options.deployProvisionVcpu ?? 0,
|
|
20651
|
+
memoryGib: options.deployProvisionMemoryGib ?? 0,
|
|
20652
|
+
diskGib: options.deployProvisionDiskGib ?? 0,
|
|
20653
|
+
egressGuaranteedMbps: options.deployProvisionGuaranteedMbps ?? 0,
|
|
20654
|
+
egressBurstMbps: options.deployProvisionBurstMbps ?? 0,
|
|
20655
|
+
confidential: options.deployIsolation === "sev-snp"
|
|
20656
|
+
},
|
|
20657
|
+
monthlyAmountCents: options.deployProvisionMonthlyAmountCents ?? "",
|
|
20631
20658
|
maxMonthlySpendMinor: options.deployMaxMonthlySpendMinor ?? ""
|
|
20632
20659
|
}
|
|
20633
20660
|
} : {}
|
|
@@ -20966,9 +20993,13 @@ function usage() {
|
|
|
20966
20993
|
--storage-gib <n> Reserved storage GiB per compute
|
|
20967
20994
|
--sharing <mode> exclusive or shared (native requires exclusive)
|
|
20968
20995
|
--reuse <mode> require existing capacity or prefer reuse then approved provisioning
|
|
20969
|
-
--provision-
|
|
20996
|
+
--provision-region <key> --provision-image <key>
|
|
20970
20997
|
--provision-environment <key> --provision-ownership <platform|tenant-metal>
|
|
20971
20998
|
--provision-metal <host> Required only for tenant-metal ownership
|
|
20999
|
+
--provision-physical-cores <n> --provision-vcpu <n>
|
|
21000
|
+
--provision-memory-gib <n> --provision-disk-gib <n>
|
|
21001
|
+
--provision-guaranteed-mbps <n> --provision-burst-mbps <n>
|
|
21002
|
+
--provision-monthly-amount-cents <n> Exact approved USD cost per created compute
|
|
20972
21003
|
--max-monthly-spend-minor <n> Hard approved scale-out spend ceiling
|
|
20973
21004
|
--force Init may replace an existing generated target
|
|
20974
21005
|
|
package/dist/metal-bootstrap.js
CHANGED
|
@@ -366,7 +366,7 @@ function systemdAgentEgressDirectives(loopbackTcpPorts = []) {
|
|
|
366
366
|
}
|
|
367
367
|
|
|
368
368
|
// src/version.ts
|
|
369
|
-
var VERSION = "0.1.
|
|
369
|
+
var VERSION = "0.1.118";
|
|
370
370
|
|
|
371
371
|
// src/otel-collector.ts
|
|
372
372
|
var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
|
|
@@ -8,7 +8,7 @@ export interface MetalCpuPool {
|
|
|
8
8
|
key: string;
|
|
9
9
|
/** Linux CPU-list syntax, including every SMT sibling in this pool. */
|
|
10
10
|
cpus: string;
|
|
11
|
-
/** Real cores represented by cpus; checked against the
|
|
11
|
+
/** Real cores represented by cpus; checked against the sellable capacity promise. */
|
|
12
12
|
physicalCores: number;
|
|
13
13
|
/** Linux NUMA node-list syntax. Optional on a non-NUMA machine. */
|
|
14
14
|
memoryNodes?: string;
|
|
@@ -1460,7 +1460,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
|
|
|
1460
1460
|
var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
|
|
1461
1461
|
|
|
1462
1462
|
// src/version.ts
|
|
1463
|
-
var VERSION = "0.1.
|
|
1463
|
+
var VERSION = "0.1.118";
|
|
1464
1464
|
|
|
1465
1465
|
// src/software.ts
|
|
1466
1466
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -3272,9 +3272,6 @@ function validatePlatformSharedEnvironment(input) {
|
|
|
3272
3272
|
} else if (input.email !== undefined) {
|
|
3273
3273
|
throw new Error("Bootstrap email provider must be smtp or jetemail.");
|
|
3274
3274
|
}
|
|
3275
|
-
if (!input.githubOAuth || !/^(?:Iv1\.[A-Fa-f0-9]{16}|Ov23li[A-Za-z0-9]{14,})$/.test(input.githubOAuth.clientId)) {
|
|
3276
|
-
throw new Error("GitHub OAuth client id is malformed.");
|
|
3277
|
-
}
|
|
3278
3275
|
boundedInteger("publicApiPort", input.publicApiPort, 1024, 65533);
|
|
3279
3276
|
if (!Array.isArray(input.seedSyncMembers) || input.seedSyncMembers.length < 3 || input.seedSyncMembers.length > 64 || new Set(input.seedSyncMembers).size !== input.seedSyncMembers.length) {
|
|
3280
3277
|
throw new Error("seedSyncMembers must contain 3 to 64 unique physical host identities.");
|
|
@@ -3405,7 +3402,6 @@ function renderPlatformSharedEnvironment(input) {
|
|
|
3405
3402
|
FZ_REALTIME_WORKER_SCRIPT: value.realtime?.workerScriptName ?? "",
|
|
3406
3403
|
FZ_REALTIME_ENDPOINT: value.realtime?.endpoint ?? "",
|
|
3407
3404
|
FZ_REALTIME_PRODUCER: value.realtime?.producer ?? "",
|
|
3408
|
-
FZ_GITHUB_OAUTH_CLIENT_ID: value.githubOAuth.clientId,
|
|
3409
3405
|
FZ_PLATFORM_INITIAL_INVENTORY: value.initialInventory ? JSON.stringify(value.initialInventory) : ""
|
|
3410
3406
|
};
|
|
3411
3407
|
return `# Generated by fz bootstrap platform. Non-secret coordinates only.
|
|
@@ -3417,7 +3413,6 @@ function platformApiCredentialSpecs(options) {
|
|
|
3417
3413
|
const optional = [
|
|
3418
3414
|
["fz_smtp.password", options.emailProvider === "smtp"],
|
|
3419
3415
|
["fz_jetemail.apiKey", options.emailProvider === "jetemail"],
|
|
3420
|
-
["fz_oauth.github.clientSecret", options.githubOAuth],
|
|
3421
3416
|
["CF_API_TOKEN", options.cloudflareKv],
|
|
3422
3417
|
["CF_TUNNEL_TOKEN", options.cloudflareKv],
|
|
3423
3418
|
["REALTIME_PUBLISH_SECRET", options.realtime],
|
|
@@ -3814,15 +3809,7 @@ function validatePlatformBootstrapSecrets(config, input) {
|
|
|
3814
3809
|
if (!input || typeof input !== "object" || Array.isArray(input))
|
|
3815
3810
|
throw new Error("bootstrap credential input must be an object");
|
|
3816
3811
|
const source = input;
|
|
3817
|
-
const allowed = [
|
|
3818
|
-
"clusterBootstrapCode",
|
|
3819
|
-
"emailSecret",
|
|
3820
|
-
"enrolmentToken",
|
|
3821
|
-
"backupS3Secret",
|
|
3822
|
-
"cloudflareTunnelToken",
|
|
3823
|
-
"cloudflareApiToken",
|
|
3824
|
-
"githubOAuthClientSecret"
|
|
3825
|
-
];
|
|
3812
|
+
const allowed = ["clusterBootstrapCode", "emailSecret", "enrolmentToken", "backupS3Secret", "cloudflareTunnelToken", "cloudflareApiToken"];
|
|
3826
3813
|
const unknown = Object.keys(source).filter((key) => !allowed.includes(key));
|
|
3827
3814
|
if (unknown.length)
|
|
3828
3815
|
throw new Error(`bootstrap credential input contains unsupported field ${unknown[0]}`);
|
|
@@ -3832,7 +3819,6 @@ function validatePlatformBootstrapSecrets(config, input) {
|
|
|
3832
3819
|
const backupS3Secret = typeof source.backupS3Secret === "string" ? source.backupS3Secret.trim() : undefined;
|
|
3833
3820
|
const cloudflareTunnelToken = typeof source.cloudflareTunnelToken === "string" ? source.cloudflareTunnelToken.trim() : undefined;
|
|
3834
3821
|
const cloudflareApiToken = typeof source.cloudflareApiToken === "string" ? source.cloudflareApiToken.trim() : undefined;
|
|
3835
|
-
const githubOAuthClientSecret = typeof source.githubOAuthClientSecret === "string" ? source.githubOAuthClientSecret.trim() : "";
|
|
3836
3822
|
if (!/^[a-f0-9]{64}$/i.test(clusterBootstrapCode))
|
|
3837
3823
|
throw new Error("cluster bootstrap code must contain exactly 64 hexadecimal characters");
|
|
3838
3824
|
if (!emailSecret || emailSecret.length > 16384 || /[\r\n\0]/.test(emailSecret))
|
|
@@ -3852,16 +3838,12 @@ function validatePlatformBootstrapSecrets(config, input) {
|
|
|
3852
3838
|
}
|
|
3853
3839
|
if (cloudflareTunnelToken)
|
|
3854
3840
|
validateCloudflareBootstrapSecretPair({ cloudflareTunnelToken, cloudflareApiToken });
|
|
3855
|
-
if (githubOAuthClientSecret.length < 20 || githubOAuthClientSecret.length > 512 || /[\r\n\0]/.test(githubOAuthClientSecret)) {
|
|
3856
|
-
throw new Error("GitHub OAuth client secret is malformed");
|
|
3857
|
-
}
|
|
3858
3841
|
return {
|
|
3859
3842
|
clusterBootstrapCode,
|
|
3860
3843
|
emailSecret,
|
|
3861
3844
|
...enrolmentToken ? { enrolmentToken } : {},
|
|
3862
3845
|
...backupS3Secret ? { backupS3Secret } : {},
|
|
3863
|
-
...cloudflareTunnelToken ? { cloudflareTunnelToken, cloudflareApiToken } : {}
|
|
3864
|
-
githubOAuthClientSecret
|
|
3846
|
+
...cloudflareTunnelToken ? { cloudflareTunnelToken, cloudflareApiToken } : {}
|
|
3865
3847
|
};
|
|
3866
3848
|
}
|
|
3867
3849
|
var platformBootstrapRunner = (config) => config.kind === "platform" && config.database.role === "master";
|
|
@@ -4784,8 +4766,7 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4784
4766
|
enrolmentToken: checked4.enrolmentToken,
|
|
4785
4767
|
backup: checked4.backupS3Secret,
|
|
4786
4768
|
cloudflareTunnelToken: checked4.cloudflareTunnelToken,
|
|
4787
|
-
cloudflareApiToken: checked4.cloudflareApiToken
|
|
4788
|
-
githubOAuthClientSecret: checked4.githubOAuthClientSecret
|
|
4769
|
+
cloudflareApiToken: checked4.cloudflareApiToken
|
|
4789
4770
|
};
|
|
4790
4771
|
})() : undefined;
|
|
4791
4772
|
const enrolledPrivate = config.kind === "enrolled-compute" ? validateEnrolledComputeBootstrapSecrets(config, secrets) : undefined;
|
|
@@ -4886,7 +4867,6 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4886
4867
|
const emailCredentialName = config.runtime.environment.email?.provider === "smtp" ? "fz_smtp.password" : config.runtime.environment.email?.provider === "jetemail" ? "fz_jetemail.apiKey" : undefined;
|
|
4887
4868
|
for (const [name, source] of Object.entries({
|
|
4888
4869
|
...emailCredentialName ? { [emailCredentialName]: platformPrivate.email } : {},
|
|
4889
|
-
"fz_oauth.github.clientSecret": platformPrivate.githubOAuthClientSecret,
|
|
4890
4870
|
"backup.s3.secretAccessKey": platformPrivate.backup
|
|
4891
4871
|
})) {
|
|
4892
4872
|
if (source) {
|
|
@@ -4903,7 +4883,6 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4903
4883
|
const credentials = platformApiCredentialSpecs({
|
|
4904
4884
|
emailProvider: runtime.environment.email?.provider,
|
|
4905
4885
|
cloudflareKv: cloudflareConfigured,
|
|
4906
|
-
githubOAuth: true,
|
|
4907
4886
|
realtime: Boolean(runtime.environment.realtime)
|
|
4908
4887
|
});
|
|
4909
4888
|
const units = renderPlatformApiUnits({
|
|
@@ -5151,7 +5130,6 @@ function strictBootstrapDocument(value) {
|
|
|
5151
5130
|
"agentOtlpEndpoint",
|
|
5152
5131
|
"custodianEmail",
|
|
5153
5132
|
"email",
|
|
5154
|
-
"githubOAuth",
|
|
5155
5133
|
"deployProfile",
|
|
5156
5134
|
"otlpFlushIntervalMs",
|
|
5157
5135
|
"otlpTraceSampleRatio",
|
|
@@ -5162,7 +5140,6 @@ function strictBootstrapDocument(value) {
|
|
|
5162
5140
|
"databaseReadPreferredCoordinators"
|
|
5163
5141
|
], "runtime environment");
|
|
5164
5142
|
const environment = runtime.environment;
|
|
5165
|
-
exactKeys(environment.githubOAuth, ["clientId"], "GitHub OAuth config");
|
|
5166
5143
|
if (environment.initialInventory !== undefined) {
|
|
5167
5144
|
const inventory = exactKeys(environment.initialInventory, ["metalHostname", "metalIdentity", "region", "computes", "attestation", "deployment"], "initial inventory");
|
|
5168
5145
|
if (inventory.metalIdentity !== undefined) {
|
|
@@ -68,14 +68,6 @@ export type PlatformBootstrapEmail = {
|
|
|
68
68
|
from: string;
|
|
69
69
|
eu: boolean;
|
|
70
70
|
};
|
|
71
|
-
/**
|
|
72
|
-
* Public coordinates for one GitHub App. Its client secret, RSA private key and
|
|
73
|
-
* webhook secret are attended inputs sealed as systemd credentials and later
|
|
74
|
-
* imported into the unlocked platform Vault.
|
|
75
|
-
*/
|
|
76
|
-
export interface PlatformBootstrapGitHubOAuth {
|
|
77
|
-
clientId: string;
|
|
78
|
-
}
|
|
79
71
|
export interface PlatformSharedEnvironment {
|
|
80
72
|
softwareProfile: PlatformSoftwareProfile;
|
|
81
73
|
databaseRole: PlatformDatabaseRole;
|
|
@@ -107,7 +99,6 @@ export interface PlatformSharedEnvironment {
|
|
|
107
99
|
otlpTraceSampleRatio: number;
|
|
108
100
|
custodianEmail?: string;
|
|
109
101
|
email?: PlatformBootstrapEmail;
|
|
110
|
-
githubOAuth: PlatformBootstrapGitHubOAuth;
|
|
111
102
|
backup?: {
|
|
112
103
|
endpoint: string;
|
|
113
104
|
region: string;
|
|
@@ -135,13 +126,12 @@ export declare function validatePlatformSharedEnvironment(input: PlatformSharedE
|
|
|
135
126
|
/** Render only non-secret runtime coordinates. Passwords/tokens have no field in this contract. */
|
|
136
127
|
export declare function renderPlatformSharedEnvironment(input: PlatformSharedEnvironment): string;
|
|
137
128
|
export interface SystemdCredentialSpec {
|
|
138
|
-
name: 'arangodb-jwt' | 'arangodb-root-password' | 'seed-sync-root' | 'fz_smtp.password' | 'fz_jetemail.apiKey' | '
|
|
129
|
+
name: 'arangodb-jwt' | 'arangodb-root-password' | 'seed-sync-root' | 'fz_smtp.password' | 'fz_jetemail.apiKey' | 'CF_API_TOKEN' | 'CF_TUNNEL_TOKEN' | 'REALTIME_PUBLISH_SECRET' | 'REALTIME_TICKET_SECRET';
|
|
139
130
|
encryptedPath: string;
|
|
140
131
|
required: boolean;
|
|
141
132
|
}
|
|
142
133
|
export declare function platformApiCredentialSpecs(options: {
|
|
143
134
|
emailProvider?: PlatformBootstrapEmail['provider'];
|
|
144
|
-
githubOAuth: boolean;
|
|
145
135
|
cloudflareKv: boolean;
|
|
146
136
|
realtime: boolean;
|
|
147
137
|
}): SystemdCredentialSpec[];
|
|
@@ -831,9 +831,6 @@ function validatePlatformSharedEnvironment(input) {
|
|
|
831
831
|
} else if (input.email !== undefined) {
|
|
832
832
|
throw new Error("Bootstrap email provider must be smtp or jetemail.");
|
|
833
833
|
}
|
|
834
|
-
if (!input.githubOAuth || !/^(?:Iv1\.[A-Fa-f0-9]{16}|Ov23li[A-Za-z0-9]{14,})$/.test(input.githubOAuth.clientId)) {
|
|
835
|
-
throw new Error("GitHub OAuth client id is malformed.");
|
|
836
|
-
}
|
|
837
834
|
boundedInteger("publicApiPort", input.publicApiPort, 1024, 65533);
|
|
838
835
|
if (!Array.isArray(input.seedSyncMembers) || input.seedSyncMembers.length < 3 || input.seedSyncMembers.length > 64 || new Set(input.seedSyncMembers).size !== input.seedSyncMembers.length) {
|
|
839
836
|
throw new Error("seedSyncMembers must contain 3 to 64 unique physical host identities.");
|
|
@@ -964,7 +961,6 @@ function renderPlatformSharedEnvironment(input) {
|
|
|
964
961
|
FZ_REALTIME_WORKER_SCRIPT: value.realtime?.workerScriptName ?? "",
|
|
965
962
|
FZ_REALTIME_ENDPOINT: value.realtime?.endpoint ?? "",
|
|
966
963
|
FZ_REALTIME_PRODUCER: value.realtime?.producer ?? "",
|
|
967
|
-
FZ_GITHUB_OAUTH_CLIENT_ID: value.githubOAuth.clientId,
|
|
968
964
|
FZ_PLATFORM_INITIAL_INVENTORY: value.initialInventory ? JSON.stringify(value.initialInventory) : ""
|
|
969
965
|
};
|
|
970
966
|
return `# Generated by fz bootstrap platform. Non-secret coordinates only.
|
|
@@ -976,7 +972,6 @@ function platformApiCredentialSpecs(options) {
|
|
|
976
972
|
const optional = [
|
|
977
973
|
["fz_smtp.password", options.emailProvider === "smtp"],
|
|
978
974
|
["fz_jetemail.apiKey", options.emailProvider === "jetemail"],
|
|
979
|
-
["fz_oauth.github.clientSecret", options.githubOAuth],
|
|
980
975
|
["CF_API_TOKEN", options.cloudflareKv],
|
|
981
976
|
["CF_TUNNEL_TOKEN", options.cloudflareKv],
|
|
982
977
|
["REALTIME_PUBLISH_SECRET", options.realtime],
|
|
@@ -3009,7 +3009,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
3009
3009
|
}
|
|
3010
3010
|
|
|
3011
3011
|
// src/version.ts
|
|
3012
|
-
var VERSION3 = "0.1.
|
|
3012
|
+
var VERSION3 = "0.1.118";
|
|
3013
3013
|
|
|
3014
3014
|
// src/egress-policy.ts
|
|
3015
3015
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
@@ -4347,9 +4347,6 @@ function validatePlatformSharedEnvironment(input) {
|
|
|
4347
4347
|
} else if (input.email !== undefined) {
|
|
4348
4348
|
throw new Error("Bootstrap email provider must be smtp or jetemail.");
|
|
4349
4349
|
}
|
|
4350
|
-
if (!input.githubOAuth || !/^(?:Iv1\.[A-Fa-f0-9]{16}|Ov23li[A-Za-z0-9]{14,})$/.test(input.githubOAuth.clientId)) {
|
|
4351
|
-
throw new Error("GitHub OAuth client id is malformed.");
|
|
4352
|
-
}
|
|
4353
4350
|
boundedInteger("publicApiPort", input.publicApiPort, 1024, 65533);
|
|
4354
4351
|
if (!Array.isArray(input.seedSyncMembers) || input.seedSyncMembers.length < 3 || input.seedSyncMembers.length > 64 || new Set(input.seedSyncMembers).size !== input.seedSyncMembers.length) {
|
|
4355
4352
|
throw new Error("seedSyncMembers must contain 3 to 64 unique physical host identities.");
|
|
@@ -4480,7 +4477,6 @@ function renderPlatformSharedEnvironment(input) {
|
|
|
4480
4477
|
FZ_REALTIME_WORKER_SCRIPT: value.realtime?.workerScriptName ?? "",
|
|
4481
4478
|
FZ_REALTIME_ENDPOINT: value.realtime?.endpoint ?? "",
|
|
4482
4479
|
FZ_REALTIME_PRODUCER: value.realtime?.producer ?? "",
|
|
4483
|
-
FZ_GITHUB_OAUTH_CLIENT_ID: value.githubOAuth.clientId,
|
|
4484
4480
|
FZ_PLATFORM_INITIAL_INVENTORY: value.initialInventory ? JSON.stringify(value.initialInventory) : ""
|
|
4485
4481
|
};
|
|
4486
4482
|
return `# Generated by fz bootstrap platform. Non-secret coordinates only.
|
|
@@ -4492,7 +4488,6 @@ function platformApiCredentialSpecs(options) {
|
|
|
4492
4488
|
const optional = [
|
|
4493
4489
|
["fz_smtp.password", options.emailProvider === "smtp"],
|
|
4494
4490
|
["fz_jetemail.apiKey", options.emailProvider === "jetemail"],
|
|
4495
|
-
["fz_oauth.github.clientSecret", options.githubOAuth],
|
|
4496
4491
|
["CF_API_TOKEN", options.cloudflareKv],
|
|
4497
4492
|
["CF_TUNNEL_TOKEN", options.cloudflareKv],
|
|
4498
4493
|
["REALTIME_PUBLISH_SECRET", options.realtime],
|
|
@@ -45,10 +45,6 @@ export interface ForgeZeroLaunchOwnerInput {
|
|
|
45
45
|
from: string;
|
|
46
46
|
eu: boolean;
|
|
47
47
|
};
|
|
48
|
-
/** Required bootstrap identity provider. Repository automation is configured after genesis. */
|
|
49
|
-
githubOAuth: {
|
|
50
|
-
clientId: string;
|
|
51
|
-
};
|
|
52
48
|
}
|
|
53
49
|
/**
|
|
54
50
|
* ForgeZero's own genesis public coordinates. They are reviewed source data,
|
package/dist/provision.js
CHANGED
|
@@ -3009,7 +3009,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
3009
3009
|
}
|
|
3010
3010
|
|
|
3011
3011
|
// src/version.ts
|
|
3012
|
-
var VERSION3 = "0.1.
|
|
3012
|
+
var VERSION3 = "0.1.118";
|
|
3013
3013
|
|
|
3014
3014
|
// src/egress-policy.ts
|
|
3015
3015
|
import { realpathSync as realpathSync3 } from "node:fs";
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** One package version shared by both public binaries. Pinned to package.json by tests. */
|
|
2
|
-
export declare const VERSION = "0.1.
|
|
2
|
+
export declare const VERSION = "0.1.118";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgezero/agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.118",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"check": "tsc --noEmit",
|
|
@@ -11,13 +11,13 @@
|
|
|
11
11
|
"typescript": "^5.6.0",
|
|
12
12
|
"@types/bun": "latest",
|
|
13
13
|
"@types/node": "^22.0.0",
|
|
14
|
-
"@forgezero/access": "0.1.
|
|
14
|
+
"@forgezero/access": "0.1.11",
|
|
15
15
|
"@noble/curves": "^2.2.0",
|
|
16
16
|
"@noble/post-quantum": "^0.6.1"
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
|
-
"@forgezero/runtime": "0.1.
|
|
20
|
-
"@forgezero/vault": "0.1.
|
|
19
|
+
"@forgezero/runtime": "0.1.16",
|
|
20
|
+
"@forgezero/vault": "0.1.21",
|
|
21
21
|
"@noble/curves": "2.2.0",
|
|
22
22
|
"@noble/hashes": "2.2.0",
|
|
23
23
|
"@noble/post-quantum": "0.6.1",
|