Documentation
¶
Overview ¶
Package localformat writes the uniform numbered local-chart bundle layout. Currently consumed by the helm deployer (--deployer helm). Designed to be consumable by additional deployers (e.g. helmfile per #632, argocd, Flux) without per-deployer changes to the writer; those integrations are not yet wired in this package.
Layout ¶
Each emitted folder is named NNN-<component>/ where NNN is a zero-padded 1-based index. Folders are one of two kinds, distinguished solely by the presence or absence of Chart.yaml:
KindUpstreamHelm — no Chart.yaml. The folder carries values.yaml, cluster-values.yaml, upstream.env (CHART/REPO/VERSION), and a rendered install.sh that installs the upstream chart via `helm upgrade --install`.
KindLocalHelm — Chart.yaml + templates/ present. The folder is a self-contained Helm chart; install.sh installs `./` as a local chart.
The Chart.yaml presence rule is the sole branch point for consumers. No component-kind metadata is re-read at deploy time. This is deliberate: a previous design branched deploy.sh on Helm/Kustomize/raw-manifest kinds, which bled component-type classification into every deployer. Chart.yaml presence reduces that to a single on-disk signal every deployer honors.
Classification ¶
Recipe shape determines the folder kind:
Helm repository set, no manifests → KindUpstreamHelm
Helm repository set, with raw manifests → KindUpstreamHelm primary +
KindLocalHelm "-post" injection
Helm repository empty, manifests only → KindLocalHelm (wrapped)
Kustomize (Tag/Path set) → KindLocalHelm (kustomize build
output wrapped as templates/manifest.yaml)
Mixed components and the "-post" injection ¶
When a single recipe component declares both an upstream Helm chart and raw manifests, Write emits two adjacent folders: the primary NNN-<name>/ as KindUpstreamHelm, immediately followed by (NNN+1)-<name>-post/ as KindLocalHelm wrapping the raw manifests. Subsequent components shift by one. The "mixed" concept does not appear in the recipe types, deployment order, or bundle result — it exists only in the bundle layout.
The -post folder deploys after the upstream chart, so raw manifests that reference the chart's CRDs apply against a cluster where those CRDs already exist. This is what makes the earlier pre-apply-with-retry mechanism (which applied raw manifests before the chart and retried on "CRD not found" errors) structurally unnecessary.
Base-format invariants ¶
These are load-bearing contracts. Callers and contributors should not violate them without changing the design:
localformat never writes deployer-specific files. deploy.sh, helmfile.yaml, argocd Application CRs, Flux HelmReleases, and the like are produced by the respective deployer after Write returns. Write owns per-folder content; deployers own top-level orchestration files. This separation is what makes a single folder layout consumable by every deployer without localformat growing per-deployer branches.
install.sh is never name-customized. Rendered from one of exactly two templates (upstream-helm, local-helm), parameterized only by data (name, namespace, upstream ref). Name-keyed component quirks (kai-scheduler async skip, skyhook taint cleanup, DRA restart, orphan CRD scan) stay in deploy.sh as name-matched blocks — not in install.sh. This is the structural barrier that keeps per-folder scripts from accumulating drift the way deploy.sh's branching did.
Write is deterministic and idempotent. Same Options in, same on-disk bytes and same Folder slice out. Map iteration is sorted; no timestamps or random suffixes are embedded in generated content.
Caller contract ¶
Callers pass an ordered Components slice (sorted by deployment order) and a ComponentManifests map (name → path → rendered bytes) that drives both the -post injection for mixed components and the template contents for manifest-only wrapped charts. Write returns a []Folder manifest so deployers can generate their own orchestration files without re-classifying or re-reading disk.
Further detail: ticket #662 carries the original design discussion and alternatives considered.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Component ¶
type Component struct {
Name string
Namespace string
// Helm upstream ref (empty for manifest-only components)
Repository string
ChartName string
Version string
IsOCI bool
// Kustomize (empty for helm components)
Tag string
Path string
// Values hydrated by the component bundler
Values map[string]any
DynamicPaths []string // paths moved from values.yaml into cluster-values.yaml
}
Component is the per-component input for Write. Fields mirror the subset of pkg/bundler/deployer/helm.ComponentData that localformat needs.
type Folder ¶
type Folder struct {
Index int // 1-based; rendered as zero-padded 3-digit prefix in Dir
Dir string // e.g. "001-nfd"
Kind FolderKind
Name string // component name, or "<name>-post" for injected
Parent string // component this folder belongs to (== Name for primary)
Upstream *Upstream // set iff Kind == KindUpstreamHelm
Files []string // relative paths (to OutputDir) of files written in this folder
}
Folder describes one written folder. Returned by Write so callers (deployers) can generate orchestration files without re-classifying.
func Write ¶
Write emits the numbered folder layout. Deterministic and idempotent.
Removes any pre-existing NNN-* folders under OutputDir before writing, so reusing the same --output across recipe regenerations does not leave stale component folders that the deployer's loop would later install. Top-level orchestration files (deploy.sh, undeploy.sh, README.md, attestation/) are left intact; only files under [0-9][0-9][0-9]-* are removed.
type FolderKind ¶
type FolderKind int
FolderKind classifies a written folder by the presence/absence of Chart.yaml.
const ( // KindUpstreamHelm: folder contains no Chart.yaml; install.sh references // an upstream Helm chart via upstream.env. KindUpstreamHelm FolderKind = iota // KindLocalHelm: folder contains a generated Chart.yaml + templates/; // install.sh installs ./ as a local chart. KindLocalHelm )
func (FolderKind) String ¶
func (k FolderKind) String() string
String returns the stable textual name for the kind. Used by logs and golden-file diagnostics so diffs show kind names rather than integers.