Grant the self-check its ban-list question, say a refusal at once, judge the engine by its delivered version (hq to-be 45 Phase 1)
Live on 2026-10-06, two of the first self-check's findings were its own:
- D8 asked every machine's node-intrusion-prevention.banned, and the
controller's grant did not name the subject: the bus refused it 24 times
and D8 timed out after thirty seconds instead of saying so. The verbs the
self-check asks are named in broker.VerbsTheSelfCheckAsks and granted
(mesh.seat.<seat>.tool.<verb>.*); each probe declares the seat verbs it
calls, askSeatTool refuses an undeclared one, and a test over the
registry fails a probe whose question the controller is not granted.
AskSeatTool now returns a refused publish at once ("the bus refused…")
instead of waiting out its timeout; D8 asks the machines in parallel.
- D10 read every machine as behind right after a push: a node-engine says
its version as the directory it is delivered into, the archive's digest
(31045596c83a, catalogue versionOf), and D10 compared that with the
build's commit (1545b00a). It now compares with the versions the
registered build is delivered as, and a hand-placed engine's commit.
This commit is contained in:
@@ -10,6 +10,7 @@ import (
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/nats-io/nats.go"
|
||||
@@ -576,9 +577,22 @@ func probeBans(ctx context.Context, d *doctor) ([]conditions.Observation, error)
|
||||
}
|
||||
sort.Strings(holders)
|
||||
var out []conditions.Observation
|
||||
// Every machine asked at once: one after another, four holders that each wait their bound
|
||||
// outlast the probe's thirty seconds, and the probe says nothing about any of them.
|
||||
answers := make([]json.RawMessage, len(holders))
|
||||
errs := make([]error, len(holders))
|
||||
var wg sync.WaitGroup
|
||||
for i, node := range holders {
|
||||
wg.Add(1)
|
||||
go func(i int, node string) {
|
||||
defer wg.Done()
|
||||
answers[i], errs[i] = askSeatTool(ctx, d.js.Conn(), "node-intrusion-prevention", "banned", node)
|
||||
}(i, node)
|
||||
}
|
||||
wg.Wait()
|
||||
var unasked []string
|
||||
for _, node := range holders {
|
||||
answer, err := askSeatTool(ctx, d.js.Conn(), "node-intrusion-prevention", "banned", node)
|
||||
for i, node := range holders {
|
||||
answer, err := answers[i], errs[i]
|
||||
if err != nil {
|
||||
unasked = append(unasked, err.Error())
|
||||
continue
|
||||
@@ -650,6 +664,11 @@ func probeCoreBuilds(ctx context.Context, d *doctor) ([]conditions.Observation,
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
shelf, err := inv.Catalogue(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hostVersions := deliveredVersions(shelf[hostModule])
|
||||
rolling := map[string]bool{}
|
||||
for _, p := range plans {
|
||||
for m := range p.Modules {
|
||||
@@ -675,9 +694,14 @@ func probeCoreBuilds(ctx context.Context, d *doctor) ([]conditions.Observation,
|
||||
continue // a machine not heard from is S1's
|
||||
}
|
||||
var behind []string
|
||||
host := current[hostModule].Commit
|
||||
if host != "" && n.HostVersion != "" && !rolling[hostModule] && !sameCommit(n.HostVersion, host) {
|
||||
behind = append(behind, fmt.Sprintf("the node-engine %s, the mesh holds %s", short(n.HostVersion), short(host)))
|
||||
// **A node-engine says its version as the directory it was delivered into** — its archive's
|
||||
// digest, twelve characters (catalogue.versionOf, ADR 0141) — not the commit it was built
|
||||
// from. Compared as a commit, every machine read as behind right after a push sent it the
|
||||
// current one (2026-10-06). An engine placed by hand reports its link-time stamp instead,
|
||||
// which a commit can match.
|
||||
if !rolling[hostModule] && engineBehind(n.HostVersion, hostVersions, current[hostModule].Commit) {
|
||||
behind = append(behind, fmt.Sprintf("the node-engine %s, the mesh holds %s (built from %s)",
|
||||
n.HostVersion, strings.Join(hostVersions, " or "), short(current[hostModule].Commit)))
|
||||
}
|
||||
assigned, err := inv.Assigned(ctx, n.Name)
|
||||
if err != nil {
|
||||
@@ -708,6 +732,34 @@ func probeCoreBuilds(ctx context.Context, d *doctor) ([]conditions.Observation,
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// deliveredVersions are the versions a module's registered build is delivered as: the last element
|
||||
// of every resource path under a `versions/` directory, which registration filled from the artifact's
|
||||
// digest (catalogue `${version}`). The node-engine names itself by that directory.
|
||||
func deliveredVersions(m catalogue.Manifest) []string {
|
||||
var out []string
|
||||
for _, r := range m.Resources {
|
||||
path, _ := r["path"].(string)
|
||||
before, version, found := strings.Cut(path, "/versions/")
|
||||
if !found || before == "" || version == "" || strings.Contains(version, "/") || strings.Contains(version, "$") {
|
||||
continue
|
||||
}
|
||||
if !slices.Contains(out, version) {
|
||||
out = append(out, version)
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// engineBehind says a node-engine's reported version is not the build the mesh holds: neither the
|
||||
// directory that build is delivered as, nor (for an engine placed by hand) its commit. A machine that
|
||||
// has not said, or a mesh that holds no delivered build, is not behind anything.
|
||||
func engineBehind(reported string, delivered []string, commit string) bool {
|
||||
if reported == "" || len(delivered) == 0 {
|
||||
return false
|
||||
}
|
||||
return !slices.Contains(delivered, reported) && !sameCommit(reported, commit)
|
||||
}
|
||||
|
||||
// hostModule is the node-engine's module.
|
||||
const hostModule = "mesh-host"
|
||||
|
||||
@@ -750,6 +802,10 @@ func probeWatchdogs(_ context.Context, d *doctor) ([]conditions.Observation, err
|
||||
// askSeatTool asks one machine's holder of a node seat a verb and answers its result; the holder's
|
||||
// own refusal is an error.
|
||||
func askSeatTool(ctx context.Context, conn *nats.Conn, seat, verb, node string) (json.RawMessage, error) {
|
||||
if who, declared := declaredBy(ctx, seat, verb); !declared {
|
||||
return nil, fmt.Errorf("%s asks %s.%s, which it does not declare in the probe registry — and so the "+
|
||||
"controller is not granted it", who, seat, verb)
|
||||
}
|
||||
answer, err := link.AskSeatTool(ctx, conn, seat, verb, node, map[string]any{}, 10*time.Second)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
Reference in New Issue
Block a user