@forgezero/agent 0.1.89 → 0.1.90
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.d.ts +3 -0
- package/dist/agent-heartbeat.js +2 -1
- package/dist/bootstrap.js +15 -10
- package/dist/fz-agent.js +35 -9
- package/dist/fz.js +19 -12
- package/dist/metal-bootstrap.js +1 -1
- package/dist/migration-pull.d.ts +1 -0
- package/dist/migration-pull.js +4 -0
- package/dist/operator-bootstrap.js +16 -11
- package/dist/platform-fleet-verification.js +12 -9
- package/dist/platform-launch-profile.d.ts +1 -0
- package/dist/provision.js +8 -5
- package/dist/ssh-bootstrap.d.ts +1 -0
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -37,6 +37,7 @@ export interface AgentHeartbeatResponse {
|
|
|
37
37
|
ok: true;
|
|
38
38
|
nodeKey: string;
|
|
39
39
|
intervalSeconds: number;
|
|
40
|
+
workClaimsEnabled?: boolean;
|
|
40
41
|
desiredAgentRelease?: AgentRelease;
|
|
41
42
|
desiredAgentUpdate?: {
|
|
42
43
|
attemptId: string;
|
|
@@ -70,6 +71,8 @@ export interface AgentHeartbeatOptions {
|
|
|
70
71
|
deploymentIntakeObservation?: () => AgentObservation['deploymentIntake'];
|
|
71
72
|
/** Apply the authenticated desired state before any new deployment claim is allowed. */
|
|
72
73
|
applyDeploymentIntake?: (directive: NonNullable<AgentHeartbeatResponse['deploymentIntake']>) => Promise<void> | void;
|
|
74
|
+
/** Server lifecycle gate for deployment, migration and delegated bootstrap claims. */
|
|
75
|
+
applyWorkClaims?: (enabled: boolean) => Promise<void> | void;
|
|
73
76
|
receiptPath?: string;
|
|
74
77
|
now?: () => number;
|
|
75
78
|
/** Stop new lifecycle/deploy claims and await current jobs after candidate readiness. */
|
package/dist/agent-heartbeat.js
CHANGED
|
@@ -917,7 +917,7 @@ async function postSignedNode(options, path, body) {
|
|
|
917
917
|
}
|
|
918
918
|
|
|
919
919
|
// src/version.ts
|
|
920
|
-
var VERSION3 = "0.1.
|
|
920
|
+
var VERSION3 = "0.1.90";
|
|
921
921
|
|
|
922
922
|
// src/agent-heartbeat.ts
|
|
923
923
|
function readAgentHostMetrics() {
|
|
@@ -991,6 +991,7 @@ async function heartbeatAgentOnce(options) {
|
|
|
991
991
|
throw new Error("agent heartbeat deployment-intake directive is invalid");
|
|
992
992
|
await options.applyDeploymentIntake?.(response.deploymentIntake);
|
|
993
993
|
}
|
|
994
|
+
await options.applyWorkClaims?.(response.workClaimsEnabled === true);
|
|
994
995
|
const desired = response.desiredAgentUpdate ?? (response.desiredAgentRelease ? {
|
|
995
996
|
attemptId: `legacy:${response.desiredAgentRelease.version}`,
|
|
996
997
|
leaseExpiresAtTs: Number.MAX_SAFE_INTEGER,
|
package/dist/bootstrap.js
CHANGED
|
@@ -1420,7 +1420,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
|
|
|
1420
1420
|
var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
|
|
1421
1421
|
|
|
1422
1422
|
// src/version.ts
|
|
1423
|
-
var VERSION = "0.1.
|
|
1423
|
+
var VERSION = "0.1.90";
|
|
1424
1424
|
|
|
1425
1425
|
// src/software.ts
|
|
1426
1426
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -2094,7 +2094,7 @@ function agentUnit(options) {
|
|
|
2094
2094
|
if (!validNodeHostname(options.nodeHostname))
|
|
2095
2095
|
throw new Error("node hostname is invalid");
|
|
2096
2096
|
if (!options.telemetryEndpoint) {
|
|
2097
|
-
throw new Error("compute Agent provisioning requires
|
|
2097
|
+
throw new Error("compute Agent provisioning requires an explicit supervised OTLP collector coordinate");
|
|
2098
2098
|
}
|
|
2099
2099
|
let telemetryEndpoint;
|
|
2100
2100
|
{
|
|
@@ -2102,10 +2102,13 @@ function agentUnit(options) {
|
|
|
2102
2102
|
try {
|
|
2103
2103
|
endpoint2 = new URL(options.telemetryEndpoint);
|
|
2104
2104
|
} catch {
|
|
2105
|
-
throw new Error("compute telemetry endpoint must be an absolute
|
|
2105
|
+
throw new Error("compute telemetry endpoint must be an absolute collector URL");
|
|
2106
|
+
}
|
|
2107
|
+
const localCollector = endpoint2.protocol === "http:" && endpoint2.hostname === "127.0.0.1" && endpoint2.port === "4318" && endpoint2.pathname === "/";
|
|
2108
|
+
const publicCollector = endpoint2.protocol === "https:" && !endpoint2.username && !endpoint2.password && !endpoint2.search && !endpoint2.hash && isIP3(endpoint2.hostname) === 0 && endpoint2.hostname.includes(".") && endpoint2.hostname !== "localhost" && !endpoint2.hostname.endsWith(".local");
|
|
2109
|
+
if (!localCollector && !publicCollector || endpoint2.username || endpoint2.password || endpoint2.search || endpoint2.hash) {
|
|
2110
|
+
throw new Error("compute telemetry endpoint must be the supervised loopback collector or credential-free public HTTPS");
|
|
2106
2111
|
}
|
|
2107
|
-
if (endpoint2.protocol !== "https:" || endpoint2.username || endpoint2.password || endpoint2.search || endpoint2.hash || isIP3(endpoint2.hostname) !== 0 || !endpoint2.hostname.includes(".") || endpoint2.hostname === "localhost" || endpoint2.hostname.endsWith(".local"))
|
|
2108
|
-
throw new Error("compute telemetry endpoint must be an absolute public HTTPS URL without credentials, query or fragment");
|
|
2109
2112
|
telemetryEndpoint = endpoint2.toString().replace(/\/$/, "");
|
|
2110
2113
|
}
|
|
2111
2114
|
const bin = options.binPath ?? "fz-agent";
|
|
@@ -4415,7 +4418,7 @@ async function bootstrapStatus(host = localBootstrapHost()) {
|
|
|
4415
4418
|
if (result.exitCode !== 0)
|
|
4416
4419
|
problems.push(`${unit} is not active`);
|
|
4417
4420
|
}
|
|
4418
|
-
for (const socket of [DEFAULT_SOCKET2
|
|
4421
|
+
for (const socket of [DEFAULT_SOCKET2]) {
|
|
4419
4422
|
services[socket] = host.exists(socket);
|
|
4420
4423
|
if (!services[socket])
|
|
4421
4424
|
problems.push(`${socket} is missing`);
|
|
@@ -4658,7 +4661,7 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4658
4661
|
}
|
|
4659
4662
|
let installedAgentPlan;
|
|
4660
4663
|
if (alreadyEnrolled) {
|
|
4661
|
-
installedAgentPlan = await host.installAgent(config, "bound");
|
|
4664
|
+
installedAgentPlan = await host.installAgent(config, bootstrapManifest ? "bootstrap" : "bound");
|
|
4662
4665
|
} else if (config.kind === "platform") {
|
|
4663
4666
|
if (bootstrapManifest)
|
|
4664
4667
|
installedAgentPlan = await host.installAgent(config, "bootstrap");
|
|
@@ -4833,6 +4836,8 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4833
4836
|
`, 384);
|
|
4834
4837
|
host.remove(config.bootstrapBundle.bundleFile);
|
|
4835
4838
|
host.remove(config.bootstrapBundle.manifestFile);
|
|
4839
|
+
if (alreadyEnrolled)
|
|
4840
|
+
installedAgentPlan = await host.installAgent(config, "bound");
|
|
4836
4841
|
}
|
|
4837
4842
|
if (!alreadyEnrolled) {
|
|
4838
4843
|
await checked3(host, [
|
|
@@ -5044,8 +5049,8 @@ function readBootstrapConfig(path) {
|
|
|
5044
5049
|
function planBootstrapAgentInstall(config, phase, context) {
|
|
5045
5050
|
const { capabilities, hasBinding, hasEnrolCredential, initialBundle } = context;
|
|
5046
5051
|
if (phase === "bootstrap") {
|
|
5047
|
-
if (config.kind !== "platform" ||
|
|
5048
|
-
throw new Error("
|
|
5052
|
+
if (config.kind !== "platform" || !initialBundle) {
|
|
5053
|
+
throw new Error("platform bundle Agent install requires a verified bootstrap bundle");
|
|
5049
5054
|
}
|
|
5050
5055
|
} else if (phase === "enrol") {
|
|
5051
5056
|
if (hasBinding || !hasEnrolCredential) {
|
|
@@ -5086,7 +5091,7 @@ function planBootstrapAgentInstall(config, phase, context) {
|
|
|
5086
5091
|
runnerLoopbackPorts: config.kind === "platform" ? [config.runtime.environment.publicApiPort, config.runtime.bluePort, config.runtime.greenPort] : [],
|
|
5087
5092
|
agentLoopbackPorts: config.kind === "platform" ? [config.runtime.environment.publicApiPort] : [],
|
|
5088
5093
|
nodeHostname: config.nodeHostname,
|
|
5089
|
-
telemetryEndpoint: config.
|
|
5094
|
+
telemetryEndpoint: config.kind === "platform" ? config.runtime.environment.otlpEndpoint : "http://127.0.0.1:4318",
|
|
5090
5095
|
binPath: "/usr/local/lib/forgezero/agent/fz-agent",
|
|
5091
5096
|
sourceBinPath: PACKAGED_AGENT_BIN,
|
|
5092
5097
|
...enrolling ? {
|
package/dist/fz-agent.js
CHANGED
|
@@ -9459,6 +9459,10 @@ function startMigrationPull(options) {
|
|
|
9459
9459
|
const tick = () => {
|
|
9460
9460
|
if (stopped || active)
|
|
9461
9461
|
return;
|
|
9462
|
+
if (options.canClaim && !options.canClaim()) {
|
|
9463
|
+
timer = setTimer(tick, interval);
|
|
9464
|
+
return;
|
|
9465
|
+
}
|
|
9462
9466
|
active = pullMigrationOnce(options).then((result) => options.onEvent?.(result.status, result)).catch((cause) => options.onEvent?.("poll-failed", cause)).finally(() => {
|
|
9463
9467
|
active = null;
|
|
9464
9468
|
if (!stopped)
|
|
@@ -9492,7 +9496,7 @@ async function writeAndCloseProcessInput(input, value) {
|
|
|
9492
9496
|
}
|
|
9493
9497
|
|
|
9494
9498
|
// src/version.ts
|
|
9495
|
-
var VERSION2 = "0.1.
|
|
9499
|
+
var VERSION2 = "0.1.90";
|
|
9496
9500
|
|
|
9497
9501
|
// src/ssh-bootstrap.ts
|
|
9498
9502
|
class SshBootstrapError extends Error {
|
|
@@ -9905,6 +9909,10 @@ function startSshBootstrapPull(options) {
|
|
|
9905
9909
|
const tick = () => {
|
|
9906
9910
|
if (stopped || active)
|
|
9907
9911
|
return;
|
|
9912
|
+
if (options.canClaim && !options.canClaim()) {
|
|
9913
|
+
timer = setTimer(tick, interval);
|
|
9914
|
+
return;
|
|
9915
|
+
}
|
|
9908
9916
|
active = pullSshBootstrapOnce(options).then((result) => options.onEvent?.(result.status, result.status === "idle" ? undefined : {
|
|
9909
9917
|
computeKey: result.computeKey,
|
|
9910
9918
|
attempt: result.attempt,
|
|
@@ -10176,6 +10184,10 @@ function startMetalAdmissionPull(options) {
|
|
|
10176
10184
|
const tick = () => {
|
|
10177
10185
|
if (stopped || active)
|
|
10178
10186
|
return;
|
|
10187
|
+
if (options.canClaim && !options.canClaim()) {
|
|
10188
|
+
timer = setTimer(tick, interval);
|
|
10189
|
+
return;
|
|
10190
|
+
}
|
|
10179
10191
|
active = pullMetalAdmissionOnce(options).then((result) => options.onEvent?.(`metal-admission-${result.status}`, result.status === "idle" ? undefined : result)).catch((cause) => options.onEvent?.("metal-admission-poll-failed", cause)).finally(() => {
|
|
10180
10192
|
active = null;
|
|
10181
10193
|
if (!stopped)
|
|
@@ -12732,6 +12744,7 @@ async function heartbeatAgentOnce(options) {
|
|
|
12732
12744
|
throw new Error("agent heartbeat deployment-intake directive is invalid");
|
|
12733
12745
|
await options.applyDeploymentIntake?.(response.deploymentIntake);
|
|
12734
12746
|
}
|
|
12747
|
+
await options.applyWorkClaims?.(response.workClaimsEnabled === true);
|
|
12735
12748
|
const desired = response.desiredAgentUpdate ?? (response.desiredAgentRelease ? {
|
|
12736
12749
|
attemptId: `legacy:${response.desiredAgentRelease.version}`,
|
|
12737
12750
|
leaseExpiresAtTs: Number.MAX_SAFE_INTEGER,
|
|
@@ -15628,7 +15641,7 @@ function agentUnit(options) {
|
|
|
15628
15641
|
if (!validNodeHostname(options.nodeHostname))
|
|
15629
15642
|
throw new Error("node hostname is invalid");
|
|
15630
15643
|
if (!options.telemetryEndpoint) {
|
|
15631
|
-
throw new Error("compute Agent provisioning requires
|
|
15644
|
+
throw new Error("compute Agent provisioning requires an explicit supervised OTLP collector coordinate");
|
|
15632
15645
|
}
|
|
15633
15646
|
let telemetryEndpoint;
|
|
15634
15647
|
{
|
|
@@ -15636,10 +15649,13 @@ function agentUnit(options) {
|
|
|
15636
15649
|
try {
|
|
15637
15650
|
endpoint = new URL(options.telemetryEndpoint);
|
|
15638
15651
|
} catch {
|
|
15639
|
-
throw new Error("compute telemetry endpoint must be an absolute
|
|
15652
|
+
throw new Error("compute telemetry endpoint must be an absolute collector URL");
|
|
15653
|
+
}
|
|
15654
|
+
const localCollector = endpoint.protocol === "http:" && endpoint.hostname === "127.0.0.1" && endpoint.port === "4318" && endpoint.pathname === "/";
|
|
15655
|
+
const publicCollector = endpoint.protocol === "https:" && !endpoint.username && !endpoint.password && !endpoint.search && !endpoint.hash && isIP4(endpoint.hostname) === 0 && endpoint.hostname.includes(".") && endpoint.hostname !== "localhost" && !endpoint.hostname.endsWith(".local");
|
|
15656
|
+
if (!localCollector && !publicCollector || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) {
|
|
15657
|
+
throw new Error("compute telemetry endpoint must be the supervised loopback collector or credential-free public HTTPS");
|
|
15640
15658
|
}
|
|
15641
|
-
if (endpoint.protocol !== "https:" || endpoint.username || endpoint.password || endpoint.search || endpoint.hash || isIP4(endpoint.hostname) !== 0 || !endpoint.hostname.includes(".") || endpoint.hostname === "localhost" || endpoint.hostname.endsWith(".local"))
|
|
15642
|
-
throw new Error("compute telemetry endpoint must be an absolute public HTTPS URL without credentials, query or fragment");
|
|
15643
15659
|
telemetryEndpoint = endpoint.toString().replace(/\/$/, "");
|
|
15644
15660
|
}
|
|
15645
15661
|
const bin = options.binPath ?? "fz-agent";
|
|
@@ -16565,7 +16581,7 @@ async function bootstrapStatus(host = localBootstrapHost()) {
|
|
|
16565
16581
|
if (result.exitCode !== 0)
|
|
16566
16582
|
problems.push(`${unit3} is not active`);
|
|
16567
16583
|
}
|
|
16568
|
-
for (const socket of [DEFAULT_SOCKET
|
|
16584
|
+
for (const socket of [DEFAULT_SOCKET]) {
|
|
16569
16585
|
services[socket] = host.exists(socket);
|
|
16570
16586
|
if (!services[socket])
|
|
16571
16587
|
problems.push(`${socket} is missing`);
|
|
@@ -16654,8 +16670,8 @@ async function bootstrapStatus(host = localBootstrapHost()) {
|
|
|
16654
16670
|
function planBootstrapAgentInstall(config, phase, context) {
|
|
16655
16671
|
const { capabilities, hasBinding, hasEnrolCredential, initialBundle } = context;
|
|
16656
16672
|
if (phase === "bootstrap") {
|
|
16657
|
-
if (config.kind !== "platform" ||
|
|
16658
|
-
throw new Error("
|
|
16673
|
+
if (config.kind !== "platform" || !initialBundle) {
|
|
16674
|
+
throw new Error("platform bundle Agent install requires a verified bootstrap bundle");
|
|
16659
16675
|
}
|
|
16660
16676
|
} else if (phase === "enrol") {
|
|
16661
16677
|
if (hasBinding || !hasEnrolCredential) {
|
|
@@ -16696,7 +16712,7 @@ function planBootstrapAgentInstall(config, phase, context) {
|
|
|
16696
16712
|
runnerLoopbackPorts: config.kind === "platform" ? [config.runtime.environment.publicApiPort, config.runtime.bluePort, config.runtime.greenPort] : [],
|
|
16697
16713
|
agentLoopbackPorts: config.kind === "platform" ? [config.runtime.environment.publicApiPort] : [],
|
|
16698
16714
|
nodeHostname: config.nodeHostname,
|
|
16699
|
-
telemetryEndpoint: config.
|
|
16715
|
+
telemetryEndpoint: config.kind === "platform" ? config.runtime.environment.otlpEndpoint : "http://127.0.0.1:4318",
|
|
16700
16716
|
binPath: "/usr/local/lib/forgezero/agent/fz-agent",
|
|
16701
16717
|
sourceBinPath: PACKAGED_AGENT_BIN,
|
|
16702
16718
|
...enrolling ? {
|
|
@@ -18168,6 +18184,7 @@ if (import.meta.main) {
|
|
|
18168
18184
|
if (attestationLoop)
|
|
18169
18185
|
console.log("[agent] periodic SEV-SNP attestation enabled");
|
|
18170
18186
|
const migrationEnabled = process.env.FZ_MIGRATION_PULL === "true";
|
|
18187
|
+
let workClaimsEnabled = false;
|
|
18171
18188
|
if (migrationEnabled && (!binding || !nodeApiUrl)) {
|
|
18172
18189
|
throw new Error("agent: outbound lifecycle work requires a persisted compute enrolment binding");
|
|
18173
18190
|
}
|
|
@@ -18176,6 +18193,7 @@ if (import.meta.main) {
|
|
|
18176
18193
|
nodeKey,
|
|
18177
18194
|
keys,
|
|
18178
18195
|
telemetry,
|
|
18196
|
+
canClaim: () => workClaimsEnabled,
|
|
18179
18197
|
run: (claim) => requestLifecycleAction(claim, process.env.FZ_LIFECYCLE_HELPER_SOCKET ?? DEFAULT_LIFECYCLE_HELPER_SOCKET),
|
|
18180
18198
|
onEvent: (event, detail) => console.log(`[agent] migration ${event}${detail ? ` ${JSON.stringify(detail)}` : ""}`)
|
|
18181
18199
|
}) : undefined;
|
|
@@ -18194,6 +18212,7 @@ if (import.meta.main) {
|
|
|
18194
18212
|
keys,
|
|
18195
18213
|
sshKeyPath: bootstrapKeyPath,
|
|
18196
18214
|
targetTelemetryEndpoint: process.env.FZ_BOOTSTRAP_TARGET_OTLP_ENDPOINT,
|
|
18215
|
+
canClaim: () => workClaimsEnabled,
|
|
18197
18216
|
onEvent: (event) => console.log(`[agent] bootstrap ${event}`)
|
|
18198
18217
|
}) : undefined;
|
|
18199
18218
|
if (bootstrapPull)
|
|
@@ -18205,6 +18224,7 @@ if (import.meta.main) {
|
|
|
18205
18224
|
keys,
|
|
18206
18225
|
sshKeyPath: bootstrapKeyPath,
|
|
18207
18226
|
targetTelemetryEndpoint: process.env.FZ_BOOTSTRAP_TARGET_OTLP_ENDPOINT,
|
|
18227
|
+
canClaim: () => workClaimsEnabled,
|
|
18208
18228
|
onEvent: (event) => console.log(`[agent] ${event}`)
|
|
18209
18229
|
}) : undefined;
|
|
18210
18230
|
if (metalAdmissionPull)
|
|
@@ -18317,6 +18337,12 @@ if (import.meta.main) {
|
|
|
18317
18337
|
deploymentIntake = { ...directive, appliedAtTs: Date.now() };
|
|
18318
18338
|
console.log(`[agent] deployment intake ${directive.state} generation ${directive.generation}`);
|
|
18319
18339
|
},
|
|
18340
|
+
applyWorkClaims(enabled) {
|
|
18341
|
+
if (workClaimsEnabled === enabled)
|
|
18342
|
+
return;
|
|
18343
|
+
workClaimsEnabled = enabled;
|
|
18344
|
+
console.log(`[agent] remote work claims ${enabled ? "enabled" : "paused"} by platform lifecycle`);
|
|
18345
|
+
},
|
|
18320
18346
|
async prepareUpdate() {
|
|
18321
18347
|
if (updatePrepared)
|
|
18322
18348
|
return;
|
package/dist/fz.js
CHANGED
|
@@ -4840,7 +4840,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
|
|
|
4840
4840
|
var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
|
|
4841
4841
|
|
|
4842
4842
|
// src/version.ts
|
|
4843
|
-
var VERSION2 = "0.1.
|
|
4843
|
+
var VERSION2 = "0.1.90";
|
|
4844
4844
|
|
|
4845
4845
|
// src/software.ts
|
|
4846
4846
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -5885,7 +5885,7 @@ function agentUnit(options) {
|
|
|
5885
5885
|
if (!validNodeHostname(options.nodeHostname))
|
|
5886
5886
|
throw new Error("node hostname is invalid");
|
|
5887
5887
|
if (!options.telemetryEndpoint) {
|
|
5888
|
-
throw new Error("compute Agent provisioning requires
|
|
5888
|
+
throw new Error("compute Agent provisioning requires an explicit supervised OTLP collector coordinate");
|
|
5889
5889
|
}
|
|
5890
5890
|
let telemetryEndpoint;
|
|
5891
5891
|
{
|
|
@@ -5893,10 +5893,13 @@ function agentUnit(options) {
|
|
|
5893
5893
|
try {
|
|
5894
5894
|
endpoint = new URL(options.telemetryEndpoint);
|
|
5895
5895
|
} catch {
|
|
5896
|
-
throw new Error("compute telemetry endpoint must be an absolute
|
|
5896
|
+
throw new Error("compute telemetry endpoint must be an absolute collector URL");
|
|
5897
|
+
}
|
|
5898
|
+
const localCollector = endpoint.protocol === "http:" && endpoint.hostname === "127.0.0.1" && endpoint.port === "4318" && endpoint.pathname === "/";
|
|
5899
|
+
const publicCollector = endpoint.protocol === "https:" && !endpoint.username && !endpoint.password && !endpoint.search && !endpoint.hash && isIP(endpoint.hostname) === 0 && endpoint.hostname.includes(".") && endpoint.hostname !== "localhost" && !endpoint.hostname.endsWith(".local");
|
|
5900
|
+
if (!localCollector && !publicCollector || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) {
|
|
5901
|
+
throw new Error("compute telemetry endpoint must be the supervised loopback collector or credential-free public HTTPS");
|
|
5897
5902
|
}
|
|
5898
|
-
if (endpoint.protocol !== "https:" || endpoint.username || endpoint.password || endpoint.search || endpoint.hash || isIP(endpoint.hostname) !== 0 || !endpoint.hostname.includes(".") || endpoint.hostname === "localhost" || endpoint.hostname.endsWith(".local"))
|
|
5899
|
-
throw new Error("compute telemetry endpoint must be an absolute public HTTPS URL without credentials, query or fragment");
|
|
5900
5903
|
telemetryEndpoint = endpoint.toString().replace(/\/$/, "");
|
|
5901
5904
|
}
|
|
5902
5905
|
const bin = options.binPath ?? "fz-agent";
|
|
@@ -14799,7 +14802,7 @@ async function bootstrapStatus(host = localBootstrapHost()) {
|
|
|
14799
14802
|
if (result.exitCode !== 0)
|
|
14800
14803
|
problems.push(`${unit} is not active`);
|
|
14801
14804
|
}
|
|
14802
|
-
for (const socket of [DEFAULT_SOCKET
|
|
14805
|
+
for (const socket of [DEFAULT_SOCKET]) {
|
|
14803
14806
|
services[socket] = host.exists(socket);
|
|
14804
14807
|
if (!services[socket])
|
|
14805
14808
|
problems.push(`${socket} is missing`);
|
|
@@ -15042,7 +15045,7 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
15042
15045
|
}
|
|
15043
15046
|
let installedAgentPlan;
|
|
15044
15047
|
if (alreadyEnrolled) {
|
|
15045
|
-
installedAgentPlan = await host.installAgent(config, "bound");
|
|
15048
|
+
installedAgentPlan = await host.installAgent(config, bootstrapManifest ? "bootstrap" : "bound");
|
|
15046
15049
|
} else if (config.kind === "platform") {
|
|
15047
15050
|
if (bootstrapManifest)
|
|
15048
15051
|
installedAgentPlan = await host.installAgent(config, "bootstrap");
|
|
@@ -15217,6 +15220,8 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
15217
15220
|
`, 384);
|
|
15218
15221
|
host.remove(config.bootstrapBundle.bundleFile);
|
|
15219
15222
|
host.remove(config.bootstrapBundle.manifestFile);
|
|
15223
|
+
if (alreadyEnrolled)
|
|
15224
|
+
installedAgentPlan = await host.installAgent(config, "bound");
|
|
15220
15225
|
}
|
|
15221
15226
|
if (!alreadyEnrolled) {
|
|
15222
15227
|
await checked3(host, [
|
|
@@ -15428,8 +15433,8 @@ function readBootstrapConfig(path) {
|
|
|
15428
15433
|
function planBootstrapAgentInstall(config, phase, context) {
|
|
15429
15434
|
const { capabilities, hasBinding, hasEnrolCredential, initialBundle } = context;
|
|
15430
15435
|
if (phase === "bootstrap") {
|
|
15431
|
-
if (config.kind !== "platform" ||
|
|
15432
|
-
throw new Error("
|
|
15436
|
+
if (config.kind !== "platform" || !initialBundle) {
|
|
15437
|
+
throw new Error("platform bundle Agent install requires a verified bootstrap bundle");
|
|
15433
15438
|
}
|
|
15434
15439
|
} else if (phase === "enrol") {
|
|
15435
15440
|
if (hasBinding || !hasEnrolCredential) {
|
|
@@ -15470,7 +15475,7 @@ function planBootstrapAgentInstall(config, phase, context) {
|
|
|
15470
15475
|
runnerLoopbackPorts: config.kind === "platform" ? [config.runtime.environment.publicApiPort, config.runtime.bluePort, config.runtime.greenPort] : [],
|
|
15471
15476
|
agentLoopbackPorts: config.kind === "platform" ? [config.runtime.environment.publicApiPort] : [],
|
|
15472
15477
|
nodeHostname: config.nodeHostname,
|
|
15473
|
-
telemetryEndpoint: config.
|
|
15478
|
+
telemetryEndpoint: config.kind === "platform" ? config.runtime.environment.otlpEndpoint : "http://127.0.0.1:4318",
|
|
15474
15479
|
binPath: "/usr/local/lib/forgezero/agent/fz-agent",
|
|
15475
15480
|
sourceBinPath: PACKAGED_AGENT_BIN,
|
|
15476
15481
|
...enrolling ? {
|
|
@@ -17416,7 +17421,7 @@ var remoteRegularFileExists = async (exec, request, knownHosts, path) => {
|
|
|
17416
17421
|
throw new Error(`remote initialized-state probe failed${result.output ? `: ${result.output.trim()}` : ""}`);
|
|
17417
17422
|
};
|
|
17418
17423
|
async function operatorMetalClusterBootstrapCode(requestInput, options = {}) {
|
|
17419
|
-
const request = validateMetalRequestValue(requestInput);
|
|
17424
|
+
const request = validateMetalRequestValue(requestInput, { validateMetalConfig: false });
|
|
17420
17425
|
publicIdentity(request.target.identityPublicKeyFile);
|
|
17421
17426
|
socketPath(request.target.agentSocket);
|
|
17422
17427
|
const exec = options.exec ?? defaultExec3;
|
|
@@ -17912,6 +17917,7 @@ var PROFILES = {
|
|
|
17912
17917
|
kvNamespaceTitle: "forgezero dev nodes",
|
|
17913
17918
|
workerScriptName: "forgezero-api-edge-development",
|
|
17914
17919
|
region: { key: "in-south", label: "India South", country: "IN" },
|
|
17920
|
+
seedSyncEpoch: "development-23c19168773d69ea",
|
|
17915
17921
|
agentOtlpEndpoint: "https://otel.forgezero.net",
|
|
17916
17922
|
privateCidrs: ["10.42.0.0/24"]
|
|
17917
17923
|
},
|
|
@@ -17924,6 +17930,7 @@ var PROFILES = {
|
|
|
17924
17930
|
kvNamespaceTitle: "forgezero nodes",
|
|
17925
17931
|
workerScriptName: "forgezero-api-edge-production",
|
|
17926
17932
|
region: { key: "in-south", label: "India South", country: "IN" },
|
|
17933
|
+
seedSyncEpoch: "production-genesis-v1",
|
|
17927
17934
|
agentOtlpEndpoint: "https://otel.forgezero.net",
|
|
17928
17935
|
privateCidrs: ["10.42.0.0/24"]
|
|
17929
17936
|
}
|
|
@@ -17991,7 +17998,7 @@ function forgeZeroLaunchTemplate(profile, guests, bundle, owner) {
|
|
|
17991
17998
|
sharedDirectory: "/opt/forgezero/shared",
|
|
17992
17999
|
seedSyncPeers: fleet.slice(1).flatMap(({ address }) => [3001, 3002].map((port) => `ws://${address}:${port}/_internal/forgezero/seed-mesh/v2`)),
|
|
17993
18000
|
seedSyncMembers: nodeHostnames,
|
|
17994
|
-
seedSyncEpoch:
|
|
18001
|
+
seedSyncEpoch: profile.seedSyncEpoch,
|
|
17995
18002
|
concurrencyLimit: 128,
|
|
17996
18003
|
drainDeadlineMs: 30000,
|
|
17997
18004
|
otlpEndpoint: "http://127.0.0.1:4318",
|
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.90";
|
|
370
370
|
|
|
371
371
|
// src/otel-collector.ts
|
|
372
372
|
var FORGEZERO_OTEL_COLLECTOR_UNIT = "forgezero-otel-collector.service";
|
package/dist/migration-pull.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ export interface MigrationPullOptions {
|
|
|
39
39
|
clearTimer?: (handle: unknown) => void;
|
|
40
40
|
onEvent?: (event: string, detail?: unknown) => void;
|
|
41
41
|
telemetry?: AgentOperationTelemetry;
|
|
42
|
+
canClaim?: () => boolean;
|
|
42
43
|
}
|
|
43
44
|
export type MigrationPullResult = {
|
|
44
45
|
status: 'idle';
|
package/dist/migration-pull.js
CHANGED
|
@@ -188,6 +188,10 @@ function startMigrationPull(options) {
|
|
|
188
188
|
const tick = () => {
|
|
189
189
|
if (stopped || active)
|
|
190
190
|
return;
|
|
191
|
+
if (options.canClaim && !options.canClaim()) {
|
|
192
|
+
timer = setTimer(tick, interval);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
191
195
|
active = pullMigrationOnce(options).then((result) => options.onEvent?.(result.status, result)).catch((cause) => options.onEvent?.("poll-failed", cause)).finally(() => {
|
|
192
196
|
active = null;
|
|
193
197
|
if (!stopped)
|
|
@@ -1420,7 +1420,7 @@ var UPDATE_RETRY_BASE_MS = 5 * 60000;
|
|
|
1420
1420
|
var UPDATE_RETRY_MAX_MS = 24 * 60 * 60000;
|
|
1421
1421
|
|
|
1422
1422
|
// src/version.ts
|
|
1423
|
-
var VERSION = "0.1.
|
|
1423
|
+
var VERSION = "0.1.90";
|
|
1424
1424
|
|
|
1425
1425
|
// src/software.ts
|
|
1426
1426
|
var PINNED_BUN_VERSION = "1.3.14";
|
|
@@ -2094,7 +2094,7 @@ function agentUnit(options) {
|
|
|
2094
2094
|
if (!validNodeHostname(options.nodeHostname))
|
|
2095
2095
|
throw new Error("node hostname is invalid");
|
|
2096
2096
|
if (!options.telemetryEndpoint) {
|
|
2097
|
-
throw new Error("compute Agent provisioning requires
|
|
2097
|
+
throw new Error("compute Agent provisioning requires an explicit supervised OTLP collector coordinate");
|
|
2098
2098
|
}
|
|
2099
2099
|
let telemetryEndpoint;
|
|
2100
2100
|
{
|
|
@@ -2102,10 +2102,13 @@ function agentUnit(options) {
|
|
|
2102
2102
|
try {
|
|
2103
2103
|
endpoint2 = new URL(options.telemetryEndpoint);
|
|
2104
2104
|
} catch {
|
|
2105
|
-
throw new Error("compute telemetry endpoint must be an absolute
|
|
2105
|
+
throw new Error("compute telemetry endpoint must be an absolute collector URL");
|
|
2106
|
+
}
|
|
2107
|
+
const localCollector = endpoint2.protocol === "http:" && endpoint2.hostname === "127.0.0.1" && endpoint2.port === "4318" && endpoint2.pathname === "/";
|
|
2108
|
+
const publicCollector = endpoint2.protocol === "https:" && !endpoint2.username && !endpoint2.password && !endpoint2.search && !endpoint2.hash && isIP3(endpoint2.hostname) === 0 && endpoint2.hostname.includes(".") && endpoint2.hostname !== "localhost" && !endpoint2.hostname.endsWith(".local");
|
|
2109
|
+
if (!localCollector && !publicCollector || endpoint2.username || endpoint2.password || endpoint2.search || endpoint2.hash) {
|
|
2110
|
+
throw new Error("compute telemetry endpoint must be the supervised loopback collector or credential-free public HTTPS");
|
|
2106
2111
|
}
|
|
2107
|
-
if (endpoint2.protocol !== "https:" || endpoint2.username || endpoint2.password || endpoint2.search || endpoint2.hash || isIP3(endpoint2.hostname) !== 0 || !endpoint2.hostname.includes(".") || endpoint2.hostname === "localhost" || endpoint2.hostname.endsWith(".local"))
|
|
2108
|
-
throw new Error("compute telemetry endpoint must be an absolute public HTTPS URL without credentials, query or fragment");
|
|
2109
2112
|
telemetryEndpoint = endpoint2.toString().replace(/\/$/, "");
|
|
2110
2113
|
}
|
|
2111
2114
|
const bin = options.binPath ?? "fz-agent";
|
|
@@ -4415,7 +4418,7 @@ async function bootstrapStatus(host = localBootstrapHost()) {
|
|
|
4415
4418
|
if (result.exitCode !== 0)
|
|
4416
4419
|
problems.push(`${unit} is not active`);
|
|
4417
4420
|
}
|
|
4418
|
-
for (const socket of [DEFAULT_SOCKET2
|
|
4421
|
+
for (const socket of [DEFAULT_SOCKET2]) {
|
|
4419
4422
|
services[socket] = host.exists(socket);
|
|
4420
4423
|
if (!services[socket])
|
|
4421
4424
|
problems.push(`${socket} is missing`);
|
|
@@ -4658,7 +4661,7 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4658
4661
|
}
|
|
4659
4662
|
let installedAgentPlan;
|
|
4660
4663
|
if (alreadyEnrolled) {
|
|
4661
|
-
installedAgentPlan = await host.installAgent(config, "bound");
|
|
4664
|
+
installedAgentPlan = await host.installAgent(config, bootstrapManifest ? "bootstrap" : "bound");
|
|
4662
4665
|
} else if (config.kind === "platform") {
|
|
4663
4666
|
if (bootstrapManifest)
|
|
4664
4667
|
installedAgentPlan = await host.installAgent(config, "bootstrap");
|
|
@@ -4833,6 +4836,8 @@ async function applyBootstrap(input, host = localBootstrapHost(), secrets, depen
|
|
|
4833
4836
|
`, 384);
|
|
4834
4837
|
host.remove(config.bootstrapBundle.bundleFile);
|
|
4835
4838
|
host.remove(config.bootstrapBundle.manifestFile);
|
|
4839
|
+
if (alreadyEnrolled)
|
|
4840
|
+
installedAgentPlan = await host.installAgent(config, "bound");
|
|
4836
4841
|
}
|
|
4837
4842
|
if (!alreadyEnrolled) {
|
|
4838
4843
|
await checked3(host, [
|
|
@@ -5044,8 +5049,8 @@ function readBootstrapConfig(path) {
|
|
|
5044
5049
|
function planBootstrapAgentInstall(config, phase, context) {
|
|
5045
5050
|
const { capabilities, hasBinding, hasEnrolCredential, initialBundle } = context;
|
|
5046
5051
|
if (phase === "bootstrap") {
|
|
5047
|
-
if (config.kind !== "platform" ||
|
|
5048
|
-
throw new Error("
|
|
5052
|
+
if (config.kind !== "platform" || !initialBundle) {
|
|
5053
|
+
throw new Error("platform bundle Agent install requires a verified bootstrap bundle");
|
|
5049
5054
|
}
|
|
5050
5055
|
} else if (phase === "enrol") {
|
|
5051
5056
|
if (hasBinding || !hasEnrolCredential) {
|
|
@@ -5086,7 +5091,7 @@ function planBootstrapAgentInstall(config, phase, context) {
|
|
|
5086
5091
|
runnerLoopbackPorts: config.kind === "platform" ? [config.runtime.environment.publicApiPort, config.runtime.bluePort, config.runtime.greenPort] : [],
|
|
5087
5092
|
agentLoopbackPorts: config.kind === "platform" ? [config.runtime.environment.publicApiPort] : [],
|
|
5088
5093
|
nodeHostname: config.nodeHostname,
|
|
5089
|
-
telemetryEndpoint: config.
|
|
5094
|
+
telemetryEndpoint: config.kind === "platform" ? config.runtime.environment.otlpEndpoint : "http://127.0.0.1:4318",
|
|
5090
5095
|
binPath: "/usr/local/lib/forgezero/agent/fz-agent",
|
|
5091
5096
|
sourceBinPath: PACKAGED_AGENT_BIN,
|
|
5092
5097
|
...enrolling ? {
|
|
@@ -6768,7 +6773,7 @@ var remoteRegularFileExists = async (exec, request, knownHosts, path) => {
|
|
|
6768
6773
|
throw new Error(`remote initialized-state probe failed${result.output ? `: ${result.output.trim()}` : ""}`);
|
|
6769
6774
|
};
|
|
6770
6775
|
async function operatorMetalClusterBootstrapCode(requestInput, options = {}) {
|
|
6771
|
-
const request = validateMetalRequestValue(requestInput);
|
|
6776
|
+
const request = validateMetalRequestValue(requestInput, { validateMetalConfig: false });
|
|
6772
6777
|
publicIdentity(request.target.identityPublicKeyFile);
|
|
6773
6778
|
socketPath(request.target.agentSocket);
|
|
6774
6779
|
const exec = options.exec ?? defaultExec3;
|
|
@@ -2908,7 +2908,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
2908
2908
|
}
|
|
2909
2909
|
|
|
2910
2910
|
// src/version.ts
|
|
2911
|
-
var VERSION3 = "0.1.
|
|
2911
|
+
var VERSION3 = "0.1.90";
|
|
2912
2912
|
|
|
2913
2913
|
// src/egress-policy.ts
|
|
2914
2914
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
@@ -3440,7 +3440,7 @@ function agentUnit(options) {
|
|
|
3440
3440
|
if (!validNodeHostname(options.nodeHostname))
|
|
3441
3441
|
throw new Error("node hostname is invalid");
|
|
3442
3442
|
if (!options.telemetryEndpoint) {
|
|
3443
|
-
throw new Error("compute Agent provisioning requires
|
|
3443
|
+
throw new Error("compute Agent provisioning requires an explicit supervised OTLP collector coordinate");
|
|
3444
3444
|
}
|
|
3445
3445
|
let telemetryEndpoint;
|
|
3446
3446
|
{
|
|
@@ -3448,10 +3448,13 @@ function agentUnit(options) {
|
|
|
3448
3448
|
try {
|
|
3449
3449
|
endpoint = new URL(options.telemetryEndpoint);
|
|
3450
3450
|
} catch {
|
|
3451
|
-
throw new Error("compute telemetry endpoint must be an absolute
|
|
3451
|
+
throw new Error("compute telemetry endpoint must be an absolute collector URL");
|
|
3452
|
+
}
|
|
3453
|
+
const localCollector = endpoint.protocol === "http:" && endpoint.hostname === "127.0.0.1" && endpoint.port === "4318" && endpoint.pathname === "/";
|
|
3454
|
+
const publicCollector = endpoint.protocol === "https:" && !endpoint.username && !endpoint.password && !endpoint.search && !endpoint.hash && isIP(endpoint.hostname) === 0 && endpoint.hostname.includes(".") && endpoint.hostname !== "localhost" && !endpoint.hostname.endsWith(".local");
|
|
3455
|
+
if (!localCollector && !publicCollector || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) {
|
|
3456
|
+
throw new Error("compute telemetry endpoint must be the supervised loopback collector or credential-free public HTTPS");
|
|
3452
3457
|
}
|
|
3453
|
-
if (endpoint.protocol !== "https:" || endpoint.username || endpoint.password || endpoint.search || endpoint.hash || isIP(endpoint.hostname) !== 0 || !endpoint.hostname.includes(".") || endpoint.hostname === "localhost" || endpoint.hostname.endsWith(".local"))
|
|
3454
|
-
throw new Error("compute telemetry endpoint must be an absolute public HTTPS URL without credentials, query or fragment");
|
|
3455
3458
|
telemetryEndpoint = endpoint.toString().replace(/\/$/, "");
|
|
3456
3459
|
}
|
|
3457
3460
|
const bin = options.binPath ?? "fz-agent";
|
|
@@ -5220,7 +5223,7 @@ async function bootstrapStatus(host = localBootstrapHost()) {
|
|
|
5220
5223
|
if (result.exitCode !== 0)
|
|
5221
5224
|
problems.push(`${unit2} is not active`);
|
|
5222
5225
|
}
|
|
5223
|
-
for (const socket of [DEFAULT_SOCKET2
|
|
5226
|
+
for (const socket of [DEFAULT_SOCKET2]) {
|
|
5224
5227
|
services[socket] = host.exists(socket);
|
|
5225
5228
|
if (!services[socket])
|
|
5226
5229
|
problems.push(`${socket} is missing`);
|
|
@@ -5309,8 +5312,8 @@ async function bootstrapStatus(host = localBootstrapHost()) {
|
|
|
5309
5312
|
function planBootstrapAgentInstall(config, phase, context) {
|
|
5310
5313
|
const { capabilities, hasBinding, hasEnrolCredential, initialBundle } = context;
|
|
5311
5314
|
if (phase === "bootstrap") {
|
|
5312
|
-
if (config.kind !== "platform" ||
|
|
5313
|
-
throw new Error("
|
|
5315
|
+
if (config.kind !== "platform" || !initialBundle) {
|
|
5316
|
+
throw new Error("platform bundle Agent install requires a verified bootstrap bundle");
|
|
5314
5317
|
}
|
|
5315
5318
|
} else if (phase === "enrol") {
|
|
5316
5319
|
if (hasBinding || !hasEnrolCredential) {
|
|
@@ -5351,7 +5354,7 @@ function planBootstrapAgentInstall(config, phase, context) {
|
|
|
5351
5354
|
runnerLoopbackPorts: config.kind === "platform" ? [config.runtime.environment.publicApiPort, config.runtime.bluePort, config.runtime.greenPort] : [],
|
|
5352
5355
|
agentLoopbackPorts: config.kind === "platform" ? [config.runtime.environment.publicApiPort] : [],
|
|
5353
5356
|
nodeHostname: config.nodeHostname,
|
|
5354
|
-
telemetryEndpoint: config.
|
|
5357
|
+
telemetryEndpoint: config.kind === "platform" ? config.runtime.environment.otlpEndpoint : "http://127.0.0.1:4318",
|
|
5355
5358
|
binPath: "/usr/local/lib/forgezero/agent/fz-agent",
|
|
5356
5359
|
sourceBinPath: PACKAGED_AGENT_BIN,
|
|
5357
5360
|
...enrolling ? {
|
package/dist/provision.js
CHANGED
|
@@ -2908,7 +2908,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
2908
2908
|
}
|
|
2909
2909
|
|
|
2910
2910
|
// src/version.ts
|
|
2911
|
-
var VERSION3 = "0.1.
|
|
2911
|
+
var VERSION3 = "0.1.90";
|
|
2912
2912
|
|
|
2913
2913
|
// src/egress-policy.ts
|
|
2914
2914
|
import { realpathSync as realpathSync3 } from "node:fs";
|
|
@@ -3440,7 +3440,7 @@ function agentUnit(options) {
|
|
|
3440
3440
|
if (!validNodeHostname(options.nodeHostname))
|
|
3441
3441
|
throw new Error("node hostname is invalid");
|
|
3442
3442
|
if (!options.telemetryEndpoint) {
|
|
3443
|
-
throw new Error("compute Agent provisioning requires
|
|
3443
|
+
throw new Error("compute Agent provisioning requires an explicit supervised OTLP collector coordinate");
|
|
3444
3444
|
}
|
|
3445
3445
|
let telemetryEndpoint;
|
|
3446
3446
|
{
|
|
@@ -3448,10 +3448,13 @@ function agentUnit(options) {
|
|
|
3448
3448
|
try {
|
|
3449
3449
|
endpoint = new URL(options.telemetryEndpoint);
|
|
3450
3450
|
} catch {
|
|
3451
|
-
throw new Error("compute telemetry endpoint must be an absolute
|
|
3451
|
+
throw new Error("compute telemetry endpoint must be an absolute collector URL");
|
|
3452
|
+
}
|
|
3453
|
+
const localCollector = endpoint.protocol === "http:" && endpoint.hostname === "127.0.0.1" && endpoint.port === "4318" && endpoint.pathname === "/";
|
|
3454
|
+
const publicCollector = endpoint.protocol === "https:" && !endpoint.username && !endpoint.password && !endpoint.search && !endpoint.hash && isIP(endpoint.hostname) === 0 && endpoint.hostname.includes(".") && endpoint.hostname !== "localhost" && !endpoint.hostname.endsWith(".local");
|
|
3455
|
+
if (!localCollector && !publicCollector || endpoint.username || endpoint.password || endpoint.search || endpoint.hash) {
|
|
3456
|
+
throw new Error("compute telemetry endpoint must be the supervised loopback collector or credential-free public HTTPS");
|
|
3452
3457
|
}
|
|
3453
|
-
if (endpoint.protocol !== "https:" || endpoint.username || endpoint.password || endpoint.search || endpoint.hash || isIP(endpoint.hostname) !== 0 || !endpoint.hostname.includes(".") || endpoint.hostname === "localhost" || endpoint.hostname.endsWith(".local"))
|
|
3454
|
-
throw new Error("compute telemetry endpoint must be an absolute public HTTPS URL without credentials, query or fragment");
|
|
3455
3458
|
telemetryEndpoint = endpoint.toString().replace(/\/$/, "");
|
|
3456
3459
|
}
|
|
3457
3460
|
const bin = options.binPath ?? "fz-agent";
|
package/dist/ssh-bootstrap.d.ts
CHANGED
|
@@ -129,6 +129,7 @@ export interface SshBootstrapPullOptions {
|
|
|
129
129
|
onEvent?: (event: string, detail?: unknown) => void;
|
|
130
130
|
telemetry?: AgentOperationTelemetry;
|
|
131
131
|
resolveHost?: GitHostResolver;
|
|
132
|
+
canClaim?: () => boolean;
|
|
132
133
|
}
|
|
133
134
|
export type SshBootstrapResult = {
|
|
134
135
|
status: 'idle';
|
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.90";
|