95 lines
7.5 KiB
Markdown
95 lines
7.5 KiB
Markdown
# mesh-config
|
|
|
|
Holds the `mesh-config` seat: the owner of every config value (novox/hq ADR 0348 §9, design 57 K3). Go, one
|
|
binary (`cmd/mesh-config`), served by a runtime of its own on its own bus account (`runs-as`), so that its
|
|
account alone writes its buckets.
|
|
|
|
## What it keeps
|
|
|
|
- `mesh-config_values`: each value set, keyed by its level: `mesh.<key>` (mesh config), `node.<node>.<key>`
|
|
(node config) and `module.<node>.<module>.<key>` (a module's own value on one node), each with who set it,
|
|
through which account, why and when.
|
|
- `mesh-config_resolved`: each assigned module's value for each key it declares on its node, keyed
|
|
`<node>.<module>.<key>`, with its source: `default`, `mesh`, `node`, `module`, or `unset` for a required value
|
|
nothing sets.
|
|
- `mesh-config_predefined`: the list of predefined keys, published from the indexer's list (the controller's mirror is no longer read, issue 774), the newest trunk
|
|
build winning. A newer list dropping a key that still holds a
|
|
value at the mesh or a node is withheld, and every listing says why, until that value is cleared.
|
|
- `mesh-config_proposals`: each value proposed for the operator's Approve, whole, with the value stored at its level
|
|
when it was proposed (what the operator is shown the change against), who proposed it, why, and what came of it.
|
|
- the log `history`: every set, clear and move of resolved values, with the proven caller and why.
|
|
|
|
## How a value resolves
|
|
|
|
For every module the seat mesh-placement places on a node (`mesh-delivery-assigner.placement`), from the module's
|
|
own manifests as the delivery built them, never from the controller (issue 1953): the trunk's, which the indexer's
|
|
`modules.<module>` names in its manifests by digest (`mesh-delivery-indexer.modules`, `.manifests`), with the build the
|
|
node's want names (`mesh-delivery-assigner.wants`, the builder's `mesh-delivery-builder.builds` naming its manifest)
|
|
laid over it key by key on that node. So a module from its own repository resolves as a catalogue module does. A placed
|
|
module none of whose manifests can be read is listed under `unresolved` with why and said in the log, and keeps the
|
|
values last resolved for it. Then: the manifest's default; mesh config for the predefined key the value falls back
|
|
to; node config for that key on the node; the module's own value on that node, the most specific winning. A value
|
|
naming no predefined key resolves from its default and the module's own value only (ADR 0348 §2). It resolves at
|
|
start, whenever a placement, a want or a trunk module moves, and every five minutes, writing only the values that moved.
|
|
|
|
## The verb
|
|
|
|
`mesh-config.config` with `action` `list` (the default), `set`, `clear` or `history`, narrowed by `module`, `node`
|
|
and `key`. A set or a clear names one level (no module and no node for mesh config, a node for node config, both
|
|
for a module's own value), needs `why`, refuses a key the module or the predefined list does not declare (naming
|
|
the declared keys), validates the value, writes it and the resolved values it moves, keeps it in the history and
|
|
the controller's hand-act log, raises `config-changed`, and answers with each module on each node whose value
|
|
moved. It opens no walk. A trusted value is taken only from the controller, which carries it from its terminal and
|
|
names who gave it in `by`, or on the operator's Approve of a proposal.
|
|
|
|
## Proposing a value (ADR 0348 §8, design 57 K4)
|
|
|
|
`action` `propose` (with `value`, or `clear`) judges the value as a set would, keeps it in `mesh-config_proposals`,
|
|
and asks the operator under mesh-config's own name on the `operator-channel` seat (its own grant, from `uses`, and
|
|
its own cap of three open asks; the same change twice is refused, and a newer proposal for the same level and key
|
|
replaces the older). The ask says the level, the key and the value, exact where who answers is proven, and that,
|
|
approved, it takes effect at once on every node it reaches; Approve and Decline are both at the level approve and
|
|
each binds the proposal's level, key, value and the value it was shown against. On the answer mesh-config reads
|
|
the router's own record of its ask and holds the warrant to the ask composed again from the proposal; it refuses,
|
|
and sets nothing, when the proposal or the value stored at the level changed since. An Approve that holds sets the
|
|
value as a set does, keeps who approved it beside the value (`approved`), and asks the controller to record the
|
|
warrant in its hand-act log. A Decline, an expiry or the router's refusal sets nothing. `action` `proposals` lists
|
|
them, newest first; with `proposal`, one read whole, with whether the router's ask is the one composed from it.
|
|
|
|
## A value renamed, a value no longer read (design 32, novox/hq ADR 0609)
|
|
|
|
- A declaration's `renamed-from` moves the value set under the old name to the new one on each node, with its trust (it
|
|
moves whole, and a trusted new name over a value set without the Approve is refused), saying `renamed`
|
|
(module, from, to, at) once. A **rename window** opens per node and keeps the old name answering the new value in
|
|
`mesh-config_resolved` until that node's node-engine runs a build that reads the new name: judged at start, on the
|
|
status view's `delivered`, and for a returning node-engine on the node-engine seat's `manifest-reads-changed` after
|
|
`manifest-reads` answers (one that does not serve it states nothing, and its window stays open). State `renames`.
|
|
- The seat verb `renames` answers the open renames and the nodes holding each open (the checker asks it); the tools
|
|
`config_renames` (all, with the closed windows), `config_rename_again` (move by hand after a refusal) and
|
|
`config_rename_close` (drop a node by hand, a hand act).
|
|
- On the indexer's `manifest-accepted` it asks the indexer's `indexer_config_readers`; an indexer that does not serve
|
|
it answers "not known" and nothing retires. A value (or secret) nobody reads is **retiring** once no node runs a
|
|
build that reads it: `retiring` is said and the operator is asked once; the value is removed only on the Approve
|
|
(a secret through the seat mesh-vault's `retire`, with a hand act naming node, module, name and ask), `retired`
|
|
said per node. State `retiring`; the tool `config_retiring` lists, asks again and cancels.
|
|
- Findings (state `findings`, read by the condition keeper): `rename-refused`, `rename-window-held` and
|
|
`retirement-held` (seven days, naming the node), `retiring-unanswered` (asked twice).
|
|
- The events `renamed`, `retiring` and `retired` are carried by the stream `config-events`, kept seven days.
|
|
|
|
## Files it does not know
|
|
|
|
Each directory or archive this module declares says how it treats a file it did not write (ADR 0422, ADR 0416).
|
|
|
|
- `${dir:state}`: everything in it is the program's; the mesh moves nothing out (ADR 0422 §2).
|
|
|
|
## The switch from the controller's records (novox/hq ADR 0565 §3, §4, §13)
|
|
|
|
- `mesh-config_declared`: each placed module's declarations at the trunk, with the manifest and commit they come
|
|
from, written only when they differ.
|
|
- Its own sources hold always (novox/hq ADR 0590): declarations from the modules' own manifests, the list from the
|
|
indexer's `predefined`, pull requests' config from the indexer's `config-candidates`. The controller's
|
|
`pull-declares`, the take-over, compare and hand-back went with the controller. `config_declared` and
|
|
`config_resync` read and write again what it keeps.
|
|
- A trusted value is set only through propose and the operator's Approve: no controller relay is trusted (issue 1126).
|
|
- Its sets, clears and warrants are recorded in the hand-act log of the seat `mesh-hand-acts` alone.
|