133 lines
6.0 KiB
Go
133 lines
6.0 KiB
Go
package delivery
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// **The control records' layouts, out of the controller** (novox/hq ADR 0565 clauses 2, 3 and 6; issue 1953 L5-S2): what
|
|
// the indexer keeps of the catalogue's predefined list and of each open pull request's config declarations, which
|
|
// mesh-config reads in place of the controller's mirrors and `pull-declares`; and each node's declared packages, which
|
|
// its engine writes in place of the controller's mirror.
|
|
|
|
// The indexer's two states (clause 2).
|
|
const (
|
|
// IndexerPredefinedState holds one key, PredefinedListKey: the catalogue's predefined.json at the newest merge taken.
|
|
IndexerPredefinedState = "predefined"
|
|
PredefinedListKey = "list"
|
|
// IndexerConfigCandidatesState holds one key per open pull request (ConfigCandidateKey).
|
|
IndexerConfigCandidatesState = "config-candidates"
|
|
)
|
|
|
|
// PredefinedKept is the indexer's key `predefined.list`: the list whole, as predefined.json holds it, with the merge it
|
|
// was read at. A merge older than the one the key names never replaces it (ADR 0348 §7).
|
|
type PredefinedKept struct {
|
|
V int `json:"v"`
|
|
Commit string `json:"commit"`
|
|
At time.Time `json:"at"`
|
|
List json.RawMessage `json:"list"`
|
|
}
|
|
|
|
// ConfigDeclaration is one config key a module's manifest declares, in the layout of the controller's declared-config
|
|
// mirror (mesh-controller internal/inventory DeclaredMirrored) unchanged, so mesh-config reads the indexer's as it read
|
|
// the mirror's.
|
|
type ConfigDeclaration struct {
|
|
Kind string `json:"kind"`
|
|
Default json.RawMessage `json:"default"`
|
|
Why string `json:"why"`
|
|
Type string `json:"type,omitempty"`
|
|
Description string `json:"description,omitempty"`
|
|
Enum json.RawMessage `json:"enum,omitempty"`
|
|
Minimum *float64 `json:"minimum,omitempty"`
|
|
Maximum *float64 `json:"maximum,omitempty"`
|
|
Pattern string `json:"pattern,omitempty"`
|
|
Trusted bool `json:"trusted,omitempty"`
|
|
Predefined string `json:"predefined,omitempty"`
|
|
Required bool `json:"required,omitempty"`
|
|
Runtime bool `json:"runtime,omitempty"`
|
|
}
|
|
|
|
// ConfigCandidate is one open pull request's key of `config-candidates`: its head, and per module the config
|
|
// declarations the head's manifests add or change against the trunk's, an empty set when none. Written at each new
|
|
// head and each trunk merge that changes a module it names; deleted when the pull request merges or closes.
|
|
type ConfigCandidate struct {
|
|
V int `json:"v"`
|
|
Pull string `json:"pull"`
|
|
Head string `json:"head"`
|
|
Declares map[string]map[string]ConfigDeclaration `json:"declares"`
|
|
At time.Time `json:"at"`
|
|
}
|
|
|
|
// ConfigCandidateKey is a pull request's key, `owner/repository#number` with `/` and `#` as dots, the form mesh-config
|
|
// keeps a pull request's values under.
|
|
func ConfigCandidateKey(pull string) (string, error) {
|
|
owner, rest, ok := strings.Cut(strings.TrimSpace(pull), "/")
|
|
repo, number, ok2 := strings.Cut(rest, "#")
|
|
if !ok || !ok2 || owner == "" || repo == "" || number == "" || strings.ContainsAny(owner+repo+number, ".*> ") {
|
|
return "", fmt.Errorf("delivery: %q is not a pull request, owner/repository#number", pull)
|
|
}
|
|
return owner + "." + repo + "." + number, nil
|
|
}
|
|
|
|
// The node-engine's packages (clause 6): its state `packages`, one key, the node's name, written by that node's engine
|
|
// alone.
|
|
const EnginePackagesState = "packages"
|
|
|
|
// PackageDeclared is one package a node's modules declare, the controller's declared-packages mirror's entry unchanged
|
|
// (mesh-controller internal/inventory PackageDeclared): its name, the modules that declare it that way, sorted, and
|
|
// whether they declare it absent.
|
|
type PackageDeclared struct {
|
|
Package string `json:"package"`
|
|
Modules []string `json:"modules"`
|
|
Absent bool `json:"absent"`
|
|
}
|
|
|
|
// DeclaredPackages is one node's key of `packages`, the mirror's value unchanged: its packages sorted by name, absent
|
|
// after present. Fixed fields and no time, so the same declaration is the same bytes (ADR 0289 §1).
|
|
type DeclaredPackages struct {
|
|
Node string `json:"node"`
|
|
Packages []PackageDeclared `json:"packages"`
|
|
}
|
|
|
|
// mesh-config's state of the approved values held for a pull request (novox/hq ADR 0565 clause 5): read by the checker
|
|
// and the assigner's composition check, which lay a pull request's own held values over its modules' values.
|
|
const (
|
|
MeshConfigKeptState = "kept"
|
|
MeshConfigKeptRead = "mesh-config." + MeshConfigKeptState
|
|
)
|
|
|
|
// KeptValue is one approved held value, mesh-config's layout unchanged (modules/mesh-config pulls.go): kept apart from
|
|
// the values mesh-config resolves, laid only over the composition of its own pull request at its head.
|
|
type KeptValue struct {
|
|
Pull string `json:"pull"`
|
|
Head string `json:"head"`
|
|
Digest string `json:"declaration"`
|
|
Node string `json:"node"`
|
|
Module string `json:"module"`
|
|
Key string `json:"key"`
|
|
// Value is the value held, as the operator approved it.
|
|
Value json.RawMessage `json:"value"`
|
|
By string `json:"by"`
|
|
Via string `json:"via"`
|
|
Why string `json:"why"`
|
|
// Approved is who approved it, as the proposal kept it.
|
|
Approved string `json:"approved"`
|
|
Proposal string `json:"proposal"`
|
|
At time.Time `json:"at"`
|
|
}
|
|
|
|
// HeldValueKey is a held value's key in `kept`: the pull request's key (ConfigCandidateKey's form), the node, the module and
|
|
// the config key, joined by dots, as mesh-config writes it.
|
|
func HeldValueKey(pull, node, module, key string) (string, error) {
|
|
p, err := ConfigCandidateKey(pull)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
return p + "." + node + "." + module + "." + key, nil
|
|
}
|
|
|
|
// The assigner's state of a person's upgrade policy, one key per module (clause 7; catalogue.PersonPolicy).
|
|
const AssignerPoliciesState = "policies"
|