@serve.zone/interfaces 32.68.0 → 32.70.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/changelog.md +14 -0
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/data/backup.d.ts +55 -0
- package/dist_ts/data/backup.js +16 -2
- package/dist_ts/data/clusternode.d.ts +15 -2
- package/dist_ts/data/clusternode.js +1 -1
- package/dist_ts/data/index.d.ts +2 -0
- package/dist_ts/data/index.js +3 -1
- package/dist_ts/data/nodeaction.d.ts +439 -0
- package/dist_ts/data/nodeaction.js +434 -0
- package/dist_ts/data/sparkfleettarget.d.ts +80 -0
- package/dist_ts/data/sparkfleettarget.js +71 -0
- package/dist_ts/data/sparknodereport.d.ts +19 -0
- package/dist_ts/data/sparknodereport.js +21 -4
- package/dist_ts/requests/backup.d.ts +8 -0
- package/dist_ts/requests/node.d.ts +100 -0
- package/package.json +1 -1
- package/readme.md +47 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/data/backup.ts +57 -0
- package/ts/data/clusternode.ts +17 -2
- package/ts/data/index.ts +2 -0
- package/ts/data/nodeaction.ts +755 -0
- package/ts/data/sparkfleettarget.ts +138 -0
- package/ts/data/sparknodereport.ts +42 -3
- package/ts/requests/backup.ts +8 -0
- package/ts/requests/node.ts +118 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type IProtocolOffer } from '../protocol.js';
|
|
2
|
+
import type { TNodeActionName } from './clusternode.js';
|
|
2
3
|
/** Host observations only. Container and workload readiness belong to Pallet. */
|
|
3
4
|
export interface ISparkNodeReport {
|
|
4
5
|
observedAt: number;
|
|
@@ -27,6 +28,24 @@ export interface ISparkNodeReport {
|
|
|
27
28
|
* it made one since it started. Whether the node carries the hostname is `runtime.hostname`.
|
|
28
29
|
*/
|
|
29
30
|
hostApply?: ISparkNodeHostApply;
|
|
31
|
+
/**
|
|
32
|
+
* The host's boot, stated by a Spark that executes node actions: how Cloudly verifies an action
|
|
33
|
+
* that reboots (`nodeActionVerification`) and whether the host waits for a reboot.
|
|
34
|
+
*/
|
|
35
|
+
boot?: ISparkNodeBoot;
|
|
36
|
+
/**
|
|
37
|
+
* The node actions this Spark executes (`sparkNodeActionContracts`), in canonical order. Cloudly
|
|
38
|
+
* admits a node runtime action only for a node whose report states its executor, so an action
|
|
39
|
+
* Spark cannot execute is refused when it is requested rather than left to expire.
|
|
40
|
+
*/
|
|
41
|
+
actionExecutors?: TNodeActionName[];
|
|
42
|
+
}
|
|
43
|
+
/** One boot of the host. */
|
|
44
|
+
export interface ISparkNodeBoot {
|
|
45
|
+
/** The kernel's `boot_id` (`/proc/sys/kernel/random/boot_id`), a lowercase UUID; it changes with every boot. */
|
|
46
|
+
id: string;
|
|
47
|
+
/** Whether the host states that a package it installed waits for a reboot (`/var/run/reboot-required`). */
|
|
48
|
+
rebootRequired: boolean;
|
|
30
49
|
}
|
|
31
50
|
/** Whether Spark applied a desired hostname: `applied` once the host carries it. */
|
|
32
51
|
export type TSparkNodeHostApplyOutcome = 'applied' | 'failed';
|
|
@@ -3,6 +3,7 @@ import { readDataProperties, readExactDataRecord } from '../private/dataproperti
|
|
|
3
3
|
import { isClusterNodeId } from '../private/nodeidentifier.js';
|
|
4
4
|
import { protocolRefusalHttpStatus, readProtocolOffer } from '../protocol.js';
|
|
5
5
|
import { isClusterNodeHostname } from './clusternodehostname.js';
|
|
6
|
+
import { isHostBootId, isNodeActionNameList } from './nodeaction.js';
|
|
6
7
|
/** Bounds of `ISparkNodeHostApply.reason`. */
|
|
7
8
|
export const sparkNodeHostApplyContract = Object.freeze({
|
|
8
9
|
maximumReasonLength: 512,
|
|
@@ -72,8 +73,10 @@ export const snapshotSparkNodeReport = (valueArg) => {
|
|
|
72
73
|
const reportKeys = ['observedAt', 'metrics', 'runtime'];
|
|
73
74
|
const properties = readDataProperties(valueArg);
|
|
74
75
|
requireValue(properties !== null);
|
|
75
|
-
|
|
76
|
-
|
|
76
|
+
// Each optional member is read exactly when the report states it, so a report without them is
|
|
77
|
+
// the report an earlier Spark sends and is read the way an earlier reader read it.
|
|
78
|
+
const optionalKeys = ['hostApply', 'boot', 'actionExecutors'].filter((keyArg) => Object.hasOwn(properties, keyArg));
|
|
79
|
+
const value = record(valueArg, [...reportKeys, ...optionalKeys]);
|
|
77
80
|
const metrics = record(value.metrics, ['cpuUsagePercent', 'memoryUsedMB', 'memoryAvailableMB',
|
|
78
81
|
'diskUsedGB', 'diskAvailableGB']);
|
|
79
82
|
const runtime = record(value.runtime, ['hostname', 'platform', 'arch', 'osRelease', 'bundle',
|
|
@@ -100,9 +103,23 @@ export const snapshotSparkNodeReport = (valueArg) => {
|
|
|
100
103
|
}),
|
|
101
104
|
localRuntimeReady: true, workloadReadiness: 'unverified',
|
|
102
105
|
}),
|
|
103
|
-
...(
|
|
106
|
+
...(optionalKeys.includes('hostApply') ? { hostApply: snapshotSparkNodeHostApply(value.hostApply) } : {}),
|
|
107
|
+
...(optionalKeys.includes('boot') ? { boot: snapshotSparkNodeBoot(value.boot) } : {}),
|
|
108
|
+
...(optionalKeys.includes('actionExecutors')
|
|
109
|
+
? { actionExecutors: snapshotActionExecutors(value.actionExecutors) } : {}),
|
|
104
110
|
});
|
|
105
111
|
};
|
|
112
|
+
/** One `boot`: exactly its keys. */
|
|
113
|
+
const snapshotSparkNodeBoot = (valueArg) => {
|
|
114
|
+
const value = record(valueArg, ['id', 'rebootRequired']);
|
|
115
|
+
requireValue(isHostBootId(value.id) && typeof value.rebootRequired === 'boolean');
|
|
116
|
+
return Object.freeze({ id: value.id, rebootRequired: value.rebootRequired });
|
|
117
|
+
};
|
|
118
|
+
/** One `actionExecutors`: a canonical list of at least one action name, detached and frozen. */
|
|
119
|
+
const snapshotActionExecutors = (valueArg) => {
|
|
120
|
+
requireValue(isNodeActionNameList(valueArg));
|
|
121
|
+
return Object.freeze([...valueArg]);
|
|
122
|
+
};
|
|
106
123
|
export const snapshotSparkNodeHeartbeatRequest = (valueArg) => {
|
|
107
124
|
const value = record(valueArg, ['nodeId', 'nodeToken', 'protocol', 'report']);
|
|
108
125
|
return Object.freeze({
|
|
@@ -163,4 +180,4 @@ export const snapshotSparkNodeDesiredHost = (valueArg) => {
|
|
|
163
180
|
protocol: readProtocolOffer(value),
|
|
164
181
|
});
|
|
165
182
|
};
|
|
166
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Bhcmtub2RlcmVwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvZGF0YS9zcGFya25vZGVyZXBvcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDdkYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQy9ELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxpQkFBaUIsRUFBdUIsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuRyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQTBDakUsOENBQThDO0FBQzlDLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDdEQsbUJBQW1CLEVBQUUsR0FBRztDQUNoQixDQUFDLENBQUM7QUE0Qlo7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3RELFFBQVEsRUFBRSx3QkFBd0I7SUFDbEMsZUFBZSxFQUFFLElBQUk7SUFDckIsZ0JBQWdCLEVBQUUsSUFBSTtJQUN0QixxQkFBcUIsRUFBRSx5QkFBeUI7Q0FDeEMsQ0FBQyxDQUFDO0FBRVosTUFBTSxJQUFJLEdBQUcsR0FBVSxFQUFFLEdBQUcsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzFGLFNBQVMsWUFBWSxDQUFDLFFBQWlCO0lBQ3JDLElBQUksQ0FBQyxRQUFRO1FBQUUsSUFBSSxFQUFFLENBQUM7QUFDeEIsQ0FBQztBQUNELHNHQUFzRztBQUN0RyxNQUFNLE1BQU0sR0FBRyxDQUFDLFFBQWlCLEVBQUUsT0FBMEIsRUFBMkIsRUFBRTtJQUN4RixNQUFN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
|
|
183
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3Bhcmtub2RlcmVwb3J0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vdHMvZGF0YS9zcGFya25vZGVyZXBvcnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDdkYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQy9ELE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxpQkFBaUIsRUFBdUIsTUFBTSxnQkFBZ0IsQ0FBQztBQUNuRyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUVqRSxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLE1BQU0saUJBQWlCLENBQUM7QUE2RHJFLDhDQUE4QztBQUM5QyxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQ3RELG1CQUFtQixFQUFFLEdBQUc7Q0FDaEIsQ0FBQyxDQUFDO0FBNEJaOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUN0RCxRQUFRLEVBQUUsd0JBQXdCO0lBQ2xDLGVBQWUsRUFBRSxJQUFJO0lBQ3JCLGdCQUFnQixFQUFFLElBQUk7SUFDdEIscUJBQXFCLEVBQUUseUJBQXlCO0NBQ3hDLENBQUMsQ0FBQztBQUVaLE1BQU0sSUFBSSxHQUFHLEdBQVUsRUFBRSxHQUFHLE1BQU0sSUFBSSxLQUFLLENBQUMseUNBQXlDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUMxRixTQUFTLFlBQVksQ0FBQyxRQUFpQjtJQUNyQyxJQUFJLENBQUMsUUFBUTtRQUFFLElBQUksRUFBRSxDQUFDO0FBQ3hCLENBQUM7QUFDRCxzR0FBc0c7QUFDdEcsTUFB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
|
|
@@ -45,6 +45,14 @@ export interface IReq_Any_Cloudly_RestoreServiceBackup extends plugins.typedrequ
|
|
|
45
45
|
backupId: string;
|
|
46
46
|
clear?: boolean;
|
|
47
47
|
resourceTypes?: Array<TBackupSnapshot['type']>;
|
|
48
|
+
/**
|
|
49
|
+
* Must be `true` to restore a `failed` backup whose failure is `incomplete`, and is refused for
|
|
50
|
+
* any other backup. Such a restore restores what the backup captured: `resourceTypes` is
|
|
51
|
+
* required and names only types it captured, none of the resources it did not capture
|
|
52
|
+
* (`failure.uncaptured`) is restored, so the service then holds data from two points in time,
|
|
53
|
+
* and the backup stays `failed`.
|
|
54
|
+
*/
|
|
55
|
+
confirmPartialRestore?: boolean;
|
|
48
56
|
};
|
|
49
57
|
response: {
|
|
50
58
|
backup: IBackupRecord;
|
|
@@ -3,6 +3,8 @@ import type { IBareMetal } from '../data/baremetal.js';
|
|
|
3
3
|
import type { ICluster } from '../data/cluster.js';
|
|
4
4
|
import type { IClusterNode, INodeAction, INodeMetricsSample, TNodeActionName } from '../data/clusternode.js';
|
|
5
5
|
import type { IDeployment } from '../data/deployment.js';
|
|
6
|
+
import type { INodeActionConfirmation, INodeActionPreview } from '../data/nodeaction.js';
|
|
7
|
+
import type { ISparkFleetTarget, ISparkFleetTargetChange, ISparkNodeTargetHold } from '../data/sparkfleettarget.js';
|
|
6
8
|
import type { IIdentity } from '../data/user.js';
|
|
7
9
|
import type { IPlatformObjectStorageEndpoint } from '../platform/objectstorage.js';
|
|
8
10
|
import type { IPlatformDatabaseEndpoint } from '../platform/database.js';
|
|
@@ -342,6 +344,18 @@ export interface IReq_Any_Cloudly_ResetClusterNodeHostname extends plugins.typed
|
|
|
342
344
|
node: IClusterNode;
|
|
343
345
|
};
|
|
344
346
|
}
|
|
347
|
+
/**
|
|
348
|
+
* An administrator requests one action on one node.
|
|
349
|
+
*
|
|
350
|
+
* A node whose Swarm-era daemon reports last receives it as before, in the metrics-sample answer;
|
|
351
|
+
* `confirmation` is not read for it. A node that reports through the node runtime is sent the
|
|
352
|
+
* action only with a `confirmation` (`data.validateNodeActionConfirmation`) of the preview the
|
|
353
|
+
* administrator read (`getNodeActionPreview`): the typed hostname, the impact digest, when the
|
|
354
|
+
* impact names a Corestore on the node the consent to restart it, and for an update the fleet Spark
|
|
355
|
+
* target revision the preview showed. The action then carries
|
|
356
|
+
* `lifecycle`, with the confirmation, the impact and, for an update, the fleet target frozen in it.
|
|
357
|
+
* Every refusal is one of `data.nodeActionRefusals` and changes nothing.
|
|
358
|
+
*/
|
|
345
359
|
export interface IReq_Any_Cloudly_CreateNodeAction extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_CreateNodeAction> {
|
|
346
360
|
method: 'createNodeAction';
|
|
347
361
|
request: {
|
|
@@ -349,11 +363,97 @@ export interface IReq_Any_Cloudly_CreateNodeAction extends plugins.typedrequestI
|
|
|
349
363
|
nodeId: string;
|
|
350
364
|
actionName: TNodeActionName;
|
|
351
365
|
payload?: INodeAction['payload'];
|
|
366
|
+
confirmation?: INodeActionConfirmation;
|
|
367
|
+
};
|
|
368
|
+
response: {
|
|
369
|
+
action: INodeAction;
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* An administrator previews one action on one node that reports through the node runtime: what it
|
|
374
|
+
* interrupts, read from Cloudly's database, the digest a confirmation names, and every reason a
|
|
375
|
+
* request would be refused now. A preview changes nothing.
|
|
376
|
+
*/
|
|
377
|
+
export interface IReq_Any_Cloudly_GetNodeActionPreview extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_GetNodeActionPreview> {
|
|
378
|
+
method: 'getNodeActionPreview';
|
|
379
|
+
request: {
|
|
380
|
+
identity: IIdentity;
|
|
381
|
+
nodeId: string;
|
|
382
|
+
actionName: TNodeActionName;
|
|
383
|
+
};
|
|
384
|
+
response: {
|
|
385
|
+
preview: INodeActionPreview;
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* An administrator withdraws one node runtime action while it is still `pending`, at the revision
|
|
390
|
+
* they read. A claimed action is never withdrawn: Spark may already have stopped the node.
|
|
391
|
+
*/
|
|
392
|
+
export interface IReq_Any_Cloudly_CancelNodeAction extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_CancelNodeAction> {
|
|
393
|
+
method: 'cancelNodeAction';
|
|
394
|
+
request: {
|
|
395
|
+
identity: IIdentity;
|
|
396
|
+
nodeId: string;
|
|
397
|
+
actionId: string;
|
|
398
|
+
expectedRevision: number;
|
|
352
399
|
};
|
|
353
400
|
response: {
|
|
354
401
|
action: INodeAction;
|
|
355
402
|
};
|
|
356
403
|
}
|
|
404
|
+
/**
|
|
405
|
+
* An administrator reads the fleet Spark target (`data.ISparkFleetTarget`, `null` while there is
|
|
406
|
+
* none), its newest changes and every node hold.
|
|
407
|
+
*/
|
|
408
|
+
export interface IReq_Any_Cloudly_GetSparkFleetTarget extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_GetSparkFleetTarget> {
|
|
409
|
+
method: 'getSparkFleetTarget';
|
|
410
|
+
request: {
|
|
411
|
+
identity: IIdentity;
|
|
412
|
+
};
|
|
413
|
+
response: {
|
|
414
|
+
target: ISparkFleetTarget | null;
|
|
415
|
+
/** Newest first, at most `data.sparkFleetTargetContract.historyLimit`. */
|
|
416
|
+
history: ISparkFleetTargetChange[];
|
|
417
|
+
/** Sorted by node id. */
|
|
418
|
+
holds: ISparkNodeTargetHold[];
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
/**
|
|
422
|
+
* An administrator sets the fleet Spark target to one release version, at the revision they read
|
|
423
|
+
* (`0` while there is none). Cloudly reads the release's `SHA256SUMS.txt` and `install.sh`, refuses
|
|
424
|
+
* any mismatch between them, and stores the version with the SHA-256 it checked. Every refusal is
|
|
425
|
+
* one of `data.sparkFleetTargetRefusals`.
|
|
426
|
+
*/
|
|
427
|
+
export interface IReq_Any_Cloudly_SetSparkFleetTarget extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_SetSparkFleetTarget> {
|
|
428
|
+
method: 'setSparkFleetTarget';
|
|
429
|
+
request: {
|
|
430
|
+
identity: IIdentity;
|
|
431
|
+
/** `data.validateSetSparkFleetTargetInput` judges these two. */
|
|
432
|
+
version: string;
|
|
433
|
+
expectedRevision: number;
|
|
434
|
+
};
|
|
435
|
+
response: {
|
|
436
|
+
target: ISparkFleetTarget;
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* An administrator holds one node at the release it runs (`hold: { reason }`) or releases it
|
|
441
|
+
* (`hold: null`). Answers the hold as it now stands.
|
|
442
|
+
*/
|
|
443
|
+
export interface IReq_Any_Cloudly_SetSparkNodeTargetHold extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_SetSparkNodeTargetHold> {
|
|
444
|
+
method: 'setSparkNodeTargetHold';
|
|
445
|
+
request: {
|
|
446
|
+
identity: IIdentity;
|
|
447
|
+
nodeId: string;
|
|
448
|
+
/** `data.validateSparkNodeTargetHoldInput` judges it. */
|
|
449
|
+
hold: {
|
|
450
|
+
reason: string;
|
|
451
|
+
} | null;
|
|
452
|
+
};
|
|
453
|
+
response: {
|
|
454
|
+
hold: ISparkNodeTargetHold | null;
|
|
455
|
+
};
|
|
456
|
+
}
|
|
357
457
|
export interface IReq_Any_Cloudly_GetNodeActions extends plugins.typedrequestInterfaces.implementsTR<plugins.typedrequestInterfaces.ITypedRequest, IReq_Any_Cloudly_GetNodeActions> {
|
|
358
458
|
method: 'getNodeActions';
|
|
359
459
|
request: {
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -216,6 +216,53 @@ next heartbeat; the node has converged when `runtime.hostname` states the intent
|
|
|
216
216
|
hostname. A Spark that sends `hostApply` raises its `minimumPeerVersion` so it
|
|
217
217
|
reaches only a Cloudly that reads it.
|
|
218
218
|
|
|
219
|
+
### Node Actions
|
|
220
|
+
|
|
221
|
+
A node action (`INodeAction`: reboot, serve.zone service update, system upgrade)
|
|
222
|
+
that a node runtime executes carries `lifecycle` (`INodeActionLifecycle`): the
|
|
223
|
+
administrator's confirmation (`INodeActionConfirmation`: the typed hostname, the
|
|
224
|
+
digest of the impact preview they read, when the impact names a Corestore on the
|
|
225
|
+
node the consent to restart it, and for an update the fleet Spark target revision
|
|
226
|
+
the preview showed, refused `target-changed` once the target moved), the impact (`INodeActionImpact`), the fleet
|
|
227
|
+
Spark target an update moves the node to, a revision, the current deadline, the
|
|
228
|
+
claim, a failure with its remedy and a timeline. A Swarm-era record carries none of
|
|
229
|
+
it and travels only in the Swarm-era metrics-sample answer. `TNodeActionStatus`
|
|
230
|
+
keeps the four shipped values (`pending` is the requested state) and adds
|
|
231
|
+
`claimed`, `executing`, `draining`, `rebooting`, `verifying`, `expired`,
|
|
232
|
+
`cancelled` and `unverified`; `data.nodeActionStatusKinds` states which are open.
|
|
233
|
+
|
|
234
|
+
`data.sparkNodeActionContracts` defines the node runtime's two action routes,
|
|
235
|
+
authenticated and judged in the heartbeat's order: `offer` (`/spark/nodes/action`)
|
|
236
|
+
answers the node's one open action (`ISparkNodeActionAssignment`) or `null`, and
|
|
237
|
+
`transition` (`/spark/nodes/action/transition`) takes one step at the revision the
|
|
238
|
+
assignment states — `claim` with the host's boot id, a forward `phase`
|
|
239
|
+
(`sparkNodeActionPhaseOrder`), `complete` (a host upgrade without a reboot) or
|
|
240
|
+
`fail` with one of `sparkNodeActionFailureCodes` — and answers `applied`,
|
|
241
|
+
`replayed` (the same step again at the same revision) or a named refusal.
|
|
242
|
+
`data.admitsSparkNodeActionTransition` states which step an action admits.
|
|
243
|
+
Cloudly verifies every action from what the node reports
|
|
244
|
+
(`data.nodeActionVerification`): a new `boot.id`, the target bundle version, or a
|
|
245
|
+
completed host upgrade; a heartbeat stating `boot.rebootRequired` after a host
|
|
246
|
+
upgrade fails it `reboot-required` rather than rebooting. A deadline
|
|
247
|
+
(`data.nodeActionCompletionBudgetMs`, `nodeActionContract`) that passes ends an
|
|
248
|
+
action `unverified`.
|
|
249
|
+
|
|
250
|
+
A Spark that executes actions states `ISparkNodeReport.boot` (the kernel boot id
|
|
251
|
+
and whether the host waits for a reboot) and `actionExecutors`, the canonical list
|
|
252
|
+
of action names it executes; Cloudly admits an action only for a node that states
|
|
253
|
+
its executor. Both are optional members an earlier reader refuses, so a Spark sends
|
|
254
|
+
them only to a Cloudly that reads them, like `hostApply`.
|
|
255
|
+
|
|
256
|
+
`data.ISparkFleetTarget` is the one fleet Spark target: a version and the SHA-256
|
|
257
|
+
its release's `SHA256SUMS.txt` states for `install.sh`, with a revision, who set
|
|
258
|
+
it and when, an append-only history (`ISparkFleetTargetChange`) and per-node
|
|
259
|
+
holds (`ISparkNodeTargetHold`). `data.readSparkNodeTargetStanding` places a node
|
|
260
|
+
at, behind or ahead of it, held, unreported or untargeted. The admin requests
|
|
261
|
+
(`getNodeActionPreview`, `createNodeAction` with `confirmation`,
|
|
262
|
+
`cancelNodeAction`, `getSparkFleetTarget`, `setSparkFleetTarget`,
|
|
263
|
+
`setSparkNodeTargetHold`) answer refusals by name from `data.nodeActionRefusals`
|
|
264
|
+
and `data.sparkFleetTargetRefusals`.
|
|
265
|
+
|
|
219
266
|
The snapshot functions reject unknown keys, accessors, malformed identities and
|
|
220
267
|
nonfinite/out-of-range numbers, then return detached frozen records. Transports
|
|
221
268
|
own byte limits, timeouts and cancellation. These contracts do not implement a
|
package/ts/00_commitinfo_data.ts
CHANGED
package/ts/data/backup.ts
CHANGED
|
@@ -72,10 +72,46 @@ export interface IBackupReplicationResult {
|
|
|
72
72
|
completedAt: number;
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* One resource a service declares that a backup of it did not capture, with why; each kind of
|
|
77
|
+
* resource has its own reason.
|
|
78
|
+
*
|
|
79
|
+
* `volume-capture-unavailable`: a service volume is a node-local storage claim on its Pallet node,
|
|
80
|
+
* which no relay can capture yet; a `volume` snapshot is a Corestore Docker volume and captures no
|
|
81
|
+
* service volume. `binding-not-snapshotted`: the backup holds no snapshot of the Corestore resource
|
|
82
|
+
* the binding names.
|
|
83
|
+
*/
|
|
84
|
+
export type TBackupUncapturedResource =
|
|
85
|
+
| { type: 'volume'; mountPath: string; reason: 'volume-capture-unavailable' }
|
|
86
|
+
| { type: 'database' | 'objectstorage'; bindingId: string; reason: 'binding-not-snapshotted' };
|
|
87
|
+
|
|
88
|
+
/** Why a resource a service declares is not in one of its backups (`TBackupUncapturedResource`). */
|
|
89
|
+
export type TBackupUncapturedReason = TBackupUncapturedResource['reason'];
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* The named kind of a `failed` backup's failure; a failure without one is named only in `errorText`.
|
|
93
|
+
*
|
|
94
|
+
* `incomplete`: the backup did not capture every resource its service declares, and `uncaptured`
|
|
95
|
+
* names each one it missed. What it did capture is restored only by a partial restore an
|
|
96
|
+
* administrator confirms (`IReq_Any_Cloudly_RestoreServiceBackup` `confirmPartialRestore`), which
|
|
97
|
+
* restores none of `uncaptured`, and the backup stays `failed`.
|
|
98
|
+
* `archive-unreadable`: its stored archive is missing or damaged, so it restores nothing.
|
|
99
|
+
*/
|
|
100
|
+
export type TBackupFailure =
|
|
101
|
+
| { kind: 'incomplete'; uncaptured: TBackupUncapturedResource[] }
|
|
102
|
+
| { kind: 'archive-unreadable' };
|
|
103
|
+
|
|
75
104
|
export interface IBackupRestoreEvent {
|
|
76
105
|
restoredAt: number;
|
|
77
106
|
status: 'restored' | 'failed';
|
|
78
107
|
errorText?: string;
|
|
108
|
+
/** The resource types the restore was limited to; absent when it restored every snapshot. */
|
|
109
|
+
resourceTypes?: TBackupResourceType[];
|
|
110
|
+
/**
|
|
111
|
+
* A confirmed partial restore of an `incomplete` backup: it restored only `resourceTypes`, and
|
|
112
|
+
* none of the backup's `failure.uncaptured`.
|
|
113
|
+
*/
|
|
114
|
+
partial?: true;
|
|
79
115
|
}
|
|
80
116
|
|
|
81
117
|
/**
|
|
@@ -114,6 +150,8 @@ export interface IBackupRecord {
|
|
|
114
150
|
completedAt?: number;
|
|
115
151
|
requestedBy?: string;
|
|
116
152
|
errorText?: string;
|
|
153
|
+
/** The named kind of a `failed` backup's failure (`TBackupFailure`). */
|
|
154
|
+
failure?: TBackupFailure;
|
|
117
155
|
restoreHistory?: IBackupRestoreEvent[];
|
|
118
156
|
/**
|
|
119
157
|
* Authoritative isolated-restore holds. Cloudly atomically appends the
|
|
@@ -124,6 +162,25 @@ export interface IBackupRecord {
|
|
|
124
162
|
tags?: Record<string, string>;
|
|
125
163
|
}
|
|
126
164
|
|
|
165
|
+
/**
|
|
166
|
+
* The resource types a partial restore of a backup may name (`confirmPartialRestore`).
|
|
167
|
+
*
|
|
168
|
+
* For a `failed` backup whose failure is `incomplete`: every type it holds a snapshot of, except
|
|
169
|
+
* `volume` (a `volume` snapshot is a Corestore Docker volume and captures no service volume) and the
|
|
170
|
+
* type of any resource it did not capture, so a partial restore never restores a snapshot standing
|
|
171
|
+
* for a resource the backup missed. For every other backup: none. Database before object storage.
|
|
172
|
+
*/
|
|
173
|
+
export const readPartialRestoreResourceTypes = (
|
|
174
|
+
backupArg: Pick<IBackupRecord, 'status' | 'failure'> & { snapshots: ReadonlyArray<Pick<TBackupSnapshot, 'type'>> },
|
|
175
|
+
): Array<Exclude<TBackupResourceType, 'volume'>> => {
|
|
176
|
+
const failure = backupArg.failure;
|
|
177
|
+
if (backupArg.status !== 'failed' || failure?.kind !== 'incomplete') return [];
|
|
178
|
+
const uncapturedTypes = new Set<TBackupResourceType>(failure.uncaptured.map((resourceArg) => resourceArg.type));
|
|
179
|
+
return (['database', 'objectstorage'] as const).filter((typeArg) => (
|
|
180
|
+
!uncapturedTypes.has(typeArg) && backupArg.snapshots.some((snapshotArg) => snapshotArg.type === typeArg)
|
|
181
|
+
));
|
|
182
|
+
};
|
|
183
|
+
|
|
127
184
|
/** Retention policy understood by containerarchive prune. */
|
|
128
185
|
export interface IArchiveRetentionPolicy {
|
|
129
186
|
keepLast?: number;
|
package/ts/data/clusternode.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as plugins from '../plugins.js';
|
|
2
2
|
import { isSha256Digest, type TSha256Digest, type TImmutableContainerPlatform } from './immutableimage.js';
|
|
3
3
|
import type { ISparkNodeReportRecord } from './sparknodereport.js';
|
|
4
|
+
import type { INodeActionExpiry, INodeActionLifecycle } from './nodeaction.js';
|
|
4
5
|
import type { IClusterNodeHostnameIntent } from './clusternodehostname.js';
|
|
5
6
|
import type { IPlatformObjectStorageEndpoint } from '../platform/objectstorage.js';
|
|
6
7
|
import type { IPlatformDatabaseEndpoint } from '../platform/database.js';
|
|
@@ -74,11 +75,21 @@ export interface INodeMetricsSample {
|
|
|
74
75
|
|
|
75
76
|
export type TNodeActionName = 'systemUpgrade' | 'reboot' | 'serveZoneServiceUpdate';
|
|
76
77
|
|
|
77
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Every state of a node action; `nodeActionStatusKinds` states which are open and what each means.
|
|
80
|
+
* The first four are the ones the Swarm-era carrier shipped and keep their meaning.
|
|
81
|
+
*/
|
|
82
|
+
export type TNodeActionStatus = 'pending' | 'running' | 'succeeded' | 'failed'
|
|
83
|
+
| 'claimed' | 'executing' | 'draining' | 'rebooting' | 'verifying'
|
|
84
|
+
| 'expired' | 'cancelled' | 'unverified';
|
|
78
85
|
|
|
79
86
|
/**
|
|
80
87
|
* An operator-requested action executed by spark on a node.
|
|
81
|
-
*
|
|
88
|
+
*
|
|
89
|
+
* A Swarm-era record is delivered to the Swarm-era daemon in metrics-sample responses, which
|
|
90
|
+
* posts results back; it carries no `lifecycle`. A node runtime action carries `lifecycle`: Spark
|
|
91
|
+
* takes it from `sparkNodeActionContracts.offer` and states each step on
|
|
92
|
+
* `sparkNodeActionContracts.transition`, and Cloudly verifies it from the node's reports.
|
|
82
93
|
*/
|
|
83
94
|
export interface INodeAction {
|
|
84
95
|
id: string;
|
|
@@ -94,6 +105,10 @@ export interface INodeAction {
|
|
|
94
105
|
startedAt?: number;
|
|
95
106
|
finishedAt?: number;
|
|
96
107
|
resultText?: string;
|
|
108
|
+
/** The node runtime's lifecycle; absent on a Swarm-era record. */
|
|
109
|
+
lifecycle?: INodeActionLifecycle;
|
|
110
|
+
/** Why the action ended `expired`; present exactly then. */
|
|
111
|
+
expiry?: INodeActionExpiry;
|
|
97
112
|
}
|
|
98
113
|
|
|
99
114
|
export interface IServeZoneServiceRuntimeInfo {
|
package/ts/data/index.ts
CHANGED
|
@@ -81,6 +81,8 @@ export * from './clusternodehostname.js';
|
|
|
81
81
|
export * from './settings.js';
|
|
82
82
|
export * from './sparklegacyretirement.js';
|
|
83
83
|
export * from './sparknodereport.js';
|
|
84
|
+
export * from './nodeaction.js';
|
|
85
|
+
export * from './sparkfleettarget.js';
|
|
84
86
|
export * from './service.js';
|
|
85
87
|
export * from './servicecredential.js';
|
|
86
88
|
export * from './serviceplatformownership.js';
|