Repository navigation
Sync Flux objects with their whole source chain, like flux reconcile --with-source - #2110
Merged
Merged
Conversation
"Sync with source" read only spec.chart.spec.sourceRef. On a HelmRelease using spec.chartRef it failed with "no source reference found", and on an inline release it refreshed the repository instead of the generated HelmChart, which is what re-resolves the chart version. Kustomizations backed by a Bucket failed too: Bucket and HelmChart weren't known kinds. Sources now come from the shared Flux source parser and follow `flux reconcile --with-source`: an inline release reconciles its generated HelmChart (status.helmChart, or Flux's generated name before it is recorded), a chartRef release reconciles the referenced HelmChart or OCIRepository, and an ExternalArtifact, which another controller produces, leaves only the release to reconcile.
nadaverell
force-pushed
the
feature/flux-sync-with-generated-chart
branch
from
October 14, 2026 11:11
6e36f5c to
650f89f
Compare
âĶed version Sync with source on a HelmRelease now reconciles the chart's own source before the chart, as `flux reconcile hr --with-source` does, so a new chart version in the repository is picked up. The generated chart is named from the current spec rather than status.helmChart, which names the previous chart while the controller replaces it. A suspended or Terminating object anywhere in the chain fails the request with 409 before anything is written. Flux operations resolve each kind to the version the cluster serves through discovery, so OCIRepository (v1beta2 before Flux 2.6), Bucket and the Helm source kinds work on older Flux installs. The success toast shows the server's message, which names what was reconciled and when an ExternalArtifact was skipped.
A source that can't be read (Forbidden, timeout, missing) now fails Sync with source before anything is written: without the object there is no suspend or deletion state to check and no chart sourceRef to follow. ServedGVR refreshes expired discovery before resolving, so a Flux CRD upgrade that retires a version is picked up by write paths on their own. The resolver argument to SyncFluxWithSource is optional, so existing callers keep compiling.
âĶsions A slow discovery endpoint for an unrelated API could otherwise use up a Flux action's deadline before it reached the healthy Flux endpoint. The caller gets the cached version; only the first action after the cache expires can still see a version a CRD upgrade just retired.
Calls arriving while a refresh is in flight return the cached version without starting another, so a stalled discovery endpoint doesn't accumulate a waiting goroutine per call. The refresh tests no longer race their own background refresh against the fake's response.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
"Sync with source" on a Flux object is meant to do what
flux reconcile <kind> --with-sourcedoes: refresh what the object builds from, then the object. On main it didn't:spec.chartRefit failed with "no source reference found", although the button is offered.spec.chartHelmRelease it refreshed the HelmRepository but not the HelmChart Flux generates from it. Refreshing the index alone doesn't re-resolve the chart version; the chart reconcile does.v1beta2before Flux 2.6, Bucket before 2.4) the patch failed with "the server could not find the requested resource".What changed
The reconcile chain follows the Flux CLI. Objects are reconciled upstream first, then the consumer:
spec.sourceRef(GitRepository, OCIRepository, Bucket), then the Kustomizationspec.chart<release namespace>-<release name>in the source's namespace, then the releasespec.chartRefto a HelmChartspec.chartRefto an OCIRepositoryThe generated chart's name comes from the current spec, as the CLI computes it, not from
status.helmChart: after a source change that field still names the previous chart until helm-controller replaces it.Every link is read and checked before anything is written. A suspended (
spec.suspend) or Terminating object anywhere in the chain fails the request with 409 and names that object, instead of annotating objects whose controller won't act. A link the caller can't read fails with that error (403, 404, or the read failure), since there is then no way to check it or to follow a chart to its source. Unlike the CLI, Radar requests the reconciles without waiting for each step to finish; the response lists the chain it requested.Flux objects are patched at the version the cluster serves.
gitops.FluxGVRResolverresolves a Flux kind through API discovery (the most stable served version). Once the discovery cache expires, one refresh runs in the background, so an action never waits on discovery; actions use the cached version until that refresh succeeds, which is when a Flux upgrade that retired a version is picked up; Reconcile, Suspend/Resume, Sync with source, the MCPmanage_gitopstool and the GitOps destination and write-evidence reads all use it. Without a resolver the static table still applies.HelmChart and Bucket are valid targets for Reconcile and Suspend/Resume through the API and MCP. No UI button offers them yet.
The success toast shows the server's message, so the user sees what was reconciled, or that an ExternalArtifact source was skipped.
pkg/gitops.SyncFluxWithSourcetakes an optional resolver as a trailing variadic argument, so existing callers compile unchanged and keep the static versions;FluxKindEntry.Servedapplies a resolver to the entry passed toReconcileFluxandSetFluxSuspend.Testing
Unit tests cover each row of the table, including the order of the patches; a stale
status.helmChartpointing at another chart; a missing generated chart (404, nothing patched); a suspended release, chart and repository (409, nothing patched); a chart or repository that can't be read (403 or timeout, nothing patched); discovery that changes version after its cache expires, and a stalled discovery refresh that must neither delay the action nor start more than one refresh; and patching av1beta2-only OCIRepository through the resolver, where the static version fails. Removing the chart's-source step, the suspension check, the read check, the discovery refresh, the resolver or the spec-derived chart name each fails a test.Live, on a kind cluster running Flux whose OCIRepository API is
v1beta2, each case was checked againststatus.lastHandledReconcileAton every object in the chain:chartRefto an OCIRepositoryspec.suspendtoggledNot covered live: an ExternalArtifact source (this Flux version has no ExternalArtifact API), and the toast in the browser (the message is checked at the API).