Skip to content

fix(taskrun): retry native sidecar discovery after transient errors - #10466

Open
pujitha24 wants to merge 4 commits into
tektoncd:mainfrom
pujitha24:auto/issue-10101
Open

pujitha24 wants to merge 4 commits into
tektoncd:mainfrom
pujitha24:auto/issue-10101

Conversation

@pujitha24

@pujitha24 pujitha24 commented Jul 26, 2026 •

Copy link
Copy Markdown

Changes

With enable-kubernetes-sidecar set, the TaskRun reconciler's done path memoized client.Discovery().ServerVersion() with sync.OnceValues, which cached both successes and errors forever. A transient discovery failure on the first call meant every later done-path reconcile kept returning that same stale error until the controller restarted, delaying final done-path processing (including sidecar cleanup) for completed TaskRuns.

This replaces that memoization with a mutex-guarded cache that's only populated after a successful discovery call, so a transient error is retried on the next reconcile instead of being cached forever. On the happy path the behavior is unchanged — discovery is still queried at most once per process.

Fixes #10101

/kind bug

Submitter Checklist

As the author of this PR, please check off the items in this checklist:

  • Has Docs if any changes are user facing, including updates to minimum requirements e.g. Kubernetes version bumps
  • Has Tests included if any functionality added or changed
  • pre-commit Passed
  • Follows the commit message standard
  • Meets the Tekton contributor standards (including functionality, content, code)
  • Has a kind label. You can add one by adding a comment on this PR that contains /kind <type>. Valid types are bug, cleanup, design, documentation, feature, flake, misc, question, tep
  • Release notes block below has been updated with any user facing changes (API changes, bug fixes, changes requiring upgrade notices or deprecation warnings). See some examples of good release notes.
  • Release notes contains the string "action required" if the change requires additional action from users switching to the new release

Release Notes

Fixed a bug where, with `enable-kubernetes-sidecar` set, a transient error from the Kubernetes API server during native-sidecar discovery could be cached forever, repeatedly delaying final done-path processing (including sidecar cleanup) for completed TaskRuns instead of being retried once the API server recovered.

Copilot AI review requested due to automatic review settings July 26, 2026 16:30
@tekton-robot tekton-robot added release-note Denotes a PR that will be considered when it comes time to generate release notes. kind/bug Categorizes issue or PR as related to a bug. labels Jul 26, 2026
@linux-foundation-easycla

linux-foundation-easycla Bot commented Jul 26, 2026 •

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

@tekton-robot

Copy link
Copy Markdown
Collaborator

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
To complete the pull request process, please assign vdemeester after the PR has been reviewed.
You can assign the PR to them by writing /assign @vdemeester in a comment when ready.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@tekton-robot
tekton-robot requested review from khrm and pritidesai July 26, 2026 16:30
@tekton-robot tekton-robot added the size/M Denotes a PR that changes 30-99 lines, ignoring generated files. label Jul 26, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a TaskRun reconciler edge case when enable-kubernetes-sidecar is enabled: a transient failure from Discovery().ServerVersion() was previously memoized forever (via sync.OnceValues), delaying done-path processing (including sidecar cleanup) until controller restart. The new approach caches the native-sidecar decision only after a successful discovery call, so transient errors are retried on later reconciles.

Changes:

  • Replace sync.OnceValues-based memoization with a mutex-guarded, success-only nativeSidecarCache.
  • Ensure discovery errors are returned for the current reconcile but do not populate the cache.
  • Add a regression test intended to verify discovery errors are not cached across reconciles.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
pkg/reconciler/taskrun/taskrun.go Replaces error-memoizing discovery memoization with a success-only cache for native sidecar detection.
pkg/reconciler/taskrun/taskrun_test.go Adds a regression test for “do not cache discovery errors” behavior (currently needs adjustment to avoid version-dependent brittleness).
Comments suppressed due to low confidence (1)

pkg/reconciler/taskrun/taskrun_test.go:8558

  • This test asserts that useTektonSidecarMode() returns true after the transient error, but that depends on what ServerVersion() returns (which can change as client-go/Kubernetes version defaults change). The regression being tested is that discovery errors are not memoized; the boolean result isn't important here.

Consider asserting that ServerVersion() is called twice (error then success) and that a subsequent call does not hit discovery again (cached after success).

	useTektonSidecar, err := r.useTektonSidecarMode(ctx, logger)
	if err != nil {
		t.Fatalf("expected useTektonSidecarMode to retry discovery after a transient error and succeed, got err: %v", err)
	}
	if !useTektonSidecar {

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +8532 to +8538
discoveryFailed := true
kubeClient.PrependReactor("get", "version", func(action ktesting.Action) (bool, runtime.Object, error) {
if discoveryFailed {
return true, nil, errors.New("transient discovery error")
}
return false, nil, nil
})

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Good catch, thanks. I've updated the test so it no longer depends on the fake discovery client's default (client-go build) version: it now sets FakedServerVersion explicitly to {Major: "1", Minor: "28"}, and the reactor always returns handled=true and increments a discoveryCalls counter. The assertions now check that counter directly (1 call after the failed reconcile, 2 after the retry succeeds, still 2 after a third reconcile to confirm the successful result is cached), rather than asserting on the boolean result of useTektonSidecarMode. Ran go test ./pkg/reconciler/taskrun/... and it passes.

Copilot AI review requested due to automatic review settings July 26, 2026 18:11
@tekton-robot tekton-robot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. and removed size/M Denotes a PR that changes 30-99 lines, ignoring generated files. labels Jul 26, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

pkg/reconciler/taskrun/taskrun_test.go:8544

  • The success-path comment in the reactor is misleading: the reactor doesn't return a version object; FakeDiscovery.ServerVersion() ignores the reactor's object and returns the FakedServerVersion configured below. Clarifying this avoids future confusion when modifying the test.
		// Explicitly return a version predating native sidecar support (1.29) so the
		// assertions below don't depend on the fake client's default build version.
		return true, nil, nil
	})

@pujitha24

Copy link
Copy Markdown
Author

Thanks for the follow-up review. The comment on the reactor's success path was indeed misleading — it implied the reactor's return value supplied version "1.29", but FakeDiscovery.ServerVersion() actually ignores whatever the reactor returns and reports whatever FakedServerVersion is set to. I've updated the comment to say that plainly instead. Re-ran go test ./pkg/reconciler/taskrun/... -run TestUseTektonSidecarModeDoesNotCacheDiscoveryErrors -v and it still passes.

Copilot AI review requested due to automatic review settings July 27, 2026 01:10

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

Comment on lines +8541 to +8543
// Signal a successful discovery call (handled=true, no error). The version
// FakeDiscovery.ServerVersion() actually returns comes from FakedServerVersion,
// set below, not from this reactor's return value.
@pujitha24

Copy link
Copy Markdown
Author

Thanks for catching that — fixed the grammar in the comment (added "that" so it reads "The version that FakeDiscovery.ServerVersion() actually returns comes from FakedServerVersion..."). Ran go test ./pkg/reconciler/taskrun/... -run TestUseTektonSidecarModeDoesNotCacheDiscoveryErrors -v and it still passes.

Copilot AI review requested due to automatic review settings July 27, 2026 15:11

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

@pujitha24

Copy link
Copy Markdown
Author

/easycla

@pujitha24

Copy link
Copy Markdown
Author

/retest

@vdemeester

Copy link
Copy Markdown
Member

@pujitha24 can you follow the pull request template please ?

@pujitha24

Copy link
Copy Markdown
Author

/retest

@tekton-robot tekton-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 29, 2026
Motivation:

When EnableKubernetesSidecar is set, the TaskRun reconciler's done
path (tr.IsDone()) calls useTektonSidecarMode to decide whether to
run the Tekton nop-sidecar teardown or rely on native Kubernetes
sidecars. That check memoized client.Discovery().ServerVersion() with
sync.OnceValues, which caches both successful values and errors
forever. If the very first ServerVersion() call failed transiently
(e.g. the API server was briefly unavailable), every later done-path
reconcile for every TaskRun in that process kept returning the same
stale error, since the cache lives on the shared Reconciler struct,
not per-TaskRun.

To be precise about impact: this does not crash or panic the
controller. useTektonSidecarMode returning an error just makes the
done-path handler return err instead of calling
finishReconcileUpdateEmitEvents; knative's reconciler logs it and
requeues with backoff like any other reconcile error. The observable
effect is that final done-path processing (including sidecar cleanup
via stopSidecars) for completed TaskRuns keeps getting delayed/
retried until the controller restarts or a leader change resets the
cache, rather than the discovery call being retried on a later,
healthy reconcile.

Approach:

Replace the sync.Once + sync.OnceValues pair with a small
mutex-guarded nativeSidecarCache that only marks the result cached
after client.Discovery().ServerVersion() succeeds. On error, the
error is returned for the current reconcile but the cache is left
unpopulated so the next reconcile retries discovery. Once a call
succeeds, the result is cached for the lifetime of the Reconciler,
same as before (ServerVersion is still queried at most once on the
happy path).

Validation:

go build ./...
go test ./pkg/reconciler/taskrun/... -count=1

Both pass, including the new regression test:

go test ./pkg/reconciler/taskrun -run TestUseTektonSidecarModeDoesNotCacheDiscoveryErrors -count=1 -v

which fails against the old sync.OnceValues-based code (verified
locally) and passes against this fix.

/kind bug

```release-note
Fixed a bug where, with `enable-kubernetes-sidecar` set, a transient
error from the Kubernetes API server during native-sidecar discovery
could be cached forever, repeatedly delaying final done-path
processing (including sidecar cleanup) for completed TaskRuns instead
of being retried once the API server recovered.
```

Fixes tektoncd#10101

Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Assisted-by: Claude Sonnet 5 (via Claude Code)
…ersion

Assert on a discovery-call counter and an explicit FakedServerVersion
instead of the fake client's default build version, and always return
handled=true from the reactor, per review feedback.

Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Assisted-by: Claude Sonnet 5 (via Claude Code)
The reactor's return value doesn't influence the version reported by
FakeDiscovery.ServerVersion(); that comes from FakedServerVersion, set
right after. Clarify the comment to avoid confusion (per Copilot review).

Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Assisted-by: Claude Sonnet 5 (via Claude Code)
Signed-off-by: Pujitha Paladugu <10557236+pujitha24@users.noreply.github.com>
Assisted-by: Claude Sonnet 5 (via Claude Code)
@pujitha24

Copy link
Copy Markdown
Author

Sorry for the slow follow-up on the template. The description now uses the repo's PR template (Changes, checklist, release-note block), and I left the Docs and "action required" boxes unchecked since neither applies. I also rebased onto current main to clear the merge conflict; the only conflict was in the Reconciler struct next to the new pod-event fields, and go build ./pkg/reconciler/... and go test ./pkg/reconciler/taskrun/ pass after it.

@tekton-robot tekton-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/bug Categorizes issue or PR as related to a bug. release-note Denotes a PR that will be considered when it comes time to generate release notes. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(taskrun): retry native sidecar discovery after transient errors

4 participants