Compare commits
19
Commits
feat/l5-l7
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc38ca3f8d | ||
|
|
d739516056 | ||
|
|
a6c225eb45 | ||
|
|
5085b681e9 | ||
|
|
9e407f8f76 | ||
|
|
8545e7fc9f | ||
|
|
55a506975b | ||
|
|
b7dfe4c637 | ||
|
|
c4b05a3e93 | ||
|
|
38f2401f17 | ||
|
|
c8b041ab37 | ||
|
|
f52f47e1ff | ||
|
|
213ebe7cfd | ||
|
|
90e278cb97 | ||
|
|
58748c2be1 | ||
|
|
8e9cc58301 | ||
|
|
fb96216e46 | ||
|
|
5059fef3e6 | ||
|
|
564a04b45c |
@@ -3,7 +3,7 @@ module mesh-delivery-assigner
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101025153-c77d17fb42e3
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101085317-790d1c82d027
|
||||||
github.com/nats-io/nats-server/v2 v2.11.17
|
github.com/nats-io/nats-server/v2 v2.11.17
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,23 +1,5 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261031084708-acbf80ad910a h1:DcSvfEmdPBKqCg5OmXRNb269EkkPe7BsEp+RykEhkgE=
|
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.20261031084708-acbf80ad910a/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
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.20261101005736-7b09de1e5502 h1:XndvkzyAFNde/821lEfYObqMTURzmve/w9Ks+QrBBJ8=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101005736-7b09de1e5502/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101012031-7cab079e2ec3 h1:an2f0MLx9OhaDLu5i51OMPBbuGwX+aoTzqOkFLMpVfE=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101012031-7cab079e2ec3/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101013319-25a2cecd989c h1:rlUCZ5ifLojqDUTkcCCcPrugTzV2RT6F6JbIVTJkaC8=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101013319-25a2cecd989c/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236 h1:JEkSnrmHs5QIRJGhtrghLC1+C0AxqMpef8a32d/BLPg=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc h1:kVq7sS4I0EnL8DcAA2a3YstnXS6WmYYzJz7eK7IZ9RY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62 h1:R5C8ICjiaDITHRFR/uIATwARPPXKxssUC70m0svstb0=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022905-ba8b8f28a364 h1:UUDPWfUjyerptar+wPwI891jTUAtbbuXori0j3phTE4=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022905-ba8b8f28a364/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101023317-8311ecb84911 h1:+82ygf2hiY5Mhwfmc1xfCe9e/KY/5ObBuE2LecM37qI=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101023317-8311ecb84911/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101025153-c77d17fb42e3 h1:lb6hz+SBsoCAzsiCCvdtPKyE66Y5Ng/DBAkonAexPzA=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101025153-c77d17fb42e3/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 h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
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=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/nats-io/nats.go"
|
"github.com/nats-io/nats.go"
|
||||||
"github.com/nats-io/nats.go/jetstream"
|
"github.com/nats-io/nats.go/jetstream"
|
||||||
|
|
||||||
|
"git.novox.be/novox/mesh-sdk/go/catalogue"
|
||||||
"git.novox.be/novox/mesh-sdk/go/delivery"
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ import (
|
|||||||
// (novox/hq issue 1937): on 2026-10-24 the store's 03:30 collection deleted the bare blobs of three done keys the
|
// (novox/hq issue 1937): on 2026-10-24 the store's 03:30 collection deleted the bare blobs of three done keys the
|
||||||
// controller had never taken in, and the builder kept them done.
|
// controller had never taken in, and the builder kept them done.
|
||||||
|
|
||||||
// heldVerb answers the controller seat's verb held on the bus, as the serving controller does: {result: {output, ok,
|
// heldVerb answers the seat mesh-artifact-sweep's verb held on the bus, as its holder does: {result: {output, ok,
|
||||||
// answer}}; a reference is gone while gone says so.
|
// answer}}; a reference is gone while gone says so.
|
||||||
type heldVerb struct {
|
type heldVerb struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
@@ -29,7 +30,7 @@ type heldVerb struct {
|
|||||||
|
|
||||||
func (h *heldVerb) serve(t *testing.T, b *bed) {
|
func (h *heldVerb) serve(t *testing.T, b *bed) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
sub, err := b.js.Conn().Subscribe("mesh.seat.mesh-controller.call.held.>", func(m *nats.Msg) {
|
sub, err := b.js.Conn().Subscribe("mesh.seat."+catalogue.ArtifactSweepSeat+".call.held.>", func(m *nats.Msg) {
|
||||||
var args struct {
|
var args struct {
|
||||||
References []string `json:"references"`
|
References []string `json:"references"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module mesh-delivery-builder
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101023317-8311ecb84911
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101143343-67354f8e019a
|
||||||
github.com/nats-io/nats-server/v2 v2.11.17
|
github.com/nats-io/nats-server/v2 v2.11.17
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101023317-8311ecb84911 h1:+82ygf2hiY5Mhwfmc1xfCe9e/KY/5ObBuE2LecM37qI=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101143343-67354f8e019a h1:AChSJUmHyOZ5smiuTrtDZNjetYNTFb+anRFjXIQHbSA=
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101023317-8311ecb84911/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101143343-67354f8e019a/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 h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
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=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"slices"
|
"slices"
|
||||||
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@@ -177,6 +178,42 @@ func (b *Builder) drop(ctx context.Context, ask delivery.StepAsk, old string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultDeclineBound is how long one ask may go on being declined, from its first decline, before its key fails (the
|
||||||
|
// checker's DefaultDeclineBound, issue 890); DefaultDeclinePause is how long the builder waits before it puts a declined
|
||||||
|
// ask again, so a lone node off the agreed toolchain cannot spin on it.
|
||||||
|
const (
|
||||||
|
DefaultDeclineBound = 30 * time.Minute
|
||||||
|
DefaultDeclinePause = 5 * time.Second
|
||||||
|
)
|
||||||
|
|
||||||
|
func (b *Builder) declineBound() time.Duration {
|
||||||
|
if b.DeclineBound > 0 {
|
||||||
|
return b.DeclineBound
|
||||||
|
}
|
||||||
|
return DefaultDeclineBound
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Builder) declinePause() time.Duration {
|
||||||
|
if b.DeclinePause != 0 {
|
||||||
|
return max(b.DeclinePause, 0)
|
||||||
|
}
|
||||||
|
return DefaultDeclinePause
|
||||||
|
}
|
||||||
|
|
||||||
|
// declinedWords names the nodes that declined an ask and why, in the order of their names.
|
||||||
|
func declinedWords(by map[string]string) string {
|
||||||
|
nodes := make([]string, 0, len(by))
|
||||||
|
for n := range by {
|
||||||
|
nodes = append(nodes, n)
|
||||||
|
}
|
||||||
|
sort.Strings(nodes)
|
||||||
|
var parts []string
|
||||||
|
for _, n := range nodes {
|
||||||
|
parts = append(parts, n+": "+by[n])
|
||||||
|
}
|
||||||
|
return strings.Join(parts, "; ")
|
||||||
|
}
|
||||||
|
|
||||||
func (b *Builder) askings() int {
|
func (b *Builder) askings() int {
|
||||||
if b.Askings > 0 {
|
if b.Askings > 0 {
|
||||||
return b.Askings
|
return b.Askings
|
||||||
@@ -255,6 +292,8 @@ func (b *Builder) unlisten(key, language string, c chan string) {
|
|||||||
var (
|
var (
|
||||||
errCheck = errors.New("the check bound passed")
|
errCheck = errors.New("the check bound passed")
|
||||||
errAgain = errors.New("asked again")
|
errAgain = errors.New("asked again")
|
||||||
|
// errDeclined: a build node on another toolchain than the agreed one sat out of the ask (ADR 0584 clause 2).
|
||||||
|
errDeclined = errors.New("declined")
|
||||||
)
|
)
|
||||||
|
|
||||||
type byHand struct{ why string }
|
type byHand struct{ why string }
|
||||||
@@ -268,11 +307,42 @@ func (b *Builder) answer(ctx context.Context, l *lane, ask delivery.StepAsk, ask
|
|||||||
again := b.listen(key, ask.Language)
|
again := b.listen(key, ask.Language)
|
||||||
defer b.unlisten(key, ask.Language, again)
|
defer b.unlisten(key, ask.Language, again)
|
||||||
asking := askingOf(asked.step, l.module)
|
asking := askingOf(asked.step, l.module)
|
||||||
|
var firstDecline time.Time
|
||||||
|
declines := map[string]string{} // node -> why it declined, the last
|
||||||
for {
|
for {
|
||||||
step, why, err := b.waitOnce(ctx, ask, again)
|
step, why, err := b.waitOnce(ctx, ask, again)
|
||||||
switch {
|
switch {
|
||||||
case errors.Is(err, errCheck):
|
case errors.Is(err, errCheck):
|
||||||
continue
|
continue
|
||||||
|
case errors.Is(err, errDeclined):
|
||||||
|
// Not an asking: a node that sits out would use them all while it idles and pulls the ask again at once.
|
||||||
|
// Bounded by time from the first decline, then failed loudly naming the nodes and their reasons (as the
|
||||||
|
// checker's decline loop is, issue 890).
|
||||||
|
now := time.Now()
|
||||||
|
if firstDecline.IsZero() {
|
||||||
|
firstDecline = now
|
||||||
|
}
|
||||||
|
declines[step.Node] = why
|
||||||
|
if bound := b.declineBound(); now.Sub(firstDecline) > bound {
|
||||||
|
return step, ask, fmt.Errorf("the ask %s of %s was declined for %s and no build node took it: %s", ask.ID, l.module, bound.Round(time.Second), declinedWords(declines))
|
||||||
|
}
|
||||||
|
// The pause is a context's bound, not a timer (ADR 0437 §8).
|
||||||
|
pause, stop := context.WithTimeout(ctx, b.declinePause())
|
||||||
|
<-pause.Done()
|
||||||
|
stop()
|
||||||
|
if ctx.Err() != nil {
|
||||||
|
return step, ask, ctx.Err()
|
||||||
|
}
|
||||||
|
old := ask.ID
|
||||||
|
ask.ID, ask.At = buildstep.NewID(), time.Now()
|
||||||
|
if err := asked.note(ctx, ask.Language, ask.ID, fmt.Sprintf("put %s again after %s declined it", l.module, step.Node)); err != nil {
|
||||||
|
return step, ask, fmt.Errorf("the ask of %s put again after a decline could not be written to the key: %w", l.module, err)
|
||||||
|
}
|
||||||
|
if err := b.Asks.Put(ctx, ask); err != nil {
|
||||||
|
return step, ask, err
|
||||||
|
}
|
||||||
|
b.drop(ctx, ask, old)
|
||||||
|
b.logf("%s: the ask %s of %s was declined on %s and is put again as %s: %s", key, old, l.module, step.Node, ask.ID, why)
|
||||||
case errors.Is(err, errAgain):
|
case errors.Is(err, errAgain):
|
||||||
if asking >= b.askings() {
|
if asking >= b.askings() {
|
||||||
return step, ask, fmt.Errorf("the ask %s could not be answered and was asked %d times, the most it is: %s", ask.ID, asking, why)
|
return step, ask, fmt.Errorf("the ask %s could not be answered and was asked %d times, the most it is: %s", ask.ID, asking, why)
|
||||||
@@ -317,6 +387,11 @@ func (b *Builder) waitOnce(ctx context.Context, ask delivery.StepAsk, again <-ch
|
|||||||
defer stop()
|
defer stop()
|
||||||
}
|
}
|
||||||
step, err := b.Asks.Wait(wait, ask)
|
step, err := b.Asks.Wait(wait, ask)
|
||||||
|
if _, declined := delivery.DeclinedOf(step); err == nil && declined {
|
||||||
|
// A build node off the agreed toolchain sat out (ADR 0584 clause 2). It is no asking: answer() puts the ask again
|
||||||
|
// after a pause, within DeclineBound.
|
||||||
|
return step, step.Reason, errDeclined
|
||||||
|
}
|
||||||
if err == nil && buildrun.IsLost(step) {
|
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
|
// 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.
|
// words of why, not at the check bound.
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ type Builder struct {
|
|||||||
// Askings is how many times one build module's part of a build is asked, the first included, before its key is failed
|
// Askings is how many times one build module's part of a build is asked, the first included, before its key is failed
|
||||||
// with why; DefaultAskings when 0.
|
// with why; DefaultAskings when 0.
|
||||||
Askings int
|
Askings int
|
||||||
|
// DeclineBound and DeclinePause bound and pace the asks build nodes off the agreed toolchain declined (ADR 0584 clause 2):
|
||||||
|
// they are no askings. DefaultDeclineBound and DefaultDeclinePause when 0; a negative DeclinePause puts it again at once.
|
||||||
|
DeclineBound, DeclinePause time.Duration
|
||||||
// Said is told each ask asked again (the builder's event build.asked-again). Nil tells nobody.
|
// Said is told each ask asked again (the builder's event build.asked-again). Nil tells nobody.
|
||||||
Said func(AskedAgain)
|
Said func(AskedAgain)
|
||||||
// Log is told each build's start and end, the entries of the builder's log (novox/hq ADR 0571 §1). Nil tells nobody.
|
// Log is told each build's start and end, the entries of the builder's log (novox/hq ADR 0571 §1). Nil tells nobody.
|
||||||
@@ -415,7 +418,7 @@ func (b *Builder) try(ctx context.Context, module string, m delivery.Module) {
|
|||||||
if planErr == nil && !nothing {
|
if planErr == nil && !nothing {
|
||||||
if why := b.stale(m, plan); why != "" {
|
if why := b.stale(m, plan); why != "" {
|
||||||
// The fingerprint names a toolchain the build nodes no longer agree on: a new fingerprint is coming, and a build
|
// The fingerprint names a toolchain the build nodes no longer agree on: a new fingerprint is coming, and a build
|
||||||
// now would be of this source with another toolchain (ADR 0477 clause 2). Nothing is written.
|
// now would be of this source with another toolchain (ADR 0584 clause 1, which changes ADR 0477 clause 2). Nothing is written.
|
||||||
b.logf("%s at %s is not built: %s", module, m.FP2, why)
|
b.logf("%s at %s is not built: %s", module, m.FP2, why)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -506,10 +509,11 @@ func (b *Builder) stale(m delivery.Module, plan Plan) string {
|
|||||||
continue // an archive is packed with no toolchain
|
continue // an archive is packed with no toolchain
|
||||||
}
|
}
|
||||||
language := buildrun.LanguageOf[bm]
|
language := buildrun.LanguageOf[bm]
|
||||||
tc, none := delivery.AgreedToolchain(b.Toolchains.Entries(language))
|
ag := delivery.ToolchainAgreement(b.Toolchains.Entries(language))
|
||||||
if none != "" {
|
if ag.Wait != "" {
|
||||||
return fmt.Sprintf("the %s toolchain is not agreed: %s", language, none)
|
return fmt.Sprintf("the %s toolchain is not agreed: %s", language, ag.Wait)
|
||||||
}
|
}
|
||||||
|
tc := ag.Toolchain
|
||||||
want, ok := m.Toolchains[language]
|
want, ok := m.Toolchains[language]
|
||||||
if !ok || want.Version != tc.Version || want.Recipe != tc.Recipe {
|
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)
|
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 +547,8 @@ func (b *Builder) build(ctx context.Context, module string, m delivery.Module, p
|
|||||||
repository := delivery.RepositoryName(m.Repository)
|
repository := delivery.RepositoryName(m.Repository)
|
||||||
var lanes []*lane
|
var lanes []*lane
|
||||||
used := map[string]delivery.ToolchainUsed{}
|
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() {
|
for _, bm := range plan.Modules() {
|
||||||
if prior != nil && len(only) > 0 && !only[bm] {
|
if prior != nil && len(only) > 0 && !only[bm] {
|
||||||
kept = append(kept, bm)
|
kept = append(kept, bm)
|
||||||
@@ -553,10 +558,12 @@ func (b *Builder) build(ctx context.Context, module string, m delivery.Module, p
|
|||||||
if bm != ImageBuildModule && plan.NeedsToolchain(bm) {
|
if bm != ImageBuildModule && plan.NeedsToolchain(bm) {
|
||||||
// The ask names the toolchain the fingerprint was computed with; a node building with another refuses it.
|
// The ask names the toolchain the fingerprint was computed with; a node building with another refuses it.
|
||||||
language := buildrun.LanguageOf[bm]
|
language := buildrun.LanguageOf[bm]
|
||||||
tc, none := delivery.AgreedToolchain(b.Toolchains.Entries(language))
|
ag := delivery.ToolchainAgreement(b.Toolchains.Entries(language))
|
||||||
if none != "" {
|
if ag.Wait != "" {
|
||||||
return failed("the %s toolchain is not agreed: %s", language, none)
|
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 {
|
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
|
return delivery.BuilderBuild{} // the agreed toolchain moved since try looked: nothing is written
|
||||||
}
|
}
|
||||||
@@ -653,6 +660,9 @@ func (b *Builder) build(ctx context.Context, module string, m delivery.Module, p
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
step := "built " + strings.Join(steps, "; ")
|
step := "built " + strings.Join(steps, "; ")
|
||||||
|
if len(sitting) > 0 {
|
||||||
|
step += " (" + strings.Join(sitting, "; ") + ")"
|
||||||
|
}
|
||||||
if len(used) == 0 {
|
if len(used) == 0 {
|
||||||
used = nil
|
used = nil
|
||||||
}
|
}
|
||||||
@@ -942,3 +952,13 @@ func LogEnded(module string, m delivery.Module, ref, by string, at time.Time, re
|
|||||||
e.Made = append([]delivery.BuiltArtifact(nil), result.Artifacts...)
|
e.Made = append([]delivery.BuiltArtifact(nil), result.Artifacts...)
|
||||||
return e
|
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
|
||||||
|
}
|
||||||
|
|||||||
@@ -223,6 +223,14 @@ var (
|
|||||||
|
|
||||||
func TestABundleAndAnArchiveAreBuiltOnOneNodeAndDone(t *testing.T) { // 1607/AC7, ADR 0478 clauses 1, 4
|
func TestABundleAndAnArchiveAreBuiltOnOneNodeAndDone(t *testing.T) { // 1607/AC7, ADR 0478 clauses 1, 4
|
||||||
r := newRig(t, goBundle, archiveA, tsBundle)
|
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 logged []delivery.BuildLogEntry
|
||||||
var lmu sync.Mutex
|
var lmu sync.Mutex
|
||||||
r.b.Node, r.b.Log = "novox", func(e delivery.BuildLogEntry) { lmu.Lock(); logged = append(logged, e); lmu.Unlock() }
|
r.b.Node, r.b.Log = "novox", func(e delivery.BuildLogEntry) { lmu.Lock(); logged = append(logged, e); lmu.Unlock() }
|
||||||
@@ -730,6 +738,25 @@ func TestABuildAskWaitingInItsStreamIsNotBounded(t *testing.T) {
|
|||||||
t.Fatalf("the key = %+v after %d asks, want done from the one ask", v, len(r.asks.Asks()))
|
t.Fatalf("the key = %+v after %d asks, want done from the one ask", v, len(r.asks.Asks()))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
t.Run("declined by a node off the agreed toolchain: put again, no asking used, the bound ends it loudly", func(t *testing.T) { // ADR 0584 clause 2
|
||||||
|
r := newRig(t, goBundle)
|
||||||
|
r.asks.Answer = nil
|
||||||
|
r.b.DeclinePause, r.b.DeclineBound = -1, 150*time.Millisecond
|
||||||
|
r.b.Module(context.Background(), "m", moduleValue(t, "modules/m"))
|
||||||
|
declined, _ := json.Marshal(delivery.StepDeclined{Declined: true, Lacks: []string{"the agreed toolchain go1.27.1 (recipe 1)"}})
|
||||||
|
waitForAsks(t, r, 1)
|
||||||
|
for ended, deadline := 0, time.Now().Add(5*time.Second); valueOf(t, r.st, r.key).State == delivery.BuildBuilding && time.Now().Before(deadline); time.Sleep(5 * time.Millisecond) {
|
||||||
|
if asks := r.asks.Asks(); len(asks) > ended { // each ask put again is declined in its turn
|
||||||
|
r.asks.End(delivery.Step{ID: asks[ended].ID, Node: "ace", State: delivery.StepRefused, Reason: "this node builds with go1.26.0", Result: declined})
|
||||||
|
ended++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
r.b.Wait()
|
||||||
|
v := valueOf(t, r.st, r.key)
|
||||||
|
if n := len(r.asks.Asks()); v.State != delivery.BuildFailed || n <= DefaultAskings || !strings.Contains(v.Error, "declined for") || !strings.Contains(v.Error, "ace: this node builds with go1.26.0") {
|
||||||
|
t.Fatalf("the key = %+v after %d asks, want it failed after more than %d asks, naming ace and its reason", v, n, DefaultAskings)
|
||||||
|
}
|
||||||
|
})
|
||||||
for _, c := range []struct {
|
for _, c := range []struct {
|
||||||
name string
|
name string
|
||||||
askings int
|
askings int
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module mesh-delivery-checker
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101143343-67354f8e019a
|
||||||
github.com/nats-io/nats-server/v2 v2.11.17
|
github.com/nats-io/nats-server/v2 v2.11.17
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,17 +1,5 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261031084708-acbf80ad910a h1:DcSvfEmdPBKqCg5OmXRNb269EkkPe7BsEp+RykEhkgE=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101143343-67354f8e019a h1:AChSJUmHyOZ5smiuTrtDZNjetYNTFb+anRFjXIQHbSA=
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261031084708-acbf80ad910a/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101143343-67354f8e019a/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101005736-7b09de1e5502 h1:XndvkzyAFNde/821lEfYObqMTURzmve/w9Ks+QrBBJ8=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101005736-7b09de1e5502/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101012031-7cab079e2ec3 h1:an2f0MLx9OhaDLu5i51OMPBbuGwX+aoTzqOkFLMpVfE=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101012031-7cab079e2ec3/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101013319-25a2cecd989c h1:rlUCZ5ifLojqDUTkcCCcPrugTzV2RT6F6JbIVTJkaC8=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101013319-25a2cecd989c/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236 h1:JEkSnrmHs5QIRJGhtrghLC1+C0AxqMpef8a32d/BLPg=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc h1:kVq7sS4I0EnL8DcAA2a3YstnXS6WmYYzJz7eK7IZ9RY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62 h1:R5C8ICjiaDITHRFR/uIATwARPPXKxssUC70m0svstb0=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62/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 h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
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=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
|
|||||||
@@ -342,6 +342,11 @@ func TestOnlyThePackageWithoutAKeptVerdictRuns(t *testing.T) { // 1288/AC1
|
|||||||
if out.Verdict.State != delivery.VerdictPass || len(asks) != 3 || len(asks[0].Needs) != 0 {
|
if out.Verdict.State != delivery.VerdictPass || len(asks) != 3 || len(asks[0].Needs) != 0 {
|
||||||
t.Fatalf("verdict %+v, asks %+v: want a pass of three asks, the first naming no need", out.Verdict, asks)
|
t.Fatalf("verdict %+v, asks %+v: want a pass of three asks, the first naming no need", out.Verdict, asks)
|
||||||
}
|
}
|
||||||
|
for _, a := range asks { // ADR 0584: every check ask names the agreed toolchain, so a node off it declines
|
||||||
|
if a.Check.Toolchain == nil || a.Check.Toolchain.Version != "go1.27.1" || a.Check.Toolchain.Recipe != "7" {
|
||||||
|
t.Errorf("a check ask names toolchain %+v, want go1.27.1 recipe 7", a.Check.Toolchain)
|
||||||
|
}
|
||||||
|
}
|
||||||
for _, a := range asks[1:] {
|
for _, a := range asks[1:] {
|
||||||
if strings.Join(a.Needs, ",") != delivery.NeedNodeBuildNode || strings.Join(a.Check.Levels, ",") != delivery.LevelIntegration || strings.Join(a.Check.Packages, ",") != "fixture/node" {
|
if strings.Join(a.Needs, ",") != delivery.NeedNodeBuildNode || strings.Join(a.Check.Levels, ",") != delivery.LevelIntegration || strings.Join(a.Check.Packages, ",") != "fixture/node" {
|
||||||
t.Errorf("a placed ask %+v, want the integration level needing node-build-node", a)
|
t.Errorf("a placed ask %+v, want the integration level needing node-build-node", a)
|
||||||
|
|||||||
@@ -166,7 +166,9 @@ type target struct {
|
|||||||
module string
|
module string
|
||||||
node string
|
node string
|
||||||
toolchain string
|
toolchain string
|
||||||
fetched Fetched
|
// agreed is the toolchain the ask names, so a node off it declines the check (ADR 0584); nil when none is agreed.
|
||||||
|
agreed *delivery.ToolchainUsed
|
||||||
|
fetched Fetched
|
||||||
// fetchArgs are the arguments of the fetch its check ask runs.
|
// fetchArgs are the arguments of the fetch its check ask runs.
|
||||||
fetchArgs map[string]any
|
fetchArgs map[string]any
|
||||||
// priority are the Go packages (import paths) or the Node module directories whose test files the merge changes.
|
// priority are the Go packages (import paths) or the Node module directories whose test files the merge changes.
|
||||||
@@ -374,6 +376,7 @@ func (st *state) judgeAll(ctx context.Context) *delivery.Verdict {
|
|||||||
t := &target{pull: p, module: bm}
|
t := &target{pull: p, module: bm}
|
||||||
if tc, none := delivery.AgreedToolchain(st.j.Toolchains.Entries(buildrun.LanguageOf[bm])); none == "" {
|
if tc, none := delivery.AgreedToolchain(st.j.Toolchains.Entries(buildrun.LanguageOf[bm])); none == "" {
|
||||||
t.toolchain = tc.Version
|
t.toolchain = tc.Version
|
||||||
|
t.agreed = &delivery.ToolchainUsed{Version: tc.Version, Recipe: tc.Recipe}
|
||||||
}
|
}
|
||||||
args := map[string]any{"repository": p.Repository, "commit": p.Head, "ref": refOf(p.Number), "base": p.Trunk}
|
args := map[string]any{"repository": p.Repository, "commit": p.Head, "ref": refOf(p.Number), "base": p.Trunk}
|
||||||
if bm == buildrun.NodeBuildModule && groupPackage != nil && p.Repository != SDKRepository {
|
if bm == buildrun.NodeBuildModule && groupPackage != nil && p.Repository != SDKRepository {
|
||||||
@@ -428,7 +431,7 @@ func (st *state) ask(ctx context.Context, t *target, merged *[]Fetched) *deliver
|
|||||||
func (st *state) askNeeding(ctx context.Context, t *target, merged *[]Fetched, levels, needs, packages []string) *delivery.Verdict {
|
func (st *state) askNeeding(ctx context.Context, t *target, merged *[]Fetched, levels, needs, packages []string) *delivery.Verdict {
|
||||||
p := t.pull
|
p := t.pull
|
||||||
placed := len(needs) > 0
|
placed := len(needs) > 0
|
||||||
job := &delivery.CheckJob{Fetch: t.fetchArgs, Levels: levels, Kept: true, Packages: packages}
|
job := &delivery.CheckJob{Fetch: t.fetchArgs, Levels: levels, Kept: true, Packages: packages, Toolchain: t.agreed}
|
||||||
if st.j.Nodes != nil {
|
if st.j.Nodes != nil {
|
||||||
names, err := st.j.Nodes.Names(ctx)
|
names, err := st.j.Nodes.Names(ctx)
|
||||||
if err == nil && len(names) == 0 {
|
if err == nil && len(names) == 0 {
|
||||||
@@ -495,8 +498,12 @@ func (st *state) askNeeding(ctx context.Context, t *target, merged *[]Fetched, l
|
|||||||
bound = DefaultDeclineBound
|
bound = DefaultDeclineBound
|
||||||
}
|
}
|
||||||
if now.Sub(firstDecline) > bound {
|
if now.Sub(firstDecline) > bound {
|
||||||
|
lacks := strings.Join(needs, ", ")
|
||||||
|
if lacks == "" {
|
||||||
|
lacks = strings.Join(d.Lacks, ", ") // a node off the agreed toolchain declined it (ADR 0584)
|
||||||
|
}
|
||||||
return fail(step.Node, fmt.Sprintf("the check of %s#%d needs a node with %s, and none took it in %s: every node that pulled it lacks it (last %s)",
|
return fail(step.Node, fmt.Sprintf("the check of %s#%d needs a node with %s, and none took it in %s: every node that pulled it lacks it (last %s)",
|
||||||
p.Repository, p.Number, strings.Join(needs, ", "), bound, step.Node))
|
p.Repository, p.Number, lacks, bound, step.Node))
|
||||||
}
|
}
|
||||||
st.j.logf("%s#%d: the ask %s was declined on %s, which lacks %s; asked again", p.Repository, p.Number, a.ID, step.Node, strings.Join(d.Lacks, ", "))
|
st.j.logf("%s#%d: the ask %s was declined on %s, which lacks %s; asked again", p.Repository, p.Number, a.ID, step.Node, strings.Join(d.Lacks, ", "))
|
||||||
a.ID, a.At = buildstep.NewID(), now.UTC()
|
a.ID, a.At = buildstep.NewID(), now.UTC()
|
||||||
|
|||||||
+3
-1
@@ -423,7 +423,9 @@ func TestBridgeWritesMergedMessage(t *testing.T) { // 1236/AC4, 1448/AC5
|
|||||||
want := delivery.Forge{V: delivery.Version, Kind: "merged", Repository: "novox/mesh-delivery", Branch: "feat/x", Number: 12, Head: head,
|
want := delivery.Forge{V: delivery.Version, Kind: "merged", Repository: "novox/mesh-delivery", Branch: "feat/x", Number: 12, Head: head,
|
||||||
Merge: merge, Root: "r0", Trees: map[string]string{"": "t0", "modules/a": "t1"},
|
Merge: merge, Root: "r0", Trees: map[string]string{"": "t0", "modules/a": "t1"},
|
||||||
Manifests: map[string]string{"": string(manifest), "modules/a": string(manifest)},
|
Manifests: map[string]string{"": string(manifest), "modules/a": string(manifest)},
|
||||||
Locks: map[string]map[string]string{"modules/a": {"go.sum": hex.EncodeToString(sha256Sum(sum))}}}
|
Locks: map[string]map[string]string{"modules/a": {"go.sum": hex.EncodeToString(sha256Sum(sum))}},
|
||||||
|
// The mesh packages its go.sum names (ADR 0573 §2, issue 1585): this module's own go.sum names mesh-sdk.
|
||||||
|
Packages: map[string][]string{"modules/a": {"git.novox.be/novox/mesh-sdk/go"}}}
|
||||||
if !delivery.SameForge(f, want) {
|
if !delivery.SameForge(f, want) {
|
||||||
t.Errorf("message = %+v, want %+v", f, want)
|
t.Errorf("message = %+v, want %+v", f, want)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module mesh-delivery-forge-bridge
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022206-8af6e7266915
|
||||||
github.com/nats-io/nats-server/v2 v2.11.17
|
github.com/nats-io/nats-server/v2 v2.11.17
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,13 +1,5 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030201806-eff81f1220e2 h1:RF73nVI1dTrrmlFosVDTMJmpUQ+rEeB7++BHH/RvZFg=
|
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.20261030201806-eff81f1220e2/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
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.20261101005726-af4e4e60a3a0 h1:q6ywchpTM9fwaJ1UNwDSuOjb5FYDFcsaeiTrKoB4scc=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101005726-af4e4e60a3a0/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236 h1:JEkSnrmHs5QIRJGhtrghLC1+C0AxqMpef8a32d/BLPg=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc h1:kVq7sS4I0EnL8DcAA2a3YstnXS6WmYYzJz7eK7IZ9RY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62 h1:R5C8ICjiaDITHRFR/uIATwARPPXKxssUC70m0svstb0=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62/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 h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
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=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module mesh-delivery-indexer
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101143343-67354f8e019a
|
||||||
github.com/nats-io/nats-server/v2 v2.11.17
|
github.com/nats-io/nats-server/v2 v2.11.17
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,17 +1,5 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261031084708-acbf80ad910a h1:DcSvfEmdPBKqCg5OmXRNb269EkkPe7BsEp+RykEhkgE=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101143343-67354f8e019a h1:AChSJUmHyOZ5smiuTrtDZNjetYNTFb+anRFjXIQHbSA=
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261031084708-acbf80ad910a/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101143343-67354f8e019a/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101005736-7b09de1e5502 h1:XndvkzyAFNde/821lEfYObqMTURzmve/w9Ks+QrBBJ8=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101005736-7b09de1e5502/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101012031-7cab079e2ec3 h1:an2f0MLx9OhaDLu5i51OMPBbuGwX+aoTzqOkFLMpVfE=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101012031-7cab079e2ec3/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101013319-25a2cecd989c h1:rlUCZ5ifLojqDUTkcCCcPrugTzV2RT6F6JbIVTJkaC8=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101013319-25a2cecd989c/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236 h1:JEkSnrmHs5QIRJGhtrghLC1+C0AxqMpef8a32d/BLPg=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc h1:kVq7sS4I0EnL8DcAA2a3YstnXS6WmYYzJz7eK7IZ9RY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62 h1:R5C8ICjiaDITHRFR/uIATwARPPXKxssUC70m0svstb0=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62/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 h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
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=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
|
|||||||
@@ -50,23 +50,37 @@ const Env = "MESH_CHECK_BESIDE"
|
|||||||
// CapturedSuffix is what a captured file's name carries that the repository's own does not.
|
// CapturedSuffix is what a captured file's name carries that the repository's own does not.
|
||||||
const CapturedSuffix = ".captured"
|
const CapturedSuffix = ".captured"
|
||||||
|
|
||||||
|
// notPlaced are the repositories the checker places beside no mesh-delivery check (besideRules in
|
||||||
|
// mesh-delivery-checker/internal/check/beside.go places mesh-sdk and the catalogue): a test reads them from the captured
|
||||||
|
// copy even in a merge check, and says so (issue 1585). Every other sibling missing from a merge check fails the test.
|
||||||
|
var notPlaced = map[string]bool{"mesh-host": true}
|
||||||
|
|
||||||
// Dir is the named repository a test reads — the clone beside a merge check, or the captured copy — and
|
// Dir is the named repository a test reads — the clone beside a merge check, or the captured copy — and
|
||||||
// says which in the test's log.
|
// says which in the test's log.
|
||||||
func Dir(t testing.TB, repository string) string {
|
func Dir(t testing.TB, repository string) string {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
if root := os.Getenv(Env); root != "" {
|
root := os.Getenv(Env)
|
||||||
|
if root != "" {
|
||||||
dir := filepath.Join(root, repository)
|
dir := filepath.Join(root, repository)
|
||||||
if _, err := os.Stat(dir); err != nil {
|
_, err := os.Stat(dir)
|
||||||
|
switch {
|
||||||
|
case err == nil:
|
||||||
|
t.Logf("judged against %s as cloned beside this check", dir)
|
||||||
|
return dir
|
||||||
|
case !notPlaced[repository]:
|
||||||
|
// A sibling the checker places that is missing is the checker's fault, never judged against a stale copy.
|
||||||
t.Fatalf("%s is not beside this check in %s=%s, so its agreement with this repository cannot be "+
|
t.Fatalf("%s is not beside this check in %s=%s, so its agreement with this repository cannot be "+
|
||||||
"judged here: %v", repository, Env, root, err)
|
"judged here: %v", repository, Env, root, err)
|
||||||
}
|
}
|
||||||
t.Logf("judged against %s as cloned beside this check", dir)
|
|
||||||
return dir
|
|
||||||
}
|
}
|
||||||
from := filepath.Join(Captured(), repository)
|
from := filepath.Join(Captured(), repository)
|
||||||
if _, err := os.Stat(from); err != nil {
|
if _, err := os.Stat(from); err != nil {
|
||||||
t.Fatalf("no captured copy of %s at %s: %v", repository, from, err)
|
t.Fatalf("no captured copy of %s at %s: %v", repository, from, err)
|
||||||
}
|
}
|
||||||
|
if root != "" {
|
||||||
|
t.Logf("%s is not beside this check in %s=%s (the checker places it beside no mesh-delivery check): read from "+
|
||||||
|
"its captured copy", repository, Env, root)
|
||||||
|
}
|
||||||
dir, err := layOut(repository, from)
|
dir, err := layOut(repository, from)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("the captured copy of %s could not be laid out: %v", repository, err)
|
t.Fatalf("the captured copy of %s could not be laid out: %v", repository, err)
|
||||||
|
|||||||
+8
-6
@@ -7,20 +7,22 @@ The copy carries the catalogue's private details: domains, first names in module
|
|||||||
private addresses. That is acceptable while mesh-sdk is private; if it ever goes public, this copy is
|
private addresses. That is acceptable while mesh-sdk is private; if it ever goes public, this copy is
|
||||||
a second place to clean besides the catalogue itself.
|
a second place to clean besides the catalogue itself.
|
||||||
|
|
||||||
Only what go/catalogue's tests read is captured (R4b, issue 1379). Refreshed 2026-10-21 from the mains of both
|
Only what go/catalogue's tests read is captured (R4b, issue 1379), copied here from mesh-sdk with the judge's tests
|
||||||
repositories; before that it was mesh-controller's copy, which still held two modules that had left the catalogue.
|
(issue 1585). mesh-host refreshed 2026-11-01 from its main, the catalogue 2026-10-21 from its main; before that it
|
||||||
|
was mesh-controller's copy, which still held two modules that had left the catalogue.
|
||||||
|
|
||||||
mesh-catalog b5dbfbb784507e211372a7c9640d91f7d6dadd84 modules/*/module.json, modules/*/files/**, modules/*/templates/**, predefined.json
|
mesh-catalog b5dbfbb784507e211372a7c9640d91f7d6dadd84 modules/*/module.json, modules/*/files/**, modules/*/templates/**, predefined.json
|
||||||
mesh-host cdcba9ca73755854d21e4e657d7e46c32b9b5265 internal/apply/placement_guard.go
|
mesh-host 233bb23bbcb1a829ce2a6164a31a5c5cc4f3d950 internal/apply/placement_guard.go
|
||||||
|
|
||||||
To move them, from this repository's go/ directory, with the two repositories checked out beside mesh-sdk:
|
To move them, from mesh-delivery's modules/mesh-delivery-indexer directory, with the two repositories checked out
|
||||||
|
beside mesh-delivery:
|
||||||
|
|
||||||
rm -rf testdata/beside/mesh-catalog testdata/beside/mesh-host
|
rm -rf testdata/beside/mesh-catalog testdata/beside/mesh-host
|
||||||
mkdir -p testdata/beside/mesh-catalog testdata/beside/mesh-host/internal/apply
|
mkdir -p testdata/beside/mesh-catalog testdata/beside/mesh-host/internal/apply
|
||||||
git -C ../../mesh-catalog archive <commit> -- predefined.json ':(glob)modules/*/module.json' \
|
git -C ../../../mesh-catalog archive <commit> -- predefined.json ':(glob)modules/*/module.json' \
|
||||||
':(glob)modules/*/files/**' ':(glob)modules/*/templates/**' | tar -x -C testdata/beside/mesh-catalog
|
':(glob)modules/*/files/**' ':(glob)modules/*/templates/**' | tar -x -C testdata/beside/mesh-catalog
|
||||||
find testdata/beside -name module.json -exec mv {} {}.captured \;
|
find testdata/beside -name module.json -exec mv {} {}.captured \;
|
||||||
git -C ../../mesh-host show <commit>:internal/apply/placement_guard.go \
|
git -C ../../../mesh-host show <commit>:internal/apply/placement_guard.go \
|
||||||
> testdata/beside/mesh-host/internal/apply/placement_guard.go.captured
|
> testdata/beside/mesh-host/internal/apply/placement_guard.go.captured
|
||||||
|
|
||||||
and write the commits here. The placement guard is kept as .captured so no Go tool reads it as this
|
and write the commits here. The placement guard is kept as .captured so no Go tool reads it as this
|
||||||
|
|||||||
Vendored
+99
-4
@@ -56,7 +56,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/novox/mesh-host/internal/declaration"
|
"git.novox.be/novox/mesh-sdk/go/declaration"
|
||||||
)
|
)
|
||||||
|
|
||||||
// protectedRoots are paths no directory, access or mount source may be, nor hold.
|
// protectedRoots are paths no directory, access or mount source may be, nor hold.
|
||||||
@@ -384,6 +384,9 @@ func ownedByAccount(owner string, a homeAccount) bool {
|
|||||||
if owner == a.Name {
|
if owner == a.Name {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
if a.UID < 0 {
|
||||||
|
return false // an account the declaration makes has no uid yet: by name alone, never by a number
|
||||||
|
}
|
||||||
user, _, _ := strings.Cut(owner, ":")
|
user, _, _ := strings.Cut(owner, ":")
|
||||||
if uid, err := strconv.Atoi(user); err == nil {
|
if uid, err := strconv.Atoi(user); err == nil {
|
||||||
return uid == a.UID
|
return uid == a.UID
|
||||||
@@ -413,12 +416,91 @@ const (
|
|||||||
// refusePath says why a path is not placed or mounted; nil when it may be. module is the resource's module,
|
// refusePath says why a path is not placed or mounted; nil when it may be. module is the resource's module,
|
||||||
// owner a directory's declared owner.
|
// owner a directory's declared owner.
|
||||||
func refusePath(path string, kind placing, module, owner string) error {
|
func refusePath(path string, kind placing, module, owner string) error {
|
||||||
|
return refusePathWith(path, kind, module, owner, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// declaredHomes is the home of each account the declaration itself makes (a user resource with a home), by the
|
||||||
|
// account's name; the account is not in the user database yet when the declaration is judged, and the engine makes
|
||||||
|
// it where it is declared, before the directory that is owned by it is reached (novox/hq issue 1542). Its uid is
|
||||||
|
// not known, so a directory is owned by it by name alone. Only for the directory placement guard; no other
|
||||||
|
// reader of accountsOfHomes sees these.
|
||||||
|
func declaredHomes(resources []declaration.Resource) map[string]homeAccount {
|
||||||
|
var accounts []passwdEntry
|
||||||
|
var out map[string]homeAccount
|
||||||
|
for _, r := range resources {
|
||||||
|
u, ok := r.(*declaration.User)
|
||||||
|
if !ok || u.Name == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
home := filepath.Clean(u.Home)
|
||||||
|
if u.Home == "" || !filepath.IsAbs(home) || home == "/" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if accounts == nil {
|
||||||
|
accounts = passwdEntries()
|
||||||
|
}
|
||||||
|
// Only ever adds a home. An account the machine has keeps the home it has (applyUser never moves it), so
|
||||||
|
// a declared home of one is not its home, unless it is the very home it has: the account an earlier apply
|
||||||
|
// made, as declared, which must be judged the same at every later apply. And a home at or below another
|
||||||
|
// account's, or at or above a protected root, is not a new one.
|
||||||
|
taken := false
|
||||||
|
for _, e := range accounts {
|
||||||
|
if e.name == u.Name && e.home != home {
|
||||||
|
taken = true
|
||||||
|
}
|
||||||
|
if e.name != u.Name && e.home != "" && atOrBelow(home, e.home) {
|
||||||
|
taken = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, root := range protectedRoots {
|
||||||
|
taken = taken || home == root || below(root, home)
|
||||||
|
}
|
||||||
|
if taken {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if out == nil {
|
||||||
|
out = map[string]homeAccount{}
|
||||||
|
}
|
||||||
|
out[home] = homeAccount{Name: u.Name, UID: -1}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// passwdEntry is an account of the user database and its home, whatever its uid.
|
||||||
|
type passwdEntry struct{ name, home string }
|
||||||
|
|
||||||
|
// passwdEntries is every account of the user database with its home (empty and root homes as "").
|
||||||
|
func passwdEntries() []passwdEntry {
|
||||||
|
out := []passwdEntry{}
|
||||||
|
f, err := os.Open(passwdFile)
|
||||||
|
if err != nil {
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
sc := bufio.NewScanner(f)
|
||||||
|
for sc.Scan() {
|
||||||
|
fields := strings.Split(sc.Text(), ":")
|
||||||
|
if len(fields) < 6 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
home := filepath.Clean(fields[5])
|
||||||
|
if home == "." || home == "/" || home == "/nonexistent" {
|
||||||
|
home = ""
|
||||||
|
}
|
||||||
|
out = append(out, passwdEntry{fields[0], home})
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// refusePathWith is refusePath with the homes of the accounts the declaration makes (declaredHomes) counted
|
||||||
|
// among the machine's.
|
||||||
|
func refusePathWith(path string, kind placing, module, owner string, declared map[string]homeAccount) error {
|
||||||
clean := filepath.Clean(path)
|
clean := filepath.Clean(path)
|
||||||
if !filepath.IsAbs(clean) {
|
if !filepath.IsAbs(clean) {
|
||||||
return nil // the declaration refuses a relative path already; a named volume is not a path
|
return nil // the declaration refuses a relative path already; a named volume is not a path
|
||||||
}
|
}
|
||||||
for _, p := range []string{clean, resolved(clean)} {
|
for _, p := range []string{clean, resolved(clean)} {
|
||||||
if err := refuseOne(p, kind, module, owner); err != nil {
|
if err := refuseOne(p, kind, module, owner, declared); err != nil {
|
||||||
if p != clean {
|
if p != clean {
|
||||||
err.Why = fmt.Sprintf("through a link, it is %s, and %s", p, err.Why)
|
err.Why = fmt.Sprintf("through a link, it is %s, and %s", p, err.Why)
|
||||||
err.Path = clean
|
err.Path = clean
|
||||||
@@ -429,7 +511,7 @@ func refusePath(path string, kind placing, module, owner string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func refuseOne(path string, kind placing, module, owner string) *PlacementRefusedError {
|
func refuseOne(path string, kind placing, module, owner string, declared map[string]homeAccount) *PlacementRefusedError {
|
||||||
for _, root := range protectedRoots {
|
for _, root := range protectedRoots {
|
||||||
if path == root || below(root, path) {
|
if path == root || below(root, path) {
|
||||||
return &PlacementRefusedError{Path: path, Why: root + " is one of the machine's own directories, " +
|
return &PlacementRefusedError{Path: path, Why: root + " is one of the machine's own directories, " +
|
||||||
@@ -482,6 +564,18 @@ func refuseOne(path string, kind placing, module, owner string) *PlacementRefuse
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
homes := accountsOfHomes()
|
homes := accountsOfHomes()
|
||||||
|
if ssh && len(declared) > 0 {
|
||||||
|
merged := map[string]homeAccount{}
|
||||||
|
for home, a := range homes {
|
||||||
|
merged[home] = a
|
||||||
|
}
|
||||||
|
for home, a := range declared {
|
||||||
|
if _, held := merged[home]; !held {
|
||||||
|
merged[home] = a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
homes = merged
|
||||||
|
}
|
||||||
var deepest string
|
var deepest string
|
||||||
for home := range homes {
|
for home := range homes {
|
||||||
if below(path, home) && len(home) > len(deepest) {
|
if below(path, home) && len(home) > len(deepest) {
|
||||||
@@ -518,11 +612,12 @@ func moduleOfID(id string) string {
|
|||||||
// a file into it, because nothing judged the file's path.
|
// a file into it, because nothing judged the file's path.
|
||||||
func refusedPlaces(resources []declaration.Resource) map[string]error {
|
func refusedPlaces(resources []declaration.Resource) map[string]error {
|
||||||
out := map[string]error{}
|
out := map[string]error{}
|
||||||
|
declared := declaredHomes(resources)
|
||||||
for _, r := range resources {
|
for _, r := range resources {
|
||||||
var err error
|
var err error
|
||||||
switch res := r.(type) {
|
switch res := r.(type) {
|
||||||
case *declaration.Directory:
|
case *declaration.Directory:
|
||||||
err = refusePath(res.Path, placingDirectory, moduleOfID(res.ID), res.Owner)
|
err = refusePathWith(res.Path, placingDirectory, moduleOfID(res.ID), res.Owner, declared)
|
||||||
// And outside every home, the walk's judgement before anything is applied (novox/hq issue 358): a
|
// And outside every home, the walk's judgement before anything is applied (novox/hq issue 358): a
|
||||||
// link another account could make in its path refuses it, and with it what is below it, whatever
|
// link another account could make in its path refuses it, and with it what is below it, whatever
|
||||||
// order they are declared in. The apply walks again at the moment of use. A directory handed over
|
// order they are declared in. The apply walks again at the moment of use. A directory handed over
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module mesh-delivery-teller
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022206-8af6e7266915
|
||||||
github.com/nats-io/nats-server/v2 v2.11.17
|
github.com/nats-io/nats-server/v2 v2.11.17
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030201806-eff81f1220e2 h1:RF73nVI1dTrrmlFosVDTMJmpUQ+rEeB7++BHH/RvZFg=
|
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.20261030201806-eff81f1220e2/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
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.20261101014012-a20bdf795236 h1:JEkSnrmHs5QIRJGhtrghLC1+C0AxqMpef8a32d/BLPg=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc h1:kVq7sS4I0EnL8DcAA2a3YstnXS6WmYYzJz7eK7IZ9RY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62 h1:R5C8ICjiaDITHRFR/uIATwARPPXKxssUC70m0svstb0=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62/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 h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
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=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module mesh-delivery-view
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022206-8af6e7266915
|
||||||
github.com/nats-io/nats-server/v2 v2.11.17
|
github.com/nats-io/nats-server/v2 v2.11.17
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,11 +1,5 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261031084708-acbf80ad910a h1:DcSvfEmdPBKqCg5OmXRNb269EkkPe7BsEp+RykEhkgE=
|
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.20261031084708-acbf80ad910a/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
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.20261101014012-a20bdf795236 h1:JEkSnrmHs5QIRJGhtrghLC1+C0AxqMpef8a32d/BLPg=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc h1:kVq7sS4I0EnL8DcAA2a3YstnXS6WmYYzJz7eK7IZ9RY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62 h1:R5C8ICjiaDITHRFR/uIATwARPPXKxssUC70m0svstb0=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62/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 h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
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=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module mesh-delivery-watchman
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101022206-8af6e7266915
|
||||||
github.com/nats-io/nats-server/v2 v2.11.17
|
github.com/nats-io/nats-server/v2 v2.11.17
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,17 +1,5 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261030201806-eff81f1220e2 h1:RF73nVI1dTrrmlFosVDTMJmpUQ+rEeB7++BHH/RvZFg=
|
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.20261030201806-eff81f1220e2/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
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.20261101005736-7b09de1e5502 h1:XndvkzyAFNde/821lEfYObqMTURzmve/w9Ks+QrBBJ8=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101005736-7b09de1e5502/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101012031-7cab079e2ec3 h1:an2f0MLx9OhaDLu5i51OMPBbuGwX+aoTzqOkFLMpVfE=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101012031-7cab079e2ec3/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101013319-25a2cecd989c h1:rlUCZ5ifLojqDUTkcCCcPrugTzV2RT6F6JbIVTJkaC8=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101013319-25a2cecd989c/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236 h1:JEkSnrmHs5QIRJGhtrghLC1+C0AxqMpef8a32d/BLPg=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014012-a20bdf795236/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc h1:kVq7sS4I0EnL8DcAA2a3YstnXS6WmYYzJz7eK7IZ9RY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101014310-19c204273bdc/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62 h1:R5C8ICjiaDITHRFR/uIATwARPPXKxssUC70m0svstb0=
|
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101020750-62cddf4efc62/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.8.0-default-no-op h1:1BOWQJweNyvZMlpAHXGLiZQn9S+QXGcz3xh94lC0w6E=
|
github.com/antithesishq/antithesis-sdk-go v0.8.0-default-no-op h1:1BOWQJweNyvZMlpAHXGLiZQn9S+QXGcz3xh94lC0w6E=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.8.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
github.com/antithesishq/antithesis-sdk-go v0.8.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
||||||
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ module mesh-grants
|
|||||||
go 1.26.0
|
go 1.26.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101023317-8311ecb84911
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101085317-790d1c82d027
|
||||||
github.com/nats-io/nats.go v1.54.0
|
github.com/nats-io/nats.go v1.54.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101023317-8311ecb84911 h1:+82ygf2hiY5Mhwfmc1xfCe9e/KY/5ObBuE2LecM37qI=
|
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.20261101023317-8311ecb84911/go.mod h1:ouERNpZizzwZ0HLEtAypsY9FR20FyUgUYRni6J7kVCY=
|
git.novox.be/novox/mesh-sdk/go v0.1.14-0.20261101085317-790d1c82d027/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 h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
|
||||||
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
|
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=
|
github.com/google/go-tpm v0.9.8 h1:slArAR9Ft+1ybZu0lBwpSmpwhRXaa85hWtMinMyRAWo=
|
||||||
|
|||||||
Reference in New Issue
Block a user