recovery: require flux bootstrap health

This commit is contained in:
codex 2026-06-18 23:42:29 -03:00
parent c8ccc970e6
commit 54f0b29bce
3 changed files with 18 additions and 1 deletions

View File

@ -2,6 +2,8 @@ package cluster
import "strings"
const fluxSystemSelfKustomization = "flux-system/flux-system"
// startupRequiredNodes runs one orchestration or CLI step.
// Signature: startupRequiredNodes(nodes []string, required []string) []string.
// Why: lets startup enforce a smaller core node set during outage recovery
@ -52,7 +54,12 @@ func (o *Orchestrator) startupNodeStrictlyRequired(node string) bool {
// Why: lets outage recovery wait on a declared core GitOps slice while leaving
// optional stacks free to converge after bootstrap succeeds.
func (o *Orchestrator) startupRequiredFluxKustomizations() map[string]struct{} {
return makeStringSet(o.cfg.Startup.FluxHealthRequiredKustomizations)
required := makeStringSet(o.cfg.Startup.FluxHealthRequiredKustomizations)
ignored := makeStringSet(o.cfg.Startup.IgnoreFluxKustomizations)
if _, ok := ignored[fluxSystemSelfKustomization]; !ok {
required[fluxSystemSelfKustomization] = struct{}{}
}
return required
}
// startupRequiredWorkloadNamespaces runs one orchestration or CLI step.

View File

@ -89,6 +89,7 @@ func TestHookFluxAndWorkloadMatrix(t *testing.T) {
case name == "kubectl" && strings.Contains(command, "get kustomizations.kustomize.toolkit.fluxcd.io -A -o json"):
return `{"items":[
{"metadata":{"namespace":"flux-system","name":"monitoring"},"spec":{"suspend":false},"status":{"conditions":[{"type":"Ready","status":"True","message":"ok"}]}},
{"metadata":{"namespace":"flux-system","name":"flux-system"},"spec":{"suspend":false},"status":{"conditions":[{"type":"Ready","status":"True","message":"ok"}]}},
{"metadata":{"namespace":"flux-system","name":"jellyfin"},"spec":{"suspend":false},"status":{"conditions":[{"type":"Ready","status":"False","message":"optional still down"}]}}
]}`, nil
default:

View File

@ -78,6 +78,15 @@ func TestHookStartupScopeAndVaultHelpers(t *testing.T) {
if _, ok := flux["flux-system/gitea"]; !ok {
t.Fatalf("expected trimmed gitea kustomization in required set: %v", flux)
}
if _, ok := flux["flux-system/flux-system"]; !ok {
t.Fatalf("expected Flux bootstrap kustomization in required set: %v", flux)
}
cfgScoped.Startup.IgnoreFluxKustomizations = []string{"flux-system/flux-system"}
orchIgnoredFluxSelf, _ := newHookOrchestrator(t, cfgScoped, nil, nil)
if _, ok := orchIgnoredFluxSelf.TestHookStartupRequiredFluxKustomizations()["flux-system/flux-system"]; ok {
t.Fatalf("expected explicit ignore to remove Flux bootstrap kustomization from required set")
}
namespaces := orchScoped.TestHookStartupRequiredWorkloadNamespaces()
if _, ok := namespaces["vault"]; !ok {