R6: the controller writes signed per-node compositions and their digests; plans, pushes and their verbs go (issue 1945) #457

Merged
mesh-tools merged 67 commits from feat/r6 into main 2026-10-24 23:00:31 +00:00
Showing only changes of commit 35e330c7f0 - Show all commits
@@ -6,6 +6,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"net/url"
"os"
"path/filepath"
@@ -225,10 +226,41 @@ func (m *servedMesh) waitFor(t *testing.T, done chan error, node, key string, af
}
time.Sleep(200 * time.Millisecond)
}
t.Fatalf("%s in %s was not written within a minute", key, bucket)
t.Fatalf("%s in %s was not written within a minute; %s", key, bucket, m.whatIsThere(t, node))
return 0
}
// whatIsThere says, for a failure, what the node's bucket holds, the ids its own composition carries and the
// fingerprints the controller has registered.
func (m *servedMesh) whatIsThere(t *testing.T, node string) string {
t.Helper()
bucket, _ := sdkdelivery.ComposedBucketFor(node)
out := "keys:"
kv, err := m.controller.KeyValue(context.Background(), bucket)
if err != nil {
return out + " " + err.Error()
}
lister, err := kv.ListKeys(context.Background())
if err == nil {
for k := range lister.Keys() {
out += " " + k
}
}
own, _ := sdkdelivery.ComposedNodeKey(node)
if e, err := kv.Get(context.Background(), own); err == nil {
if c, err := sdkdelivery.DecodeComposed(e.Value()); err == nil {
out += "; its own carries:"
for _, r := range c.Resources {
var head struct{ ID string }
_ = json.Unmarshal(r, &head)
out += " " + head.ID
}
}
}
fps, err := currentFingerprints(context.Background(), m.open.inventory)
return out + fmt.Sprintf("; fingerprints registered: %v (%v)", fps, err)
}
// revisions are a node's composition keys and their revisions.
func (m *servedMesh) revisions(t *testing.T, node string) map[string]uint64 {
t.Helper()