diff --git a/cmd/mesh-controller/bus_runs_test.go b/cmd/mesh-controller/bus_runs_test.go new file mode 100644 index 00000000..7c77c6ba --- /dev/null +++ b/cmd/mesh-controller/bus_runs_test.go @@ -0,0 +1,29 @@ +package main + +import ( + "context" + "testing" +) + +// 1945 (dev-r6-controller's B8 follows it): what a bus machine runs is read from its have, not from a send kept, so a +// machine whose have names the build the mesh holds is not moved by a bus upgrade, and one whose have names an older +// build is. +func TestABusMachineRunsWhatItsHaveNames(t *testing.T) { + was := busRuns + t.Cleanup(func() { busRuns = was }) + busRuns = func(_ context.Context, node, _ string) (string, bool, error) { + return map[string]string{"novox": "src2:new", "ace": "src2:old"}[node], node != "g14", nil + } + b := busPending{module: "nats", to: "c-new", from: map[string]string{}, same: map[string]bool{}} + commitOf := map[string]string{"src2:new": "c-new", "src2:old": "c-old"} + for _, n := range []string{"novox", "ace", "g14"} { + fp, known, _ := busRuns(context.Background(), n, "nats") + if c, ok := commitOf[fp]; known && ok { + b.from[n] = c + } + } + if b.moves("novox") || !b.moves("ace") || !b.moves("g14") { + t.Errorf("novox moves %v (runs the new build), ace %v (an older one), g14 %v (says none)", b.moves("novox"), + b.moves("ace"), b.moves("g14")) + } +} diff --git a/cmd/mesh-controller/bus_step.go b/cmd/mesh-controller/bus_step.go index d8026078..fa594e6c 100644 --- a/cmd/mesh-controller/bus_step.go +++ b/cmd/mesh-controller/bus_step.go @@ -113,20 +113,44 @@ func pendingBus(ctx context.Context, inv *inventory.Inventory) (busPending, erro b.same[commit] = true } } + // What each machine runs is its have's fingerprint (novox/hq ADR 0539 clause 9), the commit of the build of it. + commitOf := map[string]string{} + for commit, src := range sources { + if src != "" { + commitOf[src] = commit + } + } for _, n := range b.machines { - sent, known, err := inv.SentBuilds(ctx, n) + fp, known, err := busRuns(ctx, n, b.module) if err != nil { return b, err } - if known { - if c, carried := sent[b.module]; carried { - b.from[n] = c - } + if c, ok := commitOf[fp]; known && ok { + b.from[n] = c } } return b, nil } +// busRuns is the fingerprint a machine's node-engine says it runs of a module, from its have; known is false when it +// says none. A variable so a test reads it without a bus. +var busRuns = func(ctx context.Context, node, module string) (string, bool, error) { + bus, err := aBus() + if err != nil { + return "", false, err + } + defer bus.Close() + js, err := jetstream.New(bus.Conn()) + if err != nil { + return "", false, err + } + h, found, err := haveOn(ctx, js, node, module) + if err != nil || !found || h.FP == "" { + return "", false, err + } + return h.FP, true, nil +} + // busHeld names the machines a push may not send because sending them would replace the bus: the // planned step's, not a push's (ADR 0236). Said with the remedy. func busHeld(ctx context.Context, inv *inventory.Inventory, machines []string) (map[string]string, error) {