Hold consumers under a provider waiting for the operator, and say a wait beside another condition (issue 405)

A provider whose only part not healthy waits for the operator's secret or
setting let its consumers raise their own unhealthy conditions, and a
wait beside a relogin, a directory used as found or a fault was not said
until the other cleared.
This commit is contained in:
2026-10-11 02:51:11 +02:00
parent 5bddb16514
commit 1dc9961c43
3 changed files with 327 additions and 27 deletions
+18 -5
View File
@@ -3,6 +3,7 @@ package main
import (
"context"
"fmt"
"slices"
"sort"
"strings"
@@ -53,6 +54,15 @@ func readHolding(ctx context.Context, inv *inventory.Inventory, open []condition
return &holding{ctx: ctx, inv: inv, healths: healths, open: open, providers: map[string]providerLookup{}}, nil
}
// readHoldingFor is how a judging reads its holding: nothing without a store. A variable so a test can hand a
// judging the record it holds under (novox/hq issue 405).
var readHoldingFor = func(ctx context.Context, inv *inventory.Inventory, open []conditions.Condition) (*holding, error) {
if inv == nil {
return nil, nil
}
return readHolding(ctx, inv, open)
}
// heldFinding says a resource's state is a finding of its declared check that names a provision: what
// may be held. Down and restarting are liveness, the resource's own.
func heldFinding(r inventory.ResourceHealth) bool {
@@ -106,17 +116,20 @@ func (h *holding) lookUpProvider(machine, consumer, provision string) (catalogue
return catalogue.Chosen{}, false
}
// unhealthy says a provider is unhealthy on the record: its condition is open, or its machine's newest
// statement says a resource of it is unhealthy.
// unhealthy says a provider is not healthy on the record: its unhealthy or needs-operator condition is open, or its
// machine's newest statement says a resource of it is unhealthy or waiting. **A provider waiting for the operator
// holds its consumers too** (novox/hq issue 405): its secret or setting not given, what its consumers find is no more
// theirs than when it is broken, and ADR 0240 rule 5 says it once, at the provider — here under its needs-operator
// condition, which names the act.
func (h *holding) unhealthy(p catalogue.Chosen) bool {
key := moduleUnhealthyKey(p.Module, p.Node)
keys := []string{moduleUnhealthyKey(p.Module, p.Node), needsOperatorKey(p.Module, p.Node)}
for _, c := range h.open {
if c.Key == key {
if slices.Contains(keys, c.Key) {
return true
}
}
for _, r := range h.healths[p.Node].Resources {
if r.Module == p.Module && r.State == link.StateUnhealthy {
if r.Module == p.Module && (r.State == link.StateUnhealthy || r.State == link.StateWaiting) {
return true
}
}