mesh-config reads the placement, wants, haves, modules, manifests, predefined list and config candidates through the seats' types and clients, the builder's builds through its published package; the kept value is its own layout (B5f; ADR 0634 §1, §4; issue 1966)
Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
@@ -4,13 +4,16 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
assignerclient "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
||||
meshseat "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner"
|
||||
catalogclient "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
||||
catalog "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
|
||||
builds "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
)
|
||||
|
||||
// memStore is the bus as mesh-config reaches it, in memory: its states and the mirrors it reads, its history log,
|
||||
@@ -167,36 +170,36 @@ func (m *memStore) place(t *testing.T, node, module string, on bool) {
|
||||
e, _ := m.Get(PlacementRead, k)
|
||||
keys[k] = e.Value
|
||||
}
|
||||
all, err := delivery.PlacementsOf(keys)
|
||||
all, err := assignerclient.PlacementsOf(keys)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
p := all[node]
|
||||
p.Node = node
|
||||
var kept []delivery.PlacedModule
|
||||
var kept []meshseat.PlacedModule
|
||||
for _, x := range p.Modules {
|
||||
if x.Module != module {
|
||||
kept = append(kept, x)
|
||||
}
|
||||
}
|
||||
if on {
|
||||
kept = append(kept, delivery.PlacedModule{Module: module})
|
||||
kept = append(kept, meshseat.PlacedModule{Module: module})
|
||||
}
|
||||
p.Modules = kept
|
||||
for _, k := range m.keysOf(PlacementRead) {
|
||||
if n, _, _, err := delivery.ParsePlacementKey(k); err == nil && n == node {
|
||||
if n, _, _, err := assignerclient.ParseKey(k); err == nil && n == node {
|
||||
_ = m.Delete(PlacementRead, k)
|
||||
}
|
||||
}
|
||||
if node == "ace" {
|
||||
raw, err := delivery.EncodePlacement(p)
|
||||
raw, err := assignerclient.EncodePlacement(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_ = m.Put(PlacementRead, "placement.ace", json.RawMessage(raw))
|
||||
return
|
||||
}
|
||||
values, err := delivery.PlacementValues(p)
|
||||
values, err := assignerclient.PlacementValues(p)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -218,8 +221,8 @@ func (m *memStore) manifest(t *testing.T, module, raw string) string {
|
||||
if !json.Valid([]byte(raw)) {
|
||||
t.Fatalf("not JSON: %s", raw)
|
||||
}
|
||||
digest := delivery.ManifestDigest([]byte(raw))
|
||||
value, err := delivery.EncodeManifest(delivery.Manifest{Module: module, JSON: raw})
|
||||
digest := catalogclient.ManifestDigest([]byte(raw))
|
||||
value, err := catalogclient.EncodeManifest(catalog.ManifestsByDigestValue{Module: module, Manifest: raw})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -239,7 +242,7 @@ func (m *memStore) declare(t *testing.T, module, raw string) {
|
||||
func (m *memStore) want(t *testing.T, node, module, fp, raw string) {
|
||||
t.Helper()
|
||||
digest := m.manifest(t, module, raw)
|
||||
key, err := delivery.BuilderBuildKey(module, fp)
|
||||
key, err := builds.BuilderBuildKey(module, fp)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -6,10 +6,10 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
engineclient "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
|
||||
"strings"
|
||||
|
||||
"git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
)
|
||||
|
||||
// The addresses asked.
|
||||
@@ -46,7 +46,7 @@ func (d toolDelivery) Have(node, module string) (string, bool, error) {
|
||||
if err := json.Unmarshal(answer, &kept); err != nil {
|
||||
return "", false, fmt.Errorf("node_haves answered what is not its listing: %s", output)
|
||||
}
|
||||
key, err := delivery.HaveKey(node, module)
|
||||
key, err := engineclient.HaveKey(node, module)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
@@ -54,11 +54,11 @@ func (d toolDelivery) Have(node, module string) (string, bool, error) {
|
||||
if !ok {
|
||||
return "", false, nil
|
||||
}
|
||||
var h delivery.Have
|
||||
if err := json.Unmarshal(have, &h); err != nil {
|
||||
h, err := engineclient.DecodeHave(have)
|
||||
if err != nil {
|
||||
return "", false, fmt.Errorf("the have of %s on %s is not readable: %w", module, node, err)
|
||||
}
|
||||
return h.FP, true, nil
|
||||
return h.Fp, true, nil
|
||||
}
|
||||
|
||||
// Reads asks a node's node-engine what it reads; an answer means it states it.
|
||||
|
||||
@@ -19,11 +19,12 @@ func TestEveryStateAndActHasItsTool(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var m struct {
|
||||
State []string `json:"state"`
|
||||
Logs []string `json:"logs"`
|
||||
Reads []string `json:"reads"`
|
||||
Tools []string `json:"tools"`
|
||||
Claims []struct {
|
||||
State []string `json:"state"`
|
||||
Packages map[string]string `json:"packages"`
|
||||
Logs []string `json:"logs"`
|
||||
Reads []string `json:"reads"`
|
||||
Tools []string `json:"tools"`
|
||||
Claims []struct {
|
||||
Name string `json:"name"`
|
||||
Serves []string `json:"serves"`
|
||||
} `json:"claims"`
|
||||
@@ -31,6 +32,10 @@ func TestEveryStateAndActHasItsTool(t *testing.T) {
|
||||
if err := json.Unmarshal(raw, &m); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// The builder's keys are read through its published package, taken by its series (ADR 0634 §1).
|
||||
if m.Packages["builds"] != "0.1" {
|
||||
t.Errorf("packages %v: want builds of series 0.1", m.Packages)
|
||||
}
|
||||
via := map[string]string{
|
||||
ValuesState: "config list", ResolvedState: "config list", PredefinedState: "config list",
|
||||
ProposalsState: "config proposals", PullsState: "config list", KeptState: "config list", HistoryLog: "config history",
|
||||
|
||||
@@ -15,12 +15,12 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
catalog "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
stdio "git.novox.be/novox/mesh-sdk/go"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
)
|
||||
@@ -41,12 +41,12 @@ const (
|
||||
// followed is each state read through its owner: the `<owner>.<state>` name this module's code uses, the owner, its
|
||||
// state and its tool.
|
||||
var followed = []struct{ Read, Owner, State, Tool string }{
|
||||
{ModulesRead, delivery.IndexerModule, "modules", IndexerModulesTool},
|
||||
{ManifestsRead, delivery.IndexerModule, "manifests", IndexerManifestsTool},
|
||||
{IndexerPredefinedRead, delivery.IndexerModule, delivery.IndexerPredefinedState, IndexerPredefTool},
|
||||
{CandidatesRead, delivery.IndexerModule, delivery.IndexerConfigCandidatesState, IndexerCandidatesTool},
|
||||
{PlacementRead, delivery.AssignerModule, "placement", AssignerPlacementTool},
|
||||
{WantsRead, delivery.AssignerModule, "wants", AssignerWantsTool},
|
||||
{ModulesRead, indexerModule, "modules", IndexerModulesTool},
|
||||
{ManifestsRead, indexerModule, "manifests", IndexerManifestsTool},
|
||||
{IndexerPredefinedRead, indexerModule, catalog.StatePredefined, IndexerPredefTool},
|
||||
{CandidatesRead, indexerModule, catalog.StateConfigCandidates, IndexerCandidatesTool},
|
||||
{PlacementRead, assignerModule, "placement", AssignerPlacementTool},
|
||||
{WantsRead, assignerModule, "wants", AssignerWantsTool},
|
||||
}
|
||||
|
||||
// ownerViews are the pictures, by the read name.
|
||||
|
||||
@@ -10,8 +10,6 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
)
|
||||
|
||||
// A config value held for the open pull request that introduces its key (novox/hq ADR 0502, issue 1826).
|
||||
@@ -63,16 +61,29 @@ type PullDecl struct {
|
||||
At time.Time `json:"at"`
|
||||
}
|
||||
|
||||
// KeptValue is an approved held value, kept apart from the values mesh-config resolves: mesh-sdk's layout, which the
|
||||
// checker and the assigner's composition check read (novox/hq ADR 0565 §5).
|
||||
type KeptValue = delivery.KeptValue
|
||||
// KeptValue is an approved held value, kept apart from the values mesh-config resolves, in this module's own layout
|
||||
// (the owner's: its state `kept`), which the checker and the assigner's composition check read (novox/hq ADR 0565 §5).
|
||||
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"`
|
||||
}
|
||||
|
||||
// keptKey is a held value's key in `kept` (delivery.HeldValueKey), the pull request's key form kept for one that is
|
||||
// not one.
|
||||
// keptKey is a held value's key in `kept`: the pull request's key form (pullKey), the node, the module and the config
|
||||
// key, joined by dots.
|
||||
func keptKey(pull, node, module, key string) string {
|
||||
if k, err := delivery.HeldValueKey(pull, node, module, key); err == nil {
|
||||
return k
|
||||
}
|
||||
return pullKey(pull) + "." + node + "." + module + "." + key
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
meshwants "git.novox.be/novox/mesh-contracts/placement/go/seats/meshwants"
|
||||
)
|
||||
|
||||
// The holders whose states this module reads, one constant each (a reader names its holder once; ADR 0634 §4).
|
||||
const (
|
||||
assignerModule = "mesh-delivery-assigner"
|
||||
indexerModule = "mesh-delivery-indexer"
|
||||
)
|
||||
|
||||
// parseWantKey reads a want's key, `want.<node>.<module>`; the want of a node's own and a held fingerprint's key are
|
||||
// not one.
|
||||
func parseWantKey(key string) (node, module string, err error) {
|
||||
node, module, ok := meshwants.ParseWantsByWantNodeModuleKey(key)
|
||||
if !ok {
|
||||
return "", "", fmt.Errorf("%q is not the key of a module's want on a node", key)
|
||||
}
|
||||
return node, module, nil
|
||||
}
|
||||
@@ -3,11 +3,12 @@ package main
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
meshseat "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner"
|
||||
catalog "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
|
||||
builds "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
)
|
||||
|
||||
// The four sources (novox/hq ADR 0348 §2, §3, §9): a module's value on a node resolves, the most specific winning,
|
||||
@@ -25,15 +26,15 @@ const (
|
||||
// PlacementRead is the seat mesh-module-assigner's state, held by the assigner (novox/hq ADR 0567 §1, §8): each
|
||||
// node's key `placement.<node>` with the modules placed there. It is the one source of which module runs where
|
||||
// (issue 1953): the controller's assignments are no longer read.
|
||||
PlacementRead = delivery.PlacementRead
|
||||
PlacementRead = (assignerModule + "." + meshseat.StatePlacement)
|
||||
// WantsRead is the assigner's wants, `want.<node>.<module>`: the build each node is to run (ADR 0539 §1).
|
||||
WantsRead = delivery.AssignerModule + ".wants"
|
||||
WantsRead = assignerModule + ".wants"
|
||||
// BuildsRead is the builder's builds, `<module>.<fingerprint hex>`: each build's manifest digest (ADR 0525).
|
||||
BuildsRead = delivery.BuilderModule + ".builds"
|
||||
BuildsRead = builds.BuilderModule + ".builds"
|
||||
// ModulesRead is the indexer's modules, `<module>`: the trunk's manifest digest of each module, from whichever
|
||||
// repository holds it (ADR 0437 §5, ADR 0478 §9); ManifestsRead its manifests by digest (ADR 0429 §16).
|
||||
ModulesRead = delivery.IndexerModule + ".modules"
|
||||
ManifestsRead = delivery.IndexerModule + ".manifests"
|
||||
ModulesRead = indexerModule + "." + catalog.StateModules
|
||||
ManifestsRead = indexerModule + "." + catalog.StateManifests
|
||||
|
||||
// HistoryLog is the log of every set and clear, with the proven caller and why (ADR 0348 §9).
|
||||
HistoryLog = "history"
|
||||
|
||||
@@ -4,10 +4,11 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
assignerclient "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
||||
catalogclient "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
||||
builds "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
)
|
||||
|
||||
// Reading the sources, writing the resolved values, and publishing the list of predefined keys.
|
||||
@@ -64,7 +65,7 @@ func (c *Config) sources() (Sources, error) {
|
||||
}
|
||||
|
||||
// readPlacement is every module the seat mesh-module-assigner places on a node (ADR 0567 §1, §9), from the state's keys in
|
||||
// either form: a node key and its module keys, or the form before, `placement.<node>` (delivery.PlacementsOf;
|
||||
// either form: a node key and its module keys, or the form before, `placement.<node>` (assignerclient.PlacementsOf;
|
||||
// research 072 row 37). By node in name order, each node's modules in the order its placement names them.
|
||||
func (c *Config) readPlacement(s *Sources) error {
|
||||
keys := map[string][]byte{}
|
||||
@@ -74,7 +75,7 @@ func (c *Config) readPlacement(s *Sources) error {
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
placements, err := delivery.PlacementsOf(keys)
|
||||
placements, err := assignerclient.PlacementsOf(keys)
|
||||
if err != nil {
|
||||
return fmt.Errorf("the placement is not read whole: %w", err)
|
||||
}
|
||||
@@ -84,7 +85,7 @@ func (c *Config) readPlacement(s *Sources) error {
|
||||
}
|
||||
sort.Strings(nodes)
|
||||
for _, node := range nodes {
|
||||
for _, module := range placements[node].Assigned() {
|
||||
for _, module := range assignerclient.Assigned(placements[node]) {
|
||||
s.Assignments = append(s.Assignments, Assignment{Node: node, Module: module})
|
||||
}
|
||||
}
|
||||
@@ -100,7 +101,7 @@ func (c *Config) readPlacement(s *Sources) error {
|
||||
func (c *Config) readDeclarations(s *Sources) error {
|
||||
wanted := map[string]string{} // <node>.<module> → the fingerprint its want names
|
||||
if err := c.each(WantsRead, func(key string, raw []byte) error {
|
||||
node, module, err := delivery.ParseWantKey(key)
|
||||
node, module, err := parseWantKey(key)
|
||||
if err != nil {
|
||||
return nil // a held key or a node's own want
|
||||
}
|
||||
@@ -188,7 +189,7 @@ func modulesOf(as []Assignment) []string {
|
||||
|
||||
// trunkDeclarations is a module's declarations at the trunk: the manifest the indexer's `modules.<module>` names.
|
||||
func (c *Config) trunkDeclarations(module string) (ModuleDeclarations, error) {
|
||||
key, err := delivery.ModulesKey(module)
|
||||
key, err := catalogclient.ModulesKey(module)
|
||||
if err != nil {
|
||||
return ModuleDeclarations{}, err
|
||||
}
|
||||
@@ -210,7 +211,7 @@ func (c *Config) trunkDeclarations(module string) (ModuleDeclarations, error) {
|
||||
|
||||
// builtDeclarations is a module's declarations at a build: the manifest the builder's done key names.
|
||||
func (c *Config) builtDeclarations(module, fp string) (ModuleDeclarations, error) {
|
||||
key, err := delivery.BuilderBuildKey(module, fp)
|
||||
key, err := builds.BuilderBuildKey(module, fp)
|
||||
if err != nil {
|
||||
return ModuleDeclarations{}, err
|
||||
}
|
||||
@@ -239,7 +240,7 @@ func (c *Config) manifestDeclarations(module, digest string) (ModuleDeclarations
|
||||
if ok {
|
||||
return d, nil
|
||||
}
|
||||
key, err := delivery.ManifestsKey(digest)
|
||||
key, err := catalogclient.ManifestsKey(digest)
|
||||
if err != nil {
|
||||
return ModuleDeclarations{}, err
|
||||
}
|
||||
|
||||
@@ -13,8 +13,9 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
catalogclient "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
||||
catalog "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
|
||||
"time"
|
||||
)
|
||||
|
||||
// The states and reads.
|
||||
@@ -23,8 +24,8 @@ const (
|
||||
DeclaredState = "declared"
|
||||
|
||||
// IndexerPredefinedRead and CandidatesRead are the indexer's states (ADR 0565 §2).
|
||||
IndexerPredefinedRead = delivery.IndexerModule + "." + delivery.IndexerPredefinedState
|
||||
CandidatesRead = delivery.IndexerModule + "." + delivery.IndexerConfigCandidatesState
|
||||
IndexerPredefinedRead = indexerModule + "." + catalog.StatePredefined
|
||||
CandidatesRead = indexerModule + "." + catalog.StateConfigCandidates
|
||||
)
|
||||
|
||||
// SourceIndexer is the one source of a pull request's config and of the predefined list: the indexer's.
|
||||
@@ -54,7 +55,7 @@ type DeclaredKept struct {
|
||||
|
||||
// trunkKept is a module's declarations at the trunk with the manifest they come from.
|
||||
func (c *Config) trunkKept(module string) (DeclaredKept, error) {
|
||||
key, err := delivery.ModulesKey(module)
|
||||
key, err := catalogclient.ModulesKey(module)
|
||||
if err != nil {
|
||||
return DeclaredKept{}, err
|
||||
}
|
||||
@@ -119,16 +120,20 @@ func (c *Config) writeDeclared(s Sources) ([]string, error) {
|
||||
|
||||
// indexerList is the indexer's predefined list as the mirror's list holds one: the keys, and the commit.
|
||||
func (c *Config) indexerList() (PredefinedList, bool, error) {
|
||||
e, err := c.Store.Get(IndexerPredefinedRead, delivery.PredefinedListKey)
|
||||
e, err := c.Store.Get(IndexerPredefinedRead, catalog.PredefinedByListKey())
|
||||
if err != nil || e == nil {
|
||||
return PredefinedList{}, false, err
|
||||
}
|
||||
var kept delivery.PredefinedKept
|
||||
var kept catalog.PredefinedByListValue
|
||||
if err := json.Unmarshal(e.Value, &kept); err != nil {
|
||||
return PredefinedList{}, false, fmt.Errorf("the indexer's predefined list is not one: %w", err)
|
||||
}
|
||||
list := PredefinedList{Keys: map[string]PredefinedKey{}, Commit: kept.Commit}
|
||||
if err := json.Unmarshal(kept.List, &list.Keys); err != nil {
|
||||
listed, err := json.Marshal(kept.List)
|
||||
if err == nil {
|
||||
err = json.Unmarshal(listed, &list.Keys)
|
||||
}
|
||||
if err != nil {
|
||||
return PredefinedList{}, false, fmt.Errorf("the indexer's predefined list is not predefined.json: %w", err)
|
||||
}
|
||||
return list, true, nil
|
||||
@@ -138,11 +143,11 @@ func (c *Config) indexerList() (PredefinedList, bool, error) {
|
||||
func (c *Config) candidates() (map[string]PullDecl, error) {
|
||||
out := map[string]PullDecl{}
|
||||
err := c.each(CandidatesRead, func(key string, raw []byte) error {
|
||||
var cand delivery.ConfigCandidate
|
||||
var cand catalog.ConfigCandidatesByPullValue
|
||||
if err := json.Unmarshal(raw, &cand); err != nil || cand.Pull == "" {
|
||||
return fmt.Errorf("the indexer's config candidate %s is not one", key)
|
||||
}
|
||||
p := PullDecl{Pull: cand.Pull, Head: cand.Head, Declares: map[string]map[string]Declaration{}, At: cand.At}
|
||||
p := PullDecl{Pull: cand.Pull, Head: cand.Head, Declares: map[string]map[string]Declaration{}, At: timeOf(cand.At)}
|
||||
for module, keys := range cand.Declares {
|
||||
raw, _ := json.Marshal(keys)
|
||||
var d map[string]Declaration
|
||||
@@ -242,3 +247,11 @@ func (c *Config) Resync() (any, error) {
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// timeOf is an optional time of a seat's value as a time, the zero time when it is absent.
|
||||
func timeOf(t *time.Time) time.Time {
|
||||
if t == nil {
|
||||
return time.Time{}
|
||||
}
|
||||
return *t
|
||||
}
|
||||
|
||||
@@ -2,10 +2,9 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
catalog "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
)
|
||||
|
||||
// The trunk's manifests aMesh declares.
|
||||
@@ -30,14 +29,14 @@ func anAgreeingMesh(t *testing.T) (*Config, *memStore, *standIn) {
|
||||
// indexerList is the indexer's `predefined.list` at a commit.
|
||||
func indexerList(t *testing.T, m *memStore, commit, list string) {
|
||||
t.Helper()
|
||||
raw, _ := json.Marshal(delivery.PredefinedKept{V: 1, Commit: commit, List: json.RawMessage(list)})
|
||||
m.mirror(t, IndexerPredefinedRead, delivery.PredefinedListKey, string(raw))
|
||||
raw, _ := json.Marshal(catalog.PredefinedByListValue{V: 1, Commit: commit, List: json.RawMessage(list)})
|
||||
m.mirror(t, IndexerPredefinedRead, catalog.PredefinedByListKey(), string(raw))
|
||||
}
|
||||
|
||||
// candidate is the indexer's config candidate of a pull request.
|
||||
func candidate(t *testing.T, m *memStore, pull, head, declares string) {
|
||||
t.Helper()
|
||||
key, err := delivery.ConfigCandidateKey(pull)
|
||||
key, err := catalog.ConfigCandidatesByPullKey(pullKey(pull)), error(nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -18,6 +18,13 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
engineclient "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient"
|
||||
nodeengine "git.novox.be/novox/mesh-contracts/go/seats/nodeengine"
|
||||
assignerclient "git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient"
|
||||
meshseat "git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner"
|
||||
catalogclient "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient"
|
||||
catalog "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog"
|
||||
builds "git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -35,7 +42,6 @@ import (
|
||||
meshconditions "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions"
|
||||
oc "git.novox.be/novox/mesh-contracts/operator-and-conversation/go/seats/operatorchannel"
|
||||
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||
"git.novox.be/novox/mesh-sdk/go/process"
|
||||
"git.novox.be/novox/mesh-sdk/go/testbus"
|
||||
"git.novox.be/novox/mesh-sdk/go/views"
|
||||
@@ -361,10 +367,10 @@ func (p *player) asked(key string, body json.RawMessage) any {
|
||||
case key == HavesAsk:
|
||||
var q struct{ Node, Module string }
|
||||
_ = json.Unmarshal(body, &q)
|
||||
hk, _ := delivery.HaveKey(q.Node, q.Module)
|
||||
hk, _ := engineclient.HaveKey(q.Node, q.Module)
|
||||
keys := map[string]any{}
|
||||
if fp, ok := p.haves[q.Node+"."+q.Module]; ok {
|
||||
keys[hk] = delivery.Have{V: delivery.Version, FP: fp, Phase: "applied", Health: "healthy"}
|
||||
keys[hk] = nodeengine.HaveByNodeModuleValue{V: 1, Fp: fp, Phase: "running", Health: "ok"}
|
||||
}
|
||||
return map[string]any{"keys": keys}
|
||||
case strings.HasPrefix(key, ManifestReadsAsk):
|
||||
@@ -562,8 +568,8 @@ func eventually(t *testing.T, what string, ok func() bool) {
|
||||
// manifestIn writes a module's manifest into the indexer's buckets as the indexer writes it, and names it as the trunk's.
|
||||
func (p *player) manifestIn(module, raw string) string {
|
||||
p.t.Helper()
|
||||
digest := delivery.ManifestDigest([]byte(raw))
|
||||
value, err := delivery.EncodeManifest(delivery.Manifest{Module: module, JSON: raw})
|
||||
digest := catalogclient.ManifestDigest([]byte(raw))
|
||||
value, err := catalogclient.EncodeManifest(catalog.ManifestsByDigestValue{Module: module, Manifest: raw})
|
||||
if err != nil {
|
||||
p.t.Fatal(err)
|
||||
}
|
||||
@@ -575,26 +581,28 @@ func (p *player) manifestIn(module, raw string) string {
|
||||
// buildIn writes a build of a module with a manifest, and the want that names it on a node.
|
||||
func (p *player) buildIn(node, module, fp, raw string) {
|
||||
p.t.Helper()
|
||||
digest := delivery.ManifestDigest([]byte(raw))
|
||||
value, _ := delivery.EncodeManifest(delivery.Manifest{Module: module, JSON: raw})
|
||||
digest := catalogclient.ManifestDigest([]byte(raw))
|
||||
value, _ := catalogclient.EncodeManifest(catalog.ManifestsByDigestValue{Module: module, Manifest: raw})
|
||||
p.put("mesh-delivery-indexer.manifests", digest, json.RawMessage(value))
|
||||
bk, _ := delivery.BuilderBuildKey(module, fp)
|
||||
bk, _ := builds.BuilderBuildKey(module, fp)
|
||||
p.put("mesh-delivery-builder.builds", bk, map[string]any{"v": 1, "state": "done", "manifest": digest})
|
||||
p.put("mesh-delivery-assigner.wants", "want."+node+"."+module, map[string]any{"v": 1, "fp": fp, "self": true})
|
||||
}
|
||||
|
||||
func (p *player) placed(node string, modules ...string) {
|
||||
p.t.Helper()
|
||||
pl := delivery.Placement{V: delivery.Version, Node: node}
|
||||
pl := meshseat.Placement{V: 1, Node: node}
|
||||
for _, m := range modules {
|
||||
pl.Modules = append(pl.Modules, delivery.PlacedModule{Module: m})
|
||||
pl.Modules = append(pl.Modules, meshseat.PlacedModule{Module: m})
|
||||
}
|
||||
values, err := delivery.PlacementValues(pl)
|
||||
// In the order the seat's holder writes them (module keys before the node key that names their digests), so a reader
|
||||
// never holds a node key whose module keys have not arrived.
|
||||
writes, err := assignerclient.NewKeys().Writes(pl.Node, &pl)
|
||||
if err != nil {
|
||||
p.t.Fatal(err)
|
||||
}
|
||||
for k, raw := range values {
|
||||
p.put("mesh-delivery-assigner.placement", k, json.RawMessage(raw))
|
||||
for _, w := range writes {
|
||||
p.put("mesh-delivery-assigner.placement", w.Key, json.RawMessage(w.Value))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,13 @@ module mesh-config
|
||||
go 1.26.0
|
||||
|
||||
require (
|
||||
git.novox.be/novox/mesh-contracts/placement/go/seats/meshwants v0.0.0-00010101000000-000000000000
|
||||
git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient v0.0.0-00010101000000-000000000000
|
||||
git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient v0.0.0-00010101000000-000000000000
|
||||
git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog v0.0.0-00010101000000-000000000000
|
||||
git.novox.be/novox/mesh-delivery/modules/mesh-delivery-builder/builds v0.0.0-00010101000000-000000000000
|
||||
git.novox.be/novox/mesh-contracts/placement/go/clients/meshmoduleassignerclient v0.0.0-00010101000000-000000000000
|
||||
git.novox.be/novox/mesh-contracts/placement/go/seats/meshmoduleassigner v0.0.0-00010101000000-000000000000
|
||||
git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshconditions v0.0.0-00010101000000-000000000000
|
||||
git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshconditionsclient v0.0.0-00010101000000-000000000000
|
||||
git.novox.be/novox/mesh-contracts/health-and-repair/go/clients/meshhandactsclient v0.0.0-00010101000000-000000000000
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
{
|
||||
"module": "mesh-config",
|
||||
"version": "1",
|
||||
"packages": {
|
||||
"builds": "0.1"
|
||||
},
|
||||
"runs-as": "mesh-config",
|
||||
"claims": [
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user