@serfab/cadre-host 0.9.0 → 0.10.0
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/auth/index.d.ts +2 -0
- package/dist/auth/index.js +1 -0
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/self-label.d.ts +36 -0
- package/dist/auth/self-label.js +57 -0
- package/dist/auth/self-label.js.map +1 -0
- package/dist/auth/trust-circle.d.ts +32 -5
- package/dist/auth/trust-circle.js +31 -11
- package/dist/auth/trust-circle.js.map +1 -1
- package/dist/bin/host.js +41 -5
- package/dist/bin/host.js.map +1 -1
- package/dist/donation/__tests__/fake-orchestrator.d.ts +103 -0
- package/dist/donation/__tests__/fake-orchestrator.js +180 -0
- package/dist/donation/__tests__/fake-orchestrator.js.map +1 -0
- package/dist/donation/donation-service.d.ts +237 -12
- package/dist/donation/donation-service.js +491 -34
- package/dist/donation/donation-service.js.map +1 -1
- package/dist/donation/donation-store.d.ts +7 -0
- package/dist/donation/donation-store.js +7 -0
- package/dist/donation/donation-store.js.map +1 -1
- package/dist/donation/donation-supervisor.d.ts +167 -0
- package/dist/donation/donation-supervisor.js +341 -0
- package/dist/donation/donation-supervisor.js.map +1 -0
- package/dist/donation/index.d.ts +4 -2
- package/dist/donation/index.js +2 -1
- package/dist/donation/index.js.map +1 -1
- package/dist/donation/types.d.ts +26 -0
- package/dist/donation/types.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/orchestrator/host-process-orchestrator.d.ts +109 -5
- package/dist/orchestrator/host-process-orchestrator.js +341 -98
- package/dist/orchestrator/host-process-orchestrator.js.map +1 -1
- package/dist/orchestrator/node-identity.d.ts +26 -0
- package/dist/orchestrator/node-identity.js +36 -0
- package/dist/orchestrator/node-identity.js.map +1 -0
- package/dist/orchestrator/port-allocator.d.ts +14 -0
- package/dist/orchestrator/port-allocator.js +45 -0
- package/dist/orchestrator/port-allocator.js.map +1 -1
- package/dist/owner/owner-node-client.d.ts +20 -5
- package/dist/owner/owner-node-client.js +21 -4
- package/dist/owner/owner-node-client.js.map +1 -1
- package/dist/server/error-handler.d.ts +7 -1
- package/dist/server/error-handler.js +23 -1
- package/dist/server/error-handler.js.map +1 -1
- package/dist/server/events/types.d.ts +3 -0
- package/dist/server/index.d.ts +7 -0
- package/dist/server/index.js +9 -3
- package/dist/server/index.js.map +1 -1
- package/dist/server/routes/grants.js +22 -3
- package/dist/server/routes/grants.js.map +1 -1
- package/dist/server/routes/strands.d.ts +20 -0
- package/dist/server/routes/strands.js +38 -0
- package/dist/server/routes/strands.js.map +1 -0
- package/dist/strands/index.d.ts +7 -0
- package/dist/strands/index.js +6 -0
- package/dist/strands/index.js.map +1 -0
- package/dist/strands/strand-service.d.ts +50 -0
- package/dist/strands/strand-service.js +103 -0
- package/dist/strands/strand-service.js.map +1 -0
- package/dist/strands/types.d.ts +93 -0
- package/dist/strands/types.js +23 -0
- package/dist/strands/types.js.map +1 -0
- package/dist/ui/assets/index-BVoqLjyX.css +1 -0
- package/dist/ui/assets/index-C-iks41M.js +17 -0
- package/dist/ui/assets/index-C-iks41M.js.map +1 -0
- package/dist/ui/index.html +2 -2
- package/dist/update/release-key.d.ts +1 -1
- package/dist/update/release-key.js +1 -1
- package/package.json +5 -5
- package/src/__tests__/build-targets.test.ts +26 -0
- package/src/__tests__/global-setup.ts +51 -0
- package/src/__tests__/orchestrator-env-scrub.test.ts +140 -0
- package/src/__tests__/orchestrator-node-identity.test.ts +204 -0
- package/src/__tests__/orchestrator.test.ts +387 -6
- package/src/auth/__tests__/self-label.test.ts +85 -0
- package/src/auth/__tests__/trust-circle-integration.test.ts +152 -147
- package/src/auth/__tests__/trust-circle.test.ts +45 -1
- package/src/auth/index.ts +2 -0
- package/src/auth/self-label.ts +74 -0
- package/src/auth/trust-circle.ts +45 -13
- package/src/bin/host.ts +1299 -1258
- package/src/donation/__tests__/donation-service.test.ts +836 -58
- package/src/donation/__tests__/donation-supervisor.test.ts +510 -0
- package/src/donation/__tests__/fake-orchestrator.test.ts +168 -0
- package/src/donation/__tests__/fake-orchestrator.ts +225 -0
- package/src/donation/donation-service.ts +611 -41
- package/src/donation/donation-store.ts +7 -0
- package/src/donation/donation-supervisor.ts +388 -0
- package/src/donation/index.ts +15 -0
- package/src/donation/types.ts +23 -0
- package/src/index.ts +14 -0
- package/src/orchestrator/__tests__/node-identity.test.ts +62 -0
- package/src/orchestrator/host-process-orchestrator.ts +336 -97
- package/src/orchestrator/node-identity.ts +40 -0
- package/src/orchestrator/port-allocator.ts +48 -0
- package/src/owner/owner-node-client.ts +31 -5
- package/src/server/__tests__/grants-route.test.ts +80 -6
- package/src/server/__tests__/strands-route.test.ts +233 -0
- package/src/server/error-handler.ts +24 -1
- package/src/server/events/types.ts +1 -0
- package/src/server/index.ts +16 -3
- package/src/server/routes/grants.ts +27 -3
- package/src/server/routes/strands.ts +54 -0
- package/src/strands/__tests__/strand-service.test.ts +165 -0
- package/src/strands/index.ts +14 -0
- package/src/strands/strand-service.ts +135 -0
- package/src/strands/types.ts +102 -0
- package/src/update/release-key.ts +1 -1
- package/dist/ui/assets/index-BlMXQPSw.js +0 -14
- package/dist/ui/assets/index-BlMXQPSw.js.map +0 -1
- package/dist/ui/assets/index-BwU5mJGF.css +0 -1
package/dist/donation/index.js
CHANGED
|
@@ -12,5 +12,6 @@ export { GrantService, createGrantAdminHandlers, DEFAULT_MAX_NODES, } from './gr
|
|
|
12
12
|
export { GrantError, DonationError } from './types.js';
|
|
13
13
|
/* ──────────────── donation lifecycle (2-donation-service) ──────────────── */
|
|
14
14
|
export { DonationStore } from './donation-store.js';
|
|
15
|
-
export { DonationService, DONATION_AWAITING_SEED_TTL_MS, DONATION_REAP_SWEEP_MS, } from './donation-service.js';
|
|
15
|
+
export { DonationService, DONATION_AWAITING_SEED_TTL_MS, DONATION_PROVISIONING_TTL_MS, DONATION_REAP_SWEEP_MS, } from './donation-service.js';
|
|
16
|
+
export { DonationSupervisor, DONATION_RESPAWN_BACKOFF_BASE_MS, DONATION_RESPAWN_BACKOFF_MAX_MS, DONATION_RESPAWN_MAX_ATTEMPTS, DONATION_RESPAWN_HEALTHY_MS, DONATION_RESPAWN_SWEEP_MS, } from './donation-supervisor.js';
|
|
16
17
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/donation/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAWvD,+EAA+E;AAE/E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,eAAe,EACf,6BAA6B,EAC7B,sBAAsB,GACvB,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/donation/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EACL,YAAY,EACZ,wBAAwB,EACxB,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAWvD,+EAA+E;AAE/E,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EACL,eAAe,EACf,6BAA6B,EAC7B,4BAA4B,EAC5B,sBAAsB,GACvB,MAAM,uBAAuB,CAAC;AAS/B,OAAO,EACL,kBAAkB,EAClB,gCAAgC,EAChC,+BAA+B,EAC/B,6BAA6B,EAC7B,2BAA2B,EAC3B,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC"}
|
package/dist/donation/types.d.ts
CHANGED
|
@@ -120,6 +120,12 @@ export type DonationStatus = 'provisioning' | 'awaiting_seed' | 'seeded' | 'erro
|
|
|
120
120
|
* foreign party), and `seedToken` gates the node's own `POST /seed` — it is
|
|
121
121
|
* minted host-side, persisted here (so a host restart in the request→seed gap
|
|
122
122
|
* can still present the seed), and NEVER returned to the grantee.
|
|
123
|
+
*
|
|
124
|
+
* The record also carries every input the original spawn consumed
|
|
125
|
+
* (`partyId` + `profile` + `bootstrapNodes` + `ownerKeys`), so a crashed node can
|
|
126
|
+
* be re-spawned from the record alone — see `DonationService.respawn`. Records
|
|
127
|
+
* written before those two fields existed have neither; such a record is NOT
|
|
128
|
+
* respawnable and is skipped (never crashes a sweep).
|
|
123
129
|
*/
|
|
124
130
|
export interface Donation {
|
|
125
131
|
/** "grn_<nanoid>" — also the donated node's orchestrator containerId. */
|
|
@@ -128,6 +134,26 @@ export interface Donation {
|
|
|
128
134
|
grantToken: string;
|
|
129
135
|
/** The REQUESTER's cadre (a foreign party this host merely hosts a node for). */
|
|
130
136
|
partyId: string;
|
|
137
|
+
/**
|
|
138
|
+
* Requester control-network bootstrap multiaddrs — replayed on respawn.
|
|
139
|
+
* Absent on records written before respawn support; those are not respawnable.
|
|
140
|
+
*/
|
|
141
|
+
bootstrapNodes?: string[];
|
|
142
|
+
/**
|
|
143
|
+
* Requester owner public key(s), base64url — replayed as the node's pinned
|
|
144
|
+
* seed-trust anchors (`CADRE_OWNER_KEYS`) on respawn. Absent on records written
|
|
145
|
+
* before respawn support; those are not respawnable.
|
|
146
|
+
*/
|
|
147
|
+
ownerKeys?: string[];
|
|
148
|
+
/**
|
|
149
|
+
* Respawn bookkeeping, owned by the supervisor's backoff. Absent until the
|
|
150
|
+
* first respawn attempt. Not secret — it rides along in `DonationView` so the
|
|
151
|
+
* borrower's `GET /grants/:id` shows the counters for free.
|
|
152
|
+
*/
|
|
153
|
+
respawn?: {
|
|
154
|
+
attempts: number;
|
|
155
|
+
lastAttemptAt: string;
|
|
156
|
+
};
|
|
131
157
|
/** Node profile. Defaults to `storage` so the node participates and is dialable. */
|
|
132
158
|
profile: 'storage' | 'transaction';
|
|
133
159
|
status: DonationStatus;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/donation/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/donation/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAgMH,sEAAsE;AACtE,MAAM,OAAO,aAAc,SAAQ,KAAK;IAGtC,YAAY,IAAuB,EAAE,OAAe;QAClD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAUD,6DAA6D;AAC7D,MAAM,OAAO,UAAW,SAAQ,KAAK;IAGnC,YAAY,IAAoB,EAAE,OAAe;QAC/C,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -22,8 +22,10 @@ export { HostProcessOrchestrator, OWNER_CONTAINER_ID } from './orchestrator/inde
|
|
|
22
22
|
export type { HostProcessConfig, PersistedHandle, ManagedNodeInfo, NodeStateListener, NodePorts, OwnerAdminEndpoint, OwnerSpawnConfig, } from './orchestrator/index.js';
|
|
23
23
|
export { OwnerNodeClient, OwnerNodeUnavailableError } from './owner/index.js';
|
|
24
24
|
export type { OwnerNodeClientOptions } from './owner/index.js';
|
|
25
|
-
export { TrustCircleService, TrustCircleStore, TrustCircleError, createTrustCircleHandlers, parseDuration, DEFAULT_INVITE_TTL_MS, } from './auth/index.js';
|
|
25
|
+
export { TrustCircleService, TrustCircleStore, TrustCircleError, createTrustCircleHandlers, parseDuration, ensureSelfLabel, DEFAULT_INVITE_TTL_MS, } from './auth/index.js';
|
|
26
26
|
export type { TrustCircleServiceOptions, CadreNodeLike, TrustCircleMember, PendingInvite, TrustCircleFile, TrustCircleSnapshot, TrustCircleHandlers, TrustCircleErrorCode, } from './auth/index.js';
|
|
27
|
+
export { StrandService, StrandError, createStrandHandlers } from './strands/index.js';
|
|
28
|
+
export type { StrandServiceOptions, CadreNodeLike as StrandCadreNodeLike, StrandSummary, StrandListSnapshot, StrandRemovalResult, StrandHandlers, StrandErrorCode, } from './strands/index.js';
|
|
27
29
|
export { GrantStore, GrantService, createGrantAdminHandlers, GrantError, DEFAULT_MAX_NODES, DonationStore, DonationService, DonationError, } from './donation/index.js';
|
|
28
30
|
export type { Grant, GrantDenyReason, GrantValidation, GrantValidator, GrantFile, GrantAdminHandlers, GrantErrorCode, GrantServiceOptions, Donation, DonationView, DonationStatus, DonationFile, DonationErrorCode, DonationProvisionRequest, DonationSeedResult, DonationPeerInfo, DonationServiceOptions, } from './donation/index.js';
|
|
29
31
|
export { Installer, readHostConfig, updateHostConfig, writeHostConfig } from './installer/index.js';
|
package/dist/index.js
CHANGED
|
@@ -19,7 +19,9 @@
|
|
|
19
19
|
*/
|
|
20
20
|
export { HostProcessOrchestrator, OWNER_CONTAINER_ID } from './orchestrator/index.js';
|
|
21
21
|
export { OwnerNodeClient, OwnerNodeUnavailableError } from './owner/index.js';
|
|
22
|
-
export { TrustCircleService, TrustCircleStore, TrustCircleError, createTrustCircleHandlers, parseDuration, DEFAULT_INVITE_TTL_MS, } from './auth/index.js';
|
|
22
|
+
export { TrustCircleService, TrustCircleStore, TrustCircleError, createTrustCircleHandlers, parseDuration, ensureSelfLabel, DEFAULT_INVITE_TTL_MS, } from './auth/index.js';
|
|
23
|
+
/* ──────────────── strand management ──────────────── */
|
|
24
|
+
export { StrandService, StrandError, createStrandHandlers } from './strands/index.js';
|
|
23
25
|
/* ──────────────── donation grant tokens ──────────────── */
|
|
24
26
|
export { GrantStore, GrantService, createGrantAdminHandlers, GrantError, DEFAULT_MAX_NODES, DonationStore, DonationService, DonationError, } from './donation/index.js';
|
|
25
27
|
export { Installer, readHostConfig, updateHostConfig, writeHostConfig } from './installer/index.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAWH,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAWtF,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAG9E,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,aAAa,EACb,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAYzB,6DAA6D;AAE7D,OAAO,EACL,UAAU,EACV,YAAY,EACZ,wBAAwB,EACxB,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,aAAa,GACd,MAAM,qBAAqB,CAAC;AAqB7B,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAepG,mEAAmE;AAEnE,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,WAAW,EACX,UAAU,GACX,MAAM,iBAAiB,CAAC;AAQzB,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACZ,sBAAsB,EACtB,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,yBAAyB,EACzB,cAAc,EACd,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAe3B,OAAO,EACL,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,GACd,MAAM,gBAAgB,CAAC;AA+BxB,+DAA+D;AAE/D,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,iBAAiB,GAClB,MAAM,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAWH,OAAO,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAWtF,OAAO,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAG9E,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,aAAa,EACb,eAAe,EACf,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AAYzB,yDAAyD;AAEzD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAWtF,6DAA6D;AAE7D,OAAO,EACL,UAAU,EACV,YAAY,EACZ,wBAAwB,EACxB,UAAU,EACV,iBAAiB,EACjB,aAAa,EACb,eAAe,EACf,aAAa,GACd,MAAM,qBAAqB,CAAC;AAqB7B,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAepG,mEAAmE;AAEnE,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,eAAe,EACf,WAAW,EACX,UAAU,GACX,MAAM,iBAAiB,CAAC;AAQzB,OAAO,EACL,aAAa,EACb,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,aAAa,EACb,YAAY,EACZ,sBAAsB,EACtB,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,yBAAyB,EACzB,cAAc,EACd,uBAAuB,GACxB,MAAM,mBAAmB,CAAC;AAe3B,OAAO,EACL,UAAU,EACV,QAAQ,EACR,QAAQ,EACR,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,eAAe,EACf,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,kBAAkB,EAClB,WAAW,EACX,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,aAAa,GACd,MAAM,gBAAgB,CAAC;AA+BxB,+DAA+D;AAE/D,OAAO,EACL,mBAAmB,EACnB,QAAQ,EACR,iBAAiB,GAClB,MAAM,mBAAmB,CAAC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { Orchestrator, OrchestratorCreateRequest, OrchestratorCreateResult, OrchestratorStats } from '@serfab/cadre-provider';
|
|
2
|
-
import { type PersistedHandle } from './state-store.js';
|
|
3
2
|
import { type OwnerSpawnConfig, type HostProcessConfig, type ManagedNodeInfo, type NodeStateListener } from './types.js';
|
|
4
3
|
/** Fixed friendly id for the admin's owner node. */
|
|
5
4
|
export declare const OWNER_CONTAINER_ID = "owner";
|
|
@@ -84,9 +83,44 @@ export declare class HostProcessOrchestrator implements Orchestrator {
|
|
|
84
83
|
* transitions (child exit, manual stop). Returns an unsubscribe fn.
|
|
85
84
|
*/
|
|
86
85
|
onStateChange(listener: NodeStateListener): () => void;
|
|
87
|
-
/**
|
|
88
|
-
|
|
86
|
+
/**
|
|
87
|
+
* Spawn a generic managed node — the donated-node path (the requester's cadre,
|
|
88
|
+
* pinned to the *requester's* owner key). The node is given its own protobuf
|
|
89
|
+
* identity key inside its workdir (`ensureNodeIdentity`, reused across
|
|
90
|
+
* re-spawns of the same containerId), which is what makes its peer id stable
|
|
91
|
+
* across restarts AND what makes its node-local stores durable: `cadre-cli
|
|
92
|
+
* start` opens the file-backed bootstrap-peer and trusted-owner stores only
|
|
93
|
+
* when a protobuf identity key file is configured, and puts them beside it.
|
|
94
|
+
* Terminating the loan (`removeContainer`) deletes the workdir, so the key and
|
|
95
|
+
* both stores go with it.
|
|
96
|
+
*/
|
|
89
97
|
createContainer(request: OrchestratorCreateRequest): Promise<OrchestratorCreateResult>;
|
|
98
|
+
/**
|
|
99
|
+
* Remove the working directory a spawn created for `containerId` when no
|
|
100
|
+
* handle owns it — the cleanup of last resort for a donation record that
|
|
101
|
+
* never got a `dockerId` (the host died between `ensureNodeIdentity` and the
|
|
102
|
+
* handle write, so `createContainer`'s own unwind never ran). Returns whether
|
|
103
|
+
* anything was removed.
|
|
104
|
+
*
|
|
105
|
+
* Synchronous, mirroring {@link resolveDockerId}: nothing on this path needs
|
|
106
|
+
* to await.
|
|
107
|
+
*/
|
|
108
|
+
reclaimWorkdir(containerId: string): boolean;
|
|
109
|
+
/**
|
|
110
|
+
* Best-effort removal of a workdir no handle owns. Logs, never throws: every
|
|
111
|
+
* caller is either unwinding a failure it must report instead of this one, or
|
|
112
|
+
* tearing a container down along a path where a surviving directory is a
|
|
113
|
+
* nuisance rather than a fault.
|
|
114
|
+
*
|
|
115
|
+
* `retries` sizes the wait for the OS to release a cwd handle — Windows drops
|
|
116
|
+
* it asynchronously after a child exits. `createContainer`'s unwind needs none
|
|
117
|
+
* of that (its throw surface ends before any child is spawned), but
|
|
118
|
+
* `reclaimWorkdir` can still meet an orphan process the previous host left
|
|
119
|
+
* running with this directory as its cwd, so it is not a *guaranteed*
|
|
120
|
+
* no-process path either — it simply logs and leaves the directory when the
|
|
121
|
+
* removal fails.
|
|
122
|
+
*/
|
|
123
|
+
private discardWorkdir;
|
|
90
124
|
/**
|
|
91
125
|
* Resolve the push credentials to inject into the node about to spawn. Called
|
|
92
126
|
* on every spawn so a re-spawn re-reads the secret store — raw private keys are
|
|
@@ -120,12 +154,82 @@ export declare class HostProcessOrchestrator implements Orchestrator {
|
|
|
120
154
|
restartOwnerNode(): Promise<ManagedNodeInfo>;
|
|
121
155
|
/**
|
|
122
156
|
* Core spawn mechanics shared by `createContainer` and `ensureOwnerNode`.
|
|
123
|
-
*
|
|
124
|
-
*
|
|
157
|
+
*
|
|
158
|
+
* The caller has already allocated `ports` and **owns their lifetime**: this
|
|
159
|
+
* method never releases them, so every caller must release on any throw out
|
|
160
|
+
* of here (it has to unwind its handle drop on the same path anyway — see
|
|
161
|
+
* `restoreDroppedHandles`).
|
|
162
|
+
*
|
|
163
|
+
* That contract holds because this method throws only *before* the child is
|
|
164
|
+
* spawned and its handle stored — everything after that point is
|
|
165
|
+
* best-effort. Anything new added at the tail must keep it that way.
|
|
166
|
+
*
|
|
167
|
+
* Entirely synchronous, which is what makes that unwind sound. Do not add an
|
|
168
|
+
* `await` here.
|
|
125
169
|
*/
|
|
126
170
|
private launchChild;
|
|
171
|
+
/**
|
|
172
|
+
* Drop any handle left over from a previous spawn of the same `containerId`
|
|
173
|
+
* and release its ports. Handles are keyed by the per-spawn `dockerId`, so
|
|
174
|
+
* without this a re-spawn (donated-node respawn) would strand the prior
|
|
175
|
+
* handle in the map forever, leaking four ports from a bounded range each
|
|
176
|
+
* time. Mirrors the same cleanup in `ensureOwnerNode`.
|
|
177
|
+
*
|
|
178
|
+
* DO NOT delete the workdir: the identity key and node-local stores
|
|
179
|
+
* (trusted-owner anchor, retained cold-start dial targets) live there and are
|
|
180
|
+
* the whole reason a respawn comes back as the same node. `launchChild`
|
|
181
|
+
* reuses the same workdir.
|
|
182
|
+
*
|
|
183
|
+
* NOTE: releasing the ports hands them straight back to the allocator, so a
|
|
184
|
+
* re-spawn while the *previous* child is still listening can bind-clash. Every
|
|
185
|
+
* caller today re-spawns only a container it has established is not running
|
|
186
|
+
* (`DonationService.respawn`, `ensureOwnerNode`). If a caller ever needs to
|
|
187
|
+
* replace a live child, stop it first — or hold the ports until its exit.
|
|
188
|
+
*
|
|
189
|
+
* **The drop is reversible.** It happens before the launch can fail, so the
|
|
190
|
+
* dropped handles are returned and every caller restores them via
|
|
191
|
+
* {@link restoreDroppedHandles} when the launch throws — otherwise the caller
|
|
192
|
+
* would be left holding a dockerId this orchestrator no longer knows, and the
|
|
193
|
+
* node's workdir could never be reclaimed. On a *successful* spawn the drop
|
|
194
|
+
* stands: `DonationService.abandonRespawn` depends on the old handle being
|
|
195
|
+
* gone by then.
|
|
196
|
+
*/
|
|
197
|
+
private dropStaleHandle;
|
|
198
|
+
/**
|
|
199
|
+
* Inverse of {@link dropStaleHandle}, for a spawn that then failed: put each
|
|
200
|
+
* handle back in the map and re-reserve its four ports, leaving host state
|
|
201
|
+
* exactly as the failed attempt found it.
|
|
202
|
+
*
|
|
203
|
+
* **Precondition: the drop → launch window is synchronous.** Restoring is
|
|
204
|
+
* sound only because nothing can have taken those ports or run cleanup
|
|
205
|
+
* against the handle in between — `launchChild` contains no `await` and both
|
|
206
|
+
* callers resolve push credentials *before* their drop. `launchChild`'s half
|
|
207
|
+
* is enforced: its declared return type is not a Promise, so adding an
|
|
208
|
+
* `await` there is a compile error. The callers' half is not — an `await`
|
|
209
|
+
* slipped between a drop and its launch silently breaks this.
|
|
210
|
+
*
|
|
211
|
+
* No `persist()` here: `state.json` is rewritten only by `launchChild` and
|
|
212
|
+
* only *after* the new handle is stored, so throughout the failure window the
|
|
213
|
+
* on-disk state still lists the dropped handle — this restore realigns memory
|
|
214
|
+
* to disk rather than diverging from it.
|
|
215
|
+
*
|
|
216
|
+
* NOTE: a restored handle keeps `alive: true` even if its child exited while
|
|
217
|
+
* it was out of the map (`launchChild`'s exit listener looks the handle up by
|
|
218
|
+
* dockerId and finds nothing). Only reachable by re-spawning a container
|
|
219
|
+
* whose child is still live, which `dropStaleHandle`'s note above already
|
|
220
|
+
* forbids.
|
|
221
|
+
*/
|
|
222
|
+
private restoreDroppedHandles;
|
|
223
|
+
/** A managed node's own directory under `rootDir` — config, log, storage, identity. */
|
|
224
|
+
private workdirFor;
|
|
127
225
|
/** Locate the owner node's handle, if one has been spawned. */
|
|
128
226
|
private findOwnerHandle;
|
|
227
|
+
/**
|
|
228
|
+
* Inverse of {@link releasePorts} — hold a handle's whole port set against
|
|
229
|
+
* the allocator. Used both to rehydrate on `init` and to undo a drop whose
|
|
230
|
+
* launch then failed.
|
|
231
|
+
*/
|
|
232
|
+
private reservePorts;
|
|
129
233
|
private releasePorts;
|
|
130
234
|
stopContainer(dockerId: string): Promise<void>;
|
|
131
235
|
removeContainer(dockerId: string): Promise<void>;
|