You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(bundler)!: uniform NNN-folder bundle layout via localformat (#662)
Introduce pkg/bundler/deployer/localformat — a deployer-agnostic writer
that produces the NNN-<component>/ numbered folder layout. Each folder
is one of two kinds: upstream-helm (no Chart.yaml; upstream.env carries
{CHART,REPO,VERSION}) or local-helm (Chart.yaml + templates/). Mixed
components (Helm + raw manifests) emit two adjacent folders: a primary
upstream-helm + an injected -post local-helm wrapper. Each folder
carries a rendered install.sh; deploy.sh is now a generic loop with
no per-component branching, only name-matched special-case blocks.
Rewire --deployer helm to consume localformat. Generator.Generate
delegates per-component content (values.yaml, cluster-values.yaml,
Chart.yaml, templates/, install.sh) to localformat.Write and owns only
top-level orchestration files (README.md, deploy.sh, undeploy.sh,
checksums). Deletes ~195 lines of dead code: generateComponentDirectories,
buildComponentDataList (full version), writeClusterValuesFile,
hasYAMLObjects (relocated to localformat). Deletes ComponentData fields
HasChart, HasManifests, IsKustomize.
Rewrite deploy.sh.tmpl: generic install loop replaces ~90 lines of
{{ if .IsKustomize/.HasChart/.HasManifests }} branching. Delete the
~50-line CRD-race retry block — its trigger (pre-apply raw manifests)
is structurally eliminated; mixed components now apply manifests
post-install via the injected -post wrapped chart, where Helm owns
CRD ordering natively. Rewrite undeploy.sh.tmpl to a generic reverse
loop. Preserve name-matched blocks (skyhook taint cleanup, kai-scheduler
async timeout/diagnostics, DRA kubelet-plugin restart, orphaned-CRD
scan) around the loops; their simplification is deferred.
Refactor helm_test.go: introduce assertBundleGolden helper (mirroring
localformat's writer_test) + 5 golden-file scenarios under testdata/
exercising upstream-helm-only, manifest-only, mixed gpu-operator,
kai-scheduler-present, skyhook-present bundles. Goldens double as
reference examples of rendered output. Delete 11 redundant tests
covering removed code or duplicating golden coverage; add focused
error-path tests. Net: 48 → 37 tests, 3408 → 2130 lines (−37%),
coverage 87.6% → 87.9%.
Update bundler_test.go, handler_test.go, and 6 chainsaw e2e fixtures
to assert on NNN-prefixed paths.
Breaking changes for --deployer helm consumers:
- Bundle directory layout: <component>/ → NNN-<component>/
- Mixed components emit two folders (primary + -post)
- Raw manifests for mixed components apply post-install only
- CRD-race retry block removed; pre-apply mechanism gone
- No more per-component README.md (top-level README still present)
Docs: docs/user/cli-reference.md updated with new layout, folder kinds,
mixed-component -post injection, and breaking-change callout.
docs/contributor/component.md describes localformat as the shared
base format and the load-bearing invariants (localformat never writes
deployer-specific files; install.sh never name-customized; Write is
deterministic).
Copy file name to clipboardExpand all lines: docs/contributor/component.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -32,7 +32,7 @@ The bundler system converts RecipeInput objects into deployment artifacts. Artif
32
32
**Load-bearing invariants** (don't violate without changing the design):
33
33
34
34
1.**`localformat` never writes deployer-specific files.**`deploy.sh`, `helmfile.yaml`, argocd `Application` CRs, Flux `HelmRelease`s — all produced by the respective deployer after `Write()` returns. This separation is what makes a single layout consumable by every deployer.
35
-
2.**`install.sh` is never name-customized.** It is rendered from one of exactly two templates (`install-upstream-helm.sh.tmpl`, `install-local-helm.sh.tmpl`), parameterized only by data (name, namespace, upstream ref). Name-keyed quirks (kai-scheduler async timeout, 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 prevents per-folder scripts from accumulating drift.
35
+
2.**`install.sh` is never name-customized.** It is rendered from one of exactly two templates (`install-upstream-helm.sh.tmpl`, `install-local-helm.sh.tmpl`), parameterized only by data (name, namespace, upstream ref). Name-keyed quirks (kai-scheduler async timeout, nodewright-operator 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 prevents per-folder scripts from accumulating drift.
36
36
3.**`Write` is deterministic and idempotent.** Same inputs → same on-disk bytes → same `Folder` slice. Map iteration is sorted; no timestamps or random suffixes are embedded.
37
37
38
38
For the full classification table, base-format invariants, and the helm deployer's call site, see `pkg/bundler/deployer/localformat/doc.go` (godoc) and `pkg/bundler/deployer/helm/helm.go::Generate`. Further design history: ticket [#662](https://github.com/NVIDIA/aicr/issues/662).
Copy file name to clipboardExpand all lines: docs/user/cli-reference.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1156,7 +1156,7 @@ bundles/
1156
1156
1157
1157
Previous releases used a flat `<component>/` layout with `manifests/` siblings and a `--deployer helm` script that branched on component kind. The new format is uniform:
1158
1158
1159
-
- All folders carry a rendered `install.sh`. The top-level `deploy.sh` is a generic loop with no per-component branching — name-matched special-case blocks (skyhook taint cleanup, kai-scheduler async timeout, orphan-CRD scan, DRA kubelet-plugin restart) live around the loop, not inside it.
1159
+
- All folders carry a rendered `install.sh`. The top-level `deploy.sh` is a generic loop with no per-component branching — name-matched special-case blocks (nodewright-operator taint cleanup, kai-scheduler async timeout, orphan-CRD scan, DRA kubelet-plugin restart) live around the loop, not inside it.
1160
1160
- Raw manifests for mixed components now apply **post-install only**, via the injected `-post` wrapped chart. The earlier pre-apply mechanism with a CRD-race retry wrapper is gone — Helm now owns CRD ordering for mixed components natively.
1161
1161
- Tooling that parsed bundle paths by bare component name must account for the `NNN-` prefix.
@@ -60,7 +54,7 @@ Use `--no-wait` to skip Helm chart-level waiting where AICR uses `--wait` (keeps
60
54
./deploy.sh --no-wait
61
55
```
62
56
63
-
> **Note:** The deploy script's final status reflects install/apply results. If `--best-effort` was used, one or more components may still have failed; check warning lines and logs. This does **not** mean the cluster is ready for GPU workloads. On fresh GPU nodes, cluster convergence (Nodewright node tuning, GPU operator operand rollout, DRA kubelet plugin registration) continues asynchronously after the script exits. See the [AICR CLI Reference](https://github.com/NVIDIA/aicr/blob/main/docs/user/cli-reference.md#deploy-script-behavior-deploysh) for details.
57
+
> **Note:** The deploy script's final status reflects install/apply results. If `--best-effort` was used, one or more components may still have failed; check warning lines and logs. This does **not** guarantee the cluster is ready to schedule workloads — operator-driven cluster convergence (CRD reconciliation, node tuning, plugin registration, etc.) continues asynchronously after the script exits, in operator-specific ways. See the [AICR CLI Reference](https://github.com/NVIDIA/aicr/blob/main/docs/user/cli-reference.md#deploy-script-behavior-deploysh) for details.
64
58
65
59
## Manual Installation
66
60
@@ -71,56 +65,24 @@ with the right arguments baked in. To install a single component manually:
0 commit comments