Documentation
¶
Overview ¶
Package kustomize wraps sigs.k8s.io/kustomize/api so the rest of flate never invokes the `kustomize` CLI. It provides:
- Build / RenderFlux: render a kustomization directory to YAML documents. Build is the plain krusty surface; RenderFlux adds the Flux generator that handles spec.components and embedded inline Contents.
- Prepare: the standard pre-render dance (Clone + expand postBuild.substituteFrom) for embedders rendering a single Kustomization. Mirrors helm.Prepare for HelmReleases.
- Substitute: envsubst-style "${VAR}" / "${VAR:=default}" used for Flux post-build substitutions.
Concurrent builds against the same path are serialized via an internal per-path lock — krusty mutates the workspace and concurrent invocations against the same directory race.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Prepare ¶
func Prepare(ks *manifest.Kustomization, provider values.Provider) (*manifest.Kustomization, error)
Prepare runs the standard pre-render dance for a Kustomization so it is ready to feed into RenderFlux:
- Clone ks so subsequent mutations don't touch the store-canonical copy (the immutability contract every flate controller honors — see pkg/manifest/doc.go).
- Expand spec.postBuild.substituteFrom references against the supplied values provider so ks.PostBuildSubstitute reflects the merged result a render would consume.
Embedders rendering a single Kustomization without standing up the orchestrator's KS controller call Prepare then RenderFlux. Mirrors the symmetric helm.Prepare for HelmReleases.
func RenderFlux ¶
func RenderFlux(ctx context.Context, cache *StagingCache, sourceRoot, subPath string, rawSpec map[string]any) ([]byte, error)
RenderFlux renders a Flux kustomize.toolkit.fluxcd.io Kustomization using the same library that Flux's kustomize-controller uses (`github.com/fluxcd/pkg/kustomize`).
The Generator merges spec.patches / spec.images / spec.components / spec.targetNamespace / spec.namePrefix / spec.nameSuffix into the kustomization.yaml before krusty runs. spec.commonMetadata is applied post-build (see applyCommonMetadata) because the Generator does not handle it — kustomize-controller does it after build via ssautil.SetCommonMetadata.
ctx is honored at coarse boundaries — between path validation, after acquiring the per-path lock, and before/after SecureBuild — because fluxcd/pkg/kustomize.NewGenerator/SecureBuild do not themselves accept a ctx. A cancelled ctx returns ctx.Err() rather than completing the (potentially expensive) build.
The source tree at sourceRoot is never modified — staging is handled by `cache` which produces a writable copy. rawSpec must be the original Flux Kustomization document (the Contents field on manifest.Kustomization). subPath is the spec.path value relative to sourceRoot.
func Substitute ¶
Substitute replaces ${var} placeholders in data using the supplied vars map. Delegates to fluxcd/pkg/envsubst — the exact engine Flux source-controller uses — so behavior matches Flux bit-for-bit:
- $${VAR} passes through as literal ${VAR} (escape).
- ${VAR:-default}, ${VAR:=default}, ${VAR:+alt}, ${VAR:?msg} handle the unset case per POSIX parameter expansion.
- Bash-only constructs like ${VAR[@]} or ${VAR%%:*} that aren't recognized by envsubst are emitted literally, not erroneously matched as bare variable references (a divergence the previous regex-based implementation had).
- Undefined ${VAR} without a default expands to the empty string, matching kustomize-controller's default (strict mode is the opt-in `StrictPostBuildSubstitutions` feature gate, off by default). Returning the empty string with exists=true keeps envsubst out of its strict-mode error path and lines flate up with what real Flux renders against an incomplete substitute map.
Types ¶
type StagingCache ¶
type StagingCache struct {
// contains filtered or unexported fields
}
StagingCache materializes one-or-more source roots into a temp directory so Flux's kustomize Generator can safely write into the staged copy without touching the user's working tree.
Staging is done at most once per source root via sync.OnceValues. The first reconciliation against a root pays the copy cost; every subsequent reconciliation (including for other Kustomizations rooted at the same source artifact) reuses the same stage.
Lifecycle is tied to the surrounding orchestrator run — call Close to remove every staged copy.
func NewStagingCache ¶
func NewStagingCache(parent string) (*StagingCache, error)
NewStagingCache constructs a cache that places staged copies under the given parent directory. If parent is empty, the OS tempdir is used.
Sweeps any `flate-stage-*` directory under parent that's older than staleStageAge — those are crashed-process leftovers from runs where Close didn't fire (SIGKILL, panic, ctx not honored). Best-effort: a sweep error doesn't fail construction; the dirs just stay until the next successful sweep.
func (*StagingCache) FetchRemote ¶
FetchRemote returns the body of urlStr, fetched at most once per (url, success) cache entry. Successful bodies are cached for the StagingCache lifetime; transient errors (DNS, connection reset, timeout, 5xx) are NOT cached — the next caller retries. Only definitive HTTP 4xx responses are cached as negative entries (they won't change between retries within a run).
Without the success-only cache, a single transient hiccup at orchestrator startup poisoned every subsequent reconcile of every KS referencing that URL for the rest of the run.
The fetch runs in a background goroutine seeded with a detached context (httpGetURL applies remoteFetchTimeout internally) so a cancellation on the first caller doesn't propagate into the cached error. Each caller still honors its own ctx via the select below.