@forgezero/agent 0.1.62 → 0.1.64
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 +45 -16
- package/dist/agent-heartbeat.js +1 -1
- package/dist/bootstrap-bundle.d.ts +31 -0
- package/dist/bootstrap-bundle.js +165 -0
- package/dist/bootstrap.d.ts +24 -18
- package/dist/bootstrap.js +509 -269
- package/dist/cli/agent-install.d.ts +2 -0
- package/dist/community-rehearsal-host.js +7 -5
- package/dist/definition.js +7 -5
- package/dist/deploy-file.js +7 -5
- package/dist/deployment.d.ts +27 -0
- package/dist/fz-agent.js +594 -421
- package/dist/fz.js +847 -372
- package/dist/metal-bootstrap.js +1 -1
- package/dist/metal-helper-socket.js +0 -2
- package/dist/metal-provision.js +0 -2
- package/dist/operator-bootstrap.d.ts +43 -1
- package/dist/operator-bootstrap.js +788 -367
- package/dist/platform-bootstrap-runtime.d.ts +0 -2
- package/dist/platform-bootstrap-runtime.js +0 -4
- package/dist/platform-fleet-verification.js +190 -98
- package/dist/provision.d.ts +4 -1
- package/dist/provision.js +41 -32
- package/dist/software-helper.js +7 -5
- package/dist/software.d.ts +1 -1
- package/dist/software.js +7 -5
- package/dist/version.d.ts +1 -1
- package/package.json +5 -1
package/dist/provision.js
CHANGED
|
@@ -709,7 +709,8 @@ var SOFTWARE_CATALOG = [
|
|
|
709
709
|
{ id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
710
710
|
{ id: "cloudflare-warp", version: "2026.6.822.0-min", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
711
711
|
{ id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
712
|
-
{ id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
|
|
712
|
+
{ id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
713
|
+
{ id: "git", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
|
|
713
714
|
];
|
|
714
715
|
var UBUNTU_2604_X64 = [
|
|
715
716
|
{ requirement: { id: "bun", version: "1.3.14" } },
|
|
@@ -719,7 +720,8 @@ var UBUNTU_2604_X64 = [
|
|
|
719
720
|
{ requirement: { id: "cloudflared", version: "2026.7.3" } },
|
|
720
721
|
{ requirement: { id: "cloudflare-warp", version: "2026.6.822.0-min" } },
|
|
721
722
|
{ requirement: { id: "ufw", version: "ubuntu-26.04" } },
|
|
722
|
-
{ requirement: { id: "openssh-client", version: "ubuntu-26.04" } }
|
|
723
|
+
{ requirement: { id: "openssh-client", version: "ubuntu-26.04" } },
|
|
724
|
+
{ requirement: { id: "git", version: "ubuntu-26.04" } }
|
|
723
725
|
];
|
|
724
726
|
var path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
|
|
725
727
|
var DOCKER_DAEMON_PATH = "/etc/docker/daemon.json";
|
|
@@ -806,7 +808,7 @@ async function executeSoftwareOperation(operation) {
|
|
|
806
808
|
const supported = observed && observed.some((part, index) => part > minimum[index] && observed.slice(0, index).every((prior, priorIndex) => prior === minimum[priorIndex])) || observed?.every((part, index) => part === minimum[index]);
|
|
807
809
|
return { ...result, exitCode: result.exitCode === 0 && supported ? 0 : 1 };
|
|
808
810
|
});
|
|
809
|
-
const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
|
|
811
|
+
const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : software === "git" ? ["/usr/bin/git"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
|
|
810
812
|
try {
|
|
811
813
|
binaries.forEach((binary) => accessSync(binary));
|
|
812
814
|
return { exitCode: 0, output: "" };
|
|
@@ -814,7 +816,7 @@ async function executeSoftwareOperation(operation) {
|
|
|
814
816
|
return { exitCode: 1, output: cause instanceof Error ? cause.message : String(cause) };
|
|
815
817
|
}
|
|
816
818
|
}
|
|
817
|
-
if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client") {
|
|
819
|
+
if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client" || software === "git") {
|
|
818
820
|
const packageName = software === "openssh-client" ? "openssh-client" : software === "docker" ? "docker.io" : software;
|
|
819
821
|
const installed = await aptInstall(packageName);
|
|
820
822
|
if (installed.exitCode !== 0 || software !== "nginx" && software !== "docker")
|
|
@@ -914,7 +916,7 @@ function validateSoftwareRequirements(value, _options = {}) {
|
|
|
914
916
|
if (Object.keys(row).some((key) => key !== "id" && key !== "version")) {
|
|
915
917
|
throw new Error("software requirement contains an unknown field");
|
|
916
918
|
}
|
|
917
|
-
if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
|
|
919
|
+
if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client", "git"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
|
|
918
920
|
throw new Error("software requirement coordinate is invalid");
|
|
919
921
|
}
|
|
920
922
|
const requirement = { id: row.id, version: row.version };
|
|
@@ -2086,7 +2088,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
2086
2088
|
}
|
|
2087
2089
|
|
|
2088
2090
|
// src/version.ts
|
|
2089
|
-
var VERSION3 = "0.1.
|
|
2091
|
+
var VERSION3 = "0.1.64";
|
|
2090
2092
|
|
|
2091
2093
|
// src/egress-policy.ts
|
|
2092
2094
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
@@ -2215,7 +2217,11 @@ function agentEgressUnit(options) {
|
|
|
2215
2217
|
const user = options.user ?? "forgezero";
|
|
2216
2218
|
if (!/^[a-z_][a-z0-9_-]{0,30}$/.test(user))
|
|
2217
2219
|
throw new Error("invalid Agent service user");
|
|
2218
|
-
const
|
|
2220
|
+
const bootstrapBundleEnabled = Boolean(options.bootstrapBundlePath && options.bootstrapBundleManifestPath);
|
|
2221
|
+
if (Boolean(options.bootstrapBundlePath) !== Boolean(options.bootstrapBundleManifestPath) || bootstrapBundleEnabled && ![options.bootstrapBundlePath, options.bootstrapBundleManifestPath].every((path2) => path2.startsWith("/") && !/[\r\n\0:]/.test(path2))) {
|
|
2222
|
+
throw new Error("bootstrap bundle and manifest must be supplied together as absolute paths");
|
|
2223
|
+
}
|
|
2224
|
+
const deploymentEnabled = Boolean(options.repository || bootstrapBundleEnabled || options.pullDeployments);
|
|
2219
2225
|
const runnerLoopbackPorts = normalizeEgressTcpPorts(options.runnerLoopbackPorts ?? []);
|
|
2220
2226
|
const runnerPublicTcpPorts = normalizeEgressTcpPorts(options.runnerPublicTcpPorts ?? DEFAULT_RUNNER_PUBLIC_TCP_PORTS);
|
|
2221
2227
|
if (deploymentEnabled && runnerPublicTcpPorts.length < 1) {
|
|
@@ -2621,17 +2627,16 @@ function agentUnit(options) {
|
|
|
2621
2627
|
if (Boolean(options.pullMigrations) !== Boolean(options.lifecycleProfilePath)) {
|
|
2622
2628
|
throw new Error("migration pull and lifecycle profile must be supplied together");
|
|
2623
2629
|
}
|
|
2624
|
-
const
|
|
2625
|
-
if (
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
throw new Error("bootstrap pull, SSH credential, public key and target telemetry endpoint must be supplied together");
|
|
2630
|
+
const bootstrapIdentityEnabled = Boolean(options.bootstrapSshCredentialPath && options.bootstrapSshPublicKeyPath);
|
|
2631
|
+
if (Boolean(options.bootstrapSshCredentialPath) !== Boolean(options.bootstrapSshPublicKeyPath)) {
|
|
2632
|
+
throw new Error("bootstrap SSH credential and public key paths must be supplied together");
|
|
2633
|
+
}
|
|
2634
|
+
const bootstrapEnabled = Boolean(options.pullBootstrap);
|
|
2635
|
+
if (bootstrapEnabled && (!bootstrapIdentityEnabled || !options.bootstrapTargetTelemetryEndpoint) || !bootstrapEnabled && options.bootstrapTargetTelemetryEndpoint) {
|
|
2636
|
+
throw new Error("bootstrap pull, SSH identity and target telemetry endpoint must be supplied together");
|
|
2632
2637
|
}
|
|
2633
2638
|
const lifecycleHelperSocketPath = lifecycleEnabled ? systemdPath(options.lifecycleHelperSocketPath ?? LIFECYCLE_HELPER_SOCKET, "lifecycle helper socket") : undefined;
|
|
2634
|
-
const bootstrapSshCredentialPath =
|
|
2639
|
+
const bootstrapSshCredentialPath = bootstrapIdentityEnabled ? systemdPath(options.bootstrapSshCredentialPath, "bootstrap SSH credential") : undefined;
|
|
2635
2640
|
const warpValues = [
|
|
2636
2641
|
options.warpOrganization,
|
|
2637
2642
|
options.warpClientIdCredentialPath,
|
|
@@ -2685,6 +2690,8 @@ function agentUnit(options) {
|
|
|
2685
2690
|
options.gitPublicKeyPath ? `FZ_GIT_PUBLIC_KEY_FILE=${options.gitPublicKeyPath}` : null,
|
|
2686
2691
|
options.repository ? `FZ_DEPLOY_REPO=${options.repository}` : null,
|
|
2687
2692
|
options.branch ? `FZ_DEPLOY_BRANCH=${options.branch}` : null,
|
|
2693
|
+
options.bootstrapBundlePath ? `FZ_BOOTSTRAP_BUNDLE=${options.bootstrapBundlePath}` : null,
|
|
2694
|
+
options.bootstrapBundleManifestPath ? `FZ_BOOTSTRAP_BUNDLE_MANIFEST=${options.bootstrapBundleManifestPath}` : null,
|
|
2688
2695
|
options.profile ? `FZ_DEPLOY_PROFILE=${options.profile}` : null,
|
|
2689
2696
|
options.repository && options.branch ? `FZ_DEPLOY_KEY=${options.project ?? "platform"}:${options.environment ?? "production"}` : null,
|
|
2690
2697
|
deploymentEnabled ? `FZ_DEPLOY_ROOT=${deployRoot}` : null,
|
|
@@ -2868,15 +2875,13 @@ function planProvision(options) {
|
|
|
2868
2875
|
if (Boolean(options.pullMigrations) !== Boolean(options.lifecycleProfilePath)) {
|
|
2869
2876
|
throw new Error("migration pull and lifecycle profile must be supplied together");
|
|
2870
2877
|
}
|
|
2871
|
-
const
|
|
2872
|
-
if (
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
].some(Boolean) && !bootstrapEnabled) {
|
|
2879
|
-
throw new Error("bootstrap pull, SSH credential, public key and target telemetry endpoint must be supplied together");
|
|
2878
|
+
const bootstrapIdentityEnabled = Boolean(options.bootstrapSshCredentialPath && options.bootstrapSshPublicKeyPath);
|
|
2879
|
+
if (Boolean(options.bootstrapSshCredentialPath) !== Boolean(options.bootstrapSshPublicKeyPath) || options.bootstrapSshSourcePath && !bootstrapIdentityEnabled) {
|
|
2880
|
+
throw new Error("bootstrap SSH credential and public key paths must be supplied together");
|
|
2881
|
+
}
|
|
2882
|
+
const bootstrapEnabled = Boolean(options.pullBootstrap);
|
|
2883
|
+
if (bootstrapEnabled && (!bootstrapIdentityEnabled || !options.bootstrapTargetTelemetryEndpoint) || !bootstrapEnabled && options.bootstrapTargetTelemetryEndpoint) {
|
|
2884
|
+
throw new Error("bootstrap pull, SSH identity and target telemetry endpoint must be supplied together");
|
|
2880
2885
|
}
|
|
2881
2886
|
const warpValues = [
|
|
2882
2887
|
options.warpOrganization,
|
|
@@ -2886,13 +2891,13 @@ function planProvision(options) {
|
|
|
2886
2891
|
const warpEnabled = warpValues.every(Boolean);
|
|
2887
2892
|
if (warpValues.some(Boolean) && !warpEnabled)
|
|
2888
2893
|
throw new Error("WARP configuration must be supplied together");
|
|
2889
|
-
const enrolmentEnabled = Boolean(options.enrolTokenCredentialPath
|
|
2890
|
-
if (
|
|
2891
|
-
throw new Error("direct enrolment credential
|
|
2894
|
+
const enrolmentEnabled = Boolean(options.enrolTokenCredentialPath);
|
|
2895
|
+
if (options.enrolTokenCredentialPath && !options.enrolStatePath || options.enrolTokenSourcePath && (!options.enrolTokenCredentialPath || !options.enrolStatePath)) {
|
|
2896
|
+
throw new Error("direct enrolment credential requires its durable state path");
|
|
2892
2897
|
}
|
|
2893
2898
|
const enrolTokenSourcePath = options.enrolTokenSourcePath ? systemdPath(options.enrolTokenSourcePath, "enrolment source") : undefined;
|
|
2894
2899
|
const enrolTokenCredentialPath = enrolmentEnabled ? systemdPath(options.enrolTokenCredentialPath, "enrolment credential") : undefined;
|
|
2895
|
-
const enrolStatePath =
|
|
2900
|
+
const enrolStatePath = options.enrolStatePath ? systemdPath(options.enrolStatePath, "enrolment state") : undefined;
|
|
2896
2901
|
const enrolStateDir = enrolStatePath?.replace(/\/[^/]+$/, "");
|
|
2897
2902
|
const sourceBinPath = options.sourceBinPath ? systemdPath(options.sourceBinPath, "agent source binary") : undefined;
|
|
2898
2903
|
const binPath = options.binPath ? systemdPath(options.binPath, "agent binary") : undefined;
|
|
@@ -2904,8 +2909,8 @@ function planProvision(options) {
|
|
|
2904
2909
|
const gitPublicKeyDir = gitPublicKeyPath?.replace(/\/[^/]+$/, "");
|
|
2905
2910
|
const lifecycleProfilePath = lifecycleEnabled ? systemdPath(options.lifecycleProfilePath, "lifecycle profile") : undefined;
|
|
2906
2911
|
const lifecycleHelperSocketPath = lifecycleEnabled ? systemdPath(options.lifecycleHelperSocketPath ?? LIFECYCLE_HELPER_SOCKET, "lifecycle helper socket") : undefined;
|
|
2907
|
-
const bootstrapSshCredentialPath =
|
|
2908
|
-
const bootstrapSshPublicKeyPath =
|
|
2912
|
+
const bootstrapSshCredentialPath = bootstrapIdentityEnabled ? systemdPath(options.bootstrapSshCredentialPath, "bootstrap SSH credential") : undefined;
|
|
2913
|
+
const bootstrapSshPublicKeyPath = bootstrapIdentityEnabled ? systemdPath(options.bootstrapSshPublicKeyPath, "bootstrap SSH public key") : undefined;
|
|
2909
2914
|
const bootstrapSshSourcePath = options.bootstrapSshSourcePath ? systemdPath(options.bootstrapSshSourcePath, "bootstrap SSH private-key source") : undefined;
|
|
2910
2915
|
const bootstrapSshPublicKeyDir = bootstrapSshPublicKeyPath?.replace(/\/[^/]+$/, "");
|
|
2911
2916
|
const warpClientIdCredentialPath = warpEnabled ? systemdPath(options.warpClientIdCredentialPath, "WARP client-id credential") : undefined;
|
|
@@ -3005,7 +3010,7 @@ function planProvision(options) {
|
|
|
3005
3010
|
step("Git deploy identity directory", { kind: "directories", directories: [{ path: gitPublicKeyDir, mode: 493, owner: "root", group: "root" }] }),
|
|
3006
3011
|
step("unique encrypted Git deploy identity", { kind: "ensure-git-identity", credential: gitCredentialPath, publicKey: gitPublicKeyPath })
|
|
3007
3012
|
] : [],
|
|
3008
|
-
...
|
|
3013
|
+
...bootstrapIdentityEnabled ? [
|
|
3009
3014
|
step("bootstrap SSH public identity directory", { kind: "directories", directories: [
|
|
3010
3015
|
{ path: bootstrapSshPublicKeyDir, mode: 493, owner: "root", group: "root" }
|
|
3011
3016
|
] }),
|
|
@@ -3041,6 +3046,10 @@ function planProvision(options) {
|
|
|
3041
3046
|
{ argv: ["/usr/bin/rm", "-f", "/etc/systemd/system/forgezero-deploy-runner.socket"] },
|
|
3042
3047
|
{ argv: ["/usr/bin/systemctl", "daemon-reload"] }
|
|
3043
3048
|
] })] : [],
|
|
3049
|
+
...enrolStatePath && !enrolmentEnabled ? [step("retire consumed enrolment unit", { kind: "commands", commands: [
|
|
3050
|
+
{ argv: ["/usr/bin/systemctl", "disable", "--now", "forgezero-agent-enrol.service"], acceptedExitCodes: [0, 1, 5] },
|
|
3051
|
+
{ argv: ["/usr/bin/rm", "-f", ENROLMENT_UNIT_PATH] }
|
|
3052
|
+
] })] : [],
|
|
3044
3053
|
step("enable and converge services", { kind: "commands", commands: [
|
|
3045
3054
|
{ argv: ["/usr/bin/systemctl", "enable", ...enabledUnits] },
|
|
3046
3055
|
{ argv: ["/usr/bin/systemctl", "reset-failed", "forgezero-agent.service"], acceptedExitCodes: [0, 1] },
|
package/dist/software-helper.js
CHANGED
|
@@ -31,7 +31,8 @@ var SOFTWARE_CATALOG = [
|
|
|
31
31
|
{ id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
32
32
|
{ id: "cloudflare-warp", version: "2026.6.822.0-min", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
33
33
|
{ id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
34
|
-
{ id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
|
|
34
|
+
{ id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
35
|
+
{ id: "git", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
|
|
35
36
|
];
|
|
36
37
|
var UBUNTU_2604_X64 = [
|
|
37
38
|
{ requirement: { id: "bun", version: "1.3.14" } },
|
|
@@ -41,7 +42,8 @@ var UBUNTU_2604_X64 = [
|
|
|
41
42
|
{ requirement: { id: "cloudflared", version: "2026.7.3" } },
|
|
42
43
|
{ requirement: { id: "cloudflare-warp", version: "2026.6.822.0-min" } },
|
|
43
44
|
{ requirement: { id: "ufw", version: "ubuntu-26.04" } },
|
|
44
|
-
{ requirement: { id: "openssh-client", version: "ubuntu-26.04" } }
|
|
45
|
+
{ requirement: { id: "openssh-client", version: "ubuntu-26.04" } },
|
|
46
|
+
{ requirement: { id: "git", version: "ubuntu-26.04" } }
|
|
45
47
|
];
|
|
46
48
|
var path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
|
|
47
49
|
var DOCKER_DAEMON_PATH = "/etc/docker/daemon.json";
|
|
@@ -128,7 +130,7 @@ async function executeSoftwareOperation(operation) {
|
|
|
128
130
|
const supported = observed && observed.some((part, index) => part > minimum[index] && observed.slice(0, index).every((prior, priorIndex) => prior === minimum[priorIndex])) || observed?.every((part, index) => part === minimum[index]);
|
|
129
131
|
return { ...result, exitCode: result.exitCode === 0 && supported ? 0 : 1 };
|
|
130
132
|
});
|
|
131
|
-
const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
|
|
133
|
+
const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : software === "git" ? ["/usr/bin/git"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
|
|
132
134
|
try {
|
|
133
135
|
binaries.forEach((binary) => accessSync(binary));
|
|
134
136
|
return { exitCode: 0, output: "" };
|
|
@@ -136,7 +138,7 @@ async function executeSoftwareOperation(operation) {
|
|
|
136
138
|
return { exitCode: 1, output: cause instanceof Error ? cause.message : String(cause) };
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
|
-
if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client") {
|
|
141
|
+
if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client" || software === "git") {
|
|
140
142
|
const packageName = software === "openssh-client" ? "openssh-client" : software === "docker" ? "docker.io" : software;
|
|
141
143
|
const installed = await aptInstall(packageName);
|
|
142
144
|
if (installed.exitCode !== 0 || software !== "nginx" && software !== "docker")
|
|
@@ -236,7 +238,7 @@ function validateSoftwareRequirements(value, _options = {}) {
|
|
|
236
238
|
if (Object.keys(row).some((key) => key !== "id" && key !== "version")) {
|
|
237
239
|
throw new Error("software requirement contains an unknown field");
|
|
238
240
|
}
|
|
239
|
-
if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
|
|
241
|
+
if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client", "git"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
|
|
240
242
|
throw new Error("software requirement coordinate is invalid");
|
|
241
243
|
}
|
|
242
244
|
const requirement = { id: row.id, version: row.version };
|
package/dist/software.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type CatalogStatus = 'testing' | 'active' | 'retired';
|
|
2
2
|
export type DeploymentChannel = 'development' | 'production';
|
|
3
|
-
export type SoftwareId = 'bun' | 'docker' | 'nginx' | 'arangodb' | 'cloudflared' | 'cloudflare-warp' | 'ufw' | 'openssh-client';
|
|
3
|
+
export type SoftwareId = 'bun' | 'docker' | 'nginx' | 'arangodb' | 'cloudflared' | 'cloudflare-warp' | 'ufw' | 'openssh-client' | 'git';
|
|
4
4
|
/** Repository input is a catalogue coordinate, never a root command. */
|
|
5
5
|
export interface SoftwareRequirement {
|
|
6
6
|
id: SoftwareId;
|
package/dist/software.js
CHANGED
|
@@ -31,7 +31,8 @@ var SOFTWARE_CATALOG = [
|
|
|
31
31
|
{ id: "cloudflared", version: "2026.7.3", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
32
32
|
{ id: "cloudflare-warp", version: "2026.6.822.0-min", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
33
33
|
{ id: "ufw", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
34
|
-
{ id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
|
|
34
|
+
{ id: "openssh-client", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" },
|
|
35
|
+
{ id: "git", version: "ubuntu-26.04", status: "active", os: "ubuntu", osVersion: "26.04", architecture: "x64", evidence: "reviewed-strategy-and-tests" }
|
|
35
36
|
];
|
|
36
37
|
var UBUNTU_2604_X64 = [
|
|
37
38
|
{ requirement: { id: "bun", version: "1.3.14" } },
|
|
@@ -41,7 +42,8 @@ var UBUNTU_2604_X64 = [
|
|
|
41
42
|
{ requirement: { id: "cloudflared", version: "2026.7.3" } },
|
|
42
43
|
{ requirement: { id: "cloudflare-warp", version: "2026.6.822.0-min" } },
|
|
43
44
|
{ requirement: { id: "ufw", version: "ubuntu-26.04" } },
|
|
44
|
-
{ requirement: { id: "openssh-client", version: "ubuntu-26.04" } }
|
|
45
|
+
{ requirement: { id: "openssh-client", version: "ubuntu-26.04" } },
|
|
46
|
+
{ requirement: { id: "git", version: "ubuntu-26.04" } }
|
|
45
47
|
];
|
|
46
48
|
var path = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin";
|
|
47
49
|
var DOCKER_DAEMON_PATH = "/etc/docker/daemon.json";
|
|
@@ -128,7 +130,7 @@ async function executeSoftwareOperation(operation) {
|
|
|
128
130
|
const supported = observed && observed.some((part, index) => part > minimum[index] && observed.slice(0, index).every((prior, priorIndex) => prior === minimum[priorIndex])) || observed?.every((part, index) => part === minimum[index]);
|
|
129
131
|
return { ...result, exitCode: result.exitCode === 0 && supported ? 0 : 1 };
|
|
130
132
|
});
|
|
131
|
-
const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
|
|
133
|
+
const binaries = software === "ufw" ? ["/usr/sbin/ufw"] : software === "git" ? ["/usr/bin/git"] : ["/usr/bin/ssh", "/usr/bin/scp", "/usr/bin/ssh-keyscan", "/usr/bin/ssh-keygen"];
|
|
132
134
|
try {
|
|
133
135
|
binaries.forEach((binary) => accessSync(binary));
|
|
134
136
|
return { exitCode: 0, output: "" };
|
|
@@ -136,7 +138,7 @@ async function executeSoftwareOperation(operation) {
|
|
|
136
138
|
return { exitCode: 1, output: cause instanceof Error ? cause.message : String(cause) };
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
|
-
if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client") {
|
|
141
|
+
if (software === "docker" || software === "nginx" || software === "ufw" || software === "openssh-client" || software === "git") {
|
|
140
142
|
const packageName = software === "openssh-client" ? "openssh-client" : software === "docker" ? "docker.io" : software;
|
|
141
143
|
const installed = await aptInstall(packageName);
|
|
142
144
|
if (installed.exitCode !== 0 || software !== "nginx" && software !== "docker")
|
|
@@ -236,7 +238,7 @@ function validateSoftwareRequirements(value, _options = {}) {
|
|
|
236
238
|
if (Object.keys(row).some((key) => key !== "id" && key !== "version")) {
|
|
237
239
|
throw new Error("software requirement contains an unknown field");
|
|
238
240
|
}
|
|
239
|
-
if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
|
|
241
|
+
if (!["bun", "docker", "nginx", "arangodb", "cloudflared", "cloudflare-warp", "ufw", "openssh-client", "git"].includes(String(row.id)) || typeof row.version !== "string" || !/^[A-Za-z0-9][A-Za-z0-9.-]{0,31}$/.test(row.version)) {
|
|
240
242
|
throw new Error("software requirement coordinate is invalid");
|
|
241
243
|
}
|
|
242
244
|
const requirement = { id: row.id, version: row.version };
|
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.64";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgezero/agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.64",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"check": "tsc --noEmit",
|
|
@@ -56,6 +56,10 @@
|
|
|
56
56
|
},
|
|
57
57
|
"bugs": "https://github.com/forgezero-net/packages/issues",
|
|
58
58
|
"exports": {
|
|
59
|
+
"./bootstrap-bundle": {
|
|
60
|
+
"types": "./dist/bootstrap-bundle.d.ts",
|
|
61
|
+
"default": "./dist/bootstrap-bundle.js"
|
|
62
|
+
},
|
|
59
63
|
"./provision": {
|
|
60
64
|
"types": "./dist/provision.d.ts",
|
|
61
65
|
"default": "./dist/provision.js"
|