An artifact-store lookup failure refuses the compose

artifactStoreOnNetwork collapsed a failed inventory read into 'no
store', so a hiccup composed a declaration without the registry trust,
delivered by a push that reported success — and nothing recomposed the
machine until the next push. Seen once in three fresh runs of the
built-store-cross-node bed (run 11). Refused loudly instead: 'no store'
now only ever means the mesh has none.
This commit is contained in:
2026-09-18 00:14:49 +02:00
parent bc289cbe04
commit 98aea8b25c
+22 -8
View File
@@ -157,7 +157,16 @@ func network(ctx context.Context, inv *inventory.Inventory, on map[string]bool,
// provider is whichever module offers it, on whichever machine holds that module — and if // provider is whichever module offers it, on whichever machine holds that module — and if
// nothing does yet (genesis raises the registry before the catalogue knows it), there is // nothing does yet (genesis raises the registry before the catalogue knows it), there is
// no trust to write and nothing is written (novox/hq ADR 0082). // no trust to write and nothing is written (novox/hq ADR 0082).
if at, port, found := artifactStoreOnNetwork(ctx, inv, on); found { //
// Refused rather than composed without it when the question could not be answered: a
// declaration missing the trust because a lookup failed is a machine that cannot pull,
// delivered by a push that reported success — and nothing recomposes it until the next
// push (the shape of novox/hq issues 042/048, reappearing as a race).
at, port, found, storeErr := artifactStoreOnNetwork(ctx, inv, on)
if storeErr != nil {
return nil, fmt.Errorf("finding the artifact store this network reaches: %w", storeErr)
}
if found {
g.TrustRegistry(overlay.InternalName(at) + ":" + port) g.TrustRegistry(overlay.InternalName(at) + ":" + port)
} }
} }
@@ -395,12 +404,17 @@ func namesInTheMesh(ctx context.Context, inv *inventory.Inventory) (map[string]s
// artifactStoreOnNetwork is the machine and port the mesh's artifact store answers on, when a // artifactStoreOnNetwork is the machine and port the mesh's artifact store answers on, when a
// module providing it is assigned to a machine that is on the private network. // module providing it is assigned to a machine that is on the private network.
//
// A lookup failure is an error, never "not found": collapsing the two composed a declaration
// without the trust whenever the inventory hiccuped, delivered by a push that reported success —
// and nothing recomposed the machine until the next push. "No store" must mean the mesh has none,
// not that the question went unanswered.
func artifactStoreOnNetwork(ctx context.Context, inv *inventory.Inventory, func artifactStoreOnNetwork(ctx context.Context, inv *inventory.Inventory,
on map[string]bool) (node, port string, found bool) { on map[string]bool) (node, port string, found bool, err error) {
shelf, err := inv.Catalogue(ctx) shelf, err := inv.Catalogue(ctx)
if err != nil || shelf == nil { if err != nil {
return "", "", false return "", "", false, fmt.Errorf("reading the catalogue: %w", err)
} }
providers := map[string]string{} // module -> served port providers := map[string]string{} // module -> served port
for name, m := range shelf { for name, m := range shelf {
@@ -413,18 +427,18 @@ func artifactStoreOnNetwork(ctx context.Context, inv *inventory.Inventory,
} }
} }
if len(providers) == 0 { if len(providers) == 0 {
return "", "", false return "", "", false, nil
} }
for machine := range on { for machine := range on {
assigned, err := inv.Assigned(ctx, machine) assigned, err := inv.Assigned(ctx, machine)
if err != nil { if err != nil {
continue return "", "", false, fmt.Errorf("reading what %s is assigned: %w", machine, err)
} }
for _, a := range assigned { for _, a := range assigned {
if p, ok := providers[a]; ok { if p, ok := providers[a]; ok {
return machine, p, true return machine, p, true, nil
} }
} }
} }
return "", "", false return "", "", false, nil
} }