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:
+430
-60
@@ -185,6 +185,37 @@ func DecodeComposedByNodeModuleFingerprintValue(raw []byte) (ComposedByNodeModul
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// ComposedByNodeNodeKey is the key of one value of the state composed under the form "<node>.node".
|
||||
func ComposedByNodeNodeKey(node string) string { return node + ".node" }
|
||||
|
||||
// ParseComposedByNodeNodeKey reads the parts of a key of the form "<node>.node", in the order of the form; the last result is false for a key of another form.
|
||||
func ParseComposedByNodeNodeKey(key string) (string, bool) {
|
||||
rest := key
|
||||
v0, after0, found0 := strings.Cut(rest, ".node")
|
||||
if !found0 || v0 == "" {
|
||||
return "", false
|
||||
}
|
||||
rest = after0
|
||||
if rest != "" {
|
||||
return "", false
|
||||
}
|
||||
return v0, true
|
||||
}
|
||||
|
||||
// DecodeComposedByNodeNodeValue reads one value of the state composed under the form "<node>.node", refusing a field ComposedByNodeNodeValue does not know and any text after the value.
|
||||
func DecodeComposedByNodeNodeValue(raw []byte) (ComposedByNodeNodeValue, error) {
|
||||
var v ComposedByNodeNodeValue
|
||||
dec := json.NewDecoder(bytes.NewReader(raw))
|
||||
dec.DisallowUnknownFields()
|
||||
if err := dec.Decode(&v); err != nil {
|
||||
return v, err
|
||||
}
|
||||
if dec.More() {
|
||||
return v, errors.New("text after the value")
|
||||
}
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// DataByNodeModuleKey is the key of one value of the state data under the form "<node>.<module>".
|
||||
func DataByNodeModuleKey(node, module string) string { return node + "." + module }
|
||||
|
||||
@@ -314,6 +345,17 @@ func DecodeFindingsByKeyValue(raw []byte) (FindingsByKeyValue, error) {
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// AccountsHanded is the hashes of the users of the list, sealed to the vault.
|
||||
type AccountsHanded struct {
|
||||
// when
|
||||
At string `json:"at"`
|
||||
Box SealedBox `json:"box"`
|
||||
From string `json:"from"`
|
||||
// the fingerprint of the vault's key
|
||||
To string `json:"to"`
|
||||
Users int64 `json:"users"`
|
||||
}
|
||||
|
||||
// Act is one act asked through the seat, as acts reads it (ADR 0563 §9).
|
||||
type Act struct {
|
||||
// the act: hand-over, access-act, judge-directories or setuid-search
|
||||
@@ -395,6 +437,14 @@ type Acts struct {
|
||||
Node string `json:"node"`
|
||||
}
|
||||
|
||||
// Adoption is the node is adopted and which of its modules are taken.
|
||||
type Adoption struct {
|
||||
// the modules taken
|
||||
Taken []string `json:"taken"`
|
||||
// by module, the resources left untaken
|
||||
Untaken map[string][]string `json:"untaken,omitempty"`
|
||||
}
|
||||
|
||||
// Asked is the answer of an act the operator is asked.
|
||||
type Asked struct {
|
||||
// the ask's id: acts shows where it stands
|
||||
@@ -405,6 +455,112 @@ type Asked struct {
|
||||
Says string `json:"says"`
|
||||
}
|
||||
|
||||
// AttachedNetwork is a network attached to a link.
|
||||
type AttachedNetwork struct {
|
||||
Link string `json:"link"`
|
||||
Network string `json:"network"`
|
||||
}
|
||||
|
||||
// CandidateAdded is a module the candidate adds.
|
||||
type CandidateAdded struct {
|
||||
Composed string `json:"composed,omitempty"`
|
||||
Module string `json:"module"`
|
||||
Unissued []string `json:"unissued,omitempty"`
|
||||
}
|
||||
|
||||
// CandidateAnswer is the node's answer to one placement candidate naming it.
|
||||
type CandidateAnswer struct {
|
||||
Added []CandidateAdded `json:"added,omitempty"`
|
||||
Differs []CandidateDiffers `json:"differs,omitempty"`
|
||||
Held []CandidateRefusal `json:"held,omitempty"`
|
||||
Note string `json:"note,omitempty"`
|
||||
Proposal string `json:"proposal"`
|
||||
Refusals []CandidateRefusal `json:"refusals,omitempty"`
|
||||
// why the node cannot compose with the candidate at all
|
||||
Refused string `json:"refused,omitempty"`
|
||||
// modules the candidate removes
|
||||
Removed []string `json:"removed,omitempty"`
|
||||
Returns string `json:"returns,omitempty"`
|
||||
Revision int64 `json:"revision"`
|
||||
// modules whose composition is the one running
|
||||
Same []string `json:"same,omitempty"`
|
||||
ValuesDiffer int64 `json:"values_differ,omitempty"`
|
||||
// same, differs or refused
|
||||
Verdict string `json:"verdict"`
|
||||
}
|
||||
|
||||
// The values of CandidateAnswer's verdict.
|
||||
const (
|
||||
CandidateAnswerVerdictSame = "same"
|
||||
CandidateAnswerVerdictDiffers = "differs"
|
||||
CandidateAnswerVerdictRefused = "refused"
|
||||
)
|
||||
|
||||
// CandidateBodies is the bodies of one resource that differ.
|
||||
type CandidateBodies struct {
|
||||
Composed string `json:"composed,omitempty"`
|
||||
ID string `json:"id"`
|
||||
Paths []string `json:"paths,omitempty"`
|
||||
Running string `json:"running,omitempty"`
|
||||
Why string `json:"why"`
|
||||
}
|
||||
|
||||
// CandidateDiffers is a module whose composition with the candidate differs from the one running.
|
||||
type CandidateDiffers struct {
|
||||
Bodies []CandidateBodies `json:"bodies,omitempty"`
|
||||
Composed string `json:"composed,omitempty"`
|
||||
Module string `json:"module"`
|
||||
Resource string `json:"resource,omitempty"`
|
||||
Running string `json:"running,omitempty"`
|
||||
Why string `json:"why"`
|
||||
}
|
||||
|
||||
// CandidateRefusal is a module refused or held with the candidate.
|
||||
type CandidateRefusal struct {
|
||||
Module string `json:"module"`
|
||||
Today string `json:"today,omitempty"`
|
||||
Why string `json:"why"`
|
||||
}
|
||||
|
||||
// DeclaredGroup is a group.
|
||||
type DeclaredGroup struct {
|
||||
Gid int64 `json:"gid"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// DeclaredIdentity is the identity of a module assigned to the node.
|
||||
type DeclaredIdentity struct {
|
||||
Gid int64 `json:"gid"`
|
||||
Groups []int64 `json:"groups,omitempty"`
|
||||
Module string `json:"module"`
|
||||
Name string `json:"name"`
|
||||
Runner string `json:"runner,omitempty"`
|
||||
Uid int64 `json:"uid"`
|
||||
}
|
||||
|
||||
// DeclaredLibrary is a library the node is reached by.
|
||||
type DeclaredLibrary struct {
|
||||
Gid int64 `json:"gid"`
|
||||
Group string `json:"group"`
|
||||
Home bool `json:"home"`
|
||||
Library string `json:"library"`
|
||||
Paths []string `json:"paths,omitempty"`
|
||||
Root string `json:"root"`
|
||||
Runner string `json:"runner,omitempty"`
|
||||
Taken bool `json:"taken,omitempty"`
|
||||
}
|
||||
|
||||
// FailedUnit is a unit that failed.
|
||||
type FailedUnit struct {
|
||||
Load string `json:"load,omitempty"`
|
||||
Resource string `json:"resource,omitempty"`
|
||||
Result string `json:"result,omitempty"`
|
||||
Scope string `json:"scope"`
|
||||
// since when
|
||||
Since string `json:"since"`
|
||||
Unit string `json:"unit"`
|
||||
}
|
||||
|
||||
// FindingAction is one answer the operator may give from a notification.
|
||||
type FindingAction struct {
|
||||
Arguments map[string]string `json:"arguments,omitempty"`
|
||||
@@ -439,6 +595,15 @@ type FindingSubject struct {
|
||||
Scope string `json:"scope"`
|
||||
}
|
||||
|
||||
// LoginFallback is a login that fell back to another node.
|
||||
type LoginFallback struct {
|
||||
// when
|
||||
At string `json:"at"`
|
||||
From string `json:"from"`
|
||||
Node string `json:"node"`
|
||||
Why string `json:"why"`
|
||||
}
|
||||
|
||||
// ManifestReadsChanged is what a node-engine says when what it reads changed or its node returned (ADR 0618 §4).
|
||||
type ManifestReadsChanged struct {
|
||||
// when it says it, RFC 3339
|
||||
@@ -482,6 +647,115 @@ const (
|
||||
ModuleStateHeld = "held"
|
||||
)
|
||||
|
||||
// NetworkHealth is the node's network.
|
||||
type NetworkHealth struct {
|
||||
Parts []NetworkPart `json:"parts"`
|
||||
// since when
|
||||
Since string `json:"since"`
|
||||
// running, degraded or unknown
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
// NetworkPart is one part of the node's network.
|
||||
type NetworkPart struct {
|
||||
Owner string `json:"owner,omitempty"`
|
||||
Part string `json:"part"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
Said string `json:"said,omitempty"`
|
||||
// since when
|
||||
Since string `json:"since"`
|
||||
State string `json:"state"`
|
||||
Streak int64 `json:"streak,omitempty"`
|
||||
Targets []string `json:"targets,omitempty"`
|
||||
Toward []string `json:"toward,omitempty"`
|
||||
Writer string `json:"writer,omitempty"`
|
||||
}
|
||||
|
||||
// NodeAccount is an account the node needs to log in again.
|
||||
type NodeAccount struct {
|
||||
Account string `json:"account"`
|
||||
Module string `json:"module,omitempty"`
|
||||
Reason string `json:"reason"`
|
||||
Resource string `json:"resource,omitempty"`
|
||||
// since when
|
||||
Since string `json:"since"`
|
||||
}
|
||||
|
||||
// NodeDirectory is a directory found where the node expected none.
|
||||
type NodeDirectory struct {
|
||||
Module string `json:"module"`
|
||||
Path string `json:"path"`
|
||||
Reason string `json:"reason"`
|
||||
Resource string `json:"resource"`
|
||||
// since when
|
||||
Since string `json:"since"`
|
||||
}
|
||||
|
||||
// NodeOwn is what a node's own composition carries beside its resources.
|
||||
type NodeOwn struct {
|
||||
Adoption *Adoption `json:"adoption,omitempty"`
|
||||
Groups []DeclaredGroup `json:"groups,omitempty"`
|
||||
Identities []DeclaredIdentity `json:"identities,omitempty"`
|
||||
Libraries []DeclaredLibrary `json:"libraries,omitempty"`
|
||||
// the account the provisioner's client runs as on the node
|
||||
ProvisionerAccount string `json:"provisioner_account,omitempty"`
|
||||
}
|
||||
|
||||
// NodeRecord is what the machine observes of itself, for every node and composing part to read.
|
||||
type NodeRecord struct {
|
||||
Authority string `json:"authority,omitempty"`
|
||||
Capabilities []string `json:"capabilities,omitempty"`
|
||||
Certificate string `json:"certificate,omitempty"`
|
||||
Contract int64 `json:"contract,omitempty"`
|
||||
ManifestReads []string `json:"manifest-reads,omitempty"`
|
||||
Networks []AttachedNetwork `json:"networks,omitempty"`
|
||||
NetworksSaid bool `json:"networks-said,omitempty"`
|
||||
Node string `json:"node"`
|
||||
OutwardLinks []string `json:"outward-links,omitempty"`
|
||||
SealingKey string `json:"sealing-key,omitempty"`
|
||||
ServingKey string `json:"serving-key,omitempty"`
|
||||
Trusts []string `json:"trusts,omitempty"`
|
||||
TunnelKey string `json:"tunnel-key,omitempty"`
|
||||
V int64 `json:"v"`
|
||||
}
|
||||
|
||||
// PeerSeen is a tunnel peer and whether it is seen.
|
||||
type PeerSeen struct {
|
||||
Addresses []string `json:"addresses,omitempty"`
|
||||
Key string `json:"key"`
|
||||
Seen bool `json:"seen"`
|
||||
}
|
||||
|
||||
// PlacedDataItem is one data item a module declares, as placed on a node.
|
||||
type PlacedDataItem struct {
|
||||
Class string `json:"class"`
|
||||
// the path whose snapshot keeps it, empty when it is not backed up
|
||||
CoveredBy string `json:"covered_by,omitempty"`
|
||||
Item string `json:"item"`
|
||||
// walk, dataset or shallow
|
||||
Measure string `json:"measure,omitempty"`
|
||||
Module string `json:"module"`
|
||||
// the item's place on the node
|
||||
Path string `json:"path"`
|
||||
// backup, redundancy, both or none
|
||||
Protection string `json:"protection,omitempty"`
|
||||
}
|
||||
|
||||
// PullWait is the pull from a store a failed apply waits on.
|
||||
type PullWait struct {
|
||||
// when the pull began
|
||||
Began string `json:"began"`
|
||||
// that seat's holder, whose settling the apply waits for
|
||||
Holder string `json:"holder"`
|
||||
Image string `json:"image"`
|
||||
// what triggered the last try again, in words
|
||||
Retried string `json:"retried,omitempty"`
|
||||
// when the apply was last tried again
|
||||
RetriedAt string `json:"retried-at,omitempty"`
|
||||
// the seat the pull came through
|
||||
Seat string `json:"seat,omitempty"`
|
||||
}
|
||||
|
||||
// Revision is one revision of a composition key.
|
||||
type Revision struct {
|
||||
// its digest
|
||||
@@ -498,6 +772,17 @@ type Revision struct {
|
||||
Revision int64 `json:"revision,omitempty"`
|
||||
}
|
||||
|
||||
// RootAccountVerdict is the engine's verdict of whether an account's resource is root-free, as the node's health lists it.
|
||||
type RootAccountVerdict struct {
|
||||
Account string `json:"account"`
|
||||
Module string `json:"module"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
Resource string `json:"resource"`
|
||||
// since when
|
||||
Since string `json:"since"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
// RootVerdict is the engine's root-free verdict (ADR 0563 §6).
|
||||
type RootVerdict struct {
|
||||
// the machine is root-free
|
||||
@@ -518,6 +803,15 @@ type Said struct {
|
||||
Said string `json:"said"`
|
||||
}
|
||||
|
||||
// SealedBox is a value sealed to a key.
|
||||
type SealedBox struct {
|
||||
Ct string `json:"ct"`
|
||||
Eph string `json:"eph"`
|
||||
Iv string `json:"iv"`
|
||||
Tag string `json:"tag"`
|
||||
V int64 `json:"v"`
|
||||
}
|
||||
|
||||
// SeatListStatus is a type of the contract.
|
||||
type SeatListStatus struct {
|
||||
// the seat mesh-catalog has answered
|
||||
@@ -554,6 +848,37 @@ const (
|
||||
SeatListHeldSourceBootstrap = "bootstrap"
|
||||
)
|
||||
|
||||
// UnitsHealth is the node's units.
|
||||
type UnitsHealth struct {
|
||||
Away []string `json:"away,omitempty"`
|
||||
Failed []FailedUnit `json:"failed"`
|
||||
State string `json:"state"`
|
||||
Unread []string `json:"unread,omitempty"`
|
||||
}
|
||||
|
||||
// UserListWritten is the bus's user list as the engine of the bus node wrote it to the bus module's file.
|
||||
type UserListWritten struct {
|
||||
// when
|
||||
At string `json:"at"`
|
||||
// the digest of the file on the machine after the write
|
||||
Digest string `json:"digest,omitempty"`
|
||||
// why a write failed
|
||||
Error string `json:"error,omitempty"`
|
||||
// which list the node follows now
|
||||
Follows string `json:"follows,omitempty"`
|
||||
Handed *AccountsHanded `json:"handed,omitempty"`
|
||||
// the bus node's sealing key, its public half
|
||||
Key string `json:"key,omitempty"`
|
||||
Revision int64 `json:"revision"`
|
||||
// the key the list was taken from
|
||||
Source string `json:"source"`
|
||||
// why the bus node does not watch the grants part's key now
|
||||
Unwatched string `json:"unwatched,omitempty"`
|
||||
Users int64 `json:"users"`
|
||||
// the digest of the list the source holds, sha256:<hex>
|
||||
Wanted string `json:"wanted"`
|
||||
}
|
||||
|
||||
// HandOverInput is what hand-over takes.
|
||||
type HandOverInput struct {
|
||||
// the directory's absolute path, as the engine states it
|
||||
@@ -905,75 +1230,119 @@ type ManifestReadsChangedEvent = ManifestReadsChanged
|
||||
|
||||
// HaveByNodeModuleValue is one value of the state have under the key <node>.<module>.
|
||||
type HaveByNodeModuleValue struct {
|
||||
Build string `json:"build,omitempty"`
|
||||
BuildAlone bool `json:"build-alone,omitempty"`
|
||||
// the composition's digest
|
||||
Build string `json:"build,omitempty"`
|
||||
// the move changes the build alone
|
||||
BuildAlone bool `json:"build-alone,omitempty"`
|
||||
// the digest of the composition the node runs
|
||||
Composed string `json:"composed,omitempty"`
|
||||
Detail string `json:"detail,omitempty"`
|
||||
// the fingerprint held
|
||||
Fp string `json:"fp,omitempty"`
|
||||
// the accounts handed
|
||||
Handed map[string]any `json:"handed,omitempty"`
|
||||
// how it is
|
||||
Health string `json:"health"`
|
||||
Judgement string `json:"judgement,omitempty"`
|
||||
Kept []string `json:"kept,omitempty"`
|
||||
Fp string `json:"fp,omitempty"`
|
||||
Handed *AccountsHanded `json:"handed,omitempty"`
|
||||
// what the module's own check says
|
||||
Health string `json:"health"`
|
||||
// in phase waiting-yes, the judgement of the move
|
||||
Judgement string `json:"judgement,omitempty"`
|
||||
// what the node keeps of the module as it runs
|
||||
Kept []string `json:"kept,omitempty"`
|
||||
// how far it has come
|
||||
Phase string `json:"phase"`
|
||||
// a pull the engine waits for
|
||||
PullWait map[string]any `json:"pull-wait,omitempty"`
|
||||
Sealed []string `json:"sealed,omitempty"`
|
||||
SealedAt map[string]any `json:"sealed-at,omitempty"`
|
||||
// the user list written
|
||||
UserList map[string]any `json:"user-list,omitempty"`
|
||||
V int64 `json:"v"`
|
||||
// what it waits for
|
||||
Phase string `json:"phase"`
|
||||
PullWait *PullWait `json:"pull-wait,omitempty"`
|
||||
// each value sealed to the node's key
|
||||
Sealed []string `json:"sealed,omitempty"`
|
||||
// the sealed values by slot
|
||||
SealedAt map[string]string `json:"sealed-at,omitempty"`
|
||||
UserList *UserListWritten `json:"user-list,omitempty"`
|
||||
V int64 `json:"v"`
|
||||
// in phase waiting-yes, the digest of the composition that waits
|
||||
Waits string `json:"waits,omitempty"`
|
||||
}
|
||||
|
||||
// The values of HaveByNodeModuleValue's health.
|
||||
const (
|
||||
HaveByNodeModuleValueHealthOk = "ok"
|
||||
HaveByNodeModuleValueHealthFailed = "failed"
|
||||
HaveByNodeModuleValueHealthWaits = "waits"
|
||||
HaveByNodeModuleValueHealthUnknown = "unknown"
|
||||
)
|
||||
|
||||
// The values of HaveByNodeModuleValue's judgement.
|
||||
const (
|
||||
HaveByNodeModuleValueJudgementRecreates = "recreates"
|
||||
HaveByNodeModuleValueJudgementMovesData = "moves-data"
|
||||
HaveByNodeModuleValueJudgementCannotJudge = "cannot-judge"
|
||||
)
|
||||
|
||||
// The values of HaveByNodeModuleValue's phase.
|
||||
const (
|
||||
HaveByNodeModuleValuePhaseBackingUp = "backing-up"
|
||||
HaveByNodeModuleValuePhaseApplying = "applying"
|
||||
HaveByNodeModuleValuePhaseChecking = "checking"
|
||||
HaveByNodeModuleValuePhaseRunning = "running"
|
||||
HaveByNodeModuleValuePhaseFailed = "failed"
|
||||
HaveByNodeModuleValuePhaseRemoved = "removed"
|
||||
HaveByNodeModuleValuePhaseHeld = "held"
|
||||
HaveByNodeModuleValuePhaseWaitingYes = "waiting-yes"
|
||||
)
|
||||
|
||||
// HaveByNodeNodeValue is one value of the state have under the key <node>.node.
|
||||
type HaveByNodeNodeValue struct {
|
||||
Busy map[string]any `json:"busy,omitempty"`
|
||||
Candidates map[string]map[string]any `json:"candidates,omitempty"`
|
||||
Composed string `json:"composed,omitempty"`
|
||||
// own, or the controller's
|
||||
Composes string `json:"composes,omitempty"`
|
||||
ComposesWhy string `json:"composes-why,omitempty"`
|
||||
Filters map[string]any `json:"filters,omitempty"`
|
||||
Profile map[string]any `json:"profile,omitempty"`
|
||||
// the node's record: its tunnel and certificate
|
||||
Record map[string]any `json:"record,omitempty"`
|
||||
Sealed []string `json:"sealed,omitempty"`
|
||||
SealedAt map[string]any `json:"sealed-at,omitempty"`
|
||||
Strays map[string]any `json:"strays,omitempty"`
|
||||
V int64 `json:"v"`
|
||||
Windows map[string]any `json:"windows,omitempty"`
|
||||
Busy map[string]any `json:"busy,omitempty"`
|
||||
// the node's answer to each placement candidate naming it, by proposal id
|
||||
Candidates map[string]CandidateAnswer `json:"candidates,omitempty"`
|
||||
// the digest of the node's own composition it runs
|
||||
Composed string `json:"composed,omitempty"`
|
||||
// own, or none (empty)
|
||||
Composes string `json:"composes,omitempty"`
|
||||
ComposesWhy string `json:"composes-why,omitempty"`
|
||||
Filters map[string]any `json:"filters,omitempty"`
|
||||
Profile map[string]any `json:"profile,omitempty"`
|
||||
Record *NodeRecord `json:"record,omitempty"`
|
||||
Sealed []string `json:"sealed,omitempty"`
|
||||
SealedAt map[string]string `json:"sealed-at,omitempty"`
|
||||
Strays map[string]any `json:"strays,omitempty"`
|
||||
V int64 `json:"v"`
|
||||
Windows map[string]any `json:"windows,omitempty"`
|
||||
}
|
||||
|
||||
// ComposedByNodeModuleFingerprintValue is one value of the state composed under the key <node>.<module>.<fingerprint>.
|
||||
type ComposedByNodeModuleFingerprintValue struct {
|
||||
Data bool `json:"Data,omitempty"`
|
||||
FP string `json:"FP"`
|
||||
Filled []string `json:"Filled,omitempty"`
|
||||
Module string `json:"Module"`
|
||||
Node string `json:"Node"`
|
||||
// the node's own adoption, identities, groups, libraries and provisioner account
|
||||
Own map[string]any `json:"Own,omitempty"`
|
||||
// the module's plan
|
||||
Plan map[string]any `json:"Plan,omitempty"`
|
||||
// why the composition was refused
|
||||
Refused string `json:"Refused,omitempty"`
|
||||
Resources []map[string]any `json:"Resources,omitempty"`
|
||||
V int64 `json:"V,omitempty"`
|
||||
// the module declares data
|
||||
Data bool `json:"data,omitempty"`
|
||||
// the files the provisioner fills
|
||||
FilledFiles []string `json:"filled_files,omitempty"`
|
||||
Fp string `json:"fp"`
|
||||
Module string `json:"module"`
|
||||
Node string `json:"node"`
|
||||
// the module's whole provisioning plan, catalogue.Plan, kept whole: it is the manifest layer's type
|
||||
Plan map[string]any `json:"plan,omitempty"`
|
||||
// why the module cannot be composed at this fingerprint
|
||||
Refused string `json:"refused,omitempty"`
|
||||
// the declaration resources, each saying its module
|
||||
Resources []map[string]any `json:"resources"`
|
||||
V int64 `json:"v"`
|
||||
}
|
||||
|
||||
// ComposedByNodeNodeValue is one value of the state composed under the key <node>.node.
|
||||
type ComposedByNodeNodeValue struct {
|
||||
// the module declares data
|
||||
Data bool `json:"data,omitempty"`
|
||||
// the files the provisioner fills
|
||||
FilledFiles []string `json:"filled_files,omitempty"`
|
||||
Node string `json:"node"`
|
||||
Own *NodeOwn `json:"own,omitempty"`
|
||||
// the declaration resources, each saying its module
|
||||
Resources []map[string]any `json:"resources"`
|
||||
V int64 `json:"v"`
|
||||
}
|
||||
|
||||
// DataByNodeModuleValue is one value of the state data under the key <node>.<module>.
|
||||
type DataByNodeModuleValue struct {
|
||||
Digest string `json:"digest"`
|
||||
Items []map[string]any `json:"items"`
|
||||
Items []PlacedDataItem `json:"items"`
|
||||
Module string `json:"module"`
|
||||
Node string `json:"node"`
|
||||
V int64 `json:"v,omitempty"`
|
||||
V int64 `json:"v"`
|
||||
}
|
||||
|
||||
// PackagesByNodeValuePackagesItem is a type of the contract.
|
||||
@@ -991,17 +1360,18 @@ type PackagesByNodeValue struct {
|
||||
|
||||
// HealthByNodeValue is one value of the state health under the key <node>.
|
||||
type HealthByNodeValue struct {
|
||||
At string `json:"at"`
|
||||
Contract int64 `json:"contract,omitempty"`
|
||||
Fallback map[string]any `json:"fallback,omitempty"`
|
||||
Found []map[string]any `json:"found,omitempty"`
|
||||
Network map[string]any `json:"network,omitempty"`
|
||||
Node string `json:"node"`
|
||||
Peers []map[string]any `json:"peers,omitempty"`
|
||||
Relogin []map[string]any `json:"relogin,omitempty"`
|
||||
Root []map[string]any `json:"root,omitempty"`
|
||||
Units map[string]any `json:"units,omitempty"`
|
||||
V int64 `json:"v"`
|
||||
// when
|
||||
At string `json:"at"`
|
||||
Contract int64 `json:"contract,omitempty"`
|
||||
Fallback *LoginFallback `json:"fallback,omitempty"`
|
||||
Found []NodeDirectory `json:"found,omitempty"`
|
||||
Network *NetworkHealth `json:"network,omitempty"`
|
||||
Node string `json:"node"`
|
||||
Peers []PeerSeen `json:"peers,omitempty"`
|
||||
Relogin []NodeAccount `json:"relogin,omitempty"`
|
||||
Root []RootAccountVerdict `json:"root,omitempty"`
|
||||
Units *UnitsHealth `json:"units,omitempty"`
|
||||
V int64 `json:"v"`
|
||||
}
|
||||
|
||||
// FindingsByKeyValue is one value of the state findings under the key <key>.
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+994
-51
File diff suppressed because it is too large
Load Diff
@@ -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