@forgezero/agent 0.1.137 → 0.1.138
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/attended-platform-bootstrap.d.ts +6 -0
- package/dist/bootstrap.js +1 -1
- package/dist/fz-agent.js +14 -2
- package/dist/fz.js +34 -1
- package/dist/metal-bootstrap.js +1 -1
- package/dist/operator-bootstrap.js +1 -1
- package/dist/platform-bootstrap-runtime.js +13 -1
- package/dist/platform-fleet-verification.js +14 -2
- package/dist/provision.js +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/agent-heartbeat.js
CHANGED
|
@@ -12,8 +12,14 @@ export interface AttendedPlatformBootstrapResult {
|
|
|
12
12
|
export interface AttendedPlatformBootstrapDependencies {
|
|
13
13
|
cloudflare?: typeof runAttendedCloudflareBootstrap;
|
|
14
14
|
fleet?: typeof applyOperatorPlatformFleetBootstrap;
|
|
15
|
+
validateInvite?: typeof validatePlatformInvitation;
|
|
15
16
|
finalize?: typeof finalizeCloudflareBootstrapAcceptance;
|
|
16
17
|
}
|
|
18
|
+
export declare function validatePlatformInvitation(args: {
|
|
19
|
+
apiOrigin: string;
|
|
20
|
+
inviteUrl: string;
|
|
21
|
+
fetcher?: typeof fetch;
|
|
22
|
+
}): Promise<void>;
|
|
17
23
|
/**
|
|
18
24
|
* The sole attended genesis composition boundary. All non-secret coordinates
|
|
19
25
|
* are checked before the first Cloudflare or SSH mutation. Secret values exist
|
package/dist/bootstrap.js
CHANGED
package/dist/fz-agent.js
CHANGED
|
@@ -9683,7 +9683,7 @@ async function writeAndCloseProcessInput(input, value) {
|
|
|
9683
9683
|
}
|
|
9684
9684
|
|
|
9685
9685
|
// src/version.ts
|
|
9686
|
-
var VERSION2 = "0.1.
|
|
9686
|
+
var VERSION2 = "0.1.138";
|
|
9687
9687
|
|
|
9688
9688
|
// src/ssh-bootstrap.ts
|
|
9689
9689
|
function deriveMetalAdmissionProvisioning(lscpu) {
|
|
@@ -15432,7 +15432,17 @@ async function activatePlatformRelease(config, requestedRelease, options = {}) {
|
|
|
15432
15432
|
const slots = join10(normalized.root, "slots");
|
|
15433
15433
|
mkdirSync14(slots, { recursive: true, mode: 493 });
|
|
15434
15434
|
const slotFile = join10(slots, ".active");
|
|
15435
|
-
|
|
15435
|
+
let previousSlot = existsSync19(slotFile) ? readFileSync14(slotFile, "utf8").trim() : undefined;
|
|
15436
|
+
if (previousSlot !== "blue" && previousSlot !== "green") {
|
|
15437
|
+
previousSlot = undefined;
|
|
15438
|
+
for (const candidate of ["blue", "green"]) {
|
|
15439
|
+
const active = await exec(["/usr/bin/systemctl", "is-active", "--quiet", `forgezero@${candidate}.service`]);
|
|
15440
|
+
if (active.exitCode === 0) {
|
|
15441
|
+
previousSlot = candidate;
|
|
15442
|
+
break;
|
|
15443
|
+
}
|
|
15444
|
+
}
|
|
15445
|
+
}
|
|
15436
15446
|
const target2 = previousSlot === "blue" ? "green" : "blue";
|
|
15437
15447
|
const port = target2 === "blue" ? normalized.bluePort : normalized.greenPort;
|
|
15438
15448
|
const targetLink = join10(slots, target2);
|
|
@@ -15465,6 +15475,8 @@ async function activatePlatformRelease(config, requestedRelease, options = {}) {
|
|
|
15465
15475
|
const stopTarget = async () => {
|
|
15466
15476
|
await exec(["/usr/bin/systemctl", "stop", service]);
|
|
15467
15477
|
replaceLink(targetLink, previousTarget);
|
|
15478
|
+
if (previousSlot)
|
|
15479
|
+
await exec(["/usr/bin/systemctl", "start", `forgezero@${previousSlot}.service`]);
|
|
15468
15480
|
};
|
|
15469
15481
|
if (!healthy) {
|
|
15470
15482
|
await stopTarget();
|
package/dist/fz.js
CHANGED
|
@@ -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.138";
|
|
6011
6011
|
|
|
6012
6012
|
// src/software.ts
|
|
6013
6013
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -18401,6 +18401,35 @@ var invitationFrom = (fleet, master) => {
|
|
|
18401
18401
|
} catch {}
|
|
18402
18402
|
throw new Error("platform bootstrap completed without the initial custodian invitation");
|
|
18403
18403
|
};
|
|
18404
|
+
async function validatePlatformInvitation(args) {
|
|
18405
|
+
let invite;
|
|
18406
|
+
let api;
|
|
18407
|
+
try {
|
|
18408
|
+
invite = new URL(args.inviteUrl);
|
|
18409
|
+
api = new URL(args.apiOrigin);
|
|
18410
|
+
} catch {
|
|
18411
|
+
throw new Error("platform bootstrap produced malformed public invitation coordinates");
|
|
18412
|
+
}
|
|
18413
|
+
const token = invite.searchParams.get("token") ?? "";
|
|
18414
|
+
if (invite.protocol !== "https:" || api.protocol !== "https:" || !/^plt_[a-f0-9]{48}$/.test(token)) {
|
|
18415
|
+
throw new Error("platform bootstrap produced malformed public invitation coordinates");
|
|
18416
|
+
}
|
|
18417
|
+
const endpoint2 = new URL(`/api/onboarding/invite/${encodeURIComponent(token)}`, api);
|
|
18418
|
+
let response;
|
|
18419
|
+
try {
|
|
18420
|
+
response = await (args.fetcher ?? fetch)(endpoint2, {
|
|
18421
|
+
headers: { accept: "application/json" },
|
|
18422
|
+
cache: "no-store",
|
|
18423
|
+
signal: AbortSignal.timeout(15000)
|
|
18424
|
+
});
|
|
18425
|
+
} catch {
|
|
18426
|
+
throw new Error("platform bootstrap invitation could not be verified through public ingress");
|
|
18427
|
+
}
|
|
18428
|
+
const body = await response.json().catch(() => null);
|
|
18429
|
+
if (!response.ok || body?.ok !== true || body.kind !== "platform-bootstrap" || body.claimable !== true) {
|
|
18430
|
+
throw new Error("platform bootstrap invitation is not claimable; the environment was repaired from existing state instead of clean genesis");
|
|
18431
|
+
}
|
|
18432
|
+
}
|
|
18404
18433
|
async function applyAttendedPlatformBootstrap(fleetRequest, cloudflareRequest, acceptancePath, secrets, dependencies = {}) {
|
|
18405
18434
|
if (cloudflareRequest.mode !== "apply")
|
|
18406
18435
|
throw new Error("attended platform bootstrap requires Cloudflare apply mode");
|
|
@@ -18425,6 +18454,10 @@ async function applyAttendedPlatformBootstrap(fleetRequest, cloudflareRequest, a
|
|
|
18425
18454
|
if (!fleet.ok)
|
|
18426
18455
|
return { kind: "forgezero-attended-platform-bootstrap", ok: false, edge, fleet };
|
|
18427
18456
|
const inviteUrl = invitationFrom(fleet, fleetCoordinates.nodes[0].computeReference);
|
|
18457
|
+
await (dependencies.validateInvite ?? validatePlatformInvitation)({
|
|
18458
|
+
apiOrigin: fleetCoordinates.apiOrigin,
|
|
18459
|
+
inviteUrl
|
|
18460
|
+
});
|
|
18428
18461
|
const acceptance = await (dependencies.finalize ?? finalizeCloudflareBootstrapAcceptance)({
|
|
18429
18462
|
checkpointPath: edge.checkpointFile,
|
|
18430
18463
|
acceptancePath
|
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.138";
|
|
370
370
|
|
|
371
371
|
// src/otel-collector.ts
|
|
372
372
|
var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
|
|
@@ -1260,7 +1260,17 @@ async function activatePlatformRelease(config, requestedRelease, options = {}) {
|
|
|
1260
1260
|
const slots = join2(normalized.root, "slots");
|
|
1261
1261
|
mkdirSync2(slots, { recursive: true, mode: 493 });
|
|
1262
1262
|
const slotFile = join2(slots, ".active");
|
|
1263
|
-
|
|
1263
|
+
let previousSlot = existsSync2(slotFile) ? readFileSync2(slotFile, "utf8").trim() : undefined;
|
|
1264
|
+
if (previousSlot !== "blue" && previousSlot !== "green") {
|
|
1265
|
+
previousSlot = undefined;
|
|
1266
|
+
for (const candidate of ["blue", "green"]) {
|
|
1267
|
+
const active = await exec(["/usr/bin/systemctl", "is-active", "--quiet", `forgezero@${candidate}.service`]);
|
|
1268
|
+
if (active.exitCode === 0) {
|
|
1269
|
+
previousSlot = candidate;
|
|
1270
|
+
break;
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1264
1274
|
const target = previousSlot === "blue" ? "green" : "blue";
|
|
1265
1275
|
const port = target === "blue" ? normalized.bluePort : normalized.greenPort;
|
|
1266
1276
|
const targetLink = join2(slots, target);
|
|
@@ -1293,6 +1303,8 @@ async function activatePlatformRelease(config, requestedRelease, options = {}) {
|
|
|
1293
1303
|
const stopTarget = async () => {
|
|
1294
1304
|
await exec(["/usr/bin/systemctl", "stop", service]);
|
|
1295
1305
|
replaceLink(targetLink, previousTarget);
|
|
1306
|
+
if (previousSlot)
|
|
1307
|
+
await exec(["/usr/bin/systemctl", "start", `forgezero@${previousSlot}.service`]);
|
|
1296
1308
|
};
|
|
1297
1309
|
if (!healthy) {
|
|
1298
1310
|
await stopTarget();
|
|
@@ -3049,7 +3049,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
3049
3049
|
}
|
|
3050
3050
|
|
|
3051
3051
|
// src/version.ts
|
|
3052
|
-
var VERSION3 = "0.1.
|
|
3052
|
+
var VERSION3 = "0.1.138";
|
|
3053
3053
|
|
|
3054
3054
|
// src/egress-policy.ts
|
|
3055
3055
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
@@ -4776,7 +4776,17 @@ async function activatePlatformRelease(config, requestedRelease, options = {}) {
|
|
|
4776
4776
|
const slots = join5(normalized.root, "slots");
|
|
4777
4777
|
mkdirSync8(slots, { recursive: true, mode: 493 });
|
|
4778
4778
|
const slotFile = join5(slots, ".active");
|
|
4779
|
-
|
|
4779
|
+
let previousSlot = existsSync8(slotFile) ? readFileSync6(slotFile, "utf8").trim() : undefined;
|
|
4780
|
+
if (previousSlot !== "blue" && previousSlot !== "green") {
|
|
4781
|
+
previousSlot = undefined;
|
|
4782
|
+
for (const candidate of ["blue", "green"]) {
|
|
4783
|
+
const active = await exec(["/usr/bin/systemctl", "is-active", "--quiet", `forgezero@${candidate}.service`]);
|
|
4784
|
+
if (active.exitCode === 0) {
|
|
4785
|
+
previousSlot = candidate;
|
|
4786
|
+
break;
|
|
4787
|
+
}
|
|
4788
|
+
}
|
|
4789
|
+
}
|
|
4780
4790
|
const target = previousSlot === "blue" ? "green" : "blue";
|
|
4781
4791
|
const port = target === "blue" ? normalized.bluePort : normalized.greenPort;
|
|
4782
4792
|
const targetLink = join5(slots, target);
|
|
@@ -4809,6 +4819,8 @@ async function activatePlatformRelease(config, requestedRelease, options = {}) {
|
|
|
4809
4819
|
const stopTarget = async () => {
|
|
4810
4820
|
await exec(["/usr/bin/systemctl", "stop", service]);
|
|
4811
4821
|
replaceLink(targetLink, previousTarget);
|
|
4822
|
+
if (previousSlot)
|
|
4823
|
+
await exec(["/usr/bin/systemctl", "start", `forgezero@${previousSlot}.service`]);
|
|
4812
4824
|
};
|
|
4813
4825
|
if (!healthy) {
|
|
4814
4826
|
await stopTarget();
|
package/dist/provision.js
CHANGED
|
@@ -3049,7 +3049,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
3049
3049
|
}
|
|
3050
3050
|
|
|
3051
3051
|
// src/version.ts
|
|
3052
|
-
var VERSION3 = "0.1.
|
|
3052
|
+
var VERSION3 = "0.1.138";
|
|
3053
3053
|
|
|
3054
3054
|
// src/egress-policy.ts
|
|
3055
3055
|
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.138";
|