diff --git a/modules/mesh-delivery-builder/go.mod b/modules/mesh-delivery-builder/go.mod index 9b9cb54..f1d1a30 100644 --- a/modules/mesh-delivery-builder/go.mod +++ b/modules/mesh-delivery-builder/go.mod @@ -3,7 +3,7 @@ module mesh-delivery-builder go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101085317-790d1c82d027 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101142413-71be15f53066 github.com/nats-io/nats-server/v2 v2.11.17 github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/mesh-delivery-builder/go.sum b/modules/mesh-delivery-builder/go.sum index 37e06a8..c368184 100644 --- a/modules/mesh-delivery-builder/go.sum +++ b/modules/mesh-delivery-builder/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101085317-790d1c82d027 h1:a33dsavoaqllh40eVICbhxi6Kero1EGSjt1V+2fa2Hk= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101085317-790d1c82d027/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101142413-71be15f53066 h1:rpYDAiJ+245xHvmYdta/hE3gSGEoebglr4ujdOoFH/8= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101142413-71be15f53066/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= diff --git a/modules/mesh-delivery-builder/internal/build/askagain.go b/modules/mesh-delivery-builder/internal/build/askagain.go index 1b03da9..23a0974 100644 --- a/modules/mesh-delivery-builder/internal/build/askagain.go +++ b/modules/mesh-delivery-builder/internal/build/askagain.go @@ -317,6 +317,11 @@ func (b *Builder) waitOnce(ctx context.Context, ask delivery.StepAsk, again <-ch defer stop() } step, err := b.Asks.Wait(wait, ask) + if d, declined := delivery.DeclinedOf(step); err == nil && declined { + // A build node on another toolchain than the agreed one sat out (ADR 0584 clause 2): the ask is put again, for a node + // on the agreed one to take. The most askings stays the bound, and the build then fails with these reasons in it. + return step, strings.TrimSpace(step.Node + " declined: " + step.Reason + " (lacks " + strings.Join(d.Lacks, ", ") + ")"), errAgain + } if err == nil && buildrun.IsLost(step) { // The build seat gave the ask up (issue 734): it can no longer be answered, so it is asked again now, with the // words of why, not at the check bound. diff --git a/modules/mesh-delivery-builder/internal/build/run.go b/modules/mesh-delivery-builder/internal/build/run.go index 4578824..f4c2357 100644 --- a/modules/mesh-delivery-builder/internal/build/run.go +++ b/modules/mesh-delivery-builder/internal/build/run.go @@ -506,10 +506,11 @@ func (b *Builder) stale(m delivery.Module, plan Plan) string { continue // an archive is packed with no toolchain } language := buildrun.LanguageOf[bm] - tc, none := delivery.AgreedToolchain(b.Toolchains.Entries(language)) - if none != "" { - return fmt.Sprintf("the %s toolchain is not agreed: %s", language, none) + ag := delivery.ToolchainAgreement(b.Toolchains.Entries(language)) + if ag.Wait != "" { + return fmt.Sprintf("the %s toolchain is not agreed: %s", language, ag.Wait) } + tc := ag.Toolchain want, ok := m.Toolchains[language] if !ok || want.Version != tc.Version || want.Recipe != tc.Recipe { return fmt.Sprintf("the fingerprint names %s %s (recipe %s) and the nodes agree on %s (recipe %s)", language, want.Version, want.Recipe, tc.Version, tc.Recipe) @@ -543,7 +544,8 @@ func (b *Builder) build(ctx context.Context, module string, m delivery.Module, p repository := delivery.RepositoryName(m.Repository) var lanes []*lane used := map[string]delivery.ToolchainUsed{} - var kept []string // build modules whose artifacts stay as the prior done key has them + var sitting []string // the nodes that sit out of a language's build, said in the key's step (ADR 0584 clause 2) + var kept []string // build modules whose artifacts stay as the prior done key has them for _, bm := range plan.Modules() { if prior != nil && len(only) > 0 && !only[bm] { kept = append(kept, bm) @@ -553,10 +555,12 @@ func (b *Builder) build(ctx context.Context, module string, m delivery.Module, p if bm != ImageBuildModule && plan.NeedsToolchain(bm) { // The ask names the toolchain the fingerprint was computed with; a node building with another refuses it. language := buildrun.LanguageOf[bm] - tc, none := delivery.AgreedToolchain(b.Toolchains.Entries(language)) - if none != "" { - return failed("the %s toolchain is not agreed: %s", language, none) + ag := delivery.ToolchainAgreement(b.Toolchains.Entries(language)) + if ag.Wait != "" { + return failed("the %s toolchain is not agreed: %s", language, ag.Wait) } + tc := ag.Toolchain + sitting = append(sitting, SittingOutWords(language, ag)...) if want := m.Toolchains[language]; want.Version != tc.Version || want.Recipe != tc.Recipe { return delivery.BuilderBuild{} // the agreed toolchain moved since try looked: nothing is written } @@ -653,6 +657,9 @@ func (b *Builder) build(ctx context.Context, module string, m delivery.Module, p } } step := "built " + strings.Join(steps, "; ") + if len(sitting) > 0 { + step += " (" + strings.Join(sitting, "; ") + ")" + } if len(used) == 0 { used = nil } @@ -942,3 +949,13 @@ func LogEnded(module string, m delivery.Module, ref, by string, at time.Time, re e.Made = append([]delivery.BuiltArtifact(nil), result.Artifacts...) return e } + +// SittingOutWords says, per node that is not on the agreed toolchain of a language, that it sits out and which version +// it has against the agreed one: "ace sits out: typescript 26.12.1, agreed 26.13.0" (novox/hq ADR 0584 clause 2). +func SittingOutWords(language string, a delivery.Agreement) []string { + var out []string + for _, s := range a.SittingOut { + out = append(out, fmt.Sprintf("%s sits out: %s %s, agreed %s", s.Node, language, s.Version, a.Toolchain.Version)) + } + return out +} diff --git a/modules/mesh-delivery-builder/internal/build/run_test.go b/modules/mesh-delivery-builder/internal/build/run_test.go index c05901d..2eeb07d 100644 --- a/modules/mesh-delivery-builder/internal/build/run_test.go +++ b/modules/mesh-delivery-builder/internal/build/run_test.go @@ -223,6 +223,14 @@ var ( func TestABundleAndAnArchiveAreBuiltOnOneNodeAndDone(t *testing.T) { // 1607/AC7, ADR 0478 clauses 1, 4 r := newRig(t, goBundle, archiveA, tsBundle) + // ADR 0584: a third node agrees with novox and ace's typescript is the odd one; the build is done and its step says ace sits out. + r.tools.Put(buildrun.NodeBuildModule, "g14.typescript", tcValue(t, "typescript", "tsc5"), false) + r.tools.Put(buildrun.NodeBuildModule, "ace.typescript", tcValue(t, "typescript", "tsc4"), false) + defer func() { + if st := r.st.vals[r.key]; !strings.Contains(string(st), "ace sits out: typescript tsc4, agreed tsc5") { + t.Errorf("the key does not say ace sits out: %s", st) + } + }() var logged []delivery.BuildLogEntry var lmu sync.Mutex r.b.Node, r.b.Log = "novox", func(e delivery.BuildLogEntry) { lmu.Lock(); logged = append(logged, e); lmu.Unlock() } diff --git a/modules/mesh-delivery-checker/go.mod b/modules/mesh-delivery-checker/go.mod index ce26061..487fb8d 100644 --- a/modules/mesh-delivery-checker/go.mod +++ b/modules/mesh-delivery-checker/go.mod @@ -3,7 +3,7 @@ module mesh-delivery-checker go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022206-8af6e7266915 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101142413-71be15f53066 github.com/nats-io/nats-server/v2 v2.11.17 github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/mesh-delivery-checker/go.sum b/modules/mesh-delivery-checker/go.sum index 5fc11b2..c368184 100644 --- a/modules/mesh-delivery-checker/go.sum +++ b/modules/mesh-delivery-checker/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022206-8af6e7266915 h1:x8k7IeMirMTxUo8BH+xUO+MDnHYgU+636jl1NIw1wvs= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022206-8af6e7266915/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101142413-71be15f53066 h1:rpYDAiJ+245xHvmYdta/hE3gSGEoebglr4ujdOoFH/8= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101142413-71be15f53066/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo= diff --git a/modules/mesh-delivery-indexer/go.mod b/modules/mesh-delivery-indexer/go.mod index 10c900e..5c3e040 100644 --- a/modules/mesh-delivery-indexer/go.mod +++ b/modules/mesh-delivery-indexer/go.mod @@ -3,7 +3,7 @@ module mesh-delivery-indexer go 1.26.0 require ( - git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022206-8af6e7266915 + git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101142413-71be15f53066 github.com/nats-io/nats-server/v2 v2.11.17 github.com/nats-io/nats.go v1.54.0 ) diff --git a/modules/mesh-delivery-indexer/go.sum b/modules/mesh-delivery-indexer/go.sum index 5fc11b2..c368184 100644 --- a/modules/mesh-delivery-indexer/go.sum +++ b/modules/mesh-delivery-indexer/go.sum @@ -1,5 +1,5 @@ -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022206-8af6e7266915 h1:x8k7IeMirMTxUo8BH+xUO+MDnHYgU+636jl1NIw1wvs= -git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022206-8af6e7266915/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101142413-71be15f53066 h1:rpYDAiJ+245xHvmYdta/hE3gSGEoebglr4ujdOoFH/8= +git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101142413-71be15f53066/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0= github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI= github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=