Skip to content

bundler(flux): local-chart HelmReleases unreachable under OCI consumption #964

Description

@mchmarny

Summary

The flux deployer's OCI output (aicr bundle --deployer flux --output oci://...) is not consumable by Flux for local-chart components — recipes that include manifestFiles, preManifestFiles, or vendored Helm wrappers. Discovered during PR #956 while adding the flux-oci KWOK lane.

Symptom

When the bundle is consumed via an outer OCIRepository + Kustomization, the per-component HelmRelease CRs for local-chart components reference:

spec:
  chart:
    spec:
      chart: ./<component-name>
      sourceRef:
        kind: GitRepository
        name: github-com-your-org-your-repo

The GitRepository resource inside the bundle points at the bundler placeholder URL https://github.com/YOUR_ORG/YOUR_REPO.git, which Flux's source-controller cannot fetch. helm-controller observes:

release is in a failed state
terminal error: exceeded maximum retries: cannot remediate failed release

Because Flux components are chained via dependsOn, the entire HelmRelease graph downstream of any local-chart component stalls on "dependency not ready".

Why this PR doesn't fix it

Two attempts to point the inner HelmReleases at the outer OCIRepository both fail against Flux's API:

  1. HelmRelease.spec.chart.spec.sourceRef.kind: OCIRepository — rejected by the validating webhook with "supported values: HelmRepository, GitRepository, Bucket". The legacy chart-fetch path goes through a HelmChart resource whose sourceRef only accepts those three kinds.
  2. HelmRelease.spec.chartRef — accepts OCIRepository, but points at the entire OCI artifact as a single chart. There is no path support; a multi-chart bundle cannot be addressed this way.

So a single wrapper OCIRepository cannot serve sub-paths to inner local charts. The fix has to come from the bundler's side: either eliminate the local-chart HelmReleases or publish each one as its own OCI artifact.

Mitigation in PR #956

The flux-oci KWOK lane validates that the bundle artifact can be pulled (OCIRepository Ready=True), applied (Kustomization Ready=True), and produces the expected GitOps shape (per-component HelmRelease CRs created). It does NOT wait for HelmReleases to reach terminal state — that wait would always fail under the current placeholder-URL behavior.

This covers the most common bundle-format regression vector (pull, parse, schema correctness) for the flux deployer's OCI output, at the cost of deferring reconciliation validation.

Proposed fix options

Option A: Render local-chart manifests at bundle time

For local-chart components (those that today emit Chart.yaml + templates/ inside the bundle), run helm template at aicr bundle time and write the rendered manifests into the bundle. The root kustomization.yaml lists them directly; no per-component HelmRelease is emitted for these.

External-chart components (cert-manager, gpu-operator from upstream Helm repos) keep their HelmRelease + HelmRepository source CRs.

  • Pros: single OCI artifact, no per-chart push, mirrors what the helm deployer already does on its local-chart path.
  • Cons: changes the bundle layout for the flux + OCI case (manifests at component root, not under templates/); partially duplicates the helm deployer's rendering.

Option B: Push each local chart as its own OCI helm artifact

For each local-chart component, push the chart with helm.config.v1+json config + helm.chart.content.v1.tar+gzip layer (the same flow we added for argocd-helm-oci in this PR — see pkg/oci.PackageAndPushHelmChart). The bundle then contains one OCIRepository per local chart, plus a HelmRelease with spec.chartRef pointing at it.

  • Pros: native Flux pattern; uses chartRef (the post-v2.1 API).
  • Cons: N+1 OCI pushes per bundle (one outer wrapper + one per local chart); more registry traffic; more cleanup.

Option C: Both

Option A as the default; Option B behind a flag for users who want strict GitOps separation per chart.

Acceptance criteria

  • aicr bundle --deployer flux --output oci://... produces a bundle whose local-chart components reconcile successfully under Flux without external Git access.
  • PR feat(ci,bundler): validate deployer OCI bundles matrix in KWOK #956's flux-oci KWOK lane is updated to wait for HelmRelease terminal state (Ready=True OR Released+history=deployed), restoring the same depth of validation argocd-oci has today.
  • docs/contributor/kwok-testing.md "Local-chart skip" note is removed.
  • Decision between Option A, B, or C captured in an ADR or design doc before implementation.

Related

Metadata

Metadata

Assignees

Type

Fields

No fields configured for Bug.

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions