Skip to content

ssa: Add pre-dry-run field manager takeover - #1276

Open
dipti-pai wants to merge 1 commit into
fluxcd:mainfrom
dipti-pai:ssa-pre-dryrun-manager-takeover
Open

dipti-pai wants to merge 1 commit into
fluxcd:mainfrom
dipti-pai:ssa-pre-dryrun-manager-takeover

Conversation

@dipti-pai

@dipti-pai dipti-pai commented Aug 6, 2026

Copy link
Copy Markdown
Member

Add ApplyCleanupOptions.FieldManagersBeforeDryRun, a separate opt-in list of field managers whose ownership is reclaimed before the server-side dry-run in Apply and ApplyAll.

The existing FieldManagers takeover runs only after a successful dry-run (cleanupMetadata). When a stale or foreign manager co-owns a required field such that the merged object is invalid, the dry-run fails first and the takeover is never reached, leaving the object wedged on every reconcile. Taking over the named managers before the dry-run repairs ownership so the merge is valid.

This is kept separate from FieldManagers because a pre-dry-run takeover mutates managedFields even if the apply later fails, unlike the post-dry-run cleanup. Only managers explicitly identified as problematic should be listed, so the default managers keep their transactional post-dry-run behavior.

Assisted-by: GitHub Copilot/Claude Opus 4.8

Fixes: fluxcd/kustomize-controller#1722

@dipti-pai
dipti-pai force-pushed the ssa-pre-dryrun-manager-takeover branch from cad454f to 0ff5466 Compare September 17, 2026 19:33
@dipti-pai
dipti-pai marked this pull request as ready for review September 17, 2026 20:23
@dipti-pai
dipti-pai requested a review from a team as a code owner September 17, 2026 20:23

@matheuscscp matheuscscp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @dipti-pai, looks good overall!

Comment thread ssa/manager_apply_takeover_test.go
Comment thread ssa/manager_apply.go
Comment thread ssa/manager_apply.go
@dipti-pai
dipti-pai force-pushed the ssa-pre-dryrun-manager-takeover branch from 0ff5466 to 75f2c19 Compare September 18, 2026 16:27
Add ApplyCleanupOptions.FieldManagersBeforeDryRun, a separate opt-in
list of field managers whose ownership is reclaimed before the
server-side dry-run in Apply and ApplyAll.

The existing FieldManagers takeover runs only after a successful
dry-run (cleanupMetadata). When a stale or foreign manager co-owns a
required field such that the merged object is invalid, the dry-run
fails first and the takeover is never reached, leaving the object
wedged on every reconcile. Taking over the named managers before the
dry-run repairs ownership so the merge is valid.

This is kept separate from FieldManagers because a pre-dry-run takeover
mutates managedFields even if the apply later fails, unlike the
post-dry-run cleanup. Only managers explicitly identified as
problematic should be listed, so the default managers keep their
transactional post-dry-run behavior.

Signed-off-by: Dipti Pai <diptipai89@outlook.com>
Assisted-by: GitHub Copilot/Claude Opus 4.8
@dipti-pai
dipti-pai force-pushed the ssa-pre-dryrun-manager-takeover branch from 75f2c19 to 793ef82 Compare September 18, 2026 16:31
@dipti-pai

Copy link
Copy Markdown
Member Author

Thanks @dipti-pai, looks good overall!

Thanks @matheuscscp. Addressed the review comments.

@matheuscscp matheuscscp left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 🚀

Thanks @dipti-pai!

Lillecarl added a commit to Lillecarl/easykubenix that referenced this pull request Sep 20, 2026
`deployment.fieldManager` stops the split happening again. It does nothing
for the objects that already crossed one, and nothing else can: the supported
way to drop a field is for its owning manager to apply again without it, and
the owning manager is the one that has stopped applying.

So this renames the old manager's Apply records onto the new one. The new
manager then owns what the old one did, and its next apply removes what it no
longer declares -- ordinary server-side apply, from then on.

**Renamed, never deleted.** A deleted record leaves its fields unowned, and
nothing removes an unowned field. That is the bug rather than the fix.

**Apply records only.** An `Update` record says a client wrote the field with
a plain update, which server-side apply does not consult for removal.
`kube-controller-manager`'s `status` is one, and renaming it would claim
ownership this cannot act on.

Two records for one manager, operation and apiVersion is a shape the API
server never produces, so a rename into an occupied slot merges the two
`fieldsV1` trees instead of appending. A `fieldsV1` value is a nested object
whose leaves are `{}`, so the union is a recursive merge.

Writing `metadata.managedFields` is the mechanism Kubernetes calls "highly
discouraged", and its own documentation names the case: `managedFields` in an
inconsistent state. This is that case, and a plain patch is the only way in --
an apply cannot write the field, because the API server computes it from the
apply.

Flux arrived at the same shape from the same failure: `fluxcd/pkg` reclaims
stale managers, but only after a dry-run the broken state cannot pass
(fluxcd/kustomize-controller#1722, fluxcd/pkg#1276). Two projects converging
is the argument for copying it rather than inventing a third.

Serial, and not a fan-out: it runs once per transition, and a readable log of
what it touched is worth more than the seconds concurrency would save.

Assisted-By: claude-opus-5[1m]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ssa: support taking over field managers before dry-run

2 participants