The artifact store's seat is named for its scope: mesh-artifact-store
ADR 0121 decided it and deferred it as a delivering-seat migration; ADR 0122's aliases made it one update and one alias (migration 0048). The former name resolves to it forever (novox/hq ADR 0156, issue 123).
This commit is contained in:
@@ -67,7 +67,7 @@ func TestTheAgreementCheckCatchesASubscriptionThatMatchesNothing(t *testing.T) {
|
|||||||
// An event published under a seat's name is real even though no module declares it as its own.
|
// An event published under a seat's name is real even though no module declares it as its own.
|
||||||
if bad := Disagreements(nil,
|
if bad := Disagreements(nil,
|
||||||
[]AConsumer{{Module: "watcher", Consumes: []string{"mesh-artifact-store.image.pushed"}}},
|
[]AConsumer{{Module: "watcher", Consumes: []string{"mesh-artifact-store.image.pushed"}}},
|
||||||
[]DeclaredSeat{{Name: "the-artifact-store", Emits: []string{"image.pushed"}}}); len(bad) != 0 {
|
[]DeclaredSeat{{Name: "mesh-artifact-store", Emits: []string{"image.pushed"}}}); len(bad) != 0 {
|
||||||
t.Fatalf("an event a seat emits was reported as matching nothing: %v", bad)
|
t.Fatalf("an event a seat emits was reported as matching nothing: %v", bad)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package catalogue
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
// A claim written before the rename still holds (novox/hq ADR 0122, ADR 0156): with the store's
|
||||||
|
// aliases loaded, the former name resolves to the seat.
|
||||||
|
func TestTheArtifactStoresFormerNameResolvesToIt(t *testing.T) {
|
||||||
|
was := aliases
|
||||||
|
t.Cleanup(func() { aliases = was })
|
||||||
|
UseAliases(map[string]string{"the-artifact-store": "mesh-artifact-store"})
|
||||||
|
seat, known := SeatNamed("the-artifact-store")
|
||||||
|
if !known || seat.Name != "mesh-artifact-store" || seat.Delivers != "artifact-store" {
|
||||||
|
t.Fatalf("the former name did not resolve: %+v %v", seat, known)
|
||||||
|
}
|
||||||
|
if _, known := SeatNamed("mesh-artifact-store"); !known {
|
||||||
|
t.Fatal("the seat is not in the set under its name")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ func TestASecondArtifactStoreAnywhereIsRefusedByName(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// A second one, on any other machine, is refused — and the refusal names the seat.
|
// A second one, on any other machine, is refused — and the refusal names the seat.
|
||||||
elsewhere := World{Held: []Held{{Claim: "the-artifact-store", Scope: ScopeMesh,
|
elsewhere := World{Held: []Held{{Claim: "mesh-artifact-store", Scope: ScopeMesh,
|
||||||
Node: "anchor", Module: "distribution"}}}
|
Node: "anchor", Module: "distribution"}}}
|
||||||
other := workstation()
|
other := workstation()
|
||||||
other.Name = "laptop"
|
other.Name = "laptop"
|
||||||
@@ -32,7 +32,7 @@ func TestASecondArtifactStoreAnywhereIsRefusedByName(t *testing.T) {
|
|||||||
t.Fatal("a second store was accepted on another machine; it would offer artifact-store a " +
|
t.Fatal("a second store was accepted on another machine; it would offer artifact-store a " +
|
||||||
"second time and every consumer elsewhere would refuse to choose")
|
"second time and every consumer elsewhere would refuse to choose")
|
||||||
}
|
}
|
||||||
if !strings.Contains(err.Error(), "the-artifact-store") || !strings.Contains(err.Error(), "one per mesh") {
|
if !strings.Contains(err.Error(), "mesh-artifact-store") || !strings.Contains(err.Error(), "one per mesh") {
|
||||||
t.Fatalf("refused without naming the seat: %v", err)
|
t.Fatalf("refused without naming the seat: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ func TestRenamingASeatDidNotRenameTheInterfaceItDelivers(t *testing.T) {
|
|||||||
for _, pair := range []struct{ seat, delivers string }{
|
for _, pair := range []struct{ seat, delivers string }{
|
||||||
{"git", "git"},
|
{"git", "git"},
|
||||||
{"npm-package-registry", "npm-package-registry"},
|
{"npm-package-registry", "npm-package-registry"},
|
||||||
{"the-artifact-store", "artifact-store"},
|
{"mesh-artifact-store", "artifact-store"},
|
||||||
{"mesh-store", "postgres-database"},
|
{"mesh-store", "postgres-database"},
|
||||||
{"mesh-broker", "mesh-bus"},
|
{"mesh-broker", "mesh-bus"},
|
||||||
} {
|
} {
|
||||||
|
|||||||
@@ -66,7 +66,11 @@ var defaultSeats = []Seat{
|
|||||||
// rather than receives ambiently — 23 of the catalogue's modules never speak, and an ambient
|
// rather than receives ambiently — 23 of the catalogue's modules never speak, and an ambient
|
||||||
// connection would mint a credential for each.
|
// connection would mint a credential for each.
|
||||||
{Name: "mesh-broker", Scope: ScopeMesh, Delivers: "mesh-bus", Decision: "novox/hq ADR 0079"},
|
{Name: "mesh-broker", Scope: ScopeMesh, Delivers: "mesh-bus", Decision: "novox/hq ADR 0079"},
|
||||||
{Name: "the-artifact-store", Scope: ScopeMesh, Delivers: "artifact-store", Decision: "novox/hq ADR 0075"},
|
// Named for its scope since 2026-09-30 (novox/hq ADR 0156); `the-artifact-store` resolves to it as
|
||||||
|
// an alias on a mesh that predates the rename. It serves artifacts of every kind a build makes —
|
||||||
|
// images and archives, by digest — which is why the provision is the artifact store and not an
|
||||||
|
// image registry.
|
||||||
|
{Name: "mesh-artifact-store", Scope: ScopeMesh, Delivers: "artifact-store", Decision: "novox/hq ADR 0075"},
|
||||||
{Name: "mesh-catalog", Scope: ScopeMesh, Decision: "novox/hq ADR 0121"},
|
{Name: "mesh-catalog", Scope: ScopeMesh, Decision: "novox/hq ADR 0121"},
|
||||||
// Deferred renames (novox/hq ADR 0121): these deliver a provision, so renaming them is a
|
// Deferred renames (novox/hq ADR 0121): these deliver a provision, so renaming them is a
|
||||||
// delivering-seat migration with a mesh-wide cascade if a holder stops resolving mid-flight.
|
// delivering-seat migration with a mesh-wide cascade if a holder stops resolving mid-flight.
|
||||||
@@ -97,8 +101,9 @@ var defaultSeats = []Seat{
|
|||||||
// A system seat name is the control plane's namespace: `mesh-*` for a mesh-wide role, `node-*` for
|
// A system seat name is the control plane's namespace: `mesh-*` for a mesh-wide role, `node-*` for
|
||||||
// a per-node one (novox/hq ADR 0121). A claim to a system name the mesh does not define is refused;
|
// a per-node one (novox/hq ADR 0121). A claim to a system name the mesh does not define is refused;
|
||||||
// any other name is a module's own to define and claim. Some of the mesh's own seats predate this
|
// any other name is a module's own to define and claim. Some of the mesh's own seats predate this
|
||||||
// convention and are not yet renamed (git, npm-package-registry, the-artifact-store,
|
// convention and are not yet renamed (git, npm-package-registry, the-private-network) — those are
|
||||||
// the-private-network) — those are in the set, so they resolve by name, not by prefix.
|
// in the set, so they resolve by name, not by prefix. the-artifact-store was renamed on 2026-09-30
|
||||||
|
// (novox/hq ADR 0156) and resolves through the alias table on a mesh that knew it.
|
||||||
func isSystemSeatName(name string) bool {
|
func isSystemSeatName(name string) bool {
|
||||||
return strings.HasPrefix(name, "mesh-") || strings.HasPrefix(name, "node-")
|
return strings.HasPrefix(name, "mesh-") || strings.HasPrefix(name, "node-")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
-- The artifact store's seat is named for its scope, like the mesh's other seats (novox/hq ADR 0121,
|
||||||
|
-- ADR 0156, issue 123).
|
||||||
|
--
|
||||||
|
-- `the-artifact-store` was the last of the mesh's own seats named for the job it happened to do rather
|
||||||
|
-- than for the mesh; ADR 0121 decided the rename and deferred it because a delivering seat that stops
|
||||||
|
-- resolving mid-flight takes a provision away from every consumer. ADR 0122 removed that risk: a seat's
|
||||||
|
-- former name is an alias that resolves to it forever, a held record follows the rename by cascade, and
|
||||||
|
-- a claim written with the old name still holds. So the rename is one update and one alias.
|
||||||
|
update seat set name = 'mesh-artifact-store' where name = 'the-artifact-store';
|
||||||
|
insert into seat_alias (alias, seat) values ('the-artifact-store', 'mesh-artifact-store')
|
||||||
|
on conflict (alias) do update set seat = excluded.seat;
|
||||||
|
update seat_alias set seat = 'mesh-artifact-store' where seat = 'the-artifact-store';
|
||||||
Reference in New Issue
Block a user