Revert "Merge pull request 'Revert L3: its node-engine removed every held module on novox, the bus server among them (issue 774)' (#557) from revert/774-l3 into main"
This reverts commit030f9ee4e7, reversing changes made to1555241393.
This commit is contained in:
@@ -0,0 +1,10 @@
|
||||
# The modules of this catalogue that still read the controller's assignments (mesh-controller.assignments), each with
|
||||
# why. The check of this directory (noplacement) refuses any other module that reads them, and an entry here whose module no longer
|
||||
# does: the list only shrinks, and it is empty before the controller's lease is written to a holder that is no
|
||||
# controller (novox/hq ADR 0549 §3, §6; issue 774).
|
||||
gitea the provisioner's plan of a module (go/provider) rides only in an assignment's value; its home after the lease is issue 774's provisioner-plan subtask
|
||||
keycloak the provisioner's plan of a module (go/provider), as gitea
|
||||
mesh-config unioned with the placement while both stand, as the assigner and the vault do (ADR 0549 §5); its reading placement alone is a step before the lease write
|
||||
mesh-vault the provisioner's plan, which only an assignment's value carries; its home is issue 774's provisioner-plan subtask
|
||||
postgres the provisioner's plan of a module (go/provider), as gitea
|
||||
route-adapter the provisioner's plan of a module (go/provider), as gitea
|
||||
@@ -1,3 +1,7 @@
|
||||
module git.novox.be/novox/mesh-catalog/checks/noplacement
|
||||
|
||||
go 1.22
|
||||
|
||||
require git.novox.be/novox/mesh-catalog/checks/trunk v0.0.0
|
||||
|
||||
replace git.novox.be/novox/mesh-catalog/checks/trunk => ../trunk
|
||||
|
||||
@@ -8,7 +8,13 @@
|
||||
// 2. a `particulars` file at the root (the mesh's node names come from the checker's run, §16);
|
||||
//
|
||||
// 3. a manifest naming a state, stream, event or bucket of the indexer's placement (`mesh-delivery-indexer.placement…`
|
||||
// or `mesh-delivery-indexer_placement…`) in any string value, such as `reads`.
|
||||
// or `mesh-delivery-indexer_placement…`) in any string value, such as `reads`;
|
||||
//
|
||||
// 4. a manifest, other than mesh-controller's, that reads the controller's assignments (`mesh-controller.assignments`):
|
||||
// every reader takes placement from the seat mesh-placement (novox/hq ADR 0549 §3, ADR 0567), and the lease write is
|
||||
// refused while one still reads them (ADR 0549 §6; issue 774). The modules that still read them for what the
|
||||
// placement does not carry are named in checks/noplacement/assignments-readers, each with why; that list only
|
||||
// shrinks: an entry whose module no longer reads them is refused too.
|
||||
//
|
||||
// go run . <catalogue root>
|
||||
//
|
||||
@@ -55,9 +61,74 @@ func Findings(root string) ([]string, error) {
|
||||
out = append(out, fmt.Sprintf("%s: names %q, which the indexer no longer keeps; placement is the seat mesh-placement's (novox/hq ADR 0567 §12)", module, s))
|
||||
}
|
||||
}
|
||||
readers, err := assignmentsReaders(root)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, readers...)
|
||||
sort.Strings(out)
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// AssignmentsRead is the controller's assignments as a manifest reads them, and Allowed the file, relative to the
|
||||
// catalogue's root, that names the modules still reading them: `<module> <why>` per line, `#` a comment.
|
||||
const (
|
||||
AssignmentsRead = "mesh-controller.assignments"
|
||||
Allowed = "checks/noplacement/assignments-readers"
|
||||
)
|
||||
|
||||
// assignmentsReaders is every finding on the reads of the controller's assignments: a module other than the controller
|
||||
// reading them that Allowed does not name, and a module Allowed names that no longer reads them (issue 774).
|
||||
func assignmentsReaders(root string) ([]string, error) {
|
||||
allowed := map[string]bool{}
|
||||
raw, err := os.ReadFile(filepath.Join(root, Allowed))
|
||||
if err != nil && !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
for _, line := range strings.Split(string(raw), "\n") {
|
||||
if f := strings.Fields(line); len(f) > 0 && !strings.HasPrefix(f[0], "#") {
|
||||
allowed[f[0]] = true
|
||||
}
|
||||
}
|
||||
manifests, err := filepath.Glob(filepath.Join(root, "modules", "*", "module.json"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var found []string
|
||||
reads := map[string]bool{}
|
||||
for _, path := range manifests {
|
||||
raw, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var m struct {
|
||||
Module string `json:"module"`
|
||||
Reads []string `json:"reads"`
|
||||
}
|
||||
if json.Unmarshal(raw, &m) != nil || m.Module == "mesh-controller" {
|
||||
continue // a manifest that does not read is the manifest checks' to refuse
|
||||
}
|
||||
for _, r := range m.Reads {
|
||||
if strings.TrimSpace(r) != AssignmentsRead {
|
||||
continue
|
||||
}
|
||||
reads[m.Module] = true
|
||||
if !allowed[m.Module] {
|
||||
found = append(found, fmt.Sprintf("%s reads %s: read where modules run from mesh-delivery-assigner.placement, "+
|
||||
"the seat mesh-placement's (novox/hq ADR 0549 §3, ADR 0567); the lease write is refused while a module reads "+
|
||||
"the assignments (ADR 0549 §6)", m.Module, AssignmentsRead))
|
||||
}
|
||||
}
|
||||
}
|
||||
for module := range allowed {
|
||||
if !reads[module] {
|
||||
found = append(found, fmt.Sprintf("%s names %s, which no longer reads %s: take it off the list, which only shrinks",
|
||||
Allowed, module, AssignmentsRead))
|
||||
}
|
||||
}
|
||||
return found, nil
|
||||
}
|
||||
|
||||
// named collects the strings of a decoded manifest that start with one of the Prefixes.
|
||||
func named(v any, into []string) []string {
|
||||
switch v := v.(type) {
|
||||
@@ -95,5 +166,5 @@ func main() {
|
||||
if len(found) > 0 {
|
||||
os.Exit(1)
|
||||
}
|
||||
fmt.Println("no placement directory, and no manifest reads the indexer's placement")
|
||||
fmt.Println("no placement directory, no manifest reads the indexer's placement, and only the modules listed read the controller's assignments")
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"git.novox.be/novox/mesh-catalog/checks/trunk"
|
||||
)
|
||||
|
||||
func TestFindingsRefuseWhatThePlacementPathLeft(t *testing.T) {
|
||||
@@ -13,12 +15,18 @@ func TestFindingsRefuseWhatThePlacementPathLeft(t *testing.T) {
|
||||
files map[string]string
|
||||
want string // empty: clean
|
||||
}{
|
||||
{"clean", map[string]string{"modules/a/module.json": `{"module":"a","reads":["mesh-controller.assignments"]}`}, ""},
|
||||
{"clean", map[string]string{"modules/a/module.json": `{"module":"a","reads":["mesh-delivery-assigner.placement"]}`}, ""},
|
||||
{"a placement directory", map[string]string{"placement/ace.json": `{}`}, "placement: the repository holds no placement"},
|
||||
{"a particulars file", map[string]string{"particulars": "ace\n"}, "particulars: the repository lists no node names"},
|
||||
{"a read of the indexer's placement", map[string]string{"modules/a/module.json": `{"module":"a","reads":["mesh-delivery-indexer.placement"]}`}, `a: names "mesh-delivery-indexer.placement"`},
|
||||
{"a read of its candidates", map[string]string{"modules/b/module.json": `{"module":"b","reads":["mesh-delivery-indexer.placement-candidates"]}`}, "placement-candidates"},
|
||||
{"its event", map[string]string{"modules/c/module.json": `{"module":"c","on":[{"event":"mesh-delivery-indexer.placement-changed"}]}`}, "placement-changed"},
|
||||
// Issue 774 (ADR 0549 §3, §6): a reader of the controller's assignments is refused unless the list names it, the
|
||||
// controller's own manifest is not judged, and a name on the list whose module no longer reads them is refused.
|
||||
{"an unlisted reader of the assignments", map[string]string{"modules/r/module.json": `{"module":"r","reads":["mesh-controller.assignments"]}`}, "r reads mesh-controller.assignments"},
|
||||
{"a listed reader and the controller", map[string]string{"modules/l/module.json": `{"module":"l","reads":["mesh-controller.assignments"]}`,
|
||||
"modules/mesh-controller/module.json": `{"module":"mesh-controller","reads":["mesh-controller.assignments"]}`, Allowed: "# why\nl its plan\n"}, ""},
|
||||
{"a listed module that reads them no more", map[string]string{Allowed: "gone no longer reads\n"}, "names gone, which no longer reads"},
|
||||
{"the seat's own state is allowed", map[string]string{"modules/d/module.json": `{"module":"d","reads":["mesh-placement.placement"]}`}, ""},
|
||||
} {
|
||||
t.Run(row.name, func(t *testing.T) {
|
||||
@@ -52,4 +60,29 @@ func TestTheCatalogueHoldsNoPlacementOfTheRepositoryPath(t *testing.T) {
|
||||
for _, f := range got {
|
||||
t.Error(f)
|
||||
}
|
||||
// Issue 774 (ADR 0549 §3, §6; the comparison of novox/hq ADR 0529 clause 2): the list of modules still reading the
|
||||
// controller's assignments gains none the trunk's copy at the merge base does not hold. Its first copy gains nothing.
|
||||
path, ok := trunk.Copy(t, Allowed)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
names := func(path string) map[string]bool {
|
||||
raw, err := os.ReadFile(path)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
out := map[string]bool{}
|
||||
for _, line := range strings.Split(string(raw), "\n") {
|
||||
if f := strings.Fields(line); len(f) > 0 && !strings.HasPrefix(f[0], "#") {
|
||||
out[f[0]] = true
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
base := names(path)
|
||||
for module := range names(filepath.Join("..", "..", Allowed)) {
|
||||
if !base[module] {
|
||||
t.Errorf("%s gains %s, which the trunk's copy does not hold: the list only shrinks", Allowed, module)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user