node-engine: typed layouts for the states have (both forms), composed (both forms, wire names), data and health, with fixtures; Candidates typed as CandidateAnswer (ADR 0634 §1, §6; issue 1966)
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
@@ -112,6 +112,22 @@ export function parseComposedByNodeModuleFingerprintKey(key: string): { node: st
|
||||
return { node, module, fingerprint };
|
||||
}
|
||||
|
||||
/** The key of one value of the state composed under the form "<node>.node". */
|
||||
export function composedByNodeNodeKey(node: string): string {
|
||||
return node + ".node";
|
||||
}
|
||||
|
||||
/** The parts of a key of the form "<node>.node", or undefined for a key of another form. */
|
||||
export function parseComposedByNodeNodeKey(key: string): { node: string } | undefined {
|
||||
let rest = key;
|
||||
const at0 = rest.indexOf(".node");
|
||||
if (at0 <= 0) return undefined;
|
||||
const node = rest.slice(0, at0);
|
||||
rest = rest.slice(at0 + 5);
|
||||
if (rest !== "") return undefined;
|
||||
return { node };
|
||||
}
|
||||
|
||||
/** The key of one value of the state data under the form "<node>.<module>". */
|
||||
export function dataByNodeModuleKey(node: string, module: string): string {
|
||||
return node + "." + module;
|
||||
@@ -176,6 +192,17 @@ export function parseFindingsByKeyKey(key: string): { key: string } | undefined
|
||||
return { key };
|
||||
}
|
||||
|
||||
/** the hashes of the users of the list, sealed to the vault */
|
||||
export interface AccountsHanded {
|
||||
/** when */
|
||||
"at": string;
|
||||
"box": SealedBox;
|
||||
"from": string;
|
||||
/** the fingerprint of the vault's key */
|
||||
"to": string;
|
||||
"users": number;
|
||||
}
|
||||
|
||||
/** one act asked through the seat, as acts reads it (ADR 0563 §9) */
|
||||
export interface Act {
|
||||
/** the act: hand-over, access-act, judge-directories or setuid-search */
|
||||
@@ -242,6 +269,14 @@ export interface Acts {
|
||||
"node": string;
|
||||
}
|
||||
|
||||
/** the node is adopted and which of its modules are taken */
|
||||
export interface Adoption {
|
||||
/** the modules taken */
|
||||
"taken": string[];
|
||||
/** by module, the resources left untaken */
|
||||
"untaken"?: Record<string, string[]>;
|
||||
}
|
||||
|
||||
/** the answer of an act the operator is asked */
|
||||
export interface Asked {
|
||||
/** the ask's id: acts shows where it stands */
|
||||
@@ -252,6 +287,105 @@ export interface Asked {
|
||||
"says": string;
|
||||
}
|
||||
|
||||
/** a network attached to a link */
|
||||
export interface AttachedNetwork {
|
||||
"link": string;
|
||||
"network": string;
|
||||
}
|
||||
|
||||
/** a module the candidate adds */
|
||||
export interface CandidateAdded {
|
||||
"composed"?: string;
|
||||
"module": string;
|
||||
"unissued"?: string[];
|
||||
}
|
||||
|
||||
/** the node's answer to one placement candidate naming it */
|
||||
export interface CandidateAnswer {
|
||||
"added"?: CandidateAdded[];
|
||||
"differs"?: CandidateDiffers[];
|
||||
"held"?: CandidateRefusal[];
|
||||
"note"?: string;
|
||||
"proposal": string;
|
||||
"refusals"?: CandidateRefusal[];
|
||||
/** why the node cannot compose with the candidate at all */
|
||||
"refused"?: string;
|
||||
/** modules the candidate removes */
|
||||
"removed"?: string[];
|
||||
"returns"?: string;
|
||||
"revision": number;
|
||||
/** modules whose composition is the one running */
|
||||
"same"?: string[];
|
||||
"values_differ"?: number;
|
||||
/** same, differs or refused */
|
||||
"verdict": "same" | "differs" | "refused";
|
||||
}
|
||||
|
||||
/** the bodies of one resource that differ */
|
||||
export interface CandidateBodies {
|
||||
"composed"?: string;
|
||||
"id": string;
|
||||
"paths"?: string[];
|
||||
"running"?: string;
|
||||
"why": string;
|
||||
}
|
||||
|
||||
/** a module whose composition with the candidate differs from the one running */
|
||||
export interface CandidateDiffers {
|
||||
"bodies"?: CandidateBodies[];
|
||||
"composed"?: string;
|
||||
"module": string;
|
||||
"resource"?: string;
|
||||
"running"?: string;
|
||||
"why": string;
|
||||
}
|
||||
|
||||
/** a module refused or held with the candidate */
|
||||
export interface CandidateRefusal {
|
||||
"module": string;
|
||||
"today"?: string;
|
||||
"why": string;
|
||||
}
|
||||
|
||||
/** a group */
|
||||
export interface DeclaredGroup {
|
||||
"gid": number;
|
||||
"name": string;
|
||||
}
|
||||
|
||||
/** the identity of a module assigned to the node */
|
||||
export interface DeclaredIdentity {
|
||||
"gid": number;
|
||||
"groups"?: number[];
|
||||
"module": string;
|
||||
"name": string;
|
||||
"runner"?: string;
|
||||
"uid": number;
|
||||
}
|
||||
|
||||
/** a library the node is reached by */
|
||||
export interface DeclaredLibrary {
|
||||
"gid": number;
|
||||
"group": string;
|
||||
"home": boolean;
|
||||
"library": string;
|
||||
"paths"?: string[];
|
||||
"root": string;
|
||||
"runner"?: string;
|
||||
"taken"?: boolean;
|
||||
}
|
||||
|
||||
/** a unit that failed */
|
||||
export interface FailedUnit {
|
||||
"load"?: string;
|
||||
"resource"?: string;
|
||||
"result"?: string;
|
||||
"scope": string;
|
||||
/** since when */
|
||||
"since": string;
|
||||
"unit": string;
|
||||
}
|
||||
|
||||
/** one answer the operator may give from a notification */
|
||||
export interface FindingAction {
|
||||
"arguments"?: Record<string, string>;
|
||||
@@ -280,6 +414,15 @@ export interface FindingSubject {
|
||||
"scope": string;
|
||||
}
|
||||
|
||||
/** a login that fell back to another node */
|
||||
export interface LoginFallback {
|
||||
/** when */
|
||||
"at": string;
|
||||
"from": string;
|
||||
"node": string;
|
||||
"why": string;
|
||||
}
|
||||
|
||||
/** what a node-engine says when what it reads changed or its node returned (ADR 0618 §4) */
|
||||
export interface ManifestReadsChanged {
|
||||
/** when it says it, RFC 3339 */
|
||||
@@ -310,6 +453,115 @@ export interface Module {
|
||||
"words"?: string;
|
||||
}
|
||||
|
||||
/** the node's network */
|
||||
export interface NetworkHealth {
|
||||
"parts": NetworkPart[];
|
||||
/** since when */
|
||||
"since": string;
|
||||
/** running, degraded or unknown */
|
||||
"state": string;
|
||||
}
|
||||
|
||||
/** one part of the node's network */
|
||||
export interface NetworkPart {
|
||||
"owner"?: string;
|
||||
"part": string;
|
||||
"reason"?: string;
|
||||
"said"?: string;
|
||||
/** since when */
|
||||
"since": string;
|
||||
"state": string;
|
||||
"streak"?: number;
|
||||
"targets"?: string[];
|
||||
"toward"?: string[];
|
||||
"writer"?: string;
|
||||
}
|
||||
|
||||
/** an account the node needs to log in again */
|
||||
export interface NodeAccount {
|
||||
"account": string;
|
||||
"module"?: string;
|
||||
"reason": string;
|
||||
"resource"?: string;
|
||||
/** since when */
|
||||
"since": string;
|
||||
}
|
||||
|
||||
/** a directory found where the node expected none */
|
||||
export interface NodeDirectory {
|
||||
"module": string;
|
||||
"path": string;
|
||||
"reason": string;
|
||||
"resource": string;
|
||||
/** since when */
|
||||
"since": string;
|
||||
}
|
||||
|
||||
/** what a node's own composition carries beside its resources */
|
||||
export interface NodeOwn {
|
||||
"adoption"?: Adoption;
|
||||
"groups"?: DeclaredGroup[];
|
||||
"identities"?: DeclaredIdentity[];
|
||||
"libraries"?: DeclaredLibrary[];
|
||||
/** the account the provisioner's client runs as on the node */
|
||||
"provisioner_account"?: string;
|
||||
}
|
||||
|
||||
/** what the machine observes of itself, for every node and composing part to read */
|
||||
export interface NodeRecord {
|
||||
"authority"?: string;
|
||||
"capabilities"?: string[];
|
||||
"certificate"?: string;
|
||||
"contract"?: number;
|
||||
"manifest-reads"?: string[];
|
||||
"networks"?: AttachedNetwork[];
|
||||
"networks-said"?: boolean;
|
||||
"node": string;
|
||||
"outward-links"?: string[];
|
||||
"sealing-key"?: string;
|
||||
"serving-key"?: string;
|
||||
"trusts"?: string[];
|
||||
"tunnel-key"?: string;
|
||||
"v": number;
|
||||
}
|
||||
|
||||
/** a tunnel peer and whether it is seen */
|
||||
export interface PeerSeen {
|
||||
"addresses"?: string[];
|
||||
"key": string;
|
||||
"seen": boolean;
|
||||
}
|
||||
|
||||
/** one data item a module declares, as placed on a node */
|
||||
export interface PlacedDataItem {
|
||||
"class": string;
|
||||
/** the path whose snapshot keeps it, empty when it is not backed up */
|
||||
"covered_by"?: string;
|
||||
"item": string;
|
||||
/** walk, dataset or shallow */
|
||||
"measure"?: string;
|
||||
"module": string;
|
||||
/** the item's place on the node */
|
||||
"path": string;
|
||||
/** backup, redundancy, both or none */
|
||||
"protection"?: string;
|
||||
}
|
||||
|
||||
/** the pull from a store a failed apply waits on */
|
||||
export interface PullWait {
|
||||
/** when the pull began */
|
||||
"began": string;
|
||||
/** that seat's holder, whose settling the apply waits for */
|
||||
"holder": string;
|
||||
"image": string;
|
||||
/** what triggered the last try again, in words */
|
||||
"retried"?: string;
|
||||
/** when the apply was last tried again */
|
||||
"retried-at"?: string;
|
||||
/** the seat the pull came through */
|
||||
"seat"?: string;
|
||||
}
|
||||
|
||||
/** one revision of a composition key */
|
||||
export interface Revision {
|
||||
/** its digest */
|
||||
@@ -326,6 +578,17 @@ export interface Revision {
|
||||
"revision"?: number;
|
||||
}
|
||||
|
||||
/** the engine's verdict of whether an account's resource is root-free, as the node's health lists it */
|
||||
export interface RootAccountVerdict {
|
||||
"account": string;
|
||||
"module": string;
|
||||
"reason"?: string;
|
||||
"resource": string;
|
||||
/** since when */
|
||||
"since": string;
|
||||
"state": string;
|
||||
}
|
||||
|
||||
/** the engine's root-free verdict (ADR 0563 §6) */
|
||||
export interface RootVerdict {
|
||||
/** the machine is root-free */
|
||||
@@ -346,6 +609,15 @@ export interface Said {
|
||||
"said": string;
|
||||
}
|
||||
|
||||
/** a value sealed to a key */
|
||||
export interface SealedBox {
|
||||
"ct": string;
|
||||
"eph": string;
|
||||
"iv": string;
|
||||
"tag": string;
|
||||
"v": number;
|
||||
}
|
||||
|
||||
export interface SeatListStatus {
|
||||
/** the seat mesh-catalog has answered */
|
||||
"heard": boolean;
|
||||
@@ -374,6 +646,37 @@ export interface SeatListHeld {
|
||||
"source": "trunk" | "bootstrap";
|
||||
}
|
||||
|
||||
/** the node's units */
|
||||
export interface UnitsHealth {
|
||||
"away"?: string[];
|
||||
"failed": FailedUnit[];
|
||||
"state": string;
|
||||
"unread"?: string[];
|
||||
}
|
||||
|
||||
/** the bus's user list as the engine of the bus node wrote it to the bus module's file */
|
||||
export interface UserListWritten {
|
||||
/** when */
|
||||
"at": string;
|
||||
/** the digest of the file on the machine after the write */
|
||||
"digest"?: string;
|
||||
/** why a write failed */
|
||||
"error"?: string;
|
||||
/** which list the node follows now */
|
||||
"follows"?: string;
|
||||
"handed"?: AccountsHanded;
|
||||
/** the bus node's sealing key, its public half */
|
||||
"key"?: string;
|
||||
"revision": number;
|
||||
/** the key the list was taken from */
|
||||
"source": string;
|
||||
/** why the bus node does not watch the grants part's key now */
|
||||
"unwatched"?: string;
|
||||
"users": number;
|
||||
/** the digest of the list the source holds, sha256:<hex> */
|
||||
"wanted": string;
|
||||
}
|
||||
|
||||
/** is what hand-over takes. */
|
||||
export interface HandOverInput {
|
||||
/** the directory's absolute path, as the engine states it */
|
||||
@@ -711,45 +1014,48 @@ export type ManifestReadsChangedEvent = ManifestReadsChanged;
|
||||
/** is one value of the state have under the key <node>.<module>. */
|
||||
export interface HaveByNodeModuleValue {
|
||||
"build"?: string;
|
||||
/** the move changes the build alone */
|
||||
"build-alone"?: boolean;
|
||||
/** the composition's digest */
|
||||
/** the digest of the composition the node runs */
|
||||
"composed"?: string;
|
||||
"detail"?: string;
|
||||
/** the fingerprint held */
|
||||
"fp"?: string;
|
||||
/** the accounts handed */
|
||||
"handed"?: Record<string, unknown>;
|
||||
/** how it is */
|
||||
"health": string;
|
||||
"judgement"?: string;
|
||||
"handed"?: AccountsHanded;
|
||||
/** what the module's own check says */
|
||||
"health": "ok" | "failed" | "waits" | "unknown";
|
||||
/** in phase waiting-yes, the judgement of the move */
|
||||
"judgement"?: "recreates" | "moves-data" | "cannot-judge";
|
||||
/** what the node keeps of the module as it runs */
|
||||
"kept"?: string[];
|
||||
/** how far it has come */
|
||||
"phase": string;
|
||||
/** a pull the engine waits for */
|
||||
"pull-wait"?: Record<string, unknown>;
|
||||
"phase": "backing-up" | "applying" | "checking" | "running" | "failed" | "removed" | "held" | "waiting-yes";
|
||||
"pull-wait"?: PullWait;
|
||||
/** each value sealed to the node's key */
|
||||
"sealed"?: string[];
|
||||
"sealed-at"?: Record<string, unknown>;
|
||||
/** the user list written */
|
||||
"user-list"?: Record<string, unknown>;
|
||||
/** the sealed values by slot */
|
||||
"sealed-at"?: Record<string, string>;
|
||||
"user-list"?: UserListWritten;
|
||||
"v": number;
|
||||
/** what it waits for */
|
||||
/** in phase waiting-yes, the digest of the composition that waits */
|
||||
"waits"?: string;
|
||||
}
|
||||
|
||||
/** is one value of the state have under the key <node>.node. */
|
||||
export interface HaveByNodeNodeValue {
|
||||
"busy"?: Record<string, unknown>;
|
||||
"candidates"?: Record<string, Record<string, unknown>>;
|
||||
/** the node's answer to each placement candidate naming it, by proposal id */
|
||||
"candidates"?: Record<string, CandidateAnswer>;
|
||||
/** the digest of the node's own composition it runs */
|
||||
"composed"?: string;
|
||||
/** own, or the controller's */
|
||||
/** own, or none (empty) */
|
||||
"composes"?: string;
|
||||
"composes-why"?: string;
|
||||
"filters"?: Record<string, unknown>;
|
||||
"profile"?: Record<string, unknown>;
|
||||
/** the node's record: its tunnel and certificate */
|
||||
"record"?: Record<string, unknown>;
|
||||
"record"?: NodeRecord;
|
||||
"sealed"?: string[];
|
||||
"sealed-at"?: Record<string, unknown>;
|
||||
"sealed-at"?: Record<string, string>;
|
||||
"strays"?: Record<string, unknown>;
|
||||
"v": number;
|
||||
"windows"?: Record<string, unknown>;
|
||||
@@ -757,28 +1063,42 @@ export interface HaveByNodeNodeValue {
|
||||
|
||||
/** is one value of the state composed under the key <node>.<module>.<fingerprint>. */
|
||||
export interface ComposedByNodeModuleFingerprintValue {
|
||||
"Data"?: boolean;
|
||||
"FP": string;
|
||||
"Filled"?: string[];
|
||||
"Module": string;
|
||||
"Node": string;
|
||||
/** the node's own adoption, identities, groups, libraries and provisioner account */
|
||||
"Own"?: Record<string, unknown>;
|
||||
/** the module's plan */
|
||||
"Plan"?: Record<string, unknown>;
|
||||
/** why the composition was refused */
|
||||
"Refused"?: string;
|
||||
"Resources"?: Record<string, unknown>[];
|
||||
"V"?: number;
|
||||
/** the module declares data */
|
||||
"data"?: boolean;
|
||||
/** the files the provisioner fills */
|
||||
"filled_files"?: string[];
|
||||
"fp": string;
|
||||
"module": string;
|
||||
"node": string;
|
||||
/** the module's whole provisioning plan, catalogue.Plan, kept whole: it is the manifest layer's type */
|
||||
"plan"?: Record<string, unknown>;
|
||||
/** why the module cannot be composed at this fingerprint */
|
||||
"refused"?: string;
|
||||
/** the declaration resources, each saying its module */
|
||||
"resources": Record<string, unknown>[];
|
||||
"v": number;
|
||||
}
|
||||
|
||||
/** is one value of the state composed under the key <node>.node. */
|
||||
export interface ComposedByNodeNodeValue {
|
||||
/** the module declares data */
|
||||
"data"?: boolean;
|
||||
/** the files the provisioner fills */
|
||||
"filled_files"?: string[];
|
||||
"node": string;
|
||||
"own"?: NodeOwn;
|
||||
/** the declaration resources, each saying its module */
|
||||
"resources": Record<string, unknown>[];
|
||||
"v": number;
|
||||
}
|
||||
|
||||
/** is one value of the state data under the key <node>.<module>. */
|
||||
export interface DataByNodeModuleValue {
|
||||
"digest": string;
|
||||
"items": Record<string, unknown>[];
|
||||
"items": PlacedDataItem[];
|
||||
"module": string;
|
||||
"node": string;
|
||||
"v"?: number;
|
||||
"v": number;
|
||||
}
|
||||
|
||||
export interface PackagesByNodeValuePackagesItem {
|
||||
@@ -795,16 +1115,17 @@ export interface PackagesByNodeValue {
|
||||
|
||||
/** is one value of the state health under the key <node>. */
|
||||
export interface HealthByNodeValue {
|
||||
/** when */
|
||||
"at": string;
|
||||
"contract"?: number;
|
||||
"fallback"?: Record<string, unknown>;
|
||||
"found"?: Record<string, unknown>[];
|
||||
"network"?: Record<string, unknown>;
|
||||
"fallback"?: LoginFallback;
|
||||
"found"?: NodeDirectory[];
|
||||
"network"?: NetworkHealth;
|
||||
"node": string;
|
||||
"peers"?: Record<string, unknown>[];
|
||||
"relogin"?: Record<string, unknown>[];
|
||||
"root"?: Record<string, unknown>[];
|
||||
"units"?: Record<string, unknown>;
|
||||
"peers"?: PeerSeen[];
|
||||
"relogin"?: NodeAccount[];
|
||||
"root"?: RootAccountVerdict[];
|
||||
"units"?: UnitsHealth;
|
||||
"v": number;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user