@forgezero/agent 0.1.25 → 0.1.27
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 +2 -1
- package/dist/agent-heartbeat.d.ts +45 -0
- package/dist/agent-heartbeat.js +498 -0
- package/dist/agent-update-helper.d.ts +45 -0
- package/dist/agent-update-helper.js +366 -0
- package/dist/agent-update.d.ts +46 -0
- package/dist/agent-update.js +184 -0
- package/dist/definition.d.ts +1 -7
- package/dist/definition.js +92 -23
- package/dist/deployment-pull.d.ts +2 -0
- package/dist/deployment.d.ts +3 -0
- package/dist/fz-agent.js +7838 -2595
- package/dist/fz.js +8287 -38
- package/dist/index.d.ts +13 -0
- package/dist/node-vault.js +37 -10
- package/dist/provision.d.ts +13 -0
- package/dist/provision.js +685 -6
- package/dist/socket.d.ts +2 -0
- package/dist/software-helper.d.ts +14 -0
- package/dist/software-helper.js +203 -0
- package/dist/software.d.ts +27 -0
- package/dist/software.js +95 -0
- package/dist/version.d.ts +1 -1
- package/package.json +24 -4
package/dist/index.d.ts
CHANGED
|
@@ -27,6 +27,15 @@ export { DEFAULT_METAL_HELPER_SOCKET, requestMetalProvision, startMetalHelper }
|
|
|
27
27
|
export { DEFAULT_LIFECYCLE_HELPER_SOCKET, executeLifecycleAction, loadLifecycleProfile, requestLifecycleAction, startLifecycleHelper, validateLifecycleProfile } from './lifecycle-helper';
|
|
28
28
|
export type { LifecycleCommandResult, LifecycleExec, LifecycleProfile } from './lifecycle-helper';
|
|
29
29
|
export { materializeWarpMdm, renderWarpMdm } from './warp-config';
|
|
30
|
+
export { compareVersions, restoreAgentRelease, selectAgentRelease, stageAgentRelease, validateAgentRelease, DEFAULT_AGENT_RELEASE_ROOT, DEFAULT_AGENT_UPDATE_SOCKET, MAX_AGENT_TARBALL_BYTES } from './agent-update';
|
|
31
|
+
export type { AgentRelease, StagedAgentRelease, UpdateCommand, UpdateCommandResult } from './agent-update';
|
|
32
|
+
export { activateAgentRelease, probeAgentSocket, requestAgentUpdate, startAgentUpdateHelper, AGENT_UPDATE_GROUP, AGENT_UPDATE_HELPER_UNIT_PATH, AGENT_UPDATE_RECEIPT } from './agent-update-helper';
|
|
33
|
+
export type { AgentUpdateRequest, AgentUpdateResponse } from './agent-update-helper';
|
|
34
|
+
export { DEFAULT_SOFTWARE_HELPER_SOCKET, requestSoftware, startSoftwareHelper, SOFTWARE_HELPER_GROUP, SOFTWARE_HELPER_UNIT_PATH } from './software-helper';
|
|
35
|
+
export { ensureSoftwareRequirements, observeSoftwareHost, validateSoftwareRequirements } from './software';
|
|
36
|
+
export type { SoftwareCommandResult, SoftwareExec, SoftwareObservation, SoftwareRequirement } from './software';
|
|
37
|
+
export { heartbeatAgentOnce, observeAgentHost, startAgentHeartbeat } from './agent-heartbeat';
|
|
38
|
+
export type { AgentHeartbeatOptions, AgentHeartbeatResponse, AgentObservation } from './agent-heartbeat';
|
|
30
39
|
export { DEFAULT_DEPLOYMENT_RUNNER_SOCKET, requestDeploymentCommand, startDeploymentRunner } from './deployment-runner';
|
|
31
40
|
export { createSnpAttestationSource } from './snp-attestation';
|
|
32
41
|
export type { SnpAttestationOptions } from './snp-attestation';
|
|
@@ -45,6 +54,8 @@ export { assertSupportedGuestImage, SUPPORTED_GUEST_IMAGE } from './ubuntu';
|
|
|
45
54
|
export declare function loadOrCreateSeed(path: string): Uint8Array;
|
|
46
55
|
export interface AgentConfig {
|
|
47
56
|
socketPath?: string;
|
|
57
|
+
/** systemd-owned listener fd; preserves the application endpoint across replacement. */
|
|
58
|
+
listenFd?: number;
|
|
48
59
|
seedPath?: string;
|
|
49
60
|
/** Prefer this already-unsealed systemd credential over a persistent file. */
|
|
50
61
|
seedCredential?: string;
|
|
@@ -82,6 +93,8 @@ export declare const DEFAULT_SOCKET_PATH = "/run/forgezero/vault.sock";
|
|
|
82
93
|
export declare const DEFAULT_SEED_PATH = "/var/lib/forgezero/node.seed";
|
|
83
94
|
export declare const DEFAULT_SEED_CREDENTIAL = "agent-seed";
|
|
84
95
|
export declare const DEFAULT_ENROLMENT_STATE_PATH = "/var/lib/forgezero/enrolment.json";
|
|
96
|
+
/** Resolve the one descriptor systemd passes for the application Vault socket. */
|
|
97
|
+
export declare function systemdListenFd(environment?: Record<string, string | undefined>, pid?: number): number | undefined;
|
|
85
98
|
/**
|
|
86
99
|
* Read a systemd credential made available only to this unit.
|
|
87
100
|
*
|
package/dist/node-vault.js
CHANGED
|
@@ -10,30 +10,44 @@ class CacheError extends Error {
|
|
|
10
10
|
var DEFAULT_TTL_MS = 60000;
|
|
11
11
|
var DEFAULT_MAX_STALE_MS = 300000;
|
|
12
12
|
function createSecretCache(options) {
|
|
13
|
-
|
|
13
|
+
let entries = new Map;
|
|
14
14
|
const now = options.now ?? (() => Date.now());
|
|
15
15
|
const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
|
|
16
16
|
const maxStaleMs = options.maxStaleMs ?? DEFAULT_MAX_STALE_MS;
|
|
17
17
|
let cursor = 0;
|
|
18
18
|
let replicated = false;
|
|
19
19
|
let lastSyncOkMs = now();
|
|
20
|
-
const
|
|
20
|
+
const fetchScope = async () => {
|
|
21
|
+
const next = new Map;
|
|
21
22
|
if (!options.list)
|
|
22
|
-
return { loaded: 0, failed: [] };
|
|
23
|
+
return { entries: next, loaded: 0, failed: [] };
|
|
23
24
|
const names = await options.list();
|
|
24
25
|
const failed = [];
|
|
25
|
-
let loaded = 0;
|
|
26
26
|
for (const name of names) {
|
|
27
27
|
try {
|
|
28
28
|
const result = await options.fetch(name);
|
|
29
|
-
|
|
30
|
-
loaded += 1;
|
|
29
|
+
next.set(name, { value: result.value, version: result.version, fetchedAtMs: now() });
|
|
31
30
|
} catch {
|
|
32
31
|
failed.push(name);
|
|
33
32
|
}
|
|
34
33
|
}
|
|
34
|
+
return { entries: next, loaded: next.size, failed };
|
|
35
|
+
};
|
|
36
|
+
const loadScope = async () => {
|
|
37
|
+
if (!options.list)
|
|
38
|
+
return { loaded: 0, failed: [] };
|
|
39
|
+
const snapshot = await fetchScope();
|
|
40
|
+
entries = snapshot.entries;
|
|
41
|
+
replicated = snapshot.failed.length === 0;
|
|
42
|
+
return { loaded: snapshot.loaded, failed: snapshot.failed };
|
|
43
|
+
};
|
|
44
|
+
const refreshScope = async () => {
|
|
45
|
+
const snapshot = await fetchScope();
|
|
46
|
+
if (snapshot.failed.length > 0) {
|
|
47
|
+
throw new CacheError("FETCH_FAILED", `Could not refresh ${snapshot.failed.length} assigned vault ${snapshot.failed.length === 1 ? "entry" : "entries"}.`);
|
|
48
|
+
}
|
|
49
|
+
entries = snapshot.entries;
|
|
35
50
|
replicated = true;
|
|
36
|
-
return { loaded, failed };
|
|
37
51
|
};
|
|
38
52
|
return {
|
|
39
53
|
names: () => [...entries.keys()],
|
|
@@ -67,13 +81,26 @@ function createSecretCache(options) {
|
|
|
67
81
|
const result = await options.changes(cursor);
|
|
68
82
|
if (result.resync) {
|
|
69
83
|
const dropped = [...entries.keys()];
|
|
70
|
-
|
|
84
|
+
if (options.list) {
|
|
85
|
+
await refreshScope();
|
|
86
|
+
} else {
|
|
87
|
+
entries.clear();
|
|
88
|
+
}
|
|
71
89
|
cursor = 0;
|
|
72
90
|
lastSyncOkMs = now();
|
|
73
|
-
if (options.list)
|
|
74
|
-
await loadScope();
|
|
75
91
|
return { invalidated: dropped, cursor: 0, resync: true };
|
|
76
92
|
}
|
|
93
|
+
if (options.list && result.changed.length > 0) {
|
|
94
|
+
const held = new Set(entries.keys());
|
|
95
|
+
await refreshScope();
|
|
96
|
+
cursor = result.version;
|
|
97
|
+
lastSyncOkMs = now();
|
|
98
|
+
return {
|
|
99
|
+
invalidated: result.changed.filter((name) => held.has(name) || entries.has(name)),
|
|
100
|
+
cursor,
|
|
101
|
+
resync: false
|
|
102
|
+
};
|
|
103
|
+
}
|
|
77
104
|
const invalidated = [];
|
|
78
105
|
for (const name of result.changed) {
|
|
79
106
|
if (entries.delete(name))
|
package/dist/provision.d.ts
CHANGED
|
@@ -127,12 +127,25 @@ export declare const DEPLOYMENT_GROUP = "forgezero-deploy";
|
|
|
127
127
|
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
|
+
export declare const AGENT_SOCKET_UNIT_PATH = "/etc/systemd/system/forgezero-agent.socket";
|
|
130
131
|
export declare const DEPLOYMENT_RUNNER_SOCKET = "/run/forgezero-deploy/runner.sock";
|
|
131
132
|
export declare const ENROLMENT_UNIT_PATH = "/etc/systemd/system/forgezero-agent-enrol.service";
|
|
132
133
|
export declare const LIFECYCLE_HELPER_UNIT_PATH = "/etc/systemd/system/forgezero-lifecycle-helper.service";
|
|
133
134
|
export declare const LIFECYCLE_HELPER_SOCKET = "/run/forgezero-lifecycle/helper.sock";
|
|
134
135
|
export declare const WARP_CONFIG_UNIT_PATH = "/etc/systemd/system/forgezero-warp-config.service";
|
|
135
136
|
export declare const WARP_SERVICE_DROP_IN_PATH = "/etc/systemd/system/warp-svc.service.d/forgezero.conf";
|
|
137
|
+
/** Root may execute only package-owned OS strategies selected by id + version. */
|
|
138
|
+
export declare function softwareHelperUnit(options: Pick<UnitOptions, 'binPath'>): string;
|
|
139
|
+
/** Fixed root boundary for verified, health-gated Agent replacement. */
|
|
140
|
+
export declare function agentUpdateHelperUnit(options: Pick<UnitOptions, 'binPath'>): string;
|
|
141
|
+
/**
|
|
142
|
+
* PID 1 owns the stable application endpoint.
|
|
143
|
+
*
|
|
144
|
+
* New connections wait in the kernel while the credential-bearing Agent drains
|
|
145
|
+
* and a health-gated replacement starts. This is supervision, not a background
|
|
146
|
+
* terminal, and it works identically on platform and tenant computes.
|
|
147
|
+
*/
|
|
148
|
+
export declare function agentSocketUnit(options: Pick<UnitOptions, 'socketPath'>): string;
|
|
136
149
|
export declare function warpConfigUnit(options: Pick<UnitOptions, 'binPath' | 'warpOrganization' | 'warpClientIdCredentialPath' | 'warpClientSecretCredentialPath'>): string;
|
|
137
150
|
export declare function warpServiceDropIn(): string;
|
|
138
151
|
export declare function lifecycleHelperUnit(options: Pick<UnitOptions, 'binPath' | 'lifecycleProfilePath' | 'lifecycleHelperSocketPath'>): string;
|