@forgezero/agent 0.1.71 → 0.1.73
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 +2 -1
- package/dist/agent-heartbeat.js +1 -1
- package/dist/bootstrap.js +1 -1
- package/dist/fz-agent.js +1 -1
- package/dist/fz.js +17 -8
- package/dist/metal-bootstrap.d.ts +9 -2
- package/dist/metal-bootstrap.js +5 -5
- package/dist/operator-bootstrap.js +5 -5
- package/dist/platform-fleet-verification.js +1 -1
- package/dist/provision.js +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1025,7 +1025,7 @@ import type {
|
|
|
1025
1025
|
<a id="forgezero-agent-metal-bootstrap"></a>
|
|
1026
1026
|
## @forgezero/agent/metal-bootstrap
|
|
1027
1027
|
|
|
1028
|
-
Physical-metal bootstrap planning, application and status evidence. This entry exposes 10 named value exports and
|
|
1028
|
+
Physical-metal bootstrap planning, application and status evidence. This entry exposes 10 named value exports and 7 named type exports. The generated import block lists one name per line for scanning and copying; keep only the names used by your file.
|
|
1029
1029
|
|
|
1030
1030
|
```text
|
|
1031
1031
|
import {
|
|
@@ -1048,6 +1048,7 @@ import type {
|
|
|
1048
1048
|
MetalBootstrapPlan,
|
|
1049
1049
|
MetalBootstrapResult,
|
|
1050
1050
|
MetalBootstrapStatus,
|
|
1051
|
+
MetalBootstrapValidationOptions,
|
|
1051
1052
|
} from '@forgezero/agent/metal-bootstrap';
|
|
1052
1053
|
```
|
|
1053
1054
|
|
package/dist/agent-heartbeat.js
CHANGED
package/dist/bootstrap.js
CHANGED
package/dist/fz-agent.js
CHANGED
|
@@ -8588,7 +8588,7 @@ import { join as join3 } from "path";
|
|
|
8588
8588
|
import { fileURLToPath } from "url";
|
|
8589
8589
|
|
|
8590
8590
|
// src/version.ts
|
|
8591
|
-
var VERSION2 = "0.1.
|
|
8591
|
+
var VERSION2 = "0.1.73";
|
|
8592
8592
|
|
|
8593
8593
|
// src/ssh-bootstrap.ts
|
|
8594
8594
|
class SshBootstrapError extends Error {
|
package/dist/fz.js
CHANGED
|
@@ -4829,7 +4829,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
|
|
|
4829
4829
|
var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
|
|
4830
4830
|
|
|
4831
4831
|
// src/version.ts
|
|
4832
|
-
var VERSION2 = "0.1.
|
|
4832
|
+
var VERSION2 = "0.1.73";
|
|
4833
4833
|
|
|
4834
4834
|
// src/software.ts
|
|
4835
4835
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -15522,7 +15522,7 @@ var validUnit = (unit) => {
|
|
|
15522
15522
|
throw new MetalBootstrapError("the OTLP collector must be independently supervised");
|
|
15523
15523
|
}
|
|
15524
15524
|
};
|
|
15525
|
-
function validateMetalBootstrapConfig(config) {
|
|
15525
|
+
function validateMetalBootstrapConfig(config, options = {}) {
|
|
15526
15526
|
if (!config || typeof config !== "object")
|
|
15527
15527
|
throw new MetalBootstrapError("metal bootstrap config must be an object");
|
|
15528
15528
|
exactKeys4(config, ["kind", "metalHostname", "profile", "hostTelemetryEndpoint", "hostTelemetryUnit", "agentSeedFile"], "metal bootstrap config");
|
|
@@ -15566,7 +15566,7 @@ function validateMetalBootstrapConfig(config) {
|
|
|
15566
15566
|
for (const image of Object.values(config.profile.images))
|
|
15567
15567
|
if (!image.path.startsWith("/var/lib/forgezero/images/") || resolve8(image.path) !== image.path || /[\0\r\n]/.test(image.path))
|
|
15568
15568
|
throw new MetalBootstrapError("every pinned guest image must use the fixed image directory");
|
|
15569
|
-
if (config.profile.bunVersion !== SUPPORTED_BUN_VERSION || config.profile.bunReleaseSha256 !== SUPPORTED_BUN_RELEASE_SHA256 || config.profile.agentVersion !== VERSION2) {
|
|
15569
|
+
if (!options.allowHistoricalRelease && (config.profile.bunVersion !== SUPPORTED_BUN_VERSION || config.profile.bunReleaseSha256 !== SUPPORTED_BUN_RELEASE_SHA256 || config.profile.agentVersion !== VERSION2)) {
|
|
15570
15570
|
throw new MetalBootstrapError("metal guest runtime must use the package-owned Bun and Agent release coordinates");
|
|
15571
15571
|
}
|
|
15572
15572
|
let api;
|
|
@@ -15612,7 +15612,7 @@ function validateOwnerOnlyPath(path, requireRootOwner) {
|
|
|
15612
15612
|
throw new MetalBootstrapError(requireRootOwner ? "private bootstrap file must be root-owned" : "private bootstrap file has an unexpected owner");
|
|
15613
15613
|
}
|
|
15614
15614
|
}
|
|
15615
|
-
function readMetalBootstrapConfig(path) {
|
|
15615
|
+
function readMetalBootstrapConfig(path, options = {}) {
|
|
15616
15616
|
validateOwnerOnlyPath(path, false);
|
|
15617
15617
|
const metadata = statSync(path);
|
|
15618
15618
|
if (metadata.size < 2 || metadata.size > MAX_CONFIG_BYTES)
|
|
@@ -15623,7 +15623,7 @@ function readMetalBootstrapConfig(path) {
|
|
|
15623
15623
|
} catch {
|
|
15624
15624
|
throw new MetalBootstrapError("metal bootstrap config is not valid JSON");
|
|
15625
15625
|
}
|
|
15626
|
-
return validateMetalBootstrapConfig(parsed);
|
|
15626
|
+
return validateMetalBootstrapConfig(parsed, options);
|
|
15627
15627
|
}
|
|
15628
15628
|
function planMetalBootstrap(config) {
|
|
15629
15629
|
validateMetalBootstrapConfig(config);
|
|
@@ -17418,6 +17418,7 @@ function parseOptions(argv2) {
|
|
|
17418
17418
|
realm: process.env.FZ_REALM ?? "platform",
|
|
17419
17419
|
realmExplicit: Boolean(process.env.FZ_REALM),
|
|
17420
17420
|
json: false,
|
|
17421
|
+
help: false,
|
|
17421
17422
|
apply: false,
|
|
17422
17423
|
enrol: false,
|
|
17423
17424
|
socket: process.env.SSH_AUTH_SOCK,
|
|
@@ -17456,6 +17457,8 @@ function parseOptions(argv2) {
|
|
|
17456
17457
|
options.socket = argv2[++index];
|
|
17457
17458
|
else if (token === "--json")
|
|
17458
17459
|
options.json = true;
|
|
17460
|
+
else if (token === "--help" || token === "-h")
|
|
17461
|
+
options.help = true;
|
|
17459
17462
|
else if (token === "--apply")
|
|
17460
17463
|
options.apply = true;
|
|
17461
17464
|
else if (token === "--enrol")
|
|
@@ -18331,11 +18334,13 @@ function writeMetalOperatorFiles(directory) {
|
|
|
18331
18334
|
function writePlatformGenesisFleet(directory) {
|
|
18332
18335
|
const output = genesisOutputDirectory(directory);
|
|
18333
18336
|
const metalRequestFile = bootstrapAnswer("Owner-only metal remote request containing the reviewed genesis guests");
|
|
18334
|
-
const metalRequest = readOperatorMetalBootstrapRequest(metalRequestFile);
|
|
18337
|
+
const metalRequest = readOperatorMetalBootstrapRequest(metalRequestFile, { validateMetalConfig: false });
|
|
18335
18338
|
const guestHostKeysFile = bootstrapAnswer("Owner-only guest host-key evidence file");
|
|
18336
18339
|
const guestHostKeys = readOperatorGuestHostKeyEvidence(guestHostKeysFile, metalRequest);
|
|
18337
18340
|
const fleet = metalRequest.genesis.nodes;
|
|
18338
|
-
const metalHostname = readMetalBootstrapConfig(metalRequest.metalConfigFile
|
|
18341
|
+
const metalHostname = readMetalBootstrapConfig(metalRequest.metalConfigFile, {
|
|
18342
|
+
allowHistoricalRelease: true
|
|
18343
|
+
}).metalHostname;
|
|
18339
18344
|
const checkpointPath = join12(output, "cloudflare-handoff.json");
|
|
18340
18345
|
const template = interactiveBootstrap("platform", fleet, checkpointPath);
|
|
18341
18346
|
const region = {
|
|
@@ -18443,7 +18448,7 @@ function interactiveBootstrap(kind, genesisGuests, genesisCloudflareCheckpoint)
|
|
|
18443
18448
|
const backupBucket = backupEndpoint ? bootstrapAnswer("Backup S3 bucket") : undefined;
|
|
18444
18449
|
const backupAccessKeyId = backupEndpoint ? bootstrapAnswer("Backup S3 access-key id") : undefined;
|
|
18445
18450
|
const cloudflareHandoffFile = genesis ? cloudflareHostHandoffPath(genesisCloudflareCheckpoint, computeReference) : bootstrapAnswer("Node-specific Cloudflare host handoff (blank for no public edge)", "");
|
|
18446
|
-
const cloudflareNodeName = cloudflareHandoffFile ? bootstrapAnswer("Cloudflare handoff node name", computeReference) : undefined;
|
|
18451
|
+
const cloudflareNodeName = cloudflareHandoffFile ? genesis ? computeReference : bootstrapAnswer("Cloudflare handoff node name", computeReference) : undefined;
|
|
18447
18452
|
const databaseNetworkMode = "private-lan";
|
|
18448
18453
|
const enrolmentSource = genesis ? "genesis-derived" : bootstrapAnswer("Enrolment source (genesis-derived/api-token)", "genesis-derived");
|
|
18449
18454
|
return {
|
|
@@ -19471,6 +19476,10 @@ if (import.meta.main) {
|
|
|
19471
19476
|
}
|
|
19472
19477
|
async function runCli() {
|
|
19473
19478
|
const { command, args, options } = parseOptions(process.argv.slice(2));
|
|
19479
|
+
if (options.help) {
|
|
19480
|
+
usage();
|
|
19481
|
+
process.exit(0);
|
|
19482
|
+
}
|
|
19474
19483
|
try {
|
|
19475
19484
|
hydrateSession(options);
|
|
19476
19485
|
} catch (cause) {
|
|
@@ -44,10 +44,17 @@ export interface MetalBootstrapApplyOptions {
|
|
|
44
44
|
export declare class MetalBootstrapError extends Error {
|
|
45
45
|
}
|
|
46
46
|
export declare function normalizeMetalPublicIdentity(value: string): string;
|
|
47
|
-
export
|
|
47
|
+
export interface MetalBootstrapValidationOptions {
|
|
48
|
+
/**
|
|
49
|
+
* Read identity/topology from a config that was already applied by an older
|
|
50
|
+
* Agent release. New installs and repairs must never set this flag.
|
|
51
|
+
*/
|
|
52
|
+
allowHistoricalRelease?: boolean;
|
|
53
|
+
}
|
|
54
|
+
export declare function validateMetalBootstrapConfig(config: MetalBootstrapConfig, options?: MetalBootstrapValidationOptions): MetalBootstrapConfig;
|
|
48
55
|
/** Reject symlinks and group/world access before parsing coordinates or entropy. */
|
|
49
56
|
export declare function validateOwnerOnlyPath(path: string, requireRootOwner: boolean): void;
|
|
50
|
-
export declare function readMetalBootstrapConfig(path: string): MetalBootstrapConfig;
|
|
57
|
+
export declare function readMetalBootstrapConfig(path: string, options?: MetalBootstrapValidationOptions): MetalBootstrapConfig;
|
|
51
58
|
export declare function planMetalBootstrap(config: MetalBootstrapConfig): MetalBootstrapPlan;
|
|
52
59
|
export declare function renderMetalUnits(config: MetalBootstrapConfig): Record<string, string>;
|
|
53
60
|
export declare function applyMetalBootstrap(config: MetalBootstrapConfig, options: MetalBootstrapApplyOptions): Promise<MetalBootstrapResult>;
|
package/dist/metal-bootstrap.js
CHANGED
|
@@ -354,7 +354,7 @@ function systemdAgentEgressDirectives(loopbackTcpPorts = []) {
|
|
|
354
354
|
}
|
|
355
355
|
|
|
356
356
|
// src/version.ts
|
|
357
|
-
var VERSION = "0.1.
|
|
357
|
+
var VERSION = "0.1.73";
|
|
358
358
|
|
|
359
359
|
// src/otel-collector.ts
|
|
360
360
|
var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
|
|
@@ -579,7 +579,7 @@ var validUnit = (unit) => {
|
|
|
579
579
|
throw new MetalBootstrapError("the OTLP collector must be independently supervised");
|
|
580
580
|
}
|
|
581
581
|
};
|
|
582
|
-
function validateMetalBootstrapConfig(config) {
|
|
582
|
+
function validateMetalBootstrapConfig(config, options = {}) {
|
|
583
583
|
if (!config || typeof config !== "object")
|
|
584
584
|
throw new MetalBootstrapError("metal bootstrap config must be an object");
|
|
585
585
|
exactKeys(config, ["kind", "metalHostname", "profile", "hostTelemetryEndpoint", "hostTelemetryUnit", "agentSeedFile"], "metal bootstrap config");
|
|
@@ -623,7 +623,7 @@ function validateMetalBootstrapConfig(config) {
|
|
|
623
623
|
for (const image of Object.values(config.profile.images))
|
|
624
624
|
if (!image.path.startsWith("/var/lib/forgezero/images/") || resolve(image.path) !== image.path || /[\0\r\n]/.test(image.path))
|
|
625
625
|
throw new MetalBootstrapError("every pinned guest image must use the fixed image directory");
|
|
626
|
-
if (config.profile.bunVersion !== SUPPORTED_BUN_VERSION || config.profile.bunReleaseSha256 !== SUPPORTED_BUN_RELEASE_SHA256 || config.profile.agentVersion !== VERSION) {
|
|
626
|
+
if (!options.allowHistoricalRelease && (config.profile.bunVersion !== SUPPORTED_BUN_VERSION || config.profile.bunReleaseSha256 !== SUPPORTED_BUN_RELEASE_SHA256 || config.profile.agentVersion !== VERSION)) {
|
|
627
627
|
throw new MetalBootstrapError("metal guest runtime must use the package-owned Bun and Agent release coordinates");
|
|
628
628
|
}
|
|
629
629
|
let api;
|
|
@@ -669,7 +669,7 @@ function validateOwnerOnlyPath(path, requireRootOwner) {
|
|
|
669
669
|
throw new MetalBootstrapError(requireRootOwner ? "private bootstrap file must be root-owned" : "private bootstrap file has an unexpected owner");
|
|
670
670
|
}
|
|
671
671
|
}
|
|
672
|
-
function readMetalBootstrapConfig(path) {
|
|
672
|
+
function readMetalBootstrapConfig(path, options = {}) {
|
|
673
673
|
validateOwnerOnlyPath(path, false);
|
|
674
674
|
const metadata = statSync(path);
|
|
675
675
|
if (metadata.size < 2 || metadata.size > MAX_CONFIG_BYTES)
|
|
@@ -680,7 +680,7 @@ function readMetalBootstrapConfig(path) {
|
|
|
680
680
|
} catch {
|
|
681
681
|
throw new MetalBootstrapError("metal bootstrap config is not valid JSON");
|
|
682
682
|
}
|
|
683
|
-
return validateMetalBootstrapConfig(parsed);
|
|
683
|
+
return validateMetalBootstrapConfig(parsed, options);
|
|
684
684
|
}
|
|
685
685
|
function planMetalBootstrap(config) {
|
|
686
686
|
validateMetalBootstrapConfig(config);
|
|
@@ -1416,7 +1416,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
|
|
|
1416
1416
|
var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
|
|
1417
1417
|
|
|
1418
1418
|
// src/version.ts
|
|
1419
|
-
var VERSION = "0.1.
|
|
1419
|
+
var VERSION = "0.1.73";
|
|
1420
1420
|
|
|
1421
1421
|
// src/software.ts
|
|
1422
1422
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -5233,7 +5233,7 @@ var validUnit = (unit) => {
|
|
|
5233
5233
|
throw new MetalBootstrapError("the OTLP collector must be independently supervised");
|
|
5234
5234
|
}
|
|
5235
5235
|
};
|
|
5236
|
-
function validateMetalBootstrapConfig(config) {
|
|
5236
|
+
function validateMetalBootstrapConfig(config, options = {}) {
|
|
5237
5237
|
if (!config || typeof config !== "object")
|
|
5238
5238
|
throw new MetalBootstrapError("metal bootstrap config must be an object");
|
|
5239
5239
|
exactKeys2(config, ["kind", "metalHostname", "profile", "hostTelemetryEndpoint", "hostTelemetryUnit", "agentSeedFile"], "metal bootstrap config");
|
|
@@ -5277,7 +5277,7 @@ function validateMetalBootstrapConfig(config) {
|
|
|
5277
5277
|
for (const image of Object.values(config.profile.images))
|
|
5278
5278
|
if (!image.path.startsWith("/var/lib/forgezero/images/") || resolve5(image.path) !== image.path || /[\0\r\n]/.test(image.path))
|
|
5279
5279
|
throw new MetalBootstrapError("every pinned guest image must use the fixed image directory");
|
|
5280
|
-
if (config.profile.bunVersion !== SUPPORTED_BUN_VERSION || config.profile.bunReleaseSha256 !== SUPPORTED_BUN_RELEASE_SHA256 || config.profile.agentVersion !== VERSION) {
|
|
5280
|
+
if (!options.allowHistoricalRelease && (config.profile.bunVersion !== SUPPORTED_BUN_VERSION || config.profile.bunReleaseSha256 !== SUPPORTED_BUN_RELEASE_SHA256 || config.profile.agentVersion !== VERSION)) {
|
|
5281
5281
|
throw new MetalBootstrapError("metal guest runtime must use the package-owned Bun and Agent release coordinates");
|
|
5282
5282
|
}
|
|
5283
5283
|
let api;
|
|
@@ -5323,7 +5323,7 @@ function validateOwnerOnlyPath(path, requireRootOwner) {
|
|
|
5323
5323
|
throw new MetalBootstrapError(requireRootOwner ? "private bootstrap file must be root-owned" : "private bootstrap file has an unexpected owner");
|
|
5324
5324
|
}
|
|
5325
5325
|
}
|
|
5326
|
-
function readMetalBootstrapConfig(path) {
|
|
5326
|
+
function readMetalBootstrapConfig(path, options = {}) {
|
|
5327
5327
|
validateOwnerOnlyPath(path, false);
|
|
5328
5328
|
const metadata = statSync(path);
|
|
5329
5329
|
if (metadata.size < 2 || metadata.size > MAX_CONFIG_BYTES)
|
|
@@ -5334,7 +5334,7 @@ function readMetalBootstrapConfig(path) {
|
|
|
5334
5334
|
} catch {
|
|
5335
5335
|
throw new MetalBootstrapError("metal bootstrap config is not valid JSON");
|
|
5336
5336
|
}
|
|
5337
|
-
return validateMetalBootstrapConfig(parsed);
|
|
5337
|
+
return validateMetalBootstrapConfig(parsed, options);
|
|
5338
5338
|
}
|
|
5339
5339
|
function planMetalBootstrap(config) {
|
|
5340
5340
|
validateMetalBootstrapConfig(config);
|
|
@@ -2125,7 +2125,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
2125
2125
|
}
|
|
2126
2126
|
|
|
2127
2127
|
// src/version.ts
|
|
2128
|
-
var VERSION3 = "0.1.
|
|
2128
|
+
var VERSION3 = "0.1.73";
|
|
2129
2129
|
|
|
2130
2130
|
// src/egress-policy.ts
|
|
2131
2131
|
import { realpathSync as realpathSync3 } from "node:fs";
|
package/dist/provision.js
CHANGED
|
@@ -2125,7 +2125,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
2125
2125
|
}
|
|
2126
2126
|
|
|
2127
2127
|
// src/version.ts
|
|
2128
|
-
var VERSION3 = "0.1.
|
|
2128
|
+
var VERSION3 = "0.1.73";
|
|
2129
2129
|
|
|
2130
2130
|
// src/egress-policy.ts
|
|
2131
2131
|
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.73";
|