#!/usr/bin/env fish # Hard reset / "hammer" for a single Kustomization + HelmRelease pair. # Default target is Vault (KS: flux-system/vault, HR: vault/vault). set -l KS_NS flux-system set -l KS_NAME vault set -l HR_ns vault set -l HR_name vault # Timeouts set -l TIMEOUT "10m" set -l SRC_TIMEOUT "5m" function step echo (set_color --bold cyan)"$argv"(set_color normal) end function ok echo (set_color --bold green)"✔ $argv"(set_color normal) end function warn echo (set_color --bold yellow)"! $argv"(set_color normal) end function err echo (set_color --bold red)"✗ $argv"(set_color normal) end # Preflight type -q flux; or begin err "flux CLI not found in PATH"; exit 1; end type -q kubectl; or begin err "kubectl not found in PATH"; exit 1; end step "Flux: "(flux --version | string trim) step "Kube context: "(kubectl config current-context) # 1) Suspend KS and HR (best effort) step "Suspending Kustomization $KS_NS/$KS_NAME and HelmRelease $HR_ns/$HR_name" flux suspend kustomization $KS_NAME -n $KS_NS >/dev/null; or warn "KS already suspended?" flux suspend helmrelease $HR_name -n $HR_ns >/dev/null; or warn "HR already suspended?" ok "Suspended" # 2) Ensure latest sources are fetched step "Reconciling GitRepository flux-system and HelmRepository hashicorp" flux reconcile source git flux-system -n flux-system --timeout=$SRC_TIMEOUT >/dev/null; or err "GitRepository reconcile failed" flux reconcile source helm hashicorp -n flux-system --timeout=$SRC_TIMEOUT >/dev/null; or warn "HelmRepository reconcile failed (continuing)" ok "Sources refreshed" # 3) Resume KS and push desired state (don’t block here) step "Resuming Kustomization $KS_NS/$KS_NAME and reconciling (don’t wait)" flux resume kustomization $KS_NAME -n $KS_NS >/dev/null; or err "Failed to resume KS" # With Flux v2.6.x there is no --wait; use kubectl wait later. flux reconcile kustomization $KS_NAME -n $KS_NS --with-source --timeout=$TIMEOUT >/dev/null; or warn "KS reconcile returned non-zero (continuing)" # Give controller a moment to create/refresh the HelmRelease CR sleep 3 # 4) Patch HelmRelease to BYPASS readiness waiting (critical for Vault) # This prevents helm-controller from rolling back while Vault is sealed. step "Patching HelmRelease $HR_ns/$HR_name to disable readiness waiting and extend timeouts" # Wait until the HR object exists (up to ~2 minutes) for i in (seq 1 60) kubectl -n $HR_ns get helmrelease $HR_name >/dev/null 2>&1; and break sleep 2 end kubectl -n $HR_ns patch helmrelease $HR_name --type merge -p '{ "spec": { "install": { "disableWait": true, "timeout": "30m", "remediation": { "retries": 0 } }, "upgrade": { "disableWait": true, "timeout": "30m", "remediation": { "retries": 0 } } } }' >/dev/null; or warn "Patch failed (does HR exist yet?)" # 5) Resume HR and reconcile, then WAIT with kubectl step "Resuming HelmRelease $HR_ns/$HR_name and reconciling" flux resume helmrelease $HR_name -n $HR_ns >/dev/null; or err "Failed to resume HR" flux reconcile helmrelease $HR_name -n $HR_ns --with-source --timeout=$TIMEOUT >/dev/null; or warn "HR reconcile returned non-zero (continuing)" # Wait for HelmRelease Ready condition (works with CRDs; no flux --wait needed) step "Waiting for HelmRelease Ready (timeout $TIMEOUT)" kubectl -n $HR_ns wait helmrelease/$HR_name --for=condition=Ready --timeout=$TIMEOUT >/dev/null if test $status -ne 0 warn "HelmRelease did not become Ready within $TIMEOUT (showing status)" flux get helmreleases -n $HR_ns $HR_name else ok "HelmRelease is Ready" end # 6) Show final status step "Final Flux status (filtered)" flux get kustomizations -n $KS_NS $KS_NAME flux get helmreleases -n $HR_ns $HR_name # Optional: uncomment to wait for Kustomization Ready too # step "Waiting for Kustomization Ready (timeout $TIMEOUT)" # kubectl -n $KS_NS wait kustomization/$KS_NAME --for=condition=Ready --timeout=$TIMEOUT >/dev/null; and ok "Kustomization Ready"