Skip to content

fix: patch operator-owned status instead of replacing it - #277

Open
stigglor wants to merge 1 commit into
kaasops:mainfrom
stigglor:fix/status-update-conflicts
Open

fix: patch operator-owned status instead of replacing it#277
stigglor wants to merge 1 commit into
kaasops:mainfrom
stigglor:fix/status-update-conflicts

Conversation

@stigglor

Copy link
Copy Markdown
Contributor

A reconcile reads its CR, then holds it through pipeline collection, config
build, configcheck (300s by default) and the workload write before it sets
status. By then the resourceVersion is routinely stale, so Status().Update
fails with "the object has been modified" and the whole configcheck runs again
on the requeue. Cached reads widen the window: a reconcile triggered right
after a status write can read the version from before it, and the pipeline
controller pushes an event per agent from each of its 20 concurrent reconciles,
so back to back reconciles of one CR are normal.

Nothing but this operator writes these status subresources, so optimistic
concurrency buys nothing here. The status setters now send a merge patch built
against the object as read, carrying no resourceVersion and only the status
diff, so a stale object can neither lose the write nor clobber a concurrent
edit to spec or metadata. Pipelines pass that base in from the reconcile, since
the role is set into status while configcheck runs and has to stay in the patch.

The success paths force reason into the patch base. It is omitempty, so a base
read before an earlier failure was recorded would emit no reason key and leave
the old text sitting next to configCheckResult true.

Closes #174

A reconcile reads its CR, then holds it through pipeline collection, config
build, configcheck (300s by default) and the workload write before it sets
status. By then the resourceVersion is routinely stale, so Status().Update
fails with "the object has been modified" and the whole configcheck runs again
on the requeue. Cached reads widen the window: a reconcile triggered right
after a status write can read the version from before it, and the pipeline
controller pushes an event per agent from each of its 20 concurrent reconciles,
so back to back reconciles of one CR are normal.

Nothing but this operator writes these status subresources, so optimistic
concurrency buys nothing here. The status setters now send a merge patch built
against the object as read, carrying no resourceVersion and only the status
diff, so a stale object can neither lose the write nor clobber a concurrent
edit to spec or metadata. Pipelines pass that base in from the reconcile, since
the role is set into status while configcheck runs and has to stay in the patch.

The success paths force reason into the patch base. It is omitempty, so a base
read before an earlier failure was recorded would emit no reason key and leave
the old text sitting next to configCheckResult true.

Closes kaasops#174
@stigglor
stigglor force-pushed the fix/status-update-conflicts branch from 6e2cb46 to a86bf38 Compare August 11, 2026 08:11
@stigglor
stigglor marked this pull request as ready for review August 11, 2026 08:40
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.

The initial deployment of the operator always stucks

1 participant