72 lines
3.2 KiB
Go
72 lines
3.2 KiB
Go
package resolution
|
|
|
|
import (
|
|
mcat "git.novox.be/novox/mesh-sdk/go/catalogue"
|
|
)
|
|
|
|
// defaultSeats is the set the mesh ships with — the seed for the control plane's seat table and the fallback when it has none
|
|
// (novox/hq ADR 0122). It is mesh-contracts' generated list, as mesh-sdk compiles it, taken whole: the node-engine keeps no copy of
|
|
// a seat's verbs or events (design 26, ADR 0608 §5; issue 1966 ENG-3).
|
|
var defaultSeats = mcat.DefaultSeats()
|
|
|
|
// seats is the working set the lookups read. It starts as the compiled defaults and is replaced by
|
|
// what the control plane loaded from its store (novox/hq ADR 0122), so a change to the set is a
|
|
// change to data, not to this code.
|
|
var seats = defaultSeats
|
|
|
|
// configInput is the schema of mesh-config's verb: a value of the key's own type (a number for a number, never its
|
|
// text), and a limit that is a number; every other argument a string.
|
|
func configInput() map[string]any {
|
|
in := schema(map[string]string{"action": "list (when not given), set, clear or history",
|
|
"key": "the config key", "value": "for set: the value, of the key's type",
|
|
"module": "a module: its own value, with node", "node": "a node",
|
|
"why": "for set and clear: why", "by": "who gave the value at the controller's terminal",
|
|
"limit": "for history: at most this many, newest"}, nil)
|
|
props := in["properties"].(map[string]any)
|
|
props["value"] = map[string]any{"description": "for set: the value, of the key's type: a number, a string, " +
|
|
"a boolean, or for a trusted key an object or a list"}
|
|
props["limit"] = map[string]any{"type": "number", "description": "for history: at most this many, newest"}
|
|
return in
|
|
}
|
|
|
|
func providesAt(m mcat.Manifest, provision, scope string) bool {
|
|
for _, o := range m.Provides {
|
|
if o.Name == provision && o.At() == scope {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// HolderAmong is which of several providers of a provision holds the seat that delivers it.
|
|
//
|
|
// Found by the (node, module) pair, because a provider is identified by both (novox/hq to-be 23):
|
|
// two modules on one node could both provide a provision, and only the one holding the seat
|
|
// answers for it. Nothing when no seat delivers the provision, when nobody holds
|
|
// it, or when the holder is not among the providers offered.
|
|
//
|
|
// **The first holder in the providers' own order** (novox/hq ADR 0223). A replicated seat has
|
|
// several, and the answer must not depend on the order the mesh happened to resolve its machines
|
|
// in: the providers come sorted by machine, so every consumer is bound to the same one. A seat with
|
|
// one holder gets the same answer as before.
|
|
func HolderAmong(provision string, providers []mcat.Provider, held []mcat.Held) (mcat.Provider, bool) {
|
|
seat, delivered := mcat.SeatDelivering(provision)
|
|
if !delivered {
|
|
return mcat.Provider{}, false
|
|
}
|
|
for _, p := range providers {
|
|
for _, h := range held {
|
|
// Resolve the held claim to a seat rather than comparing names, so a record naming a
|
|
// seat's former name still matches it after a rename (novox/hq ADR 0122).
|
|
hs, ok := mcat.SeatNamed(h.Claim)
|
|
if !ok || hs.Name != seat.Name || h.Scope != seat.Scope {
|
|
continue
|
|
}
|
|
if p.Node == h.Node && p.Module == h.Module {
|
|
return p, true
|
|
}
|
|
}
|
|
}
|
|
return mcat.Provider{}, false
|
|
}
|