@forgezero/agent 0.1.135 → 0.1.137

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 CHANGED
@@ -101,7 +101,7 @@ export default defineDeployment({
101
101
  provisioning: {
102
102
  regionKey: 'default', imageKey: 'ubuntu-24.04-x64', environmentKey: 'production', ownership: 'platform',
103
103
  resources: {
104
- physicalCores: 1, vcpu: 2, memoryGib: 2, diskGib: 16,
104
+ physicalCores: 1, vcpu: 2, memoryGib: 2, diskGib: 16, diskEncryption: 'luks2',
105
105
  egressGuaranteedMbps: 100, egressBurstMbps: 200, confidential: false
106
106
  },
107
107
  monthlyAmountCents: '1200', maxMonthlySpendMinor: '25000'
@@ -917,7 +917,7 @@ async function postSignedNode(options, path, body) {
917
917
  }
918
918
 
919
919
  // src/version.ts
920
- var VERSION3 = "0.1.135";
920
+ var VERSION3 = "0.1.137";
921
921
 
922
922
  // src/agent-heartbeat.ts
923
923
  function readAgentHostMetrics() {
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.135";
1463
+ var VERSION = "0.1.137";
1464
1464
 
1465
1465
  // src/software.ts
1466
1466
  var PINNED_BUN_VERSION = "1.3.14";
@@ -3070,6 +3070,10 @@ function validatePlatformGenesisGuests(guests, expectedCount = 3) {
3070
3070
  throw new Error("platform genesis vCPU count cannot be smaller than physical cores");
3071
3071
  const memoryGib = integer(input.memoryGib, 1, 8192, "memory");
3072
3072
  const diskGib = integer(input.diskGib, 8, 65536, "disk");
3073
+ const diskEncryption = input.diskEncryption ?? "none";
3074
+ if (!["none", "luks2"].includes(diskEncryption)) {
3075
+ throw new Error("platform genesis disk encryption mode is unsupported");
3076
+ }
3073
3077
  const egressGuaranteedMbps = integer(input.egressGuaranteedMbps, 0, 1e6, "guaranteed egress");
3074
3078
  const egressBurstMbps = integer(input.egressBurstMbps, egressGuaranteedMbps, 1e6, "burst egress");
3075
3079
  return {
@@ -3081,6 +3085,7 @@ function validatePlatformGenesisGuests(guests, expectedCount = 3) {
3081
3085
  vcpu,
3082
3086
  memoryGib,
3083
3087
  diskGib,
3088
+ diskEncryption,
3084
3089
  egressGuaranteedMbps,
3085
3090
  egressBurstMbps,
3086
3091
  confidential: input.confidential
@@ -3111,6 +3116,7 @@ var claimFor = (guest, keys, action) => {
3111
3116
  vcpu: guest.vcpu,
3112
3117
  memoryGib: guest.memoryGib,
3113
3118
  diskGib: guest.diskGib,
3119
+ diskEncryption: guest.diskEncryption,
3114
3120
  egressGuaranteedMbps: guest.egressGuaranteedMbps,
3115
3121
  egressBurstMbps: guest.egressBurstMbps,
3116
3122
  confidential: guest.confidential
@@ -3200,6 +3206,7 @@ function validatePlatformInitialInventory(value) {
3200
3206
  "vcpu",
3201
3207
  "memoryGib",
3202
3208
  "diskGib",
3209
+ "diskEncryption",
3203
3210
  "egressGuaranteedMbps",
3204
3211
  "egressBurstMbps",
3205
3212
  "confidential",
@@ -5230,6 +5237,7 @@ function strictBootstrapDocument(value) {
5230
5237
  "vcpu",
5231
5238
  "memoryGib",
5232
5239
  "diskGib",
5240
+ "diskEncryption",
5233
5241
  "egressGuaranteedMbps",
5234
5242
  "egressBurstMbps",
5235
5243
  "confidential",
package/dist/compute.d.ts CHANGED
@@ -35,6 +35,13 @@ export interface GuestSpec {
35
35
  memoryGib: number;
36
36
  /** Block device or image path. Raw LVM on our metal; a file is allowed. */
37
37
  disk: string;
38
+ /** Host-at-rest LUKS2 envelope. The key is a host-sealed systemd credential. */
39
+ diskEncryption?: {
40
+ source: string;
41
+ mapper: string;
42
+ credentialName: string;
43
+ credentialPath: string;
44
+ };
38
45
  /** cloud-init seed, attached read-only. */
39
46
  seed: string;
40
47
  bridge: string;
package/dist/compute.js CHANGED
@@ -56,6 +56,10 @@ function guestUnit(spec) {
56
56
  `ExecStopPost=-/usr/sbin/ip link del ${spec.tap}`
57
57
  ].join(`
58
58
  `) : "";
59
+ const encryptedDisk = spec.diskEncryption ? `LoadCredentialEncrypted=${spec.diskEncryption.credentialName}:${spec.diskEncryption.credentialPath}
60
+ ExecStartPre=/usr/sbin/cryptsetup open --type luks2 --key-file %d/${spec.diskEncryption.credentialName} ${spec.diskEncryption.source} ${spec.diskEncryption.mapper}
61
+ ExecStopPost=-/usr/sbin/cryptsetup close ${spec.diskEncryption.mapper}
62
+ ` : "";
59
63
  return `[Unit]
60
64
  Description=ForgeZero guest ${spec.name}
61
65
  Documentation=https://www.forgezero.net
@@ -65,7 +69,7 @@ Wants=network-online.target
65
69
  [Service]
66
70
  Type=simple
67
71
  Slice=forgezero-guests.slice
68
- ${tapSetup}
72
+ ${encryptedDisk}${tapSetup}
69
73
  ExecStart=${argv}
70
74
  Restart=always
71
75
  RestartSec=5
@@ -20,6 +20,7 @@ export interface DeploymentInitProvisioning {
20
20
  vcpu: number;
21
21
  memoryGib: number;
22
22
  diskGib: number;
23
+ diskEncryption?: 'none' | 'luks2';
23
24
  egressGuaranteedMbps: number;
24
25
  egressBurstMbps: number;
25
26
  confidential: boolean;
@@ -928,11 +928,13 @@ function compileDeployment(sourceValue) {
928
928
  if (provisioning.metalHostname !== undefined && !/^(?=.{1,253}$)[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/.test(String(provisioning.metalHostname)))
929
929
  fail(`deployment.spec.targets.${targetName}.provisioning.metalHostname`, "is invalid.");
930
930
  const provisionedResources = object(provisioning.resources, `deployment.spec.targets.${targetName}.provisioning.resources`);
931
- exact3(provisionedResources, ["physicalCores", "vcpu", "memoryGib", "diskGib", "egressGuaranteedMbps", "egressBurstMbps", "confidential"], `deployment.spec.targets.${targetName}.provisioning.resources`);
931
+ exact3(provisionedResources, ["physicalCores", "vcpu", "memoryGib", "diskGib", "diskEncryption", "egressGuaranteedMbps", "egressBurstMbps", "confidential"], `deployment.spec.targets.${targetName}.provisioning.resources`);
932
932
  integer(provisionedResources.physicalCores, `deployment.spec.targets.${targetName}.provisioning.resources.physicalCores`, 1, 1024);
933
933
  integer(provisionedResources.vcpu, `deployment.spec.targets.${targetName}.provisioning.resources.vcpu`, 1, 4096);
934
934
  integer(provisionedResources.memoryGib, `deployment.spec.targets.${targetName}.provisioning.resources.memoryGib`, 1, 4194304);
935
935
  integer(provisionedResources.diskGib, `deployment.spec.targets.${targetName}.provisioning.resources.diskGib`, 1, 1048576);
936
+ if (provisionedResources.diskEncryption !== undefined && !["none", "luks2"].includes(String(provisionedResources.diskEncryption)))
937
+ fail(`deployment.spec.targets.${targetName}.provisioning.resources.diskEncryption`, "must be none or luks2.");
936
938
  integer(provisionedResources.egressGuaranteedMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressGuaranteedMbps`, 0, 1e7);
937
939
  integer(provisionedResources.egressBurstMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressBurstMbps`, Number(provisionedResources.egressGuaranteedMbps), 1e7);
938
940
  if (typeof provisionedResources.confidential !== "boolean")
@@ -1305,7 +1307,7 @@ function initCoordinates(options) {
1305
1307
  if (!/^[a-z][a-z0-9-]{0,62}$/.test(value))
1306
1308
  throw new Error(`deployment provisioning ${label} must be a lowercase typed name`);
1307
1309
  const resources = options.provisioning.resources;
1308
- for (const [label, value] of Object.entries(resources).filter(([key]) => key !== "confidential")) {
1310
+ for (const [label, value] of Object.entries(resources).filter(([key]) => !["confidential", "diskEncryption"].includes(key))) {
1309
1311
  if (!Number.isSafeInteger(value) || Number(value) < 0)
1310
1312
  throw new Error(`deployment provisioning ${label} must be a non-negative integer`);
1311
1313
  }
@@ -1314,6 +1316,8 @@ function initCoordinates(options) {
1314
1316
  }
1315
1317
  if (result.isolation === "sev-snp" && !resources.confidential)
1316
1318
  throw new Error("deployment provisioning must provide confidential capacity for sev-snp");
1319
+ if (resources.diskEncryption !== undefined && !["none", "luks2"].includes(resources.diskEncryption))
1320
+ throw new Error("deployment provisioning disk encryption mode is unsupported");
1317
1321
  if (!/^\d{1,18}$/.test(options.provisioning.monthlyAmountCents))
1318
1322
  throw new Error("deployment provisioning monthly amount must be a bounded USD-cent amount");
1319
1323
  if (!/^\d{1,18}$/.test(options.provisioning.maxMonthlySpendMinor))
@@ -1325,7 +1329,10 @@ function initCoordinates(options) {
1325
1329
  if (options.provisioning.metalHostname && !/^(?=.{1,253}$)[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/.test(options.provisioning.metalHostname))
1326
1330
  throw new Error("deployment provisioning metal hostname is invalid");
1327
1331
  }
1328
- return { ...result, ...options.provisioning ? { provisioning: options.provisioning } : {} };
1332
+ return { ...result, ...options.provisioning ? { provisioning: {
1333
+ ...options.provisioning,
1334
+ resources: { ...options.provisioning.resources, diskEncryption: options.provisioning.resources.diskEncryption ?? "luks2" }
1335
+ } } : {} };
1329
1336
  }
1330
1337
  function defaultTypeScriptDeployment(name, options = {}) {
1331
1338
  const selected = initCoordinates(options);
@@ -928,11 +928,13 @@ function compileDeployment(sourceValue) {
928
928
  if (provisioning.metalHostname !== undefined && !/^(?=.{1,253}$)[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/.test(String(provisioning.metalHostname)))
929
929
  fail(`deployment.spec.targets.${targetName}.provisioning.metalHostname`, "is invalid.");
930
930
  const provisionedResources = object(provisioning.resources, `deployment.spec.targets.${targetName}.provisioning.resources`);
931
- exact3(provisionedResources, ["physicalCores", "vcpu", "memoryGib", "diskGib", "egressGuaranteedMbps", "egressBurstMbps", "confidential"], `deployment.spec.targets.${targetName}.provisioning.resources`);
931
+ exact3(provisionedResources, ["physicalCores", "vcpu", "memoryGib", "diskGib", "diskEncryption", "egressGuaranteedMbps", "egressBurstMbps", "confidential"], `deployment.spec.targets.${targetName}.provisioning.resources`);
932
932
  integer(provisionedResources.physicalCores, `deployment.spec.targets.${targetName}.provisioning.resources.physicalCores`, 1, 1024);
933
933
  integer(provisionedResources.vcpu, `deployment.spec.targets.${targetName}.provisioning.resources.vcpu`, 1, 4096);
934
934
  integer(provisionedResources.memoryGib, `deployment.spec.targets.${targetName}.provisioning.resources.memoryGib`, 1, 4194304);
935
935
  integer(provisionedResources.diskGib, `deployment.spec.targets.${targetName}.provisioning.resources.diskGib`, 1, 1048576);
936
+ if (provisionedResources.diskEncryption !== undefined && !["none", "luks2"].includes(String(provisionedResources.diskEncryption)))
937
+ fail(`deployment.spec.targets.${targetName}.provisioning.resources.diskEncryption`, "must be none or luks2.");
936
938
  integer(provisionedResources.egressGuaranteedMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressGuaranteedMbps`, 0, 1e7);
937
939
  integer(provisionedResources.egressBurstMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressBurstMbps`, Number(provisionedResources.egressGuaranteedMbps), 1e7);
938
940
  if (typeof provisionedResources.confidential !== "boolean")
@@ -928,11 +928,13 @@ function compileDeployment(sourceValue) {
928
928
  if (provisioning.metalHostname !== undefined && !/^(?=.{1,253}$)[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?$/.test(String(provisioning.metalHostname)))
929
929
  fail(`deployment.spec.targets.${targetName}.provisioning.metalHostname`, "is invalid.");
930
930
  const provisionedResources = object(provisioning.resources, `deployment.spec.targets.${targetName}.provisioning.resources`);
931
- exact3(provisionedResources, ["physicalCores", "vcpu", "memoryGib", "diskGib", "egressGuaranteedMbps", "egressBurstMbps", "confidential"], `deployment.spec.targets.${targetName}.provisioning.resources`);
931
+ exact3(provisionedResources, ["physicalCores", "vcpu", "memoryGib", "diskGib", "diskEncryption", "egressGuaranteedMbps", "egressBurstMbps", "confidential"], `deployment.spec.targets.${targetName}.provisioning.resources`);
932
932
  integer(provisionedResources.physicalCores, `deployment.spec.targets.${targetName}.provisioning.resources.physicalCores`, 1, 1024);
933
933
  integer(provisionedResources.vcpu, `deployment.spec.targets.${targetName}.provisioning.resources.vcpu`, 1, 4096);
934
934
  integer(provisionedResources.memoryGib, `deployment.spec.targets.${targetName}.provisioning.resources.memoryGib`, 1, 4194304);
935
935
  integer(provisionedResources.diskGib, `deployment.spec.targets.${targetName}.provisioning.resources.diskGib`, 1, 1048576);
936
+ if (provisionedResources.diskEncryption !== undefined && !["none", "luks2"].includes(String(provisionedResources.diskEncryption)))
937
+ fail(`deployment.spec.targets.${targetName}.provisioning.resources.diskEncryption`, "must be none or luks2.");
936
938
  integer(provisionedResources.egressGuaranteedMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressGuaranteedMbps`, 0, 1e7);
937
939
  integer(provisionedResources.egressBurstMbps, `deployment.spec.targets.${targetName}.provisioning.resources.egressBurstMbps`, Number(provisionedResources.egressGuaranteedMbps), 1e7);
938
940
  if (typeof provisionedResources.confidential !== "boolean")
package/dist/deploy.d.ts CHANGED
@@ -195,6 +195,7 @@ export interface TargetDefinition {
195
195
  vcpu: number;
196
196
  memoryGib: number;
197
197
  diskGib: number;
198
+ diskEncryption?: 'none' | 'luks2';
198
199
  egressGuaranteedMbps: number;
199
200
  egressBurstMbps: number;
200
201
  confidential: boolean;
@@ -139,6 +139,7 @@ export interface ResolvedDeploymentTarget {
139
139
  vcpu: number;
140
140
  memoryGib: number;
141
141
  diskGib: number;
142
+ diskEncryption?: 'none' | 'luks2';
142
143
  egressGuaranteedMbps: number;
143
144
  egressBurstMbps: number;
144
145
  confidential: boolean;