@forgezero/agent 0.1.86 → 0.1.87

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/fz.js CHANGED
@@ -4827,9 +4827,13 @@ import { hostname } from "os";
4827
4827
 
4828
4828
  // src/agent-update.ts
4829
4829
  var DEFAULT_AGENT_RELEASE_ROOT = "/opt/forgezero/agent";
4830
+ var DEFAULT_AGENT_CANDIDATE_LINK = `${DEFAULT_AGENT_RELEASE_ROOT}/candidate`;
4830
4831
  var DEFAULT_AGENT_UPDATE_SOCKET = "/run/forgezero-update/helper.sock";
4831
4832
  var MAX_AGENT_TARBALL_BYTES = 32 * 1024 * 1024;
4832
4833
 
4834
+ // src/agent-handover.ts
4835
+ var DEFAULT_AGENT_CANDIDATE_READY_SOCKET = "/run/forgezero/candidate-ready.sock";
4836
+
4833
4837
  // src/agent-update-helper.ts
4834
4838
  var AGENT_UPDATE_GROUP = "forgezero-update";
4835
4839
  var AGENT_UPDATE_HELPER_UNIT_PATH = "/etc/systemd/system/forgezero-agent-update-helper.service";
@@ -4838,7 +4842,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
4838
4842
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
4839
4843
 
4840
4844
  // src/version.ts
4841
- var VERSION2 = "0.1.86";
4845
+ var VERSION2 = "0.1.87";
4842
4846
 
4843
4847
  // src/software.ts
4844
4848
  var PINNED_BUN_VERSION = "1.3.14";
@@ -5455,6 +5459,7 @@ var LIFECYCLE_GROUP = "forgezero-lifecycle";
5455
5459
  var DEPLOYMENT_RUNNER_UNIT_PATH = "/etc/systemd/system/forgezero-deploy-runner.service";
5456
5460
  var AGENT_SOCKET_UNIT_PATH = "/etc/systemd/system/forgezero-agent.socket";
5457
5461
  var AGENT_SOCKET_PROXY_UNIT_PATH = "/etc/systemd/system/forgezero-agent-proxy.service";
5462
+ var AGENT_CANDIDATE_UNIT_PATH = "/etc/systemd/system/forgezero-agent-candidate.service";
5458
5463
  var DEPLOYMENT_RUNNER_SOCKET = "/run/forgezero-deploy/runner.sock";
5459
5464
  var ENROLMENT_UNIT_PATH = "/etc/systemd/system/forgezero-agent-enrol.service";
5460
5465
  var LIFECYCLE_HELPER_UNIT_PATH = "/etc/systemd/system/forgezero-lifecycle-helper.service";
@@ -5566,6 +5571,7 @@ Type=simple
5566
5571
  User=root
5567
5572
  Group=${AGENT_UPDATE_GROUP}
5568
5573
  Environment=FZ_AGENT_UPDATE_SOCKET=${DEFAULT_AGENT_UPDATE_SOCKET}
5574
+ Environment=FZ_AGENT_PUBLIC_SOCKET=${systemdPath(options.socketPath, "agent socket")}
5569
5575
  ExecStart=${bin} update-helper
5570
5576
  Restart=always
5571
5577
  RestartSec=2
@@ -5610,13 +5616,11 @@ WantedBy=sockets.target
5610
5616
  `;
5611
5617
  }
5612
5618
  function agentSocketProxyUnit(options) {
5613
- const backend = agentBackendSocketPath(options.socketPath);
5619
+ const backend = agentRoutingSocketPath(options.socketPath);
5614
5620
  const user = options.user ?? "forgezero";
5615
5621
  return `[Unit]
5616
5622
  Description=ForgeZero application Vault socket proxy
5617
5623
  Documentation=https://www.forgezero.net/docs/agent
5618
- Requires=forgezero-agent.service
5619
- After=forgezero-agent.service
5620
5624
 
5621
5625
  [Service]
5622
5626
  User=${user}
@@ -5637,12 +5641,26 @@ RestrictAddressFamilies=AF_UNIX
5637
5641
  `;
5638
5642
  }
5639
5643
  function agentBackendSocketPath(publicSocketPath) {
5644
+ const socket = systemdPath(publicSocketPath, "agent socket");
5645
+ const backend = `${socket}.backend.active`;
5646
+ if (Buffer.byteLength(backend) > 100)
5647
+ throw new Error("agent socket path is too long for a Unix socket");
5648
+ return backend;
5649
+ }
5650
+ function agentRoutingSocketPath(publicSocketPath) {
5640
5651
  const socket = systemdPath(publicSocketPath, "agent socket");
5641
5652
  const backend = `${socket}.backend`;
5642
5653
  if (Buffer.byteLength(backend) > 100)
5643
5654
  throw new Error("agent socket path is too long for a Unix socket");
5644
5655
  return backend;
5645
5656
  }
5657
+ function agentCandidateSocketPath(publicSocketPath) {
5658
+ const socket = systemdPath(publicSocketPath, "agent socket");
5659
+ const backend = `${socket}.backend.candidate`;
5660
+ if (Buffer.byteLength(backend) > 100)
5661
+ throw new Error("agent socket path is too long for a Unix socket");
5662
+ return backend;
5663
+ }
5646
5664
  var systemdPath = (value, label) => {
5647
5665
  if (!value || !/^\/[A-Za-z0-9._@/-]+$/.test(value))
5648
5666
  throw new Error(`invalid ${label} path`);
@@ -5926,7 +5944,11 @@ function agentUnit(options) {
5926
5944
  }
5927
5945
  const environment = [
5928
5946
  "NODE_ENV=production",
5929
- `FZ_SOCKET_PATH=${agentBackendSocketPath(options.socketPath)}`,
5947
+ `FZ_SOCKET_PATH=${options.backendSocketPath ?? agentBackendSocketPath(options.socketPath)}`,
5948
+ `FZ_AGENT_PUBLIC_SOCKET=${options.socketPath}`,
5949
+ `FZ_AGENT_ROUTE_SOCKET=${agentRoutingSocketPath(options.socketPath)}`,
5950
+ options.handoverCandidate ? "FZ_AGENT_HANDOVER_CANDIDATE=true" : null,
5951
+ options.handoverCandidate ? `FZ_AGENT_HANDOVER_READY_SOCKET=${DEFAULT_AGENT_CANDIDATE_READY_SOCKET}` : null,
5930
5952
  `FZ_CONTROL_SOCKET=${controlSocketPath}`,
5931
5953
  `FZ_SEED_CREDENTIAL=agent-seed`,
5932
5954
  `FZ_AGENT_MODE=${options.mode}`,
@@ -6063,6 +6085,26 @@ ${deploymentWrites}
6063
6085
  WantedBy=multi-user.target
6064
6086
  `;
6065
6087
  }
6088
+ function agentCandidateUnit(options) {
6089
+ return agentUnit({
6090
+ ...options,
6091
+ binPath: `${DEFAULT_AGENT_RELEASE_ROOT}/candidate/dist/fz-agent.js`,
6092
+ backendSocketPath: agentCandidateSocketPath(options.socketPath),
6093
+ handoverCandidate: true,
6094
+ gitCredentialPath: undefined,
6095
+ deploymentCredentials: {},
6096
+ bootstrapSshCredentialPath: undefined,
6097
+ bootstrapSshPublicKeyPath: undefined,
6098
+ pullBootstrap: false,
6099
+ pullDeployments: false,
6100
+ pullMigrations: false,
6101
+ lifecycleProfilePath: undefined,
6102
+ bootstrapTargetTelemetryEndpoint: undefined,
6103
+ repository: undefined,
6104
+ bootstrapBundlePath: undefined,
6105
+ bootstrapBundleManifestPath: undefined
6106
+ }).replace("Description=ForgeZero node agent", "Description=ForgeZero candidate node agent");
6107
+ }
6066
6108
  var renderOperation = (operation) => {
6067
6109
  if (operation.kind === "commands")
6068
6110
  return operation.commands.map(({ argv: argv2 }) => argv2.join(" ")).join(`
@@ -6198,6 +6240,7 @@ function planProvision(options) {
6198
6240
  auxiliaryUnits: [
6199
6241
  { path: AGENT_SOCKET_UNIT_PATH, unit: agentSocketUnit(options) },
6200
6242
  { path: AGENT_SOCKET_PROXY_UNIT_PATH, unit: agentSocketProxyUnit(options) },
6243
+ { path: AGENT_CANDIDATE_UNIT_PATH, unit: agentCandidateUnit(options) },
6201
6244
  { path: AGENT_UPDATE_HELPER_UNIT_PATH, unit: agentUpdateHelperUnit(options) },
6202
6245
  ...options.enforceEgress ? [
6203
6246
  { path: AGENT_EGRESS_UNIT_PATH, unit: agentEgressUnit(options) }
@@ -16041,6 +16084,7 @@ function planMetalBootstrap(config) {
16041
16084
  "forgezero-metal-helper.service",
16042
16085
  "forgezero-agent-update-helper.service",
16043
16086
  "forgezero-metal-agent-egress.service",
16087
+ "forgezero-metal-agent-candidate.service",
16044
16088
  "forgezero-metal-agent.service"
16045
16089
  ],
16046
16090
  steps: [
@@ -16182,6 +16226,44 @@ RestrictAddressFamilies=AF_UNIX AF_NETLINK
16182
16226
 
16183
16227
  [Install]
16184
16228
  WantedBy=multi-user.target
16229
+ `,
16230
+ "forgezero-metal-agent-candidate.service": `[Unit]
16231
+ Description=ForgeZero candidate physical-host Agent
16232
+ After=network-online.target ${config.hostTelemetryUnit} forgezero-agent-update-helper.service forgezero-metal-agent-egress.service
16233
+ Requires=forgezero-agent-update-helper.service forgezero-metal-agent-egress.service
16234
+
16235
+ [Service]
16236
+ Type=simple
16237
+ User=forgezero-metal
16238
+ Group=forgezero-metal
16239
+ SupplementaryGroups=forgezero-update
16240
+ LoadCredentialEncrypted=metal-agent-seed:${SEED_CREDENTIAL_PATH}
16241
+ Environment=FZ_SEED_CREDENTIAL=metal-agent-seed
16242
+ Environment=FZ_AGENT_ROLE=metal
16243
+ Environment=FZ_AGENT_HANDOVER_CANDIDATE=true
16244
+ Environment=FZ_AGENT_HANDOVER_READY_SOCKET=/run/forgezero/candidate-ready.sock
16245
+ Environment=FZ_METAL_HOSTNAME=${config.metalHostname}
16246
+ Environment=FZ_API=${config.profile.apiUrl}
16247
+ Environment=NODE_ENV=production
16248
+ Environment=OTEL_EXPORTER_OTLP_ENDPOINT=${config.hostTelemetryEndpoint}
16249
+ Environment=OTEL_SERVICE_NAME=forgezero-metal-agent-candidate
16250
+ ExecStart=/opt/forgezero/agent/candidate/dist/fz-agent.js
16251
+ Restart=on-failure
16252
+ RestartSec=2
16253
+ RuntimeDirectory=forgezero
16254
+ RuntimeDirectoryMode=0750
16255
+ RuntimeDirectoryPreserve=yes
16256
+ LimitCORE=0
16257
+ NoNewPrivileges=true
16258
+ PrivateTmp=true
16259
+ ProtectSystem=strict
16260
+ ProtectHome=true
16261
+ ProtectKernelTunables=true
16262
+ ProtectKernelModules=true
16263
+ ProtectControlGroups=true
16264
+ RestrictSUIDSGID=true
16265
+ LockPersonality=true
16266
+ ${egress}
16185
16267
  `,
16186
16268
  "forgezero-metal-agent.service": `[Unit]
16187
16269
  Description=ForgeZero identity-only physical-host Agent
@@ -366,7 +366,7 @@ function systemdAgentEgressDirectives(loopbackTcpPorts = []) {
366
366
  }
367
367
 
368
368
  // src/version.ts
369
- var VERSION = "0.1.86";
369
+ var VERSION = "0.1.87";
370
370
 
371
371
  // src/otel-collector.ts
372
372
  var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
@@ -705,6 +705,7 @@ function planMetalBootstrap(config) {
705
705
  "forgezero-metal-helper.service",
706
706
  "forgezero-agent-update-helper.service",
707
707
  "forgezero-metal-agent-egress.service",
708
+ "forgezero-metal-agent-candidate.service",
708
709
  "forgezero-metal-agent.service"
709
710
  ],
710
711
  steps: [
@@ -846,6 +847,44 @@ RestrictAddressFamilies=AF_UNIX AF_NETLINK
846
847
 
847
848
  [Install]
848
849
  WantedBy=multi-user.target
850
+ `,
851
+ "forgezero-metal-agent-candidate.service": `[Unit]
852
+ Description=ForgeZero candidate physical-host Agent
853
+ After=network-online.target ${config.hostTelemetryUnit} forgezero-agent-update-helper.service forgezero-metal-agent-egress.service
854
+ Requires=forgezero-agent-update-helper.service forgezero-metal-agent-egress.service
855
+
856
+ [Service]
857
+ Type=simple
858
+ User=forgezero-metal
859
+ Group=forgezero-metal
860
+ SupplementaryGroups=forgezero-update
861
+ LoadCredentialEncrypted=metal-agent-seed:${SEED_CREDENTIAL_PATH}
862
+ Environment=FZ_SEED_CREDENTIAL=metal-agent-seed
863
+ Environment=FZ_AGENT_ROLE=metal
864
+ Environment=FZ_AGENT_HANDOVER_CANDIDATE=true
865
+ Environment=FZ_AGENT_HANDOVER_READY_SOCKET=/run/forgezero/candidate-ready.sock
866
+ Environment=FZ_METAL_HOSTNAME=${config.metalHostname}
867
+ Environment=FZ_API=${config.profile.apiUrl}
868
+ Environment=NODE_ENV=production
869
+ Environment=OTEL_EXPORTER_OTLP_ENDPOINT=${config.hostTelemetryEndpoint}
870
+ Environment=OTEL_SERVICE_NAME=forgezero-metal-agent-candidate
871
+ ExecStart=/opt/forgezero/agent/candidate/dist/fz-agent.js
872
+ Restart=on-failure
873
+ RestartSec=2
874
+ RuntimeDirectory=forgezero
875
+ RuntimeDirectoryMode=0750
876
+ RuntimeDirectoryPreserve=yes
877
+ LimitCORE=0
878
+ NoNewPrivileges=true
879
+ PrivateTmp=true
880
+ ProtectSystem=strict
881
+ ProtectHome=true
882
+ ProtectKernelTunables=true
883
+ ProtectKernelModules=true
884
+ ProtectControlGroups=true
885
+ RestrictSUIDSGID=true
886
+ LockPersonality=true
887
+ ${egress}
849
888
  `,
850
889
  "forgezero-metal-agent.service": `[Unit]
851
890
  Description=ForgeZero identity-only physical-host Agent
@@ -1405,9 +1405,13 @@ import { DEFAULT_SOCKET } from "@forgezero/vault";
1405
1405
 
1406
1406
  // src/agent-update.ts
1407
1407
  var DEFAULT_AGENT_RELEASE_ROOT = "/opt/forgezero/agent";
1408
+ var DEFAULT_AGENT_CANDIDATE_LINK = `${DEFAULT_AGENT_RELEASE_ROOT}/candidate`;
1408
1409
  var DEFAULT_AGENT_UPDATE_SOCKET = "/run/forgezero-update/helper.sock";
1409
1410
  var MAX_AGENT_TARBALL_BYTES = 32 * 1024 * 1024;
1410
1411
 
1412
+ // src/agent-handover.ts
1413
+ var DEFAULT_AGENT_CANDIDATE_READY_SOCKET = "/run/forgezero/candidate-ready.sock";
1414
+
1411
1415
  // src/agent-update-helper.ts
1412
1416
  var AGENT_UPDATE_GROUP = "forgezero-update";
1413
1417
  var AGENT_UPDATE_HELPER_UNIT_PATH = "/etc/systemd/system/forgezero-agent-update-helper.service";
@@ -1416,7 +1420,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
1416
1420
  var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
1417
1421
 
1418
1422
  // src/version.ts
1419
- var VERSION = "0.1.86";
1423
+ var VERSION = "0.1.87";
1420
1424
 
1421
1425
  // src/software.ts
1422
1426
  var PINNED_BUN_VERSION = "1.3.14";
@@ -1674,6 +1678,7 @@ var LIFECYCLE_GROUP = "forgezero-lifecycle";
1674
1678
  var DEPLOYMENT_RUNNER_UNIT_PATH = "/etc/systemd/system/forgezero-deploy-runner.service";
1675
1679
  var AGENT_SOCKET_UNIT_PATH = "/etc/systemd/system/forgezero-agent.socket";
1676
1680
  var AGENT_SOCKET_PROXY_UNIT_PATH = "/etc/systemd/system/forgezero-agent-proxy.service";
1681
+ var AGENT_CANDIDATE_UNIT_PATH = "/etc/systemd/system/forgezero-agent-candidate.service";
1677
1682
  var DEPLOYMENT_RUNNER_SOCKET = "/run/forgezero-deploy/runner.sock";
1678
1683
  var ENROLMENT_UNIT_PATH = "/etc/systemd/system/forgezero-agent-enrol.service";
1679
1684
  var LIFECYCLE_HELPER_UNIT_PATH = "/etc/systemd/system/forgezero-lifecycle-helper.service";
@@ -1785,6 +1790,7 @@ Type=simple
1785
1790
  User=root
1786
1791
  Group=${AGENT_UPDATE_GROUP}
1787
1792
  Environment=FZ_AGENT_UPDATE_SOCKET=${DEFAULT_AGENT_UPDATE_SOCKET}
1793
+ Environment=FZ_AGENT_PUBLIC_SOCKET=${systemdPath(options.socketPath, "agent socket")}
1788
1794
  ExecStart=${bin} update-helper
1789
1795
  Restart=always
1790
1796
  RestartSec=2
@@ -1829,13 +1835,11 @@ WantedBy=sockets.target
1829
1835
  `;
1830
1836
  }
1831
1837
  function agentSocketProxyUnit(options) {
1832
- const backend = agentBackendSocketPath(options.socketPath);
1838
+ const backend = agentRoutingSocketPath(options.socketPath);
1833
1839
  const user = options.user ?? "forgezero";
1834
1840
  return `[Unit]
1835
1841
  Description=ForgeZero application Vault socket proxy
1836
1842
  Documentation=https://www.forgezero.net/docs/agent
1837
- Requires=forgezero-agent.service
1838
- After=forgezero-agent.service
1839
1843
 
1840
1844
  [Service]
1841
1845
  User=${user}
@@ -1856,12 +1860,26 @@ RestrictAddressFamilies=AF_UNIX
1856
1860
  `;
1857
1861
  }
1858
1862
  function agentBackendSocketPath(publicSocketPath) {
1863
+ const socket = systemdPath(publicSocketPath, "agent socket");
1864
+ const backend = `${socket}.backend.active`;
1865
+ if (Buffer.byteLength(backend) > 100)
1866
+ throw new Error("agent socket path is too long for a Unix socket");
1867
+ return backend;
1868
+ }
1869
+ function agentRoutingSocketPath(publicSocketPath) {
1859
1870
  const socket = systemdPath(publicSocketPath, "agent socket");
1860
1871
  const backend = `${socket}.backend`;
1861
1872
  if (Buffer.byteLength(backend) > 100)
1862
1873
  throw new Error("agent socket path is too long for a Unix socket");
1863
1874
  return backend;
1864
1875
  }
1876
+ function agentCandidateSocketPath(publicSocketPath) {
1877
+ const socket = systemdPath(publicSocketPath, "agent socket");
1878
+ const backend = `${socket}.backend.candidate`;
1879
+ if (Buffer.byteLength(backend) > 100)
1880
+ throw new Error("agent socket path is too long for a Unix socket");
1881
+ return backend;
1882
+ }
1865
1883
  var systemdPath = (value, label) => {
1866
1884
  if (!value || !/^\/[A-Za-z0-9._@/-]+$/.test(value))
1867
1885
  throw new Error(`invalid ${label} path`);
@@ -2145,7 +2163,11 @@ function agentUnit(options) {
2145
2163
  }
2146
2164
  const environment = [
2147
2165
  "NODE_ENV=production",
2148
- `FZ_SOCKET_PATH=${agentBackendSocketPath(options.socketPath)}`,
2166
+ `FZ_SOCKET_PATH=${options.backendSocketPath ?? agentBackendSocketPath(options.socketPath)}`,
2167
+ `FZ_AGENT_PUBLIC_SOCKET=${options.socketPath}`,
2168
+ `FZ_AGENT_ROUTE_SOCKET=${agentRoutingSocketPath(options.socketPath)}`,
2169
+ options.handoverCandidate ? "FZ_AGENT_HANDOVER_CANDIDATE=true" : null,
2170
+ options.handoverCandidate ? `FZ_AGENT_HANDOVER_READY_SOCKET=${DEFAULT_AGENT_CANDIDATE_READY_SOCKET}` : null,
2149
2171
  `FZ_CONTROL_SOCKET=${controlSocketPath}`,
2150
2172
  `FZ_SEED_CREDENTIAL=agent-seed`,
2151
2173
  `FZ_AGENT_MODE=${options.mode}`,
@@ -2282,6 +2304,26 @@ ${deploymentWrites}
2282
2304
  WantedBy=multi-user.target
2283
2305
  `;
2284
2306
  }
2307
+ function agentCandidateUnit(options) {
2308
+ return agentUnit({
2309
+ ...options,
2310
+ binPath: `${DEFAULT_AGENT_RELEASE_ROOT}/candidate/dist/fz-agent.js`,
2311
+ backendSocketPath: agentCandidateSocketPath(options.socketPath),
2312
+ handoverCandidate: true,
2313
+ gitCredentialPath: undefined,
2314
+ deploymentCredentials: {},
2315
+ bootstrapSshCredentialPath: undefined,
2316
+ bootstrapSshPublicKeyPath: undefined,
2317
+ pullBootstrap: false,
2318
+ pullDeployments: false,
2319
+ pullMigrations: false,
2320
+ lifecycleProfilePath: undefined,
2321
+ bootstrapTargetTelemetryEndpoint: undefined,
2322
+ repository: undefined,
2323
+ bootstrapBundlePath: undefined,
2324
+ bootstrapBundleManifestPath: undefined
2325
+ }).replace("Description=ForgeZero node agent", "Description=ForgeZero candidate node agent");
2326
+ }
2285
2327
  var renderOperation = (operation) => {
2286
2328
  if (operation.kind === "commands")
2287
2329
  return operation.commands.map(({ argv }) => argv.join(" ")).join(`
@@ -2417,6 +2459,7 @@ function planProvision(options) {
2417
2459
  auxiliaryUnits: [
2418
2460
  { path: AGENT_SOCKET_UNIT_PATH, unit: agentSocketUnit(options) },
2419
2461
  { path: AGENT_SOCKET_PROXY_UNIT_PATH, unit: agentSocketProxyUnit(options) },
2462
+ { path: AGENT_CANDIDATE_UNIT_PATH, unit: agentCandidateUnit(options) },
2420
2463
  { path: AGENT_UPDATE_HELPER_UNIT_PATH, unit: agentUpdateHelperUnit(options) },
2421
2464
  ...options.enforceEgress ? [
2422
2465
  { path: AGENT_EGRESS_UNIT_PATH, unit: agentEgressUnit(options) }
@@ -5397,6 +5440,7 @@ function planMetalBootstrap(config) {
5397
5440
  "forgezero-metal-helper.service",
5398
5441
  "forgezero-agent-update-helper.service",
5399
5442
  "forgezero-metal-agent-egress.service",
5443
+ "forgezero-metal-agent-candidate.service",
5400
5444
  "forgezero-metal-agent.service"
5401
5445
  ],
5402
5446
  steps: [
@@ -5538,6 +5582,44 @@ RestrictAddressFamilies=AF_UNIX AF_NETLINK
5538
5582
 
5539
5583
  [Install]
5540
5584
  WantedBy=multi-user.target
5585
+ `,
5586
+ "forgezero-metal-agent-candidate.service": `[Unit]
5587
+ Description=ForgeZero candidate physical-host Agent
5588
+ After=network-online.target ${config.hostTelemetryUnit} forgezero-agent-update-helper.service forgezero-metal-agent-egress.service
5589
+ Requires=forgezero-agent-update-helper.service forgezero-metal-agent-egress.service
5590
+
5591
+ [Service]
5592
+ Type=simple
5593
+ User=forgezero-metal
5594
+ Group=forgezero-metal
5595
+ SupplementaryGroups=forgezero-update
5596
+ LoadCredentialEncrypted=metal-agent-seed:${SEED_CREDENTIAL_PATH}
5597
+ Environment=FZ_SEED_CREDENTIAL=metal-agent-seed
5598
+ Environment=FZ_AGENT_ROLE=metal
5599
+ Environment=FZ_AGENT_HANDOVER_CANDIDATE=true
5600
+ Environment=FZ_AGENT_HANDOVER_READY_SOCKET=/run/forgezero/candidate-ready.sock
5601
+ Environment=FZ_METAL_HOSTNAME=${config.metalHostname}
5602
+ Environment=FZ_API=${config.profile.apiUrl}
5603
+ Environment=NODE_ENV=production
5604
+ Environment=OTEL_EXPORTER_OTLP_ENDPOINT=${config.hostTelemetryEndpoint}
5605
+ Environment=OTEL_SERVICE_NAME=forgezero-metal-agent-candidate
5606
+ ExecStart=/opt/forgezero/agent/candidate/dist/fz-agent.js
5607
+ Restart=on-failure
5608
+ RestartSec=2
5609
+ RuntimeDirectory=forgezero
5610
+ RuntimeDirectoryMode=0750
5611
+ RuntimeDirectoryPreserve=yes
5612
+ LimitCORE=0
5613
+ NoNewPrivileges=true
5614
+ PrivateTmp=true
5615
+ ProtectSystem=strict
5616
+ ProtectHome=true
5617
+ ProtectKernelTunables=true
5618
+ ProtectKernelModules=true
5619
+ ProtectControlGroups=true
5620
+ RestrictSUIDSGID=true
5621
+ LockPersonality=true
5622
+ ${egress}
5541
5623
  `,
5542
5624
  "forgezero-metal-agent.service": `[Unit]
5543
5625
  Description=ForgeZero identity-only physical-host Agent