Keep the builds every want names and each composition's provisioner plans; find the replaced controller in the build records (issue 1945)
With no plan left to name a build or a send to keep the plans, a want names what a collection must keep, and the composition is where the provisioner's plans are composed for the assignments mirror (ADR 0539 clauses 1 and 5); the assignments no longer name a node's build, so the controller replaced is the newest earlier build of it.
This commit is contained in:
@@ -2,6 +2,7 @@ package inventory
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
@@ -47,6 +48,9 @@ const (
|
||||
KeptByRecentRecord = "recorded-lately"
|
||||
// KeptByOpenPlan: a plan that has not ended names the build that made it (novox/hq issue 1933).
|
||||
KeptByOpenPlan = "open-plan"
|
||||
// KeptByWant: a want names the fingerprint of the build that made it, so a node may be told to run it (novox/hq
|
||||
// ADR 0539 clause 1): with no plan, the want is what names a build a node runs or moves to.
|
||||
KeptByWant = "wanted"
|
||||
)
|
||||
|
||||
// KeptLately is how long after a build is recorded its artifacts are kept whatever else the records say (novox/hq
|
||||
@@ -458,7 +462,8 @@ func keptLately(builds []Build, planned map[string]bool, now time.Time, within t
|
||||
return out
|
||||
}
|
||||
|
||||
// keptLatelyOrPlanned is keptLately of every build the records hold, (no plan names a build any more, ADR 0539 §17).
|
||||
// keptLatelyOrPlanned is keptLately of every build the records hold, and the builds of every fingerprint a want names
|
||||
// (no plan names a build any more, ADR 0539 §17; a want does, clause 1).
|
||||
func (i *Inventory) keptLatelyOrPlanned(ctx context.Context) (map[string][]string, error) {
|
||||
c, err := i.theChain(ctx)
|
||||
if err != nil {
|
||||
@@ -468,7 +473,44 @@ func (i *Inventory) keptLatelyOrPlanned(ctx context.Context) (map[string][]strin
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return keptLately(all, nil, time.Now().UTC(), i.lately()), nil
|
||||
out := keptLately(all, nil, time.Now().UTC(), i.lately())
|
||||
if i.wanted == nil {
|
||||
return out, nil
|
||||
}
|
||||
wanted, err := i.wanted(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("the fingerprints the wants name: %w", err)
|
||||
}
|
||||
for reference, whys := range keptByWants(all, wanted) {
|
||||
for _, why := range whys {
|
||||
if !slices.Contains(out[reference], why) {
|
||||
out[reference] = append(out[reference], why)
|
||||
}
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// keptByWants is, of these builds, the artifacts of each that worked and whose module and fingerprint a want names
|
||||
// (`<module> <fingerprint>`), each kept as wanted.
|
||||
func keptByWants(builds []Build, wanted map[string]bool) map[string][]string {
|
||||
out := map[string][]string{}
|
||||
for _, b := range builds {
|
||||
if !b.Worked() || b.SourceFingerprint == "" || !wanted[b.Module+" "+b.SourceFingerprint] {
|
||||
continue
|
||||
}
|
||||
for _, a := range b.Made {
|
||||
if reference := asRecorded(a.Reference); reference != "" && !slices.Contains(out[reference], KeptByWant) {
|
||||
out[reference] = append(out[reference], KeptByWant)
|
||||
}
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// SetWanted gives the keep set every fingerprint a want names, as `<module> <fingerprint>` (ADR 0539 clause 1).
|
||||
func (i *Inventory) SetWanted(wanted func(ctx context.Context) (map[string]bool, error)) {
|
||||
i.wanted = wanted
|
||||
}
|
||||
|
||||
// digestIn is the `sha256:<hex>` a reference names, empty when it names none.
|
||||
|
||||
Reference in New Issue
Block a user