fix(bundler): carry localformat createNamespace into helmfile.yaml#901
Conversation
The helmfile deployer set a global helmDefaults.createNamespace: true and ignored localformat's per-folder chart-owns-Namespace decision. When a recipe ships a pre-manifest containing a kind: Namespace (e.g., the os-talos privileged-namespace pattern), helmfile apply would invoke helm install --create-namespace, creating the namespace out-of-band without release ownership labels; the chart's own Namespace template then collides because Helm 3 refuses to import a pre-existing namespace that lacks the release's ownership metadata. The localformat writer already encodes the right decision into install.sh (effectiveCreateNamespace = caller intent && no chart-owned Namespace), but it didn't expose the result on the returned Folder, so deployers that bypass install.sh (helmfile) couldn't see it. Expose Folder.CreateNamespace and have the helmfile deployer emit a per-release `createNamespace: false` for folders where the chart owns the namespace. helmDefaults.createNamespace: true stays the global default; the override is only rendered for the affected release, so existing recipe shapes are unchanged. The bug is dormant in main today (no current leaf overlay opts into os-talos), but the fix prevents the regression as soon as one does or a new pre-manifest declares a Namespace.
📝 WalkthroughWalkthroughThis PR extends the Helm deployment pipeline to support per-release control of namespace creation. A new Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested labels
Suggested reviewers
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Summary
Fixes an issue introduced by PR #899: the new
--deployer helmfilepath ignored localformat's per-folder chart-owns-Namespace decision and always relied onhelmDefaults.createNamespace: true, causinghelmfile applyto collide with charts that ship their ownkind: Namespaceresource (e.g., the os-talos privileged-namespace pattern). ExposeFolder.CreateNamespaceand emit a per-releasecreateNamespace: falseoverride for those folders.Motivation / Context
The localformat writer already encodes the right decision into
install.sh(effectiveCreateNamespace = caller intent && no chart-owned Namespace), originally to keep helm's--create-namespaceaway from charts that own their target Namespace. The helmfile deployer added in PR #899 bypassesinstall.shand emits its own release graph, so it never saw that signal and fell back to the global default.Failure mode at
helmfile applytime: helm creates the namespace out-of-band via--create-namespace(no release ownership labels), then the chart's own Namespace template can't claim it because Helm 3 refuses to import a namespace it created out-of-band. Install fails.The bug is dormant in
maintoday (no current leaf overlay opts intoos-talos, and no other in-tree pre-manifest declares aNamespace), so existing recipe shapes are unaffected. It would activate as soon as a leaf overlay opts in or a new pre-manifest declares a Namespace.Fixes: post-merge follow-up to #899; surfaced during cross-review.
Related: #632, #899
Type of Change
Component(s) Affected
cmd/aicr,pkg/cli)cmd/aicrd,pkg/api,pkg/server)pkg/recipe)pkg/bundler,pkg/component/*)pkg/collector,pkg/snapshotter)pkg/validator)pkg/errors,pkg/k8s)docs/,examples/)Implementation Notes
localformat.Foldergains aCreateNamespace boolfield. Populated bywriteLocalHelmFolderfrom the existingeffectiveCreateNamespacevalue (no new detection logic);upstream_helm.goandvendor_folder.goset it totruesince those paths don't render AICR templates and the chart-owns-Namespace heuristic doesn't apply.helmfile.ReleasegainsCreateNamespace *boolwithyaml:"createNamespace,omitempty".buildHelmfileonly emits the field when the folder'sCreateNamespaceis false —helmDefaults.createNamespace: truecontinues to cover the common case, so the helmfile.yaml stays minimal for unaffected recipes.falsesurvives YAML marshaling and absence omits the field.Testing
All 21 chainsaw tests pass. Two new unit tests added:
TestBuildHelmfile_CreateNamespaceFromFolder— synthetic folders with mixedCreateNamespacevalues; verifies the per-release override is emitted only when the folder's flag is false.TestGenerate_NamespaceOwningPreManifest— end-to-end: a pre-manifest containingkind: Namespaceflows throughlocalformat.Write→buildHelmfileand surfaces ascreateNamespace: falseon the injected<name>-prerelease in the rendered helmfile.yaml.Per-package coverage:
pkg/bundler/deployer/helmfile91.9% → 92.5% (+0.6%).pkg/bundler/deployer/localformatunchanged.Empirical check (helmfile v1.5.1) — pre-fix bundle for a synthetic Namespace-owning pre-manifest emitted
helmDefaults.createNamespace: truewith no override; post-fix bundle emitscreateNamespace: falseon the affected pre-release while every other release uses the default.helmfile show-dagagainst current main bundles continues to pass (no DAG regression).Risk Assessment
Rollout notes: Backwards-compatible. The helmfile.yaml shape changes only for releases whose folder declared a Namespace resource — no such recipe ships today. Existing goldens are unchanged.
Checklist
make testwith-race)make lint)git commit -S)