@forgezero/agent 0.1.124 → 0.1.125
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 +1 -1
- package/dist/community-rehearsal-host.d.ts +9 -0
- package/dist/community-rehearsal-host.js +120 -0
- package/dist/fz-agent.js +117 -1
- package/dist/fz.js +1 -1
- package/dist/metal-bootstrap.js +1 -1
- package/dist/operator-bootstrap.js +1 -1
- 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/dist/agent-heartbeat.js
CHANGED
package/dist/bootstrap.js
CHANGED
|
@@ -9,6 +9,8 @@ export declare const COMMUNITY_REHEARSAL_COORDINATOR_PORT = 18529;
|
|
|
9
9
|
export declare const COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE = "18528:18539";
|
|
10
10
|
export declare const COMMUNITY_REHEARSAL_API_PORT = 18787;
|
|
11
11
|
export declare const COMMUNITY_REHEARSAL_FIREWALL_COMMENT = "fz-community-rehearsal";
|
|
12
|
+
export declare const COMMUNITY_REHEARSAL_EGRESS_TABLE = "forgezero_agent_egress";
|
|
13
|
+
export declare const COMMUNITY_REHEARSAL_EGRESS_CHAIN = "output";
|
|
12
14
|
export interface CommunityRehearsalNode {
|
|
13
15
|
name: string;
|
|
14
16
|
address: string;
|
|
@@ -48,6 +50,11 @@ export type CommunityHostOperation = {
|
|
|
48
50
|
path: typeof COMMUNITY_DATABASE_ROOT | typeof COMMUNITY_REHEARSAL_ROOT | typeof COMMUNITY_CREDENTIAL_PARENT;
|
|
49
51
|
} | {
|
|
50
52
|
kind: 'clear-firewall';
|
|
53
|
+
} | {
|
|
54
|
+
kind: 'prepare-egress';
|
|
55
|
+
addresses: readonly string[];
|
|
56
|
+
} | {
|
|
57
|
+
kind: 'clear-egress';
|
|
51
58
|
} | {
|
|
52
59
|
kind: 'write';
|
|
53
60
|
path: string;
|
|
@@ -75,5 +82,7 @@ export declare function planCommunityRehearsalPrepare(request: Extract<Community
|
|
|
75
82
|
/** Remove only the dedicated rehearsal units, credentials, release and data. */
|
|
76
83
|
export declare function planCommunityRehearsalCleanup(): CommunityHostOperation[];
|
|
77
84
|
export declare function communityRehearsalFirewallRuleNumbers(status: string): number[];
|
|
85
|
+
export declare function communityRehearsalEgressRuleHandles(ruleset: string): number[];
|
|
86
|
+
export declare function communityRehearsalEgressRuleArguments(uid: string, addresses: readonly string[]): readonly (readonly string[])[];
|
|
78
87
|
/** Execute only the dedicated four-node rehearsal operation selected by a typed request. */
|
|
79
88
|
export declare function runCommunityRehearsalHost(request: CommunityRehearsalHostRequest): Promise<Record<string, unknown>>;
|
|
@@ -577,6 +577,8 @@ var COMMUNITY_REHEARSAL_COORDINATOR_PORT = 18529;
|
|
|
577
577
|
var COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE = "18528:18539";
|
|
578
578
|
var COMMUNITY_REHEARSAL_API_PORT = 18787;
|
|
579
579
|
var COMMUNITY_REHEARSAL_FIREWALL_COMMENT = "fz-community-rehearsal";
|
|
580
|
+
var COMMUNITY_REHEARSAL_EGRESS_TABLE = "forgezero_agent_egress";
|
|
581
|
+
var COMMUNITY_REHEARSAL_EGRESS_CHAIN = "output";
|
|
580
582
|
var RELEASE = /^[a-f0-9]{64}$/;
|
|
581
583
|
var SAFE_NAME = /^[a-z][a-z0-9-]{0,62}$/;
|
|
582
584
|
async function ensureCommunityRehearsalArango(execute = executeSoftwareOperation) {
|
|
@@ -740,6 +742,7 @@ function planCommunityRehearsalPrepare(request) {
|
|
|
740
742
|
{ kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-community-api.service"], accepted: [0, 5] },
|
|
741
743
|
{ kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-rehearsal-db.service"], accepted: [0, 5] },
|
|
742
744
|
{ kind: "clear-firewall" },
|
|
745
|
+
{ kind: "prepare-egress", addresses: topology.map(({ address }) => address) },
|
|
743
746
|
...topology.map(({ address }) => ({
|
|
744
747
|
kind: "exec",
|
|
745
748
|
argv: [
|
|
@@ -802,6 +805,7 @@ function planCommunityRehearsalCleanup() {
|
|
|
802
805
|
{ kind: "remove-tree", path: COMMUNITY_DATABASE_ROOT },
|
|
803
806
|
{ kind: "remove-tree", path: COMMUNITY_REHEARSAL_ROOT },
|
|
804
807
|
{ kind: "remove-tree", path: COMMUNITY_CREDENTIAL_PARENT },
|
|
808
|
+
{ kind: "clear-egress" },
|
|
805
809
|
{ kind: "clear-firewall" },
|
|
806
810
|
{ kind: "exec", argv: ["/usr/bin/systemctl", "daemon-reload"] },
|
|
807
811
|
{ kind: "exec", argv: ["/usr/bin/systemctl", "reset-failed", "forgezero-community-api.service", "forgezero-rehearsal-db.service"], accepted: [0, 1, 5] }
|
|
@@ -824,6 +828,10 @@ async function applyOperations(operations) {
|
|
|
824
828
|
rmSync2(operation.path, { recursive: true, force: true });
|
|
825
829
|
else if (operation.kind === "clear-firewall")
|
|
826
830
|
await clearCommunityRehearsalFirewall();
|
|
831
|
+
else if (operation.kind === "prepare-egress")
|
|
832
|
+
await prepareCommunityRehearsalEgress(operation.addresses);
|
|
833
|
+
else if (operation.kind === "clear-egress")
|
|
834
|
+
await clearCommunityRehearsalEgress();
|
|
827
835
|
else if (operation.kind === "write") {
|
|
828
836
|
mkdirSync2(dirname2(operation.path), { recursive: true });
|
|
829
837
|
writeFileSync2(operation.path, operation.content, { mode: operation.mode });
|
|
@@ -854,6 +862,49 @@ function communityRehearsalFirewallRuleNumbers(status) {
|
|
|
854
862
|
return match ? [Number(match[1])] : [];
|
|
855
863
|
}).filter((number) => Number.isSafeInteger(number) && number > 0).sort((left, right) => right - left);
|
|
856
864
|
}
|
|
865
|
+
function communityRehearsalEgressRuleHandles(ruleset) {
|
|
866
|
+
return ruleset.split(/\r?\n/).flatMap((line) => {
|
|
867
|
+
if (!line.includes(`comment "${COMMUNITY_REHEARSAL_FIREWALL_COMMENT}"`))
|
|
868
|
+
return [];
|
|
869
|
+
const match = line.match(/# handle (\d+)\s*$/);
|
|
870
|
+
return match ? [Number(match[1])] : [];
|
|
871
|
+
}).filter((number) => Number.isSafeInteger(number) && number > 0).sort((left, right) => right - left);
|
|
872
|
+
}
|
|
873
|
+
function communityRehearsalEgressRuleArguments(uid, addresses) {
|
|
874
|
+
if (!/^\d+$/.test(uid) || addresses.some((address) => isIP(address) !== 4) || new Set(addresses).size !== addresses.length) {
|
|
875
|
+
throw new Error("rehearsal egress arguments require one uid and unique IPv4 addresses");
|
|
876
|
+
}
|
|
877
|
+
return addresses.flatMap((address) => [
|
|
878
|
+
[
|
|
879
|
+
"meta",
|
|
880
|
+
"skuid",
|
|
881
|
+
uid,
|
|
882
|
+
"ct",
|
|
883
|
+
"state",
|
|
884
|
+
"established,related",
|
|
885
|
+
"ip",
|
|
886
|
+
"daddr",
|
|
887
|
+
address,
|
|
888
|
+
"accept",
|
|
889
|
+
"comment",
|
|
890
|
+
COMMUNITY_REHEARSAL_FIREWALL_COMMENT
|
|
891
|
+
],
|
|
892
|
+
[
|
|
893
|
+
"meta",
|
|
894
|
+
"skuid",
|
|
895
|
+
uid,
|
|
896
|
+
"ip",
|
|
897
|
+
"daddr",
|
|
898
|
+
address,
|
|
899
|
+
"tcp",
|
|
900
|
+
"dport",
|
|
901
|
+
String(COMMUNITY_REHEARSAL_COORDINATOR_PORT),
|
|
902
|
+
"accept",
|
|
903
|
+
"comment",
|
|
904
|
+
COMMUNITY_REHEARSAL_FIREWALL_COMMENT
|
|
905
|
+
]
|
|
906
|
+
]);
|
|
907
|
+
}
|
|
857
908
|
async function clearCommunityRehearsalFirewall() {
|
|
858
909
|
const status = await exec(["/usr/sbin/ufw", "status", "numbered"]);
|
|
859
910
|
if (status.exitCode !== 0)
|
|
@@ -865,6 +916,71 @@ async function clearCommunityRehearsalFirewall() {
|
|
|
865
916
|
}
|
|
866
917
|
}
|
|
867
918
|
}
|
|
919
|
+
var rehearsalEgressRules = async () => {
|
|
920
|
+
const result = await exec([
|
|
921
|
+
"/usr/sbin/nft",
|
|
922
|
+
"-a",
|
|
923
|
+
"list",
|
|
924
|
+
"chain",
|
|
925
|
+
"inet",
|
|
926
|
+
COMMUNITY_REHEARSAL_EGRESS_TABLE,
|
|
927
|
+
COMMUNITY_REHEARSAL_EGRESS_CHAIN
|
|
928
|
+
]);
|
|
929
|
+
if (result.exitCode === 0)
|
|
930
|
+
return { exists: true, output: result.output };
|
|
931
|
+
if (/No such file or directory|does not exist/i.test(result.output))
|
|
932
|
+
return { exists: false, output: result.output };
|
|
933
|
+
throw new Error(`unable to inspect rehearsal egress rules: ${result.output.trim()}`);
|
|
934
|
+
};
|
|
935
|
+
async function clearCommunityRehearsalEgress() {
|
|
936
|
+
const listed = await rehearsalEgressRules();
|
|
937
|
+
if (!listed.exists)
|
|
938
|
+
return;
|
|
939
|
+
for (const handle of communityRehearsalEgressRuleHandles(listed.output)) {
|
|
940
|
+
const removed = await exec([
|
|
941
|
+
"/usr/sbin/nft",
|
|
942
|
+
"delete",
|
|
943
|
+
"rule",
|
|
944
|
+
"inet",
|
|
945
|
+
COMMUNITY_REHEARSAL_EGRESS_TABLE,
|
|
946
|
+
COMMUNITY_REHEARSAL_EGRESS_CHAIN,
|
|
947
|
+
"handle",
|
|
948
|
+
String(handle)
|
|
949
|
+
]);
|
|
950
|
+
if (removed.exitCode !== 0) {
|
|
951
|
+
throw new Error(`unable to remove rehearsal egress rule ${handle}: ${removed.output.trim()}`);
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
}
|
|
955
|
+
async function prepareCommunityRehearsalEgress(addresses) {
|
|
956
|
+
await clearCommunityRehearsalEgress();
|
|
957
|
+
if (!(await rehearsalEgressRules()).exists)
|
|
958
|
+
return;
|
|
959
|
+
const identity = await exec(["/usr/bin/id", "-u", "forgezero"]);
|
|
960
|
+
const uid = identity.output.trim();
|
|
961
|
+
if (identity.exitCode !== 0 || !/^\d+$/.test(uid))
|
|
962
|
+
throw new Error("unable to resolve the forgezero service uid");
|
|
963
|
+
for (const rule of communityRehearsalEgressRuleArguments(uid, addresses)) {
|
|
964
|
+
const inserted = await exec([
|
|
965
|
+
"/usr/sbin/nft",
|
|
966
|
+
"insert",
|
|
967
|
+
"rule",
|
|
968
|
+
"inet",
|
|
969
|
+
COMMUNITY_REHEARSAL_EGRESS_TABLE,
|
|
970
|
+
COMMUNITY_REHEARSAL_EGRESS_CHAIN,
|
|
971
|
+
...rule
|
|
972
|
+
]);
|
|
973
|
+
if (inserted.exitCode !== 0) {
|
|
974
|
+
await clearCommunityRehearsalEgress();
|
|
975
|
+
throw new Error(`unable to install a rehearsal egress rule: ${inserted.output.trim()}`);
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
const installed = communityRehearsalEgressRuleHandles((await rehearsalEgressRules()).output);
|
|
979
|
+
if (installed.length !== addresses.length * 2) {
|
|
980
|
+
await clearCommunityRehearsalEgress();
|
|
981
|
+
throw new Error("rehearsal egress rule verification failed");
|
|
982
|
+
}
|
|
983
|
+
}
|
|
868
984
|
var responseFor = async (request) => {
|
|
869
985
|
const node = request.topology.find((entry) => entry.name === request.node);
|
|
870
986
|
const base = `http://${node.address}:${COMMUNITY_REHEARSAL_API_PORT}`;
|
|
@@ -953,10 +1069,14 @@ export {
|
|
|
953
1069
|
parseCommunityRehearsalHostRequest,
|
|
954
1070
|
ensureCommunityRehearsalArango,
|
|
955
1071
|
communityRehearsalFirewallRuleNumbers,
|
|
1072
|
+
communityRehearsalEgressRuleHandles,
|
|
1073
|
+
communityRehearsalEgressRuleArguments,
|
|
956
1074
|
COMMUNITY_REHEARSAL_VERSION,
|
|
957
1075
|
COMMUNITY_REHEARSAL_STARTER_PORT,
|
|
958
1076
|
COMMUNITY_REHEARSAL_ROOT,
|
|
959
1077
|
COMMUNITY_REHEARSAL_FIREWALL_COMMENT,
|
|
1078
|
+
COMMUNITY_REHEARSAL_EGRESS_TABLE,
|
|
1079
|
+
COMMUNITY_REHEARSAL_EGRESS_CHAIN,
|
|
960
1080
|
COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE,
|
|
961
1081
|
COMMUNITY_REHEARSAL_COORDINATOR_PORT,
|
|
962
1082
|
COMMUNITY_REHEARSAL_API_PORT,
|
package/dist/fz-agent.js
CHANGED
|
@@ -9640,7 +9640,7 @@ async function writeAndCloseProcessInput(input, value) {
|
|
|
9640
9640
|
}
|
|
9641
9641
|
|
|
9642
9642
|
// src/version.ts
|
|
9643
|
-
var VERSION2 = "0.1.
|
|
9643
|
+
var VERSION2 = "0.1.125";
|
|
9644
9644
|
|
|
9645
9645
|
// src/ssh-bootstrap.ts
|
|
9646
9646
|
class SshBootstrapError extends Error {
|
|
@@ -17125,6 +17125,8 @@ var COMMUNITY_REHEARSAL_COORDINATOR_PORT = 18529;
|
|
|
17125
17125
|
var COMMUNITY_REHEARSAL_DATABASE_PORT_RANGE = "18528:18539";
|
|
17126
17126
|
var COMMUNITY_REHEARSAL_API_PORT = 18787;
|
|
17127
17127
|
var COMMUNITY_REHEARSAL_FIREWALL_COMMENT = "fz-community-rehearsal";
|
|
17128
|
+
var COMMUNITY_REHEARSAL_EGRESS_TABLE = "forgezero_agent_egress";
|
|
17129
|
+
var COMMUNITY_REHEARSAL_EGRESS_CHAIN = "output";
|
|
17128
17130
|
var RELEASE = /^[a-f0-9]{64}$/;
|
|
17129
17131
|
var SAFE_NAME2 = /^[a-z][a-z0-9-]{0,62}$/;
|
|
17130
17132
|
async function ensureCommunityRehearsalArango(execute3 = executeSoftwareOperation) {
|
|
@@ -17288,6 +17290,7 @@ function planCommunityRehearsalPrepare(request) {
|
|
|
17288
17290
|
{ kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-community-api.service"], accepted: [0, 5] },
|
|
17289
17291
|
{ kind: "exec", argv: ["/usr/bin/systemctl", "stop", "forgezero-rehearsal-db.service"], accepted: [0, 5] },
|
|
17290
17292
|
{ kind: "clear-firewall" },
|
|
17293
|
+
{ kind: "prepare-egress", addresses: topology.map(({ address }) => address) },
|
|
17291
17294
|
...topology.map(({ address }) => ({
|
|
17292
17295
|
kind: "exec",
|
|
17293
17296
|
argv: [
|
|
@@ -17350,6 +17353,7 @@ function planCommunityRehearsalCleanup() {
|
|
|
17350
17353
|
{ kind: "remove-tree", path: COMMUNITY_DATABASE_ROOT },
|
|
17351
17354
|
{ kind: "remove-tree", path: COMMUNITY_REHEARSAL_ROOT },
|
|
17352
17355
|
{ kind: "remove-tree", path: COMMUNITY_CREDENTIAL_PARENT },
|
|
17356
|
+
{ kind: "clear-egress" },
|
|
17353
17357
|
{ kind: "clear-firewall" },
|
|
17354
17358
|
{ kind: "exec", argv: ["/usr/bin/systemctl", "daemon-reload"] },
|
|
17355
17359
|
{ kind: "exec", argv: ["/usr/bin/systemctl", "reset-failed", "forgezero-community-api.service", "forgezero-rehearsal-db.service"], accepted: [0, 1, 5] }
|
|
@@ -17372,6 +17376,10 @@ async function applyOperations(operations) {
|
|
|
17372
17376
|
rmSync13(operation.path, { recursive: true, force: true });
|
|
17373
17377
|
else if (operation.kind === "clear-firewall")
|
|
17374
17378
|
await clearCommunityRehearsalFirewall();
|
|
17379
|
+
else if (operation.kind === "prepare-egress")
|
|
17380
|
+
await prepareCommunityRehearsalEgress(operation.addresses);
|
|
17381
|
+
else if (operation.kind === "clear-egress")
|
|
17382
|
+
await clearCommunityRehearsalEgress();
|
|
17375
17383
|
else if (operation.kind === "write") {
|
|
17376
17384
|
mkdirSync17(dirname15(operation.path), { recursive: true });
|
|
17377
17385
|
writeFileSync17(operation.path, operation.content, { mode: operation.mode });
|
|
@@ -17402,6 +17410,49 @@ function communityRehearsalFirewallRuleNumbers(status) {
|
|
|
17402
17410
|
return match ? [Number(match[1])] : [];
|
|
17403
17411
|
}).filter((number2) => Number.isSafeInteger(number2) && number2 > 0).sort((left, right) => right - left);
|
|
17404
17412
|
}
|
|
17413
|
+
function communityRehearsalEgressRuleHandles(ruleset) {
|
|
17414
|
+
return ruleset.split(/\r?\n/).flatMap((line) => {
|
|
17415
|
+
if (!line.includes(`comment "${COMMUNITY_REHEARSAL_FIREWALL_COMMENT}"`))
|
|
17416
|
+
return [];
|
|
17417
|
+
const match = line.match(/# handle (\d+)\s*$/);
|
|
17418
|
+
return match ? [Number(match[1])] : [];
|
|
17419
|
+
}).filter((number2) => Number.isSafeInteger(number2) && number2 > 0).sort((left, right) => right - left);
|
|
17420
|
+
}
|
|
17421
|
+
function communityRehearsalEgressRuleArguments(uid, addresses) {
|
|
17422
|
+
if (!/^\d+$/.test(uid) || addresses.some((address) => isIP6(address) !== 4) || new Set(addresses).size !== addresses.length) {
|
|
17423
|
+
throw new Error("rehearsal egress arguments require one uid and unique IPv4 addresses");
|
|
17424
|
+
}
|
|
17425
|
+
return addresses.flatMap((address) => [
|
|
17426
|
+
[
|
|
17427
|
+
"meta",
|
|
17428
|
+
"skuid",
|
|
17429
|
+
uid,
|
|
17430
|
+
"ct",
|
|
17431
|
+
"state",
|
|
17432
|
+
"established,related",
|
|
17433
|
+
"ip",
|
|
17434
|
+
"daddr",
|
|
17435
|
+
address,
|
|
17436
|
+
"accept",
|
|
17437
|
+
"comment",
|
|
17438
|
+
COMMUNITY_REHEARSAL_FIREWALL_COMMENT
|
|
17439
|
+
],
|
|
17440
|
+
[
|
|
17441
|
+
"meta",
|
|
17442
|
+
"skuid",
|
|
17443
|
+
uid,
|
|
17444
|
+
"ip",
|
|
17445
|
+
"daddr",
|
|
17446
|
+
address,
|
|
17447
|
+
"tcp",
|
|
17448
|
+
"dport",
|
|
17449
|
+
String(COMMUNITY_REHEARSAL_COORDINATOR_PORT),
|
|
17450
|
+
"accept",
|
|
17451
|
+
"comment",
|
|
17452
|
+
COMMUNITY_REHEARSAL_FIREWALL_COMMENT
|
|
17453
|
+
]
|
|
17454
|
+
]);
|
|
17455
|
+
}
|
|
17405
17456
|
async function clearCommunityRehearsalFirewall() {
|
|
17406
17457
|
const status = await exec(["/usr/sbin/ufw", "status", "numbered"]);
|
|
17407
17458
|
if (status.exitCode !== 0)
|
|
@@ -17413,6 +17464,71 @@ async function clearCommunityRehearsalFirewall() {
|
|
|
17413
17464
|
}
|
|
17414
17465
|
}
|
|
17415
17466
|
}
|
|
17467
|
+
var rehearsalEgressRules = async () => {
|
|
17468
|
+
const result = await exec([
|
|
17469
|
+
"/usr/sbin/nft",
|
|
17470
|
+
"-a",
|
|
17471
|
+
"list",
|
|
17472
|
+
"chain",
|
|
17473
|
+
"inet",
|
|
17474
|
+
COMMUNITY_REHEARSAL_EGRESS_TABLE,
|
|
17475
|
+
COMMUNITY_REHEARSAL_EGRESS_CHAIN
|
|
17476
|
+
]);
|
|
17477
|
+
if (result.exitCode === 0)
|
|
17478
|
+
return { exists: true, output: result.output };
|
|
17479
|
+
if (/No such file or directory|does not exist/i.test(result.output))
|
|
17480
|
+
return { exists: false, output: result.output };
|
|
17481
|
+
throw new Error(`unable to inspect rehearsal egress rules: ${result.output.trim()}`);
|
|
17482
|
+
};
|
|
17483
|
+
async function clearCommunityRehearsalEgress() {
|
|
17484
|
+
const listed = await rehearsalEgressRules();
|
|
17485
|
+
if (!listed.exists)
|
|
17486
|
+
return;
|
|
17487
|
+
for (const handle of communityRehearsalEgressRuleHandles(listed.output)) {
|
|
17488
|
+
const removed = await exec([
|
|
17489
|
+
"/usr/sbin/nft",
|
|
17490
|
+
"delete",
|
|
17491
|
+
"rule",
|
|
17492
|
+
"inet",
|
|
17493
|
+
COMMUNITY_REHEARSAL_EGRESS_TABLE,
|
|
17494
|
+
COMMUNITY_REHEARSAL_EGRESS_CHAIN,
|
|
17495
|
+
"handle",
|
|
17496
|
+
String(handle)
|
|
17497
|
+
]);
|
|
17498
|
+
if (removed.exitCode !== 0) {
|
|
17499
|
+
throw new Error(`unable to remove rehearsal egress rule ${handle}: ${removed.output.trim()}`);
|
|
17500
|
+
}
|
|
17501
|
+
}
|
|
17502
|
+
}
|
|
17503
|
+
async function prepareCommunityRehearsalEgress(addresses) {
|
|
17504
|
+
await clearCommunityRehearsalEgress();
|
|
17505
|
+
if (!(await rehearsalEgressRules()).exists)
|
|
17506
|
+
return;
|
|
17507
|
+
const identity = await exec(["/usr/bin/id", "-u", "forgezero"]);
|
|
17508
|
+
const uid = identity.output.trim();
|
|
17509
|
+
if (identity.exitCode !== 0 || !/^\d+$/.test(uid))
|
|
17510
|
+
throw new Error("unable to resolve the forgezero service uid");
|
|
17511
|
+
for (const rule of communityRehearsalEgressRuleArguments(uid, addresses)) {
|
|
17512
|
+
const inserted = await exec([
|
|
17513
|
+
"/usr/sbin/nft",
|
|
17514
|
+
"insert",
|
|
17515
|
+
"rule",
|
|
17516
|
+
"inet",
|
|
17517
|
+
COMMUNITY_REHEARSAL_EGRESS_TABLE,
|
|
17518
|
+
COMMUNITY_REHEARSAL_EGRESS_CHAIN,
|
|
17519
|
+
...rule
|
|
17520
|
+
]);
|
|
17521
|
+
if (inserted.exitCode !== 0) {
|
|
17522
|
+
await clearCommunityRehearsalEgress();
|
|
17523
|
+
throw new Error(`unable to install a rehearsal egress rule: ${inserted.output.trim()}`);
|
|
17524
|
+
}
|
|
17525
|
+
}
|
|
17526
|
+
const installed = communityRehearsalEgressRuleHandles((await rehearsalEgressRules()).output);
|
|
17527
|
+
if (installed.length !== addresses.length * 2) {
|
|
17528
|
+
await clearCommunityRehearsalEgress();
|
|
17529
|
+
throw new Error("rehearsal egress rule verification failed");
|
|
17530
|
+
}
|
|
17531
|
+
}
|
|
17416
17532
|
var responseFor = async (request) => {
|
|
17417
17533
|
const node = request.topology.find((entry) => entry.name === request.node);
|
|
17418
17534
|
const base = `http://${node.address}:${COMMUNITY_REHEARSAL_API_PORT}`;
|
package/dist/fz.js
CHANGED
|
@@ -4844,7 +4844,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
|
|
|
4844
4844
|
var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
|
|
4845
4845
|
|
|
4846
4846
|
// src/version.ts
|
|
4847
|
-
var VERSION2 = "0.1.
|
|
4847
|
+
var VERSION2 = "0.1.125";
|
|
4848
4848
|
|
|
4849
4849
|
// src/software.ts
|
|
4850
4850
|
var PINNED_BUN_VERSION = "1.3.14";
|
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.125";
|
|
370
370
|
|
|
371
371
|
// src/otel-collector.ts
|
|
372
372
|
var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
|
|
@@ -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.125";
|
|
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.125";
|
|
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.125";
|