diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go index fd1ec37a..a0af01fb 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/integration_test.go @@ -8,6 +8,8 @@ import ( "errors" "fmt" "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "io" "maps" "mesh-delivery-assigner/internal/buckets" @@ -246,7 +248,7 @@ func TestTheAssignerDoesNotStartWithoutABucketItReads(t *testing.T) { t.Fatal(err) } pkey, _ := delivery.PutKey("n1", "web") - asked := delivery.Put{FP: delivery.SourcePrefix2 + strings.Repeat("b", 64), Why: "a try", At: time.Now()}.Said(time.Now(), delivery.PutAsked, "asked") + asked := delivery.Put{FP: meshcatalogclient.SourcePrefix2 + strings.Repeat("b", 64), Why: "a try", At: time.Now()}.Said(time.Now(), delivery.PutAsked, "asked") raw, _ := delivery.EncodePut(asked) if _, err := puts.Put(b.ctx, pkey, raw); err != nil { t.Fatal(err) @@ -340,9 +342,9 @@ func (b *bed) compose(t *testing.T, node string, d byte) string { // manifest keeps a manifest in the indexer's bucket by its digest and answers the digest. func (b *bed) manifest(t *testing.T, module, body string) string { t.Helper() - digest := delivery.ManifestDigest([]byte(body)) - key, _ := delivery.ManifestsKey(digest) - value, err := delivery.EncodeManifest(delivery.Manifest{Module: module, JSON: body}) + digest := meshcatalogclient.ManifestDigest([]byte(body)) + key, _ := meshcatalogclient.ManifestsKey(digest) + value, err := meshcatalogclient.EncodeManifest(meshcatalog.ManifestsByDigestValue{Module: module, Manifest: body}) if err != nil { t.Fatal(err) } @@ -383,9 +385,9 @@ func TestWantsAreWrittenAndNoDifferenceIs(t *testing.T) { } } b := startBed(t, "") - fNew, fOld := delivery.SourcePrefix2+strings.Repeat("b", 64), delivery.SourcePrefix2+strings.Repeat("a", 64) + fNew, fOld := meshcatalogclient.SourcePrefix2+strings.Repeat("b", 64), meshcatalogclient.SourcePrefix2+strings.Repeat("a", 64) digest := b.manifest(t, "web", `{"module":"web","version":"1"}`) - mod, _ := delivery.EncodeModule(delivery.Module{FP2: fNew, Manifest: digest, Repository: "novox/web", Commit: strings.Repeat("1", 40), Path: delivery.RootPath}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fNew, Manifest: digest, Repository: "novox/web", Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath}) b.putJSON(t, buckets.Modules, "web", mod) built, err := delivery.EncodeBuilderBuild(delivery.BuilderBuild{State: delivery.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: digest}) if err != nil { @@ -526,12 +528,12 @@ func TestWantsAreWrittenAndNoDifferenceIs(t *testing.T) { } // The provisioner keys it from the manifests, as soon as they are known and whether the provider is placed yet or not. asked(provisions.Asked, "the provider's build is not done") - fpOf := func(c byte) string { return delivery.SourcePrefix2 + strings.Repeat(string(c), 64) } + fpOf := func(c byte) string { return meshcatalogclient.SourcePrefix2 + strings.Repeat(string(c), 64) } toolOld := fpOf('1') for module, row := range map[string]struct { fp, digest string }{"db": {fpOf('2'), dbDigest}, "app": {fpOf('3'), appDigest}, "tool": {fpOf('4'), toolDigest}} { - mod, _ := delivery.EncodeModule(delivery.Module{FP2: row.fp, Manifest: row.digest, Repository: "novox/" + module, Commit: strings.Repeat("2", 40), Path: delivery.RootPath}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: row.fp, Manifest: row.digest, Repository: "novox/" + module, Commit: strings.Repeat("2", 40), Path: meshcatalogclient.RootPath}) b.putJSON(t, buckets.Modules, module, mod) fps := []string{row.fp} if module == "tool" { @@ -590,7 +592,7 @@ func TestWantsAreWrittenAndNoDifferenceIs(t *testing.T) { formsOld, formsNew := fpOf('5'), fpOf('6') formsDigest := b.manifest(t, "forms", `{"module":"forms","version":"1"}`) formsAt := func(fp string) { - mod, _ := delivery.EncodeModule(delivery.Module{FP2: fp, Manifest: formsDigest, Repository: "novox/forms", Commit: strings.Repeat("3", 40), Path: delivery.RootPath}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fp, Manifest: formsDigest, Repository: "novox/forms", Commit: strings.Repeat("3", 40), Path: meshcatalogclient.RootPath}) b.putJSON(t, buckets.Modules, "forms", mod) } for _, fp := range []string{formsOld, formsNew} { @@ -679,9 +681,9 @@ func (s bedState) Await(key string, after uint64, done func([]byte) bool, bound // the one its manifest declares (ownBuckets, held equal to the manifest by TestOpensWhatItsManifestNames). func TestAHeldFingerprintIsAskedAbout(t *testing.T) { b := startBed(t, "") - fNew := delivery.SourcePrefix2 + strings.Repeat("c", 64) + fNew := meshcatalogclient.SourcePrefix2 + strings.Repeat("c", 64) digest := b.manifest(t, "web", `{"module":"web","version":"1"}`) - mod, _ := delivery.EncodeModule(delivery.Module{FP2: fNew, Manifest: digest, Repository: "novox/web", Commit: strings.Repeat("1", 40), Path: delivery.RootPath}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fNew, Manifest: digest, Repository: "novox/web", Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath}) b.putJSON(t, buckets.Modules, "web", mod) on, _ := delivery.EncodePresence(delivery.Presence{Online: true}) b.putJSON(t, buckets.Presence, "ace", on) @@ -737,9 +739,9 @@ func (b *bed) conditionsSaid(t *testing.T) map[string]oc.Condition { // and the check's words. func TestAFailedDataModuleIsAskedToRestore(t *testing.T) { b := startBed(t, "") - fNew := delivery.SourcePrefix2 + strings.Repeat("d", 64) + fNew := meshcatalogclient.SourcePrefix2 + strings.Repeat("d", 64) digest := b.manifest(t, "mail", `{"module":"mail","version":"1","resources":[{"id":"data","type":"directory","path":"/var/lib/mail"}],"data":{"own":[{"id":"mail","path":"${dir:data}","class":"irreplaceable","backup":"copy"}]}}`) - mod, _ := delivery.EncodeModule(delivery.Module{FP2: fNew, Manifest: digest, Repository: "novox/mail", Commit: strings.Repeat("1", 40), Path: delivery.RootPath}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fNew, Manifest: digest, Repository: "novox/mail", Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath}) b.putJSON(t, buckets.Modules, "mail", mod) on, _ := delivery.EncodePresence(delivery.Presence{Online: true}) b.putJSON(t, buckets.Presence, "ace", on) @@ -787,9 +789,9 @@ func TestTheAssignerReplacedResumesWithNothingLostOrRepeated(t *testing.T) { for i := range names { name := fmt.Sprintf("mod%02d", i) names[i] = name - fp := delivery.SourcePrefix2 + strings.Repeat(string(rune('a'+i%6)), 63) + fmt.Sprintf("%x", i%16) + fp := meshcatalogclient.SourcePrefix2 + strings.Repeat(string(rune('a'+i%6)), 63) + fmt.Sprintf("%x", i%16) digest := b.manifest(t, name, fmt.Sprintf(`{"module":%q,"version":"1"}`, name)) - mod, _ := delivery.EncodeModule(delivery.Module{FP2: fp, Manifest: digest, Repository: "novox/" + name, Commit: strings.Repeat("1", 40), Path: delivery.RootPath}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fp, Manifest: digest, Repository: "novox/" + name, Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath}) b.putJSON(t, buckets.Modules, name, mod) built, err := delivery.EncodeBuilderBuild(delivery.BuilderBuild{State: delivery.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: digest}) if err != nil { @@ -835,7 +837,7 @@ func TestTheAssignerReplacedResumesWithNothingLostOrRepeated(t *testing.T) { func (b *bed) fixture(t *testing.T, name, fp, manifest string) { t.Helper() digest := b.manifest(t, name, manifest) - mod, _ := delivery.EncodeModule(delivery.Module{FP2: fp, Manifest: digest, Repository: "novox/" + name, Commit: strings.Repeat("1", 40), Path: delivery.RootPath}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fp, Manifest: digest, Repository: "novox/" + name, Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath}) b.putJSON(t, buckets.Modules, name, mod) built, _ := delivery.EncodeBuilderBuild(delivery.BuilderBuild{State: delivery.BuildDone, By: "builder.novox.1", Step: "pushed", Manifest: digest}) bkey, _ := delivery.BuilderBuildKey(name, fp) @@ -906,7 +908,7 @@ func (b *bed) hasKey(bucket, key string) bool { // and clears the condition. func TestAReleaseAnswerWritesTheWantAgain(t *testing.T) { b := startBed(t, "") - fNew, fOld := delivery.SourcePrefix2+strings.Repeat("b", 64), delivery.SourcePrefix2+strings.Repeat("a", 64) + fNew, fOld := meshcatalogclient.SourcePrefix2+strings.Repeat("b", 64), meshcatalogclient.SourcePrefix2+strings.Repeat("a", 64) b.fixture(t, "web", fNew, `{"module":"web","version":"1"}`) b.compose(t, "ace", 'b') b.compose(t, "ace", 'a') @@ -958,7 +960,7 @@ func (b *bed) askNow(t *testing.T, key string, asking int) decodedAsk { // value, so the node retries. func TestABackupAnswerIsWrittenIntoTheNodesWant(t *testing.T) { b := startBed(t, "") - fNew := delivery.SourcePrefix2 + strings.Repeat("b", 64) + fNew := meshcatalogclient.SourcePrefix2 + strings.Repeat("b", 64) b.fixture(t, "web", fNew, `{"module":"web","version":"1"}`) b.compose(t, "ace", 'b') b.putWant(t, "ace", "web", delivery.Want{FP: fNew, Self: true}) // a placed node's want names the build alone @@ -1002,7 +1004,7 @@ const recorded = `{"module":"web","version":"1","upgrade":{"policy":"record","wh // cleared saying why, and the want stays at the fingerprint. func TestAHoldIsLiftedOnceEveryNodeRunsItHealthy(t *testing.T) { b := startBed(t, "") - fNew := delivery.SourcePrefix2 + strings.Repeat("b", 64) + fNew := meshcatalogclient.SourcePrefix2 + strings.Repeat("b", 64) b.fixture(t, "web", fNew, `{"module":"web","version":"1"}`) b.compose(t, "ace", 'b') failed, _ := nodeengineclient.EncodeHave(nodeengine.HaveByNodeModuleValue{Fp: fNew, Phase: nodeengineclient.PhaseRunning, Health: nodeengineclient.HealthFailed, Detail: "connection refused"}) @@ -1035,7 +1037,7 @@ func TestAHoldIsLiftedOnceEveryNodeRunsItHealthy(t *testing.T) { // new id, so the teller raises it; the answer to the first hold does not carry over (1906/H4). func TestAHoldWrittenAgainAfterALiftAndARestartIsAskedAgain(t *testing.T) { b := startBed(t, "") - fNew := delivery.SourcePrefix2 + strings.Repeat("b", 64) + fNew := meshcatalogclient.SourcePrefix2 + strings.Repeat("b", 64) b.fixture(t, "web", fNew, `{"module":"web","version":"1"}`) b.compose(t, "ace", 'b') failed, _ := nodeengineclient.EncodeHave(nodeengine.HaveByNodeModuleValue{Fp: fNew, Phase: nodeengineclient.PhaseRunning, Health: nodeengineclient.HealthFailed, Detail: "connection refused"}) diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass.go index 4a7ac479..161c1dc4 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" + "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "maps" "mesh-delivery-assigner/internal/buckets" "slices" @@ -200,7 +201,7 @@ func (p *passer) wants(ctx context.Context) { served := p.served(ctx, get, moduleGraph, nodes) offering := p.offering(ctx, get, manifests, nodes) // bus state (ADR 0614 §5) for name := range names { - fp := trunk[name].FP2 + fp := trunk[name].Fp2 name := name m := assign.Module{Name: name, FP: fp, Manifest: manifests[name], Needs: trunk[name].Needs, Chosen: chosenOf(chosen, name), Provisions: provisionsOf(name), Answering: answering(manifests, nodes), Offered: offered(manifests), Nodes: nodesOf[name], Now: time.Now(), Puts: puts[name], FormNeeds: p.w.buildNeeds(name, fp), Self: func(node string) bool { return placed[node] }, @@ -601,7 +602,7 @@ func (p *passer) lift(ctx context.Context, module, fp string) { // controller no longer composes for the node at that fingerprint. A backup ask and an ask of another kind are never stale here. // A module of the trunk whose fingerprint is not read yet, and a composition not read yet, are not stale: nothing known is // nothing taken away. -func (p *passer) staleAsk(key string, trunk map[string]delivery.Module) bool { +func (p *passer) staleAsk(key string, trunk map[string]meshcatalog.ModulesByModuleValue) bool { k, err := delivery.ParseAnyAskKey(key) if err != nil { return false @@ -609,7 +610,7 @@ func (p *passer) staleAsk(key string, trunk map[string]delivery.Module) bool { switch k.Kind { case delivery.AskKindHold, delivery.AskKindRestore: m, on := trunk[k.Module] - return !on || (m.FP2 != "" && m.FP2 != k.FP) + return !on || (m.Fp2 != "" && m.Fp2 != k.FP) case delivery.AskKindRecord: m, on := trunk[k.Module] if !on { @@ -627,13 +628,13 @@ func (p *passer) staleAsk(key string, trunk map[string]delivery.Module) bool { // revised composition of the fingerprint it runs (ADR 0545), and a node's first want at the older fingerprint it runs. So a // record ask is stale only when its digest is the composition of none of the fingerprints the node can still want (the // trunk's, its want's, its have's), and only when every one of them is read. - for _, fp := range p.fingerprintsOf(k.Node, k.Module, m.FP2) { + for _, fp := range p.fingerprintsOf(k.Node, k.Module, m.Fp2) { d, ok := p.w.composed(k.Node, k.Module, fp) if !ok || d.Digest == k.Composed { return false } } - return len(p.fingerprintsOf(k.Node, k.Module, m.FP2)) > 0 + return len(p.fingerprintsOf(k.Node, k.Module, m.Fp2)) > 0 } return false } @@ -664,7 +665,7 @@ func (p *passer) fingerprintsOf(node, module, trunkFP string) []string { // staleAsks takes away, at every pass, each hold, restore and record ask that staleAsk names (issue 1906, note 28): an ask // outlived its fingerprint, and the teller takes its router ask back from the operator when the key goes. With the trunk not // read at all (no module), nothing is taken away. -func (p *passer) staleAsks(ctx context.Context, trunk map[string]delivery.Module) { +func (p *passer) staleAsks(ctx context.Context, trunk map[string]meshcatalog.ModulesByModuleValue) { if len(trunk) == 0 { return } diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go index 33589508..4698a858 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/pass_test.go @@ -7,6 +7,8 @@ import ( "errors" "fmt" "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "mesh-delivery-assigner/internal/buckets" "slices" "strings" @@ -88,7 +90,7 @@ func composes(t *testing.T, w *world, node, digest string) { w.put(buckets.Have, key, raw) } -var fpTest = delivery.SourcePrefix2 + strings.Repeat("b", 64) +var fpTest = meshcatalogclient.SourcePrefix2 + strings.Repeat("b", 64) // 1906/H2: given a hold lifted by itself, when the assigner is started again and the same fingerprint is held again, then the // hold ask is written under another asking, with an id of its own, so the teller raises it (the router drops a second ask under @@ -315,7 +317,7 @@ func (b *fakeBus) Emit(eventType string, body any) error { func putOfTheBus(t *testing.T) { ctx := context.Background() now := time.Date(2026, 10, 25, 22, 0, 0, 0, time.UTC) - fp := delivery.SourcePrefix2 + "fd497ab8" + strings.Repeat("0", 56) + fp := meshcatalogclient.SourcePrefix2 + "fd497ab8" + strings.Repeat("0", 56) digest := "sha256:" + strings.Repeat("d", 64) mem := func() *memKV { return &memKV{values: map[string][]byte{}} } puts, asksKV, wantsKV := mem(), mem(), mem() @@ -340,14 +342,14 @@ func putOfTheBus(t *testing.T) { } placeOn(t, p.w, "novox", "nats") mdigest := strings.Repeat("e", 64) - mod, _ := delivery.EncodeModule(delivery.Module{FP2: fp, Manifest: mdigest, Repository: "novox/mesh-catalog", Commit: strings.Repeat("c", 40)}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fp, Manifest: mdigest, Repository: "novox/mesh-catalog", Commit: strings.Repeat("c", 40)}) world(buckets.Modules, "nats", mod) p.w.manifests[mdigest] = parsed{module: "nats", manifest: catalogue.Manifest{Module: "nats", Provides: []catalogue.Offer{{Name: "mesh-bus"}}}} bkey, _ := delivery.BuilderBuildKey("nats", fp) built, _ := delivery.EncodeBuilderBuild(delivery.BuilderBuild{State: delivery.BuildDone, Manifest: mdigest}) world(buckets.Builds, bkey, built) hkey, _ := nodeengineclient.HaveKey("novox", "nats") - before, _ := nodeengineclient.EncodeHave(nodeengine.HaveByNodeModuleValue{Fp: delivery.SourcePrefix2 + strings.Repeat("a", 64), Phase: nodeengineclient.PhaseRunning, Health: nodeengineclient.HealthOK}) + before, _ := nodeengineclient.EncodeHave(nodeengine.HaveByNodeModuleValue{Fp: meshcatalogclient.SourcePrefix2 + strings.Repeat("a", 64), Phase: nodeengineclient.PhaseRunning, Health: nodeengineclient.HealthOK}) world(buckets.Have, hkey, before) builds := mem() @@ -464,7 +466,7 @@ func putOfTheBus(t *testing.T) { } <-woke // Released between the pass's read and its write: the pass writes no want for the put that no longer stands. - oldWant, _ := delivery.EncodeWant(delivery.Want{FP: delivery.SourcePrefix2 + strings.Repeat("a", 64)}) + oldWant, _ := delivery.EncodeWant(delivery.Want{FP: meshcatalogclient.SourcePrefix2 + strings.Repeat("a", 64)}) wantsKV.values["want.novox.nats"] = oldWant world(buckets.Wants, "want.novox.nats", oldWant) if _, err := s.doRelease(map[string]any{"node": "novox", "module": "nats", "why": "changed my mind"}, "shanks.node-tools"); err != nil { @@ -655,7 +657,7 @@ func TestTheFirstPassAfterAStartClearsWhatAPreviousProcessRaised(t *testing.T) { p := newPasser(kvSet{buckets.Wants: wantsKV, buckets.Asks: &memKV{values: map[string][]byte{}}}, time.Now()) var said []oc.Condition p.say = func(c oc.Condition) error { said = append(said, c); return nil } - mod, _ := delivery.EncodeModule(delivery.Module{FP2: fpTest, Repository: "novox/web", Commit: strings.Repeat("1", 40), Path: delivery.RootPath}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fpTest, Repository: "novox/web", Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath}) p.w.put(buckets.Modules, "web", mod) placeOn(t, p.w, "g14", "web") on, _ := delivery.EncodePresence(delivery.Presence{Online: true}) @@ -693,7 +695,7 @@ func testAHeldModuleRaisesNoNeitherAndClearsAStandingOne(t *testing.T) { p := newPasser(kvSet{buckets.Wants: &memKV{values: map[string][]byte{}}, buckets.Asks: &memKV{values: map[string][]byte{}}}, time.Now()) said := &[]oc.Condition{} p.say = func(c oc.Condition) error { *said = append(*said, c); return nil } - mod, _ := delivery.EncodeModule(delivery.Module{FP2: fpTest, Repository: "novox/resolved", Commit: strings.Repeat("1", 40), Path: delivery.RootPath}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fpTest, Repository: "novox/resolved", Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath}) p.w.put(buckets.Modules, "systemd-resolved", mod) placeOn(t, p.w, "shanks", "systemd-resolved") on, _ := delivery.EncodePresence(delivery.Presence{Online: true}) @@ -740,10 +742,10 @@ func testAHeldModuleRaisesNoNeitherAndClearsAStandingOne(t *testing.T) { // fingerprint (or composition) is not the trunk's now, or whose module left the trunk; a trunk not read takes nothing away; a // backup ask is left; and a lift takes the restore asks of its fingerprint on every node. func TestAsksOfAFingerprintTheTrunkLeftBehindAreTakenAway(t *testing.T) { - fpOld, fpNew := delivery.SourcePrefix2+strings.Repeat("a", 64), delivery.SourcePrefix2+strings.Repeat("c", 64) + fpOld, fpNew := meshcatalogclient.SourcePrefix2+strings.Repeat("a", 64), meshcatalogclient.SourcePrefix2+strings.Repeat("c", 64) digOld, digNew := "sha256:"+strings.Repeat("d", 64), "sha256:"+strings.Repeat("e", 64) - trunkOf := func(fp string) map[string]delivery.Module { - return map[string]delivery.Module{"web": {FP2: fp, Manifest: "sha256:" + strings.Repeat("1", 64), Repository: "novox/web", Commit: strings.Repeat("1", 40), Path: delivery.RootPath}} + trunkOf := func(fp string) map[string]meshcatalog.ModulesByModuleValue { + return map[string]meshcatalog.ModulesByModuleValue{"web": {Fp2: fp, Manifest: "sha256:" + strings.Repeat("1", 64), Repository: "novox/web", Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath}} } type ask struct{ name, key string } holdOld, _ := delivery.HoldAskKey("web", fpOld) @@ -757,7 +759,7 @@ func TestAsksOfAFingerprintTheTrunkLeftBehindAreTakenAway(t *testing.T) { all := []string{holdOld, holdNew, holdGone, restOld, restNew, recOld, recNew, backOld} for _, c := range []struct { name string - trunk map[string]delivery.Module + trunk map[string]meshcatalog.ModulesByModuleValue gone []string // the keys taken away noDigit bool // the node's own composition is not read }{ @@ -899,7 +901,7 @@ func TestARecordAskOfAHeldBackNodeSurvivesPassesAndItsYesMovesTheWant(t *testing // given its yes by that Approve, the want naming the release, and no record ask is raised; a move that changes a setting or a // secret too, one at the build it runs, and one no approved release carries are asked of a person as before. func aReleasesApproveAnswersTheMoveOfItsBuildAlone(t *testing.T) { - fpOld := delivery.SourcePrefix2 + strings.Repeat("a", 64) + fpOld := meshcatalogclient.SourcePrefix2 + strings.Repeat("a", 64) waiting, was := "sha256:"+strings.Repeat("e", 64), "sha256:"+strings.Repeat("d", 64) commit := strings.Repeat("1", 40) for _, c := range []struct { @@ -907,7 +909,7 @@ func aReleasesApproveAnswersTheMoveOfItsBuildAlone(t *testing.T) { alone bool at string // the fingerprint the have runs mergedAt string // the commit the release merged web at; "" for no merge of the release - fpSrc uint64 // the source revision at which web's fingerprint last changed + fpSrc int64 // the source revision at which web's fingerprint last changed yes, asked bool }{ {"the build alone, its release approved", true, fpOld, commit, 7, true, false}, @@ -924,7 +926,7 @@ func aReleasesApproveAnswersTheMoveOfItsBuildAlone(t *testing.T) { asksKV := &memKV{values: map[string][]byte{}} p := newPasser(kvSet{buckets.Asks: asksKV}, time.Now()) p.logf = t.Logf - mod, _ := delivery.EncodeModule(delivery.Module{FP2: fpTest, Repository: "novox/web", Commit: commit, Src: 7, FPSrc: c.fpSrc, Path: delivery.RootPath}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fpTest, Repository: "novox/web", Commit: commit, Src: 7, FpSrc: c.fpSrc, Path: meshcatalogclient.RootPath}) p.w.put(buckets.Modules, "web", mod) src, _ := delivery.EncodeSource(delivery.Source{Group: "feat/web", Heads: map[string]string{"novox/web": commit}}) p.w.putEntry(buckets.Source, delivery.SourceMainKey, src, 7, time.Now()) @@ -981,13 +983,13 @@ func aPlacementAloneNamesWhereModulesRun(t *testing.T) { // names no composition; a have waiting for a yes raises the record ask once, and the yes is written into the want and // kept there while the want stays at its build. func aPlacedNodesWantsNameTheBuildAloneAndItsYesComesFromItsHave(t *testing.T) { - fpOld := delivery.SourcePrefix2 + strings.Repeat("a", 64) + fpOld := meshcatalogclient.SourcePrefix2 + strings.Repeat("a", 64) waiting, was := "sha256:"+strings.Repeat("e", 64), "sha256:"+strings.Repeat("d", 64) asksKV, wantsKV := &memKV{values: map[string][]byte{}}, &memKV{values: map[string][]byte{}} p := newPasser(kvSet{buckets.Asks: asksKV, buckets.Wants: wantsKV}, time.Now()) p.logf = t.Logf put := func(bucket, key string, v []byte) { p.w.put(bucket, key, v) } - mod, _ := delivery.EncodeModule(delivery.Module{FP2: fpTest, Repository: "novox/web", Commit: strings.Repeat("1", 40), Path: delivery.RootPath}) + mod, _ := meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{Fp2: fpTest, Repository: "novox/web", Commit: strings.Repeat("1", 40), Path: meshcatalogclient.RootPath}) put(buckets.Modules, "web", mod) // the trunk's build is not done: rule 1 holds g14 at fpOld placeOn(t, p.w, "g14", "web") pl, _ := mmac.EncodePlacement(mma.Placement{Node: "g14", Modules: []mma.PlacedModule{{Module: "web"}}}) @@ -1106,7 +1108,7 @@ func TestAnApprovedPlacementCallsNoControllerVerb(t *testing.T) { // serves it, and a build whose manifest cannot be read counts what the graph says its module serves. No graph read: no wait. func aWantWaitsOnTheVerbEdgesTheGraphKeeps(t *testing.T) { p := newPasser(kvSet{}, time.Now()) - fp := func(c string) string { return delivery.SourcePrefix2 + strings.Repeat(c, 64) } + fp := func(c string) string { return meshcatalogclient.SourcePrefix2 + strings.Repeat(c, 64) } if p.served(context.Background(), nil, graph.Graph{}, assign.Nodes{}) != nil { t.Error("with no graph read, a want waits on a verb") } @@ -1128,7 +1130,7 @@ func aWantWaitsOnTheVerbEdgesTheGraphKeeps(t *testing.T) { t.Errorf("the kept verb edges of caller = %v", got) } digest := strings.Repeat("d", 64) - man, _ := delivery.EncodeManifest(delivery.Manifest{Module: "server", JSON: `{"module":"server","claims":[{"name":"x","scope":"mesh","serves":["w"]}]}`}) + man, _ := meshcatalogclient.EncodeManifest(meshcatalog.ManifestsByDigestValue{Module: "server", Manifest: `{"module":"server","claims":[{"name":"x","scope":"mesh","serves":["w"]}]}`}) get := func(_ context.Context, key string) ([]byte, error) { if key == digest { return man, nil diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/puts.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/puts.go index bb5ce799..46553b58 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/puts.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/puts.go @@ -170,7 +170,7 @@ func normalWant(w delivery.Want) delivery.Want { // putWorld is what one step of a put reads from the world. func (p *passer) putWorld(node, module string, put delivery.Put, manifest catalogue.Manifest, assignedHere []string) assign.PutWorld { - w := assign.PutWorld{Node: node, Module: module, Put: put, Now: p.clock(), Bus: catalogue.ProvidesBus(manifest), Newest: p.w.trunk()[module].FP2} + w := assign.PutWorld{Node: node, Module: module, Put: put, Now: p.clock(), Bus: catalogue.ProvidesBus(manifest), Newest: p.w.trunk()[module].Fp2} for _, m := range assignedHere { if m == module { w.Assigned = true diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go index 9e5b551c..487dcf9c 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat.go @@ -7,6 +7,7 @@ import ( "fmt" "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "maps" "mesh-delivery-assigner/internal/buckets" "reflect" @@ -453,7 +454,7 @@ func (p *passer) layAgain(ctx context.Context, prop mma.Proposal, rev uint64, cu func (p *passer) lays(ctx context.Context) (func(string) bool, func(string) bool) { held := map[string]bool{} for key := range p.w.read(buckets.Modules) { - if name, err := delivery.ParseModulesKey(key); err == nil { + if name, err := meshcatalogclient.ParseModulesKey(key); err == nil { held[name] = true } } diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go index 613a5c2a..74d44e61 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools.go @@ -6,6 +6,7 @@ import ( "fmt" "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "slices" "sort" "strings" @@ -103,7 +104,7 @@ func (s *seatTools) lays() (func(string) bool, func(string) bool, error) { } held := map[string]bool{} for _, k := range mods { - if name, err := delivery.ParseModulesKey(k); err == nil { + if name, err := meshcatalogclient.ParseModulesKey(k); err == nil { held[name] = true } } diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools_test.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools_test.go index c6e34b3b..c5ff72f7 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools_test.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/seat_tools_test.go @@ -7,6 +7,8 @@ import ( "fmt" "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "git.novox.be/novox/mesh-sdk/go/keys" "mesh-delivery-assigner/internal/buckets" "os" @@ -195,7 +197,7 @@ func TestTheSeatsVerbs(t *testing.T) { t.Run("1953/D4-D6: the seat mesh-wants' upgrade and bus", wantsVerbs) t.Run("1955/L7 (ADR 0571 §6): rule 7 reads the node's own composition; an unplaced node is said", func(t *testing.T) { w := newWorld() - fp := delivery.SourcePrefix2 + strings.Repeat("2", 64) + fp := meshcatalogclient.SourcePrefix2 + strings.Repeat("2", 64) pl, _ := mmac.EncodePlacement(mma.Placement{V: keys.Version, Node: "ace", Modules: []mma.PlacedModule{{Module: "web"}}}) pkey, _ := mmac.LegacyKey("ace") w.putEntry(plc.PlacementBucket, pkey, pl, 1, time.Now()) @@ -373,7 +375,7 @@ func TestTheSeatsVerbs(t *testing.T) { // written with who and why, recorded as a hand act in the seat's log and said as policy-changed, and default takes it back; // the bus is refused; compare lists each node's composition and the findings; bus names the node behind the indexer's newest. func wantsVerbs(t *testing.T) { - fpOld, fpNew := delivery.SourcePrefix2+strings.Repeat("1", 64), delivery.SourcePrefix2+strings.Repeat("2", 64) + fpOld, fpNew := meshcatalogclient.SourcePrefix2+strings.Repeat("1", 64), meshcatalogclient.SourcePrefix2+strings.Repeat("2", 64) st := memStore{} for _, state := range []string{modulesState, manifestsState, policiesState, haveState, putsState, "findings", buckets.ComposedRead} { st[state] = &memKV{values: map[string][]byte{}} @@ -387,9 +389,9 @@ func wantsVerbs(t *testing.T) { st[buckets.ComposedRead].values[refusedKey], _ = delivery.EncodeComposed(delivery.Composed{Node: "laptop", Module: "web", FP: fpNew, Refused: "a required value is unset"}) manifest := func(name, extra string) { raw := `{"module":"` + name + `","version":"1"` + extra + `}` - digest := delivery.ManifestDigest([]byte(raw)) - st[manifestsState].values[digest], _ = delivery.EncodeManifest(delivery.Manifest{V: keys.Version, Module: name, JSON: raw}) - st[modulesState].values[name], _ = delivery.EncodeModule(delivery.Module{V: keys.Version, FP2: fpNew, Manifest: digest, Repository: "novox/x", Commit: "c"}) + digest := meshcatalogclient.ManifestDigest([]byte(raw)) + st[manifestsState].values[digest], _ = meshcatalogclient.EncodeManifest(meshcatalog.ManifestsByDigestValue{V: keys.Version, Module: name, Manifest: raw}) + st[modulesState].values[name], _ = meshcatalogclient.EncodeModule(meshcatalog.ModulesByModuleValue{V: keys.Version, Fp2: fpNew, Manifest: digest, Repository: "novox/x", Commit: "c"}) } manifest("web", "") manifest("photos", `,"upgrade":{"policy":"record","why":"a person checks the albums"}`) diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go index 59cab6a3..9aa373cf 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/tools.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "os" "regexp" "slices" @@ -81,18 +82,18 @@ func (s *putTools) version(module, version string) (string, error) { if !found { return "", fmt.Errorf("the indexer holds no module %s at the trunk", module) } - m, err := delivery.DecodeModule(raw) + m, err := meshcatalogclient.DecodeModule(raw) if err != nil { return "", fmt.Errorf("the indexer's %s cannot be read: %w", module, err) } - if m.FP2 == "" { + if m.Fp2 == "" { return "", fmt.Errorf("the indexer holds no fingerprint of the new form for %s: %s", module, m.None2) } - return m.FP2, nil + return m.Fp2, nil case fullFP.MatchString(v): return v, nil case prefix.MatchString(v): - start := strings.TrimPrefix(v, delivery.SourcePrefix2) + start := strings.TrimPrefix(v, meshcatalogclient.SourcePrefix2) keys, err := s.st.keys(delivery.BuilderModule + ".builds") if err != nil { return "", fmt.Errorf("the builder's builds cannot be listed: %w", err) @@ -100,7 +101,7 @@ func (s *putTools) version(module, version string) (string, error) { var found []string for _, k := range keys { m, fp, err := delivery.ParseBuilderBuildKey(k) - if err == nil && m == module && strings.HasPrefix(strings.TrimPrefix(fp, delivery.SourcePrefix2), start) { + if err == nil && m == module && strings.HasPrefix(strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2), start) { found = append(found, fp) } } @@ -371,7 +372,7 @@ func serveTools() error { // shortFP is a fingerprint's first twelve hex digits. func shortFP(fp string) string { - part, err := delivery.FingerprintKeyPart(fp) + part, err := meshcatalogclient.KeyPart(fp) if err != nil || len(part) < 12 { return fp } diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go index 3886f495..d622a712 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/wants_tools.go @@ -7,6 +7,8 @@ import ( "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" meshhandacts "git.novox.be/novox/mesh-contracts/health-and-repair/go/seats/meshhandacts" "git.novox.be/novox/mesh-contracts/placement/go/seats/meshwants" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "mesh-delivery-assigner/internal/buckets" "sort" "strconv" @@ -96,14 +98,14 @@ func (s *wantsTools) manifest(digest string) ([]byte, bool, error) { } // manifests is every module the indexer holds, with its trunk manifest and fingerprint. -func (s *wantsTools) manifests() (map[string]catalogue.Manifest, map[string]delivery.Module, error) { +func (s *wantsTools) manifests() (map[string]catalogue.Manifest, map[string]meshcatalog.ModulesByModuleValue, error) { mods, err := s.values(modulesState) if err != nil { return nil, nil, err } - out, held := map[string]catalogue.Manifest{}, map[string]delivery.Module{} + out, held := map[string]catalogue.Manifest{}, map[string]meshcatalog.ModulesByModuleValue{} for name, raw := range mods { - m, err := delivery.DecodeModule(raw) + m, err := meshcatalogclient.DecodeModule(raw) if err != nil { continue } @@ -115,12 +117,12 @@ func (s *wantsTools) manifests() (map[string]catalogue.Manifest, map[string]deli if err != nil || !found { continue } - kept, err := delivery.DecodeManifest(mraw) + kept, err := meshcatalogclient.DecodeManifest(mraw) if err != nil { continue } // Decoded, never judged (ADR 0578 §3); one that does not decode is left out of the answer, as before. - if man, err := catalogue.Decode([]byte(kept.JSON)); err == nil { + if man, err := catalogue.Decode([]byte(kept.Manifest)); err == nil { out[name] = man } } @@ -270,7 +272,7 @@ func (s *wantsTools) doBus(map[string]any) (any, error) { if bus == "" { return nil, errors.New("the indexer holds no module that provides the bus") } - newest := held[bus].FP2 + newest := held[bus].Fp2 haves, err := s.values(haveState) if err != nil { return nil, err diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go index 095a1dd3..7e7ef6b7 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world.go @@ -5,6 +5,8 @@ import ( "errors" "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "git.novox.be/novox/mesh-sdk/go/keys" "maps" "mesh-delivery-assigner/internal/buckets" @@ -96,11 +98,11 @@ func (w *world) putEntry(bucket, key string, value []byte, revision uint64, at t // unknown: none, and the move is asked of a person. func (w *world) release(module, fp string) (string, bool) { t, ok := w.trunk()[module] - if !ok || fp == "" || t.FP2 != fp || t.FPSrc == 0 || t.Commit == "" { + if !ok || fp == "" || t.Fp2 != fp || t.FpSrc == 0 || t.Commit == "" { return "", false } w.mu.Lock() - group := w.sourceGroups[t.FPSrc] + group := w.sourceGroups[uint64(t.FpSrc)] w.mu.Unlock() key, err := delivery.MergesKey(group) if group == "" || err != nil { @@ -226,7 +228,7 @@ func (w *world) manifest(ctx context.Context, get getter, digest string) parsed if ok { return p } - key, err := delivery.ManifestsKey(digest) + key, err := meshcatalogclient.ManifestsKey(digest) if err != nil { return parsed{err: err.Error()} } @@ -237,10 +239,10 @@ func (w *world) manifest(ctx context.Context, get getter, digest string) parsed if err != nil { return parsed{err: err.Error()} } - m, err := delivery.DecodeManifest(value) + m, err := meshcatalogclient.DecodeManifest(value) if err != nil { p = parsed{err: err.Error()} - } else if man, err := catalogue.Decode([]byte(m.JSON)); err != nil { + } else if man, err := catalogue.Decode([]byte(m.Manifest)); err != nil { // Decoded, never judged (novox/hq ADR 0578 §3): the indexer's judge judged it, and its verdict is taken from the // module's value where it is read (world.mesh). p = parsed{module: m.Module, err: "it does not decode: " + err.Error()} @@ -292,14 +294,14 @@ func (w *world) placedNodes() map[string]bool { } // trunk is every module the indexer holds at the trunk, with its value. -func (w *world) trunk() map[string]delivery.Module { - out := map[string]delivery.Module{} +func (w *world) trunk() map[string]meshcatalog.ModulesByModuleValue { + out := map[string]meshcatalog.ModulesByModuleValue{} for key, value := range w.read(buckets.Modules) { - name, err := delivery.ParseModulesKey(key) + name, err := meshcatalogclient.ParseModulesKey(key) if err != nil { continue } - if m, err := delivery.DecodeModule(value); err == nil { + if m, err := meshcatalogclient.DecodeModule(value); err == nil { out[name] = m } } diff --git a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go index 64c4e0f8..358ebe41 100644 --- a/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go +++ b/modules/mesh-delivery-assigner/cmd/mesh-delivery-assigner/world_test.go @@ -2,6 +2,8 @@ package main import ( "context" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" + "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshcatalog" "mesh-delivery-assigner/internal/buckets" "slices" "strings" @@ -16,8 +18,8 @@ type fakeManifests map[string][]byte func (f fakeManifests) add(t *testing.T, module, body string) string { t.Helper() - digest := delivery.ManifestDigest([]byte(body)) - value, err := delivery.EncodeManifest(delivery.Manifest{Module: module, JSON: body}) + digest := meshcatalogclient.ManifestDigest([]byte(body)) + value, err := meshcatalogclient.EncodeManifest(meshcatalog.ManifestsByDigestValue{Module: module, Manifest: body}) if err != nil { t.Fatal(err) } @@ -32,7 +34,7 @@ func (f fakeManifests) get(_ context.Context, key string) ([]byte, error) { return nil, errNotThere } -func fp(c byte) string { return delivery.SourcePrefix2 + strings.Repeat(string(c), 64) } +func fp(c byte) string { return meshcatalogclient.SourcePrefix2 + strings.Repeat(string(c), 64) } func pull(repo string, number int, modules map[string]delivery.CandidateModule) delivery.CandidatePull { p := delivery.CandidatePull{Head: delivery.Head{Repository: repo, Number: number, Head: strings.Repeat("3", 40)}, Fps: modules} @@ -56,7 +58,7 @@ func theWorldCountsTheValuesAKeyTakes(t *testing.T) { t.Errorf("changed = %d for a key never seen", got) } // ADR 0571 clause 9: grants are read from the grants part's bucket, the one bucket of grants (ADR 0590). - fp := delivery.SourcePrefix2 + strings.Repeat("d", 64) + fp := meshcatalogclient.SourcePrefix2 + strings.Repeat("d", 64) gkey, _ := delivery.PartGrantKey("web", fp) grant, _ := delivery.EncodeGrant(delivery.Grant{Accounts: []string{"ace.web"}}) for _, row := range []struct { diff --git a/modules/mesh-delivery-assigner/internal/assign/asks.go b/modules/mesh-delivery-assigner/internal/assign/asks.go index 203a7529..34a0493d 100644 --- a/modules/mesh-delivery-assigner/internal/assign/asks.go +++ b/modules/mesh-delivery-assigner/internal/assign/asks.go @@ -2,6 +2,7 @@ package assign import ( "fmt" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "regexp" "strings" "time" @@ -64,7 +65,7 @@ func RestoreAsk(key, node, module, fp, words string, now time.Time) delivery.Ass // words, under the assigner's own name (ADR 0437 clause 9), keyed by the held fingerprint. needsYou is true for a module holding // data, whose restore ask waits for the operator. func HeldCondition(module, fp, node, words string, raised, needsYou bool) oc.Condition { - key := delivery.AssignerModule + ".held." + module + "." + strings.TrimPrefix(fp, delivery.SourcePrefix2) + key := delivery.AssignerModule + ".held." + module + "." + strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2) subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node} if !raised { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared} @@ -232,7 +233,7 @@ func BackupAsk(key, node, module, fp, digest, words string, asking int, now time // BackupCondition is the condition raised when a backup before an apply fails and the module is held on the node (ADR 0539 §16), // naming the node, the module and the backup's words; cleared under the same key. func BackupCondition(node, module, fp, words string, raised bool) oc.Condition { - key := delivery.AssignerModule + ".backup." + node + "." + module + "." + strings.TrimPrefix(fp, delivery.SourcePrefix2) + key := delivery.AssignerModule + ".backup." + node + "." + module + "." + strings.TrimPrefix(fp, meshcatalogclient.SourcePrefix2) subject := oc.ConditionSubject{Scope: "module", ID: module, Machine: node} if !raised { return oc.Condition{Key: key, Subject: subject, State: occ.StateCleared} diff --git a/modules/mesh-delivery-assigner/internal/assign/asks_test.go b/modules/mesh-delivery-assigner/internal/assign/asks_test.go index 2009f35b..0028497b 100644 --- a/modules/mesh-delivery-assigner/internal/assign/asks_test.go +++ b/modules/mesh-delivery-assigner/internal/assign/asks_test.go @@ -2,6 +2,7 @@ package assign import ( "fmt" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "slices" "strings" "testing" @@ -137,11 +138,11 @@ func saidConditionsAreFindings(t *testing.T) { raised, cleared oc.Condition key string }{ - {HeldCondition("mail", fNew, "ace", "refused", true, true), LiftedCondition("mail", fNew), "module.mail." + strings.TrimPrefix(fNew, delivery.SourcePrefix2) + ".held"}, + {HeldCondition("mail", fNew, "ace", "refused", true, true), LiftedCondition("mail", fNew), "module.mail." + strings.TrimPrefix(fNew, meshcatalogclient.SourcePrefix2) + ".held"}, {NodeFailedCondition("ace", "mail", fNew, NodeFailure{Words: "x", Others: []string{"g14"}}, true), NodeFailedCondition("ace", "mail", fNew, NodeFailure{}, false), "module.ace.mail.failed-alone"}, {NeitherCondition("ace", "mail", Holding{Rule: 3, Words: "w"}, true), NeitherCondition("ace", "mail", Holding{}, false), "module.ace.mail.neither"}, {SeatWaitsCondition([]string{"placement"}), SeatWaitsCondition(nil), "module.mesh-delivery-assigner.seat-states"}, - {BackupCondition("ace", "mail", fNew, "disk full", true), BackupCondition("ace", "mail", fNew, "", false), "module.ace.mail." + strings.TrimPrefix(fNew, delivery.SourcePrefix2) + ".backup"}, + {BackupCondition("ace", "mail", fNew, "disk full", true), BackupCondition("ace", "mail", fNew, "", false), "module.ace.mail." + strings.TrimPrefix(fNew, meshcatalogclient.SourcePrefix2) + ".backup"}, } { puts, deletes, said := map[string]health.Finding{}, []string{}, 0 f := Findings{Put: func(k string, v []byte) error { diff --git a/modules/mesh-delivery-assigner/internal/assign/wants.go b/modules/mesh-delivery-assigner/internal/assign/wants.go index bba9b9c2..ebf8d2d9 100644 --- a/modules/mesh-delivery-assigner/internal/assign/wants.go +++ b/modules/mesh-delivery-assigner/internal/assign/wants.go @@ -4,6 +4,7 @@ import ( "fmt" "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "maps" "slices" "sort" @@ -452,12 +453,12 @@ func Wants(m Module, n Nodes, wants map[string]delivery.Want, lastHealthy map[st // A node that runs an old-form build, which no want can name, stays under the canary (issue 1945, a design limit): // its first want names F once the canary runs F healthy. Any other node that runs it (F itself, or an older // fingerprint with no composition or grant) gets F by the rules without which there is nothing to want. - older := ran && runs(have) && have.Fp != m.FP && strings.HasPrefix(have.Fp, delivery.SourcePrefix2) + older := ran && runs(have) && have.Fp != m.FP && strings.HasPrefix(have.Fp, meshcatalogclient.SourcePrefix2) if older { _, composed := m.composition(node, have.Fp) older = composed && m.GrantedAt != nil && m.GrantedAt(have.Fp) } - oldForm := ran && runs(have) && have.Fp != m.FP && !strings.HasPrefix(have.Fp, delivery.SourcePrefix2) + oldForm := ran && runs(have) && have.Fp != m.FP && !strings.HasPrefix(have.Fp, meshcatalogclient.SourcePrefix2) switch { case older: ok, target = true, have.Fp @@ -722,7 +723,7 @@ func normal(w delivery.Want) delivery.Want { } func short(fp string) string { - part, err := delivery.FingerprintKeyPart(fp) + part, err := meshcatalogclient.KeyPart(fp) if err != nil || len(part) < 12 { return fp } diff --git a/modules/mesh-delivery-assigner/internal/assign/wants_test.go b/modules/mesh-delivery-assigner/internal/assign/wants_test.go index ddbd3938..ac771dc2 100644 --- a/modules/mesh-delivery-assigner/internal/assign/wants_test.go +++ b/modules/mesh-delivery-assigner/internal/assign/wants_test.go @@ -3,6 +3,7 @@ package assign import ( "git.novox.be/novox/mesh-contracts/go/clients/nodeengineclient" "git.novox.be/novox/mesh-contracts/go/seats/nodeengine" + "git.novox.be/novox/mesh-delivery/contracts/go/clients/meshcatalogclient" "slices" "strings" "testing" @@ -15,7 +16,7 @@ import ( "git.novox.be/novox/mesh-delivery/sdk/graph" ) -func fpOf(c byte) string { return delivery.SourcePrefix2 + strings.Repeat(string(c), 64) } +func fpOf(c byte) string { return meshcatalogclient.SourcePrefix2 + strings.Repeat(string(c), 64) } var ( fNew = fpOf('b')