@forgezero/agent 0.1.129 → 0.1.130
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/dist/agent-heartbeat.js +1 -1
- package/dist/bootstrap.js +46 -2
- package/dist/fz-agent.js +1 -1
- package/dist/fz.js +48 -4
- package/dist/metal-bootstrap.js +1 -1
- package/dist/operator-bootstrap.js +47 -3
- package/dist/platform-fleet-verification.js +1 -1
- package/dist/provision.js +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +3 -3
package/dist/agent-heartbeat.js
CHANGED
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.130";
|
|
1464
1464
|
|
|
1465
1465
|
// src/software.ts
|
|
1466
1466
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -4664,6 +4664,7 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4664
4664
|
installed = parseStoredState(host.read(STATE_PATH));
|
|
4665
4665
|
let bootstrapManifest;
|
|
4666
4666
|
let releaseEvidence;
|
|
4667
|
+
let redundantBootstrapBundle = false;
|
|
4667
4668
|
if (config.kind === "platform") {
|
|
4668
4669
|
const staged = host.exists(config.bootstrapBundle.bundleFile) || host.exists(config.bootstrapBundle.manifestFile);
|
|
4669
4670
|
if (staged && !(host.exists(config.bootstrapBundle.bundleFile) && host.exists(config.bootstrapBundle.manifestFile))) {
|
|
@@ -4684,8 +4685,11 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4684
4685
|
if (typeof evidence.revision !== "string" || !/^[a-f0-9]{40}$/.test(evidence.revision) || typeof evidence.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(evidence.sha256) || typeof evidence.branch !== "string")
|
|
4685
4686
|
throw new Error("bootstrap release evidence is malformed");
|
|
4686
4687
|
releaseEvidence = { revision: evidence.revision, sha256: evidence.sha256, branch: evidence.branch };
|
|
4687
|
-
if (evidence.revision !== reviewed.revision || evidence.
|
|
4688
|
+
if (evidence.revision !== reviewed.revision || evidence.branch !== reviewed.branch) {
|
|
4688
4689
|
bootstrapManifest = reviewed;
|
|
4690
|
+
} else {
|
|
4691
|
+
redundantBootstrapBundle = true;
|
|
4692
|
+
}
|
|
4689
4693
|
} else if (host.exists(BOOTSTRAP_RELEASE_EVIDENCE)) {
|
|
4690
4694
|
let evidence;
|
|
4691
4695
|
try {
|
|
@@ -4962,6 +4966,46 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4962
4966
|
await checked3(host, ["nginx", "-t"], "nginx configuration");
|
|
4963
4967
|
await checked3(host, ["systemctl", "daemon-reload"], "systemd reload");
|
|
4964
4968
|
await checked3(host, ["systemctl", "enable", "--now", "nginx.service"], "nginx supervision");
|
|
4969
|
+
if (alreadyEnrolled && !bootstrapManifest) {
|
|
4970
|
+
const healthCommand = [
|
|
4971
|
+
"curl",
|
|
4972
|
+
"--fail",
|
|
4973
|
+
"--silent",
|
|
4974
|
+
"--show-error",
|
|
4975
|
+
"--max-time",
|
|
4976
|
+
"10",
|
|
4977
|
+
`http://127.0.0.1:${runtime.environment.publicApiPort}${runtime.healthPath}`
|
|
4978
|
+
];
|
|
4979
|
+
const health = await host.exec(healthCommand);
|
|
4980
|
+
if (health.exitCode !== 0) {
|
|
4981
|
+
const activeSlotFile = `${runtime.slotsDirectory}/.active`;
|
|
4982
|
+
if (!host.exists(activeSlotFile))
|
|
4983
|
+
throw new Error("enrolled platform active API slot evidence is missing");
|
|
4984
|
+
const activeSlot = host.read(activeSlotFile).trim();
|
|
4985
|
+
if (activeSlot !== "blue" && activeSlot !== "green") {
|
|
4986
|
+
throw new Error("enrolled platform active API slot evidence is malformed");
|
|
4987
|
+
}
|
|
4988
|
+
await checked3(host, ["systemctl", "start", `forgezero@${activeSlot}.service`], "active API slot repair");
|
|
4989
|
+
let ready = false;
|
|
4990
|
+
let lastHealthOutput = "";
|
|
4991
|
+
for (let attempt = 0;attempt < 30; attempt += 1) {
|
|
4992
|
+
const repairedHealth = await host.exec(healthCommand);
|
|
4993
|
+
if (repairedHealth.exitCode === 0) {
|
|
4994
|
+
ready = true;
|
|
4995
|
+
break;
|
|
4996
|
+
}
|
|
4997
|
+
lastHealthOutput = repairedHealth.output.trim();
|
|
4998
|
+
if (attempt < 29)
|
|
4999
|
+
await (host.sleep?.(1000) ?? Bun.sleep(1000));
|
|
5000
|
+
}
|
|
5001
|
+
if (!ready)
|
|
5002
|
+
throw new Error(`repaired API health failed: ${lastHealthOutput || "readiness deadline exceeded"}`);
|
|
5003
|
+
}
|
|
5004
|
+
if (redundantBootstrapBundle) {
|
|
5005
|
+
host.remove(config.bootstrapBundle.bundleFile);
|
|
5006
|
+
host.remove(config.bootstrapBundle.manifestFile);
|
|
5007
|
+
}
|
|
5008
|
+
}
|
|
4965
5009
|
if (config.database.role === "master") {
|
|
4966
5010
|
const invite = `${runtime.environment.sharedDirectory}/platform-invite.token`;
|
|
4967
5011
|
if (!host.exists(invite)) {
|
package/dist/fz-agent.js
CHANGED
package/dist/fz.js
CHANGED
|
@@ -5788,7 +5788,7 @@ var VaultRuntimeClientError, json = (value) => ({ method: "POST", body: JSON.str
|
|
|
5788
5788
|
} catch {
|
|
5789
5789
|
return;
|
|
5790
5790
|
}
|
|
5791
|
-
}, VERSION = "0.1.
|
|
5791
|
+
}, VERSION = "0.1.27";
|
|
5792
5792
|
var init_dist = __esm(() => {
|
|
5793
5793
|
init_vault_runtime();
|
|
5794
5794
|
init_identity();
|
|
@@ -6007,7 +6007,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
|
|
|
6007
6007
|
var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
|
|
6008
6008
|
|
|
6009
6009
|
// src/version.ts
|
|
6010
|
-
var VERSION2 = "0.1.
|
|
6010
|
+
var VERSION2 = "0.1.130";
|
|
6011
6011
|
|
|
6012
6012
|
// src/software.ts
|
|
6013
6013
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -15284,6 +15284,7 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
15284
15284
|
installed = parseStoredState(host.read(STATE_PATH));
|
|
15285
15285
|
let bootstrapManifest;
|
|
15286
15286
|
let releaseEvidence;
|
|
15287
|
+
let redundantBootstrapBundle = false;
|
|
15287
15288
|
if (config.kind === "platform") {
|
|
15288
15289
|
const staged = host.exists(config.bootstrapBundle.bundleFile) || host.exists(config.bootstrapBundle.manifestFile);
|
|
15289
15290
|
if (staged && !(host.exists(config.bootstrapBundle.bundleFile) && host.exists(config.bootstrapBundle.manifestFile))) {
|
|
@@ -15304,8 +15305,11 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
15304
15305
|
if (typeof evidence.revision !== "string" || !/^[a-f0-9]{40}$/.test(evidence.revision) || typeof evidence.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(evidence.sha256) || typeof evidence.branch !== "string")
|
|
15305
15306
|
throw new Error("bootstrap release evidence is malformed");
|
|
15306
15307
|
releaseEvidence = { revision: evidence.revision, sha256: evidence.sha256, branch: evidence.branch };
|
|
15307
|
-
if (evidence.revision !== reviewed.revision || evidence.
|
|
15308
|
+
if (evidence.revision !== reviewed.revision || evidence.branch !== reviewed.branch) {
|
|
15308
15309
|
bootstrapManifest = reviewed;
|
|
15310
|
+
} else {
|
|
15311
|
+
redundantBootstrapBundle = true;
|
|
15312
|
+
}
|
|
15309
15313
|
} else if (host.exists(BOOTSTRAP_RELEASE_EVIDENCE)) {
|
|
15310
15314
|
let evidence;
|
|
15311
15315
|
try {
|
|
@@ -15582,6 +15586,46 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
15582
15586
|
await checked3(host, ["nginx", "-t"], "nginx configuration");
|
|
15583
15587
|
await checked3(host, ["systemctl", "daemon-reload"], "systemd reload");
|
|
15584
15588
|
await checked3(host, ["systemctl", "enable", "--now", "nginx.service"], "nginx supervision");
|
|
15589
|
+
if (alreadyEnrolled && !bootstrapManifest) {
|
|
15590
|
+
const healthCommand = [
|
|
15591
|
+
"curl",
|
|
15592
|
+
"--fail",
|
|
15593
|
+
"--silent",
|
|
15594
|
+
"--show-error",
|
|
15595
|
+
"--max-time",
|
|
15596
|
+
"10",
|
|
15597
|
+
`http://127.0.0.1:${runtime.environment.publicApiPort}${runtime.healthPath}`
|
|
15598
|
+
];
|
|
15599
|
+
const health = await host.exec(healthCommand);
|
|
15600
|
+
if (health.exitCode !== 0) {
|
|
15601
|
+
const activeSlotFile = `${runtime.slotsDirectory}/.active`;
|
|
15602
|
+
if (!host.exists(activeSlotFile))
|
|
15603
|
+
throw new Error("enrolled platform active API slot evidence is missing");
|
|
15604
|
+
const activeSlot = host.read(activeSlotFile).trim();
|
|
15605
|
+
if (activeSlot !== "blue" && activeSlot !== "green") {
|
|
15606
|
+
throw new Error("enrolled platform active API slot evidence is malformed");
|
|
15607
|
+
}
|
|
15608
|
+
await checked3(host, ["systemctl", "start", `forgezero@${activeSlot}.service`], "active API slot repair");
|
|
15609
|
+
let ready = false;
|
|
15610
|
+
let lastHealthOutput = "";
|
|
15611
|
+
for (let attempt = 0;attempt < 30; attempt += 1) {
|
|
15612
|
+
const repairedHealth = await host.exec(healthCommand);
|
|
15613
|
+
if (repairedHealth.exitCode === 0) {
|
|
15614
|
+
ready = true;
|
|
15615
|
+
break;
|
|
15616
|
+
}
|
|
15617
|
+
lastHealthOutput = repairedHealth.output.trim();
|
|
15618
|
+
if (attempt < 29)
|
|
15619
|
+
await (host.sleep?.(1000) ?? Bun.sleep(1000));
|
|
15620
|
+
}
|
|
15621
|
+
if (!ready)
|
|
15622
|
+
throw new Error(`repaired API health failed: ${lastHealthOutput || "readiness deadline exceeded"}`);
|
|
15623
|
+
}
|
|
15624
|
+
if (redundantBootstrapBundle) {
|
|
15625
|
+
host.remove(config.bootstrapBundle.bundleFile);
|
|
15626
|
+
host.remove(config.bootstrapBundle.manifestFile);
|
|
15627
|
+
}
|
|
15628
|
+
}
|
|
15585
15629
|
if (config.database.role === "master") {
|
|
15586
15630
|
const invite = `${runtime.environment.sharedDirectory}/platform-invite.token`;
|
|
15587
15631
|
if (!host.exists(invite)) {
|
|
@@ -18174,7 +18218,7 @@ async function applyOperatorPlatformBootstrap(request, mode, options = {}) {
|
|
|
18174
18218
|
` : undefined, mode === "apply");
|
|
18175
18219
|
return { plan, output };
|
|
18176
18220
|
} finally {
|
|
18177
|
-
if (knownHosts) {
|
|
18221
|
+
if (knownHosts && mode !== "status") {
|
|
18178
18222
|
await remote(exec, request, knownHosts, ["/usr/bin/sudo", "-n", "/usr/bin/rm", "-rf", "--", REMOTE_STAGE, remoteTemp], "remote bootstrap cleanup", true).catch(() => {
|
|
18179
18223
|
return;
|
|
18180
18224
|
});
|
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.130";
|
|
370
370
|
|
|
371
371
|
// src/otel-collector.ts
|
|
372
372
|
var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
|
|
@@ -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.130";
|
|
1464
1464
|
|
|
1465
1465
|
// src/software.ts
|
|
1466
1466
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -4664,6 +4664,7 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4664
4664
|
installed = parseStoredState(host.read(STATE_PATH));
|
|
4665
4665
|
let bootstrapManifest;
|
|
4666
4666
|
let releaseEvidence;
|
|
4667
|
+
let redundantBootstrapBundle = false;
|
|
4667
4668
|
if (config.kind === "platform") {
|
|
4668
4669
|
const staged = host.exists(config.bootstrapBundle.bundleFile) || host.exists(config.bootstrapBundle.manifestFile);
|
|
4669
4670
|
if (staged && !(host.exists(config.bootstrapBundle.bundleFile) && host.exists(config.bootstrapBundle.manifestFile))) {
|
|
@@ -4684,8 +4685,11 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4684
4685
|
if (typeof evidence.revision !== "string" || !/^[a-f0-9]{40}$/.test(evidence.revision) || typeof evidence.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(evidence.sha256) || typeof evidence.branch !== "string")
|
|
4685
4686
|
throw new Error("bootstrap release evidence is malformed");
|
|
4686
4687
|
releaseEvidence = { revision: evidence.revision, sha256: evidence.sha256, branch: evidence.branch };
|
|
4687
|
-
if (evidence.revision !== reviewed.revision || evidence.
|
|
4688
|
+
if (evidence.revision !== reviewed.revision || evidence.branch !== reviewed.branch) {
|
|
4688
4689
|
bootstrapManifest = reviewed;
|
|
4690
|
+
} else {
|
|
4691
|
+
redundantBootstrapBundle = true;
|
|
4692
|
+
}
|
|
4689
4693
|
} else if (host.exists(BOOTSTRAP_RELEASE_EVIDENCE)) {
|
|
4690
4694
|
let evidence;
|
|
4691
4695
|
try {
|
|
@@ -4962,6 +4966,46 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4962
4966
|
await checked3(host, ["nginx", "-t"], "nginx configuration");
|
|
4963
4967
|
await checked3(host, ["systemctl", "daemon-reload"], "systemd reload");
|
|
4964
4968
|
await checked3(host, ["systemctl", "enable", "--now", "nginx.service"], "nginx supervision");
|
|
4969
|
+
if (alreadyEnrolled && !bootstrapManifest) {
|
|
4970
|
+
const healthCommand = [
|
|
4971
|
+
"curl",
|
|
4972
|
+
"--fail",
|
|
4973
|
+
"--silent",
|
|
4974
|
+
"--show-error",
|
|
4975
|
+
"--max-time",
|
|
4976
|
+
"10",
|
|
4977
|
+
`http://127.0.0.1:${runtime.environment.publicApiPort}${runtime.healthPath}`
|
|
4978
|
+
];
|
|
4979
|
+
const health = await host.exec(healthCommand);
|
|
4980
|
+
if (health.exitCode !== 0) {
|
|
4981
|
+
const activeSlotFile = `${runtime.slotsDirectory}/.active`;
|
|
4982
|
+
if (!host.exists(activeSlotFile))
|
|
4983
|
+
throw new Error("enrolled platform active API slot evidence is missing");
|
|
4984
|
+
const activeSlot = host.read(activeSlotFile).trim();
|
|
4985
|
+
if (activeSlot !== "blue" && activeSlot !== "green") {
|
|
4986
|
+
throw new Error("enrolled platform active API slot evidence is malformed");
|
|
4987
|
+
}
|
|
4988
|
+
await checked3(host, ["systemctl", "start", `forgezero@${activeSlot}.service`], "active API slot repair");
|
|
4989
|
+
let ready = false;
|
|
4990
|
+
let lastHealthOutput = "";
|
|
4991
|
+
for (let attempt = 0;attempt < 30; attempt += 1) {
|
|
4992
|
+
const repairedHealth = await host.exec(healthCommand);
|
|
4993
|
+
if (repairedHealth.exitCode === 0) {
|
|
4994
|
+
ready = true;
|
|
4995
|
+
break;
|
|
4996
|
+
}
|
|
4997
|
+
lastHealthOutput = repairedHealth.output.trim();
|
|
4998
|
+
if (attempt < 29)
|
|
4999
|
+
await (host.sleep?.(1000) ?? Bun.sleep(1000));
|
|
5000
|
+
}
|
|
5001
|
+
if (!ready)
|
|
5002
|
+
throw new Error(`repaired API health failed: ${lastHealthOutput || "readiness deadline exceeded"}`);
|
|
5003
|
+
}
|
|
5004
|
+
if (redundantBootstrapBundle) {
|
|
5005
|
+
host.remove(config.bootstrapBundle.bundleFile);
|
|
5006
|
+
host.remove(config.bootstrapBundle.manifestFile);
|
|
5007
|
+
}
|
|
5008
|
+
}
|
|
4965
5009
|
if (config.database.role === "master") {
|
|
4966
5010
|
const invite = `${runtime.environment.sharedDirectory}/platform-invite.token`;
|
|
4967
5011
|
if (!host.exists(invite)) {
|
|
@@ -7353,7 +7397,7 @@ async function applyOperatorPlatformBootstrap(request, mode, options = {}) {
|
|
|
7353
7397
|
` : undefined, mode === "apply");
|
|
7354
7398
|
return { plan, output };
|
|
7355
7399
|
} finally {
|
|
7356
|
-
if (knownHosts) {
|
|
7400
|
+
if (knownHosts && mode !== "status") {
|
|
7357
7401
|
await remote(exec, request, knownHosts, ["/usr/bin/sudo", "-n", "/usr/bin/rm", "-rf", "--", REMOTE_STAGE, remoteTemp], "remote bootstrap cleanup", true).catch(() => {
|
|
7358
7402
|
return;
|
|
7359
7403
|
});
|
|
@@ -3020,7 +3020,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
3020
3020
|
}
|
|
3021
3021
|
|
|
3022
3022
|
// src/version.ts
|
|
3023
|
-
var VERSION3 = "0.1.
|
|
3023
|
+
var VERSION3 = "0.1.130";
|
|
3024
3024
|
|
|
3025
3025
|
// src/egress-policy.ts
|
|
3026
3026
|
import { realpathSync as realpathSync3 } from "node:fs";
|
package/dist/provision.js
CHANGED
|
@@ -3020,7 +3020,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
3020
3020
|
}
|
|
3021
3021
|
|
|
3022
3022
|
// src/version.ts
|
|
3023
|
-
var VERSION3 = "0.1.
|
|
3023
|
+
var VERSION3 = "0.1.130";
|
|
3024
3024
|
|
|
3025
3025
|
// src/egress-policy.ts
|
|
3026
3026
|
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.130";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgezero/agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.130",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"check": "tsc --noEmit",
|
|
@@ -16,8 +16,8 @@
|
|
|
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.21",
|
|
20
|
+
"@forgezero/vault": "0.1.27",
|
|
21
21
|
"@noble/curves": "2.2.0",
|
|
22
22
|
"@noble/hashes": "2.2.0",
|
|
23
23
|
"@noble/post-quantum": "0.6.1",
|