@forgezero/agent 0.1.28 → 0.1.29
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/fz-agent.js +3 -5
- package/dist/fz.js +63 -13
- package/dist/metal-helper-socket.js +2 -3
- package/dist/metal-provision.js +2 -3
- package/dist/provision.d.ts +8 -0
- package/dist/provision.js +67 -14
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/agent-heartbeat.js
CHANGED
package/dist/fz-agent.js
CHANGED
|
@@ -6377,11 +6377,10 @@ ${attestationSetup}if [[ ! -x /usr/local/bin/bun ]]; then
|
|
|
6377
6377
|
install -m 0755 ${agentBun}/bin/bun /usr/local/bin/bun
|
|
6378
6378
|
rm -f /run/fz-bun-install
|
|
6379
6379
|
fi
|
|
6380
|
-
if [[ ! -x /usr/local/
|
|
6380
|
+
if [[ ! -x /usr/local/lib/forgezero/agent/fz-agent ]] || [[ "$(/usr/local/lib/forgezero/agent/fz-agent --version 2>/dev/null || true)" != "${profile.agentVersion}" ]]; then
|
|
6381
6381
|
env BUN_INSTALL=${agentBun} /usr/local/bin/bun add -g --no-cache --force @forgezero/agent@${profile.agentVersion}
|
|
6382
|
-
ln -sfn ${agentBun}/bin/fz-agent /usr/local/bin/fz-agent
|
|
6383
6382
|
fi
|
|
6384
|
-
env FZ_API=${profile.apiUrl} FZ_AGENT_BIN=/usr/local/
|
|
6383
|
+
env FZ_API=${profile.apiUrl} FZ_AGENT_BIN=/usr/local/lib/forgezero/agent/fz-agent FZ_AGENT_USER=forgezero-agent FZ_SOCKET_PATH=/run/forgezero/vault.sock FZ_SEED_CREDENTIAL_PATH=/etc/forgezero/creds/agent-seed.cred FZ_GIT_CREDENTIAL_PATH=/etc/forgezero/creds/git-deploy-key.cred FZ_GIT_PUBLIC_KEY_PATH=/etc/forgezero/git/deploy.pub FZ_DEPLOY_ROOT=/opt/forgezero FZ_DEPLOY_PULL=${hasEnrolment ? "true" : "false"} FZ_NODE_LABEL=${nodeLabel} ${agentBun}/bin/fz agent install --apply${hasEnrolment ? " --enrol" : ""}
|
|
6385
6384
|
`;
|
|
6386
6385
|
}
|
|
6387
6386
|
function cloudInit(profile, claim, manifest) {
|
|
@@ -7876,7 +7875,7 @@ function requestAgentUpdate(request, socketPath = DEFAULT_AGENT_UPDATE_SOCKET, t
|
|
|
7876
7875
|
import { readFileSync as readFileSync7 } from "fs";
|
|
7877
7876
|
|
|
7878
7877
|
// src/version.ts
|
|
7879
|
-
var VERSION2 = "0.1.
|
|
7878
|
+
var VERSION2 = "0.1.29";
|
|
7880
7879
|
|
|
7881
7880
|
// src/agent-heartbeat.ts
|
|
7882
7881
|
var unquote = (value) => value.replace(/^['"]|['"]$/g, "");
|
|
@@ -8487,7 +8486,6 @@ if (import.meta.main) {
|
|
|
8487
8486
|
const attestationSource = existsSync13("/dev/sev-guest") ? createSnpAttestationSource() : undefined;
|
|
8488
8487
|
const running = runAgent({
|
|
8489
8488
|
socketPath: process.env.FZ_SOCKET_PATH ?? DEFAULT_SOCKET_PATH,
|
|
8490
|
-
listenFd: systemdListenFd(),
|
|
8491
8489
|
seedCredential: process.env.FZ_SEED_CREDENTIAL,
|
|
8492
8490
|
seedPath: process.env.FZ_SEED_PATH ?? DEFAULT_SEED_PATH,
|
|
8493
8491
|
nodeKey: process.env.FZ_NODE_KEY,
|
package/dist/fz.js
CHANGED
|
@@ -4886,7 +4886,7 @@ var AGENT_UPDATE_HELPER_UNIT_PATH = "/etc/systemd/system/forgezero-agent-update-
|
|
|
4886
4886
|
var MAX_REQUEST_BYTES = 8 * 1024;
|
|
4887
4887
|
|
|
4888
4888
|
// src/version.ts
|
|
4889
|
-
var VERSION2 = "0.1.
|
|
4889
|
+
var VERSION2 = "0.1.29";
|
|
4890
4890
|
|
|
4891
4891
|
// src/software.ts
|
|
4892
4892
|
var BUN_INSTALLER_SHA256 = "bab8acfb046aac8c72407bdcce903957665d655d7acaa3e11c7c4616beae68dd";
|
|
@@ -4973,6 +4973,7 @@ var VAULT_GROUP = "forgezero-vault";
|
|
|
4973
4973
|
var LIFECYCLE_GROUP = "forgezero-lifecycle";
|
|
4974
4974
|
var DEPLOYMENT_RUNNER_UNIT_PATH = "/etc/systemd/system/forgezero-deploy-runner.service";
|
|
4975
4975
|
var AGENT_SOCKET_UNIT_PATH = "/etc/systemd/system/forgezero-agent.socket";
|
|
4976
|
+
var AGENT_SOCKET_PROXY_UNIT_PATH = "/etc/systemd/system/forgezero-agent-proxy.service";
|
|
4976
4977
|
var DEPLOYMENT_RUNNER_SOCKET = "/run/forgezero-deploy/runner.sock";
|
|
4977
4978
|
var ENROLMENT_UNIT_PATH = "/etc/systemd/system/forgezero-agent-enrol.service";
|
|
4978
4979
|
var LIFECYCLE_HELPER_UNIT_PATH = "/etc/systemd/system/forgezero-lifecycle-helper.service";
|
|
@@ -5062,17 +5063,55 @@ SocketGroup=${VAULT_GROUP}
|
|
|
5062
5063
|
SocketMode=0660
|
|
5063
5064
|
DirectoryMode=0750
|
|
5064
5065
|
RemoveOnStop=true
|
|
5065
|
-
Service=forgezero-agent.service
|
|
5066
|
+
Service=forgezero-agent-proxy.service
|
|
5066
5067
|
|
|
5067
5068
|
[Install]
|
|
5068
5069
|
WantedBy=sockets.target
|
|
5069
5070
|
`;
|
|
5070
5071
|
}
|
|
5072
|
+
function agentSocketProxyUnit(options) {
|
|
5073
|
+
const backend = agentBackendSocketPath(options.socketPath);
|
|
5074
|
+
const user = options.user ?? "forgezero";
|
|
5075
|
+
return `[Unit]
|
|
5076
|
+
Description=ForgeZero application Vault socket proxy
|
|
5077
|
+
Documentation=https://www.forgezero.net/docs/agent
|
|
5078
|
+
Requires=forgezero-agent.service
|
|
5079
|
+
After=forgezero-agent.service
|
|
5080
|
+
|
|
5081
|
+
[Service]
|
|
5082
|
+
User=${user}
|
|
5083
|
+
Group=${VAULT_GROUP}
|
|
5084
|
+
ExecStart=/usr/lib/systemd/systemd-socket-proxyd ${backend}
|
|
5085
|
+
NoNewPrivileges=true
|
|
5086
|
+
PrivateTmp=true
|
|
5087
|
+
ProtectSystem=strict
|
|
5088
|
+
ProtectHome=true
|
|
5089
|
+
ProtectKernelTunables=true
|
|
5090
|
+
ProtectKernelModules=true
|
|
5091
|
+
ProtectControlGroups=true
|
|
5092
|
+
RestrictSUIDSGID=true
|
|
5093
|
+
RestrictRealtime=true
|
|
5094
|
+
MemoryDenyWriteExecute=true
|
|
5095
|
+
LockPersonality=true
|
|
5096
|
+
RestrictAddressFamilies=AF_UNIX
|
|
5097
|
+
`;
|
|
5098
|
+
}
|
|
5099
|
+
function agentBackendSocketPath(publicSocketPath) {
|
|
5100
|
+
const socket = systemdPath(publicSocketPath, "agent socket");
|
|
5101
|
+
const backend = `${socket}.backend`;
|
|
5102
|
+
if (Buffer.byteLength(backend) > 100)
|
|
5103
|
+
throw new Error("agent socket path is too long for a Unix socket");
|
|
5104
|
+
return backend;
|
|
5105
|
+
}
|
|
5071
5106
|
var systemdPath = (value, label) => {
|
|
5072
5107
|
if (!value || !/^\/[A-Za-z0-9._@/-]+$/.test(value))
|
|
5073
5108
|
throw new Error(`invalid ${label} path`);
|
|
5074
5109
|
return value;
|
|
5075
5110
|
};
|
|
5111
|
+
var awaitSocketCommand = (path) => {
|
|
5112
|
+
const socket = systemdPath(path, "readiness socket");
|
|
5113
|
+
return `for attempt in $(seq 1 100); do test -S ${socket} && exit 0; sleep 0.1; done; exit 1`;
|
|
5114
|
+
};
|
|
5076
5115
|
var validNodeHostname = (value) => !value || value.length <= 253 && value === value.toLowerCase() && value.split(".").length >= 3 && value.split(".").every((label) => /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(label));
|
|
5077
5116
|
function warpConfigUnit(options) {
|
|
5078
5117
|
if (!options.warpOrganization || !/^[a-z0-9][a-z0-9-]{0,62}$/i.test(options.warpOrganization)) {
|
|
@@ -5311,7 +5350,7 @@ function agentUnit(options) {
|
|
|
5311
5350
|
}
|
|
5312
5351
|
}
|
|
5313
5352
|
const environment = [
|
|
5314
|
-
`FZ_SOCKET_PATH=${options.socketPath}`,
|
|
5353
|
+
`FZ_SOCKET_PATH=${agentBackendSocketPath(options.socketPath)}`,
|
|
5315
5354
|
`FZ_CONTROL_SOCKET=${controlSocketPath}`,
|
|
5316
5355
|
`FZ_SEED_CREDENTIAL=agent-seed`,
|
|
5317
5356
|
`FZ_AGENT_MODE=${options.mode}`,
|
|
@@ -5391,7 +5430,6 @@ Type=simple
|
|
|
5391
5430
|
User=${user}
|
|
5392
5431
|
Group=${VAULT_GROUP}
|
|
5393
5432
|
${deploymentGroup}
|
|
5394
|
-
Sockets=forgezero-agent.socket
|
|
5395
5433
|
LoadCredentialEncrypted=agent-seed:${seedCredentialPath}
|
|
5396
5434
|
${gitCredential}${projectCredentials}${projectCredentials ? `
|
|
5397
5435
|
` : ""}${snpPrepare}ExecStart=${bin}
|
|
@@ -5479,6 +5517,7 @@ function planProvision(options) {
|
|
|
5479
5517
|
unit: agentUnit({ ...options, mode, lifecycleProfilePath, lifecycleHelperSocketPath }),
|
|
5480
5518
|
auxiliaryUnits: [
|
|
5481
5519
|
{ path: AGENT_SOCKET_UNIT_PATH, unit: agentSocketUnit(options) },
|
|
5520
|
+
{ path: AGENT_SOCKET_PROXY_UNIT_PATH, unit: agentSocketProxyUnit(options) },
|
|
5482
5521
|
{ path: AGENT_UPDATE_HELPER_UNIT_PATH, unit: agentUpdateHelperUnit(options) },
|
|
5483
5522
|
...deploymentEnabled ? [
|
|
5484
5523
|
{ path: DEPLOYMENT_RUNNER_UNIT_PATH, unit: deploymentRunnerUnit(options) },
|
|
@@ -5554,6 +5593,10 @@ function planProvision(options) {
|
|
|
5554
5593
|
label: "credential directory",
|
|
5555
5594
|
command: `install -d -o root -g root -m 0700 ${credentialDir}`
|
|
5556
5595
|
},
|
|
5596
|
+
{
|
|
5597
|
+
label: "Agent state directory",
|
|
5598
|
+
command: "install -d -o root -g root -m 0750 /var/lib/forgezero"
|
|
5599
|
+
},
|
|
5557
5600
|
{
|
|
5558
5601
|
label: "encrypted node identity",
|
|
5559
5602
|
command: `test -s ${seedCredentialPath} || { ` + `openssl rand -base64 32 | tr '+/' '-_' | tr -d '=\\n' | ` + `systemd-creds encrypt --name=agent-seed - ${seedCredentialPath}; ` + `chmod 0400 ${seedCredentialPath}; }`
|
|
@@ -5588,8 +5631,8 @@ function planProvision(options) {
|
|
|
5588
5631
|
command: "systemctl disable --now forgezero-deploy-runner.socket 2>/dev/null || true; rm -f /etc/systemd/system/forgezero-deploy-runner.socket; systemctl daemon-reload"
|
|
5589
5632
|
}] : [],
|
|
5590
5633
|
{
|
|
5591
|
-
label: "enable and
|
|
5592
|
-
command: `systemctl enable
|
|
5634
|
+
label: "enable and converge services",
|
|
5635
|
+
command: `systemctl enable ${[
|
|
5593
5636
|
"forgezero-agent.socket",
|
|
5594
5637
|
"forgezero-agent-update-helper.service",
|
|
5595
5638
|
...deploymentEnabled ? ["forgezero-deploy-runner.service", "forgezero-software-helper.service"] : [],
|
|
@@ -5597,25 +5640,32 @@ function planProvision(options) {
|
|
|
5597
5640
|
...warpEnabled ? ["forgezero-warp-config.service", "warp-svc.service"] : [],
|
|
5598
5641
|
...enrolmentEnabled ? ["forgezero-agent-enrol.service"] : [],
|
|
5599
5642
|
"forgezero-agent.service"
|
|
5600
|
-
].join(" ")}
|
|
5643
|
+
].join(" ")}; systemctl reset-failed forgezero-agent.service || true; systemctl restart ${[
|
|
5644
|
+
"forgezero-agent-update-helper.service",
|
|
5645
|
+
...deploymentEnabled ? ["forgezero-deploy-runner.service", "forgezero-software-helper.service"] : [],
|
|
5646
|
+
...lifecycleEnabled ? ["forgezero-lifecycle-helper.service"] : [],
|
|
5647
|
+
...warpEnabled ? ["forgezero-warp-config.service", "warp-svc.service"] : [],
|
|
5648
|
+
...enrolmentEnabled ? ["forgezero-agent-enrol.service"] : []
|
|
5649
|
+
].join(" ")}; systemctl restart forgezero-agent.socket; systemctl reset-failed forgezero-agent.service || true; systemctl restart forgezero-agent.service`
|
|
5601
5650
|
},
|
|
5602
5651
|
...enrolmentEnabled ? [{
|
|
5603
5652
|
label: "prove the compute binding is durable",
|
|
5604
5653
|
command: `test -s ${enrolStatePath}`
|
|
5605
5654
|
}] : [],
|
|
5606
5655
|
{ label: "prove it is running", command: "systemctl is-active forgezero-agent.service" },
|
|
5607
|
-
{ label: "prove the
|
|
5608
|
-
{ label: "prove the Agent
|
|
5656
|
+
{ label: "prove the public Vault socket exists", command: awaitSocketCommand(options.socketPath) },
|
|
5657
|
+
{ label: "prove the Agent Vault backend exists", command: awaitSocketCommand(agentBackendSocketPath(options.socketPath)) },
|
|
5658
|
+
{ label: "prove the Agent update helper exists", command: awaitSocketCommand(DEFAULT_AGENT_UPDATE_SOCKET) },
|
|
5609
5659
|
...deploymentEnabled ? [{
|
|
5610
5660
|
label: "prove the deployment runner socket exists",
|
|
5611
|
-
command:
|
|
5661
|
+
command: awaitSocketCommand(DEPLOYMENT_RUNNER_SOCKET)
|
|
5612
5662
|
}, {
|
|
5613
5663
|
label: "prove the software strategy helper socket exists",
|
|
5614
|
-
command:
|
|
5664
|
+
command: awaitSocketCommand(DEFAULT_SOFTWARE_HELPER_SOCKET)
|
|
5615
5665
|
}] : [],
|
|
5616
5666
|
...lifecycleEnabled ? [{
|
|
5617
5667
|
label: "prove the lifecycle helper socket exists",
|
|
5618
|
-
command:
|
|
5668
|
+
command: awaitSocketCommand(lifecycleHelperSocketPath)
|
|
5619
5669
|
}] : [],
|
|
5620
5670
|
...warpEnabled ? [{
|
|
5621
5671
|
label: "prove Cloudflare WARP is connected",
|
|
@@ -5623,7 +5673,7 @@ function planProvision(options) {
|
|
|
5623
5673
|
}] : [],
|
|
5624
5674
|
...options.repository ? [{
|
|
5625
5675
|
label: "prove the deployment control socket exists",
|
|
5626
|
-
command:
|
|
5676
|
+
command: awaitSocketCommand(options.controlSocketPath ?? "/run/forgezero/control.sock")
|
|
5627
5677
|
}] : []
|
|
5628
5678
|
]
|
|
5629
5679
|
};
|
|
@@ -352,11 +352,10 @@ ${attestationSetup}if [[ ! -x /usr/local/bin/bun ]]; then
|
|
|
352
352
|
install -m 0755 ${agentBun}/bin/bun /usr/local/bin/bun
|
|
353
353
|
rm -f /run/fz-bun-install
|
|
354
354
|
fi
|
|
355
|
-
if [[ ! -x /usr/local/
|
|
355
|
+
if [[ ! -x /usr/local/lib/forgezero/agent/fz-agent ]] || [[ "$(/usr/local/lib/forgezero/agent/fz-agent --version 2>/dev/null || true)" != "${profile.agentVersion}" ]]; then
|
|
356
356
|
env BUN_INSTALL=${agentBun} /usr/local/bin/bun add -g --no-cache --force @forgezero/agent@${profile.agentVersion}
|
|
357
|
-
ln -sfn ${agentBun}/bin/fz-agent /usr/local/bin/fz-agent
|
|
358
357
|
fi
|
|
359
|
-
env FZ_API=${profile.apiUrl} FZ_AGENT_BIN=/usr/local/
|
|
358
|
+
env FZ_API=${profile.apiUrl} FZ_AGENT_BIN=/usr/local/lib/forgezero/agent/fz-agent FZ_AGENT_USER=forgezero-agent FZ_SOCKET_PATH=/run/forgezero/vault.sock FZ_SEED_CREDENTIAL_PATH=/etc/forgezero/creds/agent-seed.cred FZ_GIT_CREDENTIAL_PATH=/etc/forgezero/creds/git-deploy-key.cred FZ_GIT_PUBLIC_KEY_PATH=/etc/forgezero/git/deploy.pub FZ_DEPLOY_ROOT=/opt/forgezero FZ_DEPLOY_PULL=${hasEnrolment ? "true" : "false"} FZ_NODE_LABEL=${nodeLabel} ${agentBun}/bin/fz agent install --apply${hasEnrolment ? " --enrol" : ""}
|
|
360
359
|
`;
|
|
361
360
|
}
|
|
362
361
|
function cloudInit(profile, claim, manifest) {
|
package/dist/metal-provision.js
CHANGED
|
@@ -352,11 +352,10 @@ ${attestationSetup}if [[ ! -x /usr/local/bin/bun ]]; then
|
|
|
352
352
|
install -m 0755 ${agentBun}/bin/bun /usr/local/bin/bun
|
|
353
353
|
rm -f /run/fz-bun-install
|
|
354
354
|
fi
|
|
355
|
-
if [[ ! -x /usr/local/
|
|
355
|
+
if [[ ! -x /usr/local/lib/forgezero/agent/fz-agent ]] || [[ "$(/usr/local/lib/forgezero/agent/fz-agent --version 2>/dev/null || true)" != "${profile.agentVersion}" ]]; then
|
|
356
356
|
env BUN_INSTALL=${agentBun} /usr/local/bin/bun add -g --no-cache --force @forgezero/agent@${profile.agentVersion}
|
|
357
|
-
ln -sfn ${agentBun}/bin/fz-agent /usr/local/bin/fz-agent
|
|
358
357
|
fi
|
|
359
|
-
env FZ_API=${profile.apiUrl} FZ_AGENT_BIN=/usr/local/
|
|
358
|
+
env FZ_API=${profile.apiUrl} FZ_AGENT_BIN=/usr/local/lib/forgezero/agent/fz-agent FZ_AGENT_USER=forgezero-agent FZ_SOCKET_PATH=/run/forgezero/vault.sock FZ_SEED_CREDENTIAL_PATH=/etc/forgezero/creds/agent-seed.cred FZ_GIT_CREDENTIAL_PATH=/etc/forgezero/creds/git-deploy-key.cred FZ_GIT_PUBLIC_KEY_PATH=/etc/forgezero/git/deploy.pub FZ_DEPLOY_ROOT=/opt/forgezero FZ_DEPLOY_PULL=${hasEnrolment ? "true" : "false"} FZ_NODE_LABEL=${nodeLabel} ${agentBun}/bin/fz agent install --apply${hasEnrolment ? " --enrol" : ""}
|
|
360
359
|
`;
|
|
361
360
|
}
|
|
362
361
|
function cloudInit(profile, claim, manifest) {
|
package/dist/provision.d.ts
CHANGED
|
@@ -128,6 +128,7 @@ export declare const VAULT_GROUP = "forgezero-vault";
|
|
|
128
128
|
export declare const LIFECYCLE_GROUP = "forgezero-lifecycle";
|
|
129
129
|
export declare const DEPLOYMENT_RUNNER_UNIT_PATH = "/etc/systemd/system/forgezero-deploy-runner.service";
|
|
130
130
|
export declare const AGENT_SOCKET_UNIT_PATH = "/etc/systemd/system/forgezero-agent.socket";
|
|
131
|
+
export declare const AGENT_SOCKET_PROXY_UNIT_PATH = "/etc/systemd/system/forgezero-agent-proxy.service";
|
|
131
132
|
export declare const DEPLOYMENT_RUNNER_SOCKET = "/run/forgezero-deploy/runner.sock";
|
|
132
133
|
export declare const ENROLMENT_UNIT_PATH = "/etc/systemd/system/forgezero-agent-enrol.service";
|
|
133
134
|
export declare const LIFECYCLE_HELPER_UNIT_PATH = "/etc/systemd/system/forgezero-lifecycle-helper.service";
|
|
@@ -146,6 +147,13 @@ export declare function agentUpdateHelperUnit(options: Pick<UnitOptions, 'binPat
|
|
|
146
147
|
* terminal, and it works identically on platform and tenant computes.
|
|
147
148
|
*/
|
|
148
149
|
export declare function agentSocketUnit(options: Pick<UnitOptions, 'socketPath'>): string;
|
|
150
|
+
/**
|
|
151
|
+
* Bun does not support inheriting systemd's listening file descriptor. Keep
|
|
152
|
+
* PID 1 as the owner of the stable application socket and let systemd's small,
|
|
153
|
+
* credential-free proxy bridge it to the Agent-owned backend Unix socket.
|
|
154
|
+
*/
|
|
155
|
+
export declare function agentSocketProxyUnit(options: Pick<UnitOptions, 'socketPath' | 'user'>): string;
|
|
156
|
+
export declare function agentBackendSocketPath(publicSocketPath: string): string;
|
|
149
157
|
export declare function warpConfigUnit(options: Pick<UnitOptions, 'binPath' | 'warpOrganization' | 'warpClientIdCredentialPath' | 'warpClientSecretCredentialPath'>): string;
|
|
150
158
|
export declare function warpServiceDropIn(): string;
|
|
151
159
|
export declare function lifecycleHelperUnit(options: Pick<UnitOptions, 'binPath' | 'lifecycleProfilePath' | 'lifecycleHelperSocketPath'>): string;
|
package/dist/provision.js
CHANGED
|
@@ -554,7 +554,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
554
554
|
}
|
|
555
555
|
|
|
556
556
|
// src/version.ts
|
|
557
|
-
var VERSION2 = "0.1.
|
|
557
|
+
var VERSION2 = "0.1.29";
|
|
558
558
|
|
|
559
559
|
// src/provision.ts
|
|
560
560
|
function atLeast(version, floor) {
|
|
@@ -603,6 +603,7 @@ var VAULT_GROUP = "forgezero-vault";
|
|
|
603
603
|
var LIFECYCLE_GROUP = "forgezero-lifecycle";
|
|
604
604
|
var DEPLOYMENT_RUNNER_UNIT_PATH = "/etc/systemd/system/forgezero-deploy-runner.service";
|
|
605
605
|
var AGENT_SOCKET_UNIT_PATH = "/etc/systemd/system/forgezero-agent.socket";
|
|
606
|
+
var AGENT_SOCKET_PROXY_UNIT_PATH = "/etc/systemd/system/forgezero-agent-proxy.service";
|
|
606
607
|
var DEPLOYMENT_RUNNER_SOCKET = "/run/forgezero-deploy/runner.sock";
|
|
607
608
|
var ENROLMENT_UNIT_PATH = "/etc/systemd/system/forgezero-agent-enrol.service";
|
|
608
609
|
var LIFECYCLE_HELPER_UNIT_PATH = "/etc/systemd/system/forgezero-lifecycle-helper.service";
|
|
@@ -692,17 +693,55 @@ SocketGroup=${VAULT_GROUP}
|
|
|
692
693
|
SocketMode=0660
|
|
693
694
|
DirectoryMode=0750
|
|
694
695
|
RemoveOnStop=true
|
|
695
|
-
Service=forgezero-agent.service
|
|
696
|
+
Service=forgezero-agent-proxy.service
|
|
696
697
|
|
|
697
698
|
[Install]
|
|
698
699
|
WantedBy=sockets.target
|
|
699
700
|
`;
|
|
700
701
|
}
|
|
702
|
+
function agentSocketProxyUnit(options) {
|
|
703
|
+
const backend = agentBackendSocketPath(options.socketPath);
|
|
704
|
+
const user = options.user ?? "forgezero";
|
|
705
|
+
return `[Unit]
|
|
706
|
+
Description=ForgeZero application Vault socket proxy
|
|
707
|
+
Documentation=https://www.forgezero.net/docs/agent
|
|
708
|
+
Requires=forgezero-agent.service
|
|
709
|
+
After=forgezero-agent.service
|
|
710
|
+
|
|
711
|
+
[Service]
|
|
712
|
+
User=${user}
|
|
713
|
+
Group=${VAULT_GROUP}
|
|
714
|
+
ExecStart=/usr/lib/systemd/systemd-socket-proxyd ${backend}
|
|
715
|
+
NoNewPrivileges=true
|
|
716
|
+
PrivateTmp=true
|
|
717
|
+
ProtectSystem=strict
|
|
718
|
+
ProtectHome=true
|
|
719
|
+
ProtectKernelTunables=true
|
|
720
|
+
ProtectKernelModules=true
|
|
721
|
+
ProtectControlGroups=true
|
|
722
|
+
RestrictSUIDSGID=true
|
|
723
|
+
RestrictRealtime=true
|
|
724
|
+
MemoryDenyWriteExecute=true
|
|
725
|
+
LockPersonality=true
|
|
726
|
+
RestrictAddressFamilies=AF_UNIX
|
|
727
|
+
`;
|
|
728
|
+
}
|
|
729
|
+
function agentBackendSocketPath(publicSocketPath) {
|
|
730
|
+
const socket = systemdPath(publicSocketPath, "agent socket");
|
|
731
|
+
const backend = `${socket}.backend`;
|
|
732
|
+
if (Buffer.byteLength(backend) > 100)
|
|
733
|
+
throw new Error("agent socket path is too long for a Unix socket");
|
|
734
|
+
return backend;
|
|
735
|
+
}
|
|
701
736
|
var systemdPath = (value, label) => {
|
|
702
737
|
if (!value || !/^\/[A-Za-z0-9._@/-]+$/.test(value))
|
|
703
738
|
throw new Error(`invalid ${label} path`);
|
|
704
739
|
return value;
|
|
705
740
|
};
|
|
741
|
+
var awaitSocketCommand = (path) => {
|
|
742
|
+
const socket = systemdPath(path, "readiness socket");
|
|
743
|
+
return `for attempt in $(seq 1 100); do test -S ${socket} && exit 0; sleep 0.1; done; exit 1`;
|
|
744
|
+
};
|
|
706
745
|
var validNodeHostname = (value) => !value || value.length <= 253 && value === value.toLowerCase() && value.split(".").length >= 3 && value.split(".").every((label) => /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?$/.test(label));
|
|
707
746
|
function warpConfigUnit(options) {
|
|
708
747
|
if (!options.warpOrganization || !/^[a-z0-9][a-z0-9-]{0,62}$/i.test(options.warpOrganization)) {
|
|
@@ -941,7 +980,7 @@ function agentUnit(options) {
|
|
|
941
980
|
}
|
|
942
981
|
}
|
|
943
982
|
const environment = [
|
|
944
|
-
`FZ_SOCKET_PATH=${options.socketPath}`,
|
|
983
|
+
`FZ_SOCKET_PATH=${agentBackendSocketPath(options.socketPath)}`,
|
|
945
984
|
`FZ_CONTROL_SOCKET=${controlSocketPath}`,
|
|
946
985
|
`FZ_SEED_CREDENTIAL=agent-seed`,
|
|
947
986
|
`FZ_AGENT_MODE=${options.mode}`,
|
|
@@ -1021,7 +1060,6 @@ Type=simple
|
|
|
1021
1060
|
User=${user}
|
|
1022
1061
|
Group=${VAULT_GROUP}
|
|
1023
1062
|
${deploymentGroup}
|
|
1024
|
-
Sockets=forgezero-agent.socket
|
|
1025
1063
|
LoadCredentialEncrypted=agent-seed:${seedCredentialPath}
|
|
1026
1064
|
${gitCredential}${projectCredentials}${projectCredentials ? `
|
|
1027
1065
|
` : ""}${snpPrepare}ExecStart=${bin}
|
|
@@ -1109,6 +1147,7 @@ function planProvision(options) {
|
|
|
1109
1147
|
unit: agentUnit({ ...options, mode, lifecycleProfilePath, lifecycleHelperSocketPath }),
|
|
1110
1148
|
auxiliaryUnits: [
|
|
1111
1149
|
{ path: AGENT_SOCKET_UNIT_PATH, unit: agentSocketUnit(options) },
|
|
1150
|
+
{ path: AGENT_SOCKET_PROXY_UNIT_PATH, unit: agentSocketProxyUnit(options) },
|
|
1112
1151
|
{ path: AGENT_UPDATE_HELPER_UNIT_PATH, unit: agentUpdateHelperUnit(options) },
|
|
1113
1152
|
...deploymentEnabled ? [
|
|
1114
1153
|
{ path: DEPLOYMENT_RUNNER_UNIT_PATH, unit: deploymentRunnerUnit(options) },
|
|
@@ -1184,6 +1223,10 @@ function planProvision(options) {
|
|
|
1184
1223
|
label: "credential directory",
|
|
1185
1224
|
command: `install -d -o root -g root -m 0700 ${credentialDir}`
|
|
1186
1225
|
},
|
|
1226
|
+
{
|
|
1227
|
+
label: "Agent state directory",
|
|
1228
|
+
command: "install -d -o root -g root -m 0750 /var/lib/forgezero"
|
|
1229
|
+
},
|
|
1187
1230
|
{
|
|
1188
1231
|
label: "encrypted node identity",
|
|
1189
1232
|
command: `test -s ${seedCredentialPath} || { ` + `openssl rand -base64 32 | tr '+/' '-_' | tr -d '=\\n' | ` + `systemd-creds encrypt --name=agent-seed - ${seedCredentialPath}; ` + `chmod 0400 ${seedCredentialPath}; }`
|
|
@@ -1218,8 +1261,8 @@ function planProvision(options) {
|
|
|
1218
1261
|
command: "systemctl disable --now forgezero-deploy-runner.socket 2>/dev/null || true; rm -f /etc/systemd/system/forgezero-deploy-runner.socket; systemctl daemon-reload"
|
|
1219
1262
|
}] : [],
|
|
1220
1263
|
{
|
|
1221
|
-
label: "enable and
|
|
1222
|
-
command: `systemctl enable
|
|
1264
|
+
label: "enable and converge services",
|
|
1265
|
+
command: `systemctl enable ${[
|
|
1223
1266
|
"forgezero-agent.socket",
|
|
1224
1267
|
"forgezero-agent-update-helper.service",
|
|
1225
1268
|
...deploymentEnabled ? ["forgezero-deploy-runner.service", "forgezero-software-helper.service"] : [],
|
|
@@ -1227,25 +1270,32 @@ function planProvision(options) {
|
|
|
1227
1270
|
...warpEnabled ? ["forgezero-warp-config.service", "warp-svc.service"] : [],
|
|
1228
1271
|
...enrolmentEnabled ? ["forgezero-agent-enrol.service"] : [],
|
|
1229
1272
|
"forgezero-agent.service"
|
|
1230
|
-
].join(" ")}
|
|
1273
|
+
].join(" ")}; systemctl reset-failed forgezero-agent.service || true; systemctl restart ${[
|
|
1274
|
+
"forgezero-agent-update-helper.service",
|
|
1275
|
+
...deploymentEnabled ? ["forgezero-deploy-runner.service", "forgezero-software-helper.service"] : [],
|
|
1276
|
+
...lifecycleEnabled ? ["forgezero-lifecycle-helper.service"] : [],
|
|
1277
|
+
...warpEnabled ? ["forgezero-warp-config.service", "warp-svc.service"] : [],
|
|
1278
|
+
...enrolmentEnabled ? ["forgezero-agent-enrol.service"] : []
|
|
1279
|
+
].join(" ")}; systemctl restart forgezero-agent.socket; systemctl reset-failed forgezero-agent.service || true; systemctl restart forgezero-agent.service`
|
|
1231
1280
|
},
|
|
1232
1281
|
...enrolmentEnabled ? [{
|
|
1233
1282
|
label: "prove the compute binding is durable",
|
|
1234
1283
|
command: `test -s ${enrolStatePath}`
|
|
1235
1284
|
}] : [],
|
|
1236
1285
|
{ label: "prove it is running", command: "systemctl is-active forgezero-agent.service" },
|
|
1237
|
-
{ label: "prove the
|
|
1238
|
-
{ label: "prove the Agent
|
|
1286
|
+
{ label: "prove the public Vault socket exists", command: awaitSocketCommand(options.socketPath) },
|
|
1287
|
+
{ label: "prove the Agent Vault backend exists", command: awaitSocketCommand(agentBackendSocketPath(options.socketPath)) },
|
|
1288
|
+
{ label: "prove the Agent update helper exists", command: awaitSocketCommand(DEFAULT_AGENT_UPDATE_SOCKET) },
|
|
1239
1289
|
...deploymentEnabled ? [{
|
|
1240
1290
|
label: "prove the deployment runner socket exists",
|
|
1241
|
-
command:
|
|
1291
|
+
command: awaitSocketCommand(DEPLOYMENT_RUNNER_SOCKET)
|
|
1242
1292
|
}, {
|
|
1243
1293
|
label: "prove the software strategy helper socket exists",
|
|
1244
|
-
command:
|
|
1294
|
+
command: awaitSocketCommand(DEFAULT_SOFTWARE_HELPER_SOCKET)
|
|
1245
1295
|
}] : [],
|
|
1246
1296
|
...lifecycleEnabled ? [{
|
|
1247
1297
|
label: "prove the lifecycle helper socket exists",
|
|
1248
|
-
command:
|
|
1298
|
+
command: awaitSocketCommand(lifecycleHelperSocketPath)
|
|
1249
1299
|
}] : [],
|
|
1250
1300
|
...warpEnabled ? [{
|
|
1251
1301
|
label: "prove Cloudflare WARP is connected",
|
|
@@ -1253,7 +1303,7 @@ function planProvision(options) {
|
|
|
1253
1303
|
}] : [],
|
|
1254
1304
|
...options.repository ? [{
|
|
1255
1305
|
label: "prove the deployment control socket exists",
|
|
1256
|
-
command:
|
|
1306
|
+
command: awaitSocketCommand(options.controlSocketPath ?? "/run/forgezero/control.sock")
|
|
1257
1307
|
}] : []
|
|
1258
1308
|
]
|
|
1259
1309
|
};
|
|
@@ -1271,7 +1321,9 @@ export {
|
|
|
1271
1321
|
agentUpdateHelperUnit,
|
|
1272
1322
|
agentUnit,
|
|
1273
1323
|
agentSocketUnit,
|
|
1324
|
+
agentSocketProxyUnit,
|
|
1274
1325
|
agentEnrolmentUnit,
|
|
1326
|
+
agentBackendSocketPath,
|
|
1275
1327
|
WARP_SERVICE_DROP_IN_PATH,
|
|
1276
1328
|
WARP_CONFIG_UNIT_PATH,
|
|
1277
1329
|
VAULT_GROUP,
|
|
@@ -1285,5 +1337,6 @@ export {
|
|
|
1285
1337
|
DEPLOYMENT_RUNNER_SOCKET,
|
|
1286
1338
|
DEPLOYMENT_GROUP,
|
|
1287
1339
|
CAPABILITY_CHECKS,
|
|
1288
|
-
AGENT_SOCKET_UNIT_PATH
|
|
1340
|
+
AGENT_SOCKET_UNIT_PATH,
|
|
1341
|
+
AGENT_SOCKET_PROXY_UNIT_PATH
|
|
1289
1342
|
};
|
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.29";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"//": "Publishing happens from an operator's machine, not CI \u2014 CLAUDE.md records that the absence of CI is deliberate. npm's `provenance` attests a tarball was built by a recognised CI provider from a named commit, so it cannot be produced here: it was set, and the first publish failed with `Automatic provenance generation not supported for provider: null`. A setting that can never be satisfied is worse than none, because it reads as a guarantee nobody is getting. Restore it the day this publishes from CI, and not before.",
|
|
3
3
|
"name": "@forgezero/agent",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.29",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"check": "tsc --noEmit",
|