Skip to content

CM-1039: Thread context.Context from Reconcile() through controller helpers#419

Open
sebrandon1 wants to merge 1 commit intoopenshift:masterfrom
sebrandon1:ctx-consistency-rebase
Open

CM-1039: Thread context.Context from Reconcile() through controller helpers#419
sebrandon1 wants to merge 1 commit intoopenshift:masterfrom
sebrandon1:ctx-consistency-rebase

Conversation

@sebrandon1
Copy link
Copy Markdown
Member

@sebrandon1 sebrandon1 commented May 6, 2026

Summary

  • Removes the stored ctx context.Context field from both istiocsr and trustmanager Reconciler structs
  • Threads context from Reconcile(ctx context.Context, ...) through every helper method call chain (37 files, ~90 call sites)
  • Tests pass context.Background() explicitly (semantically correct for test entrypoints)

Motivation

Both controllers stored a context.Context initialized once to context.Background() in New(). The Reconcile() method receives a proper request-scoped context from controller-runtime, but all helper methods used the stale struct field. This defeats cancellation and deadline propagation from the framework.

This supersedes #242, which attempted to standardize context usage by replacing context.Background() with context.TODO() everywhere — semantically backwards since context.TODO() signals "placeholder, haven't decided yet" while context.Background() is correct for top-level contexts.

Test plan

  • go test ./pkg/controller/istiocsr/... passes
  • go test ./pkg/controller/trustmanager/... passes
  • go build ./... succeeds
  • make lint shows only pre-existing issues (none introduced)
  • No remaining r.ctx references in either package

Summary by CodeRabbit

  • Refactor
    • Improved internal request handling mechanisms across resource reconciliation processes to better support operation cancellation and timeout management.

…elpers

Both istiocsr and trustmanager controllers stored a context.Context field
on their Reconciler struct, initialized once in New(). The Reconcile()
method receives a request-scoped context from controller-runtime but all
helper methods used the stale struct field instead. This defeats
cancellation and deadline propagation from the framework.

Remove the ctx field from both Reconciler structs and thread the context
parameter from Reconcile() through every helper method call chain.
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label May 6, 2026
@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented May 6, 2026

@sebrandon1: This pull request references CM-1039 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Removes the stored ctx context.Context field from both istiocsr and trustmanager Reconciler structs
  • Threads context from Reconcile(ctx context.Context, ...) through every helper method call chain (37 files, ~90 call sites)
  • Tests pass context.Background() explicitly (semantically correct for test entrypoints)

Motivation

Both controllers stored a context.Context initialized once to context.Background() in New(). The Reconcile() method receives a proper request-scoped context from controller-runtime, but all helper methods used the stale struct field. This defeats cancellation and deadline propagation from the framework.

This supersedes #242, which attempted to standardize context usage by replacing context.Background() with context.TODO() everywhere — semantically backwards since context.TODO() signals "placeholder, haven't decided yet" while context.Background() is correct for top-level contexts.

Test plan

  • go test ./pkg/controller/istiocsr/... passes
  • go test ./pkg/controller/trustmanager/... passes
  • go build ./... succeeds
  • make lint shows only pre-existing issues (none introduced)
  • No remaining r.ctx references in either package

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 6, 2026

Walkthrough

This PR propagates Go context throughout IstioCSR and TrustManager controller reconciliation flows by adding context.Context parameters to method signatures, replacing internal context storage with explicit parameter passing, and updating all Kubernetes API calls to use the passed context instead of a receiver-stored context.

Changes

Context Propagation Refactoring

Layer / File(s) Summary
Struct & Field Changes
pkg/controller/trustmanager/controller.go, pkg/controller/trustmanager/test_utils.go
Removed ctx field from TrustManager Reconciler struct; test utils no longer initialize stored context, delegating to explicit parameter passing.
Core Reconciliation Signatures
pkg/controller/istiocsr/controller.go, pkg/controller/trustmanager/controller.go
Updated Reconcile methods to delegate to context-aware processReconcileRequest(ctx, ...) and reconcileIstioCSRDeployment(ctx, ...) / reconcileTrustManagerDeployment(ctx, ...).
Installation & Orchestration
pkg/controller/istiocsr/install_istiocsr.go, pkg/controller/trustmanager/install_trustmanager.go
Added context propagation through resource reconciliation orchestrators; all createOrApply* and status update calls now thread ctx through the flow.
Resource Reconciliation Methods
pkg/controller/istiocsr/{certificates,deployments,networkpolicies,rbacs,serviceaccounts,services}.go, pkg/controller/trustmanager/{certificates,configmaps,deployments,rbacs,serviceaccounts,services,webhooks}.go
Updated all createOrApply*, helper, and utility method signatures to accept ctx context.Context as the first parameter; replaced r.ctx usage with passed-in ctx in Kubernetes API calls.
Utility & Condition Methods
pkg/controller/istiocsr/utils.go, pkg/controller/trustmanager/utils.go
Added context-aware updateCondition(ctx, ...), namespaceExists(ctx, ...), disallowMultipleIstioCSRInstances(ctx, ...) and updated status-update paths to propagate context.
Kubernetes API Calls
pkg/controller/istiocsr/*.go, pkg/controller/trustmanager/*.go
Updated all Exists(ctx, ...), Get(ctx, ...), Patch(ctx, ...), Create(ctx, ...), UpdateWithRetry(ctx, ...), List(ctx, ...), and Delete(ctx, ...) calls to use the passed context instead of stored or implicit context.
Tests
pkg/controller/istiocsr/*_test.go, pkg/controller/trustmanager/*_test.go
Updated all test invocations to pass context.Background() as the first argument to context-aware methods, aligning with updated function signatures.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 10 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.70% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Single Node Openshift (Sno) Test Compatibility ⚠️ Warning New e2e test uses PodAntiAffinity with TopologyKey requiring multiple nodes without SNO skip protection at trustmanager_test.go:521. Add [Skipped:SingleReplicaTopology] label to test or guard with exutil.IsSingleNode() check that skips on SNO clusters.
✅ Passed checks (10 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: threading context.Context from Reconcile() through controller helpers across both istiocsr and trustmanager packages.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All test names in the modified test files are static and deterministic. No dynamic values (timestamps, UUIDs, pod/node names, IP addresses, or generated suffixes) found in test titles.
Test Structure And Quality ✅ Passed Tests use table-driven patterns with single-responsibility cases, meaningful assertions, mock setup, and proper timeouts. PR only adds context parameters without changing test structure.
Microshift Test Compatibility ✅ Passed No new Ginkgo e2e tests added. PR only contains Go unit tests with func Test* pattern. This is a context.Context propagation refactoring with only existing test updates.
Topology-Aware Scheduling Compatibility ✅ Passed This PR is a context propagation refactoring with no deployment manifest changes or new scheduling constraints. No affinity, anti-affinity, nodeSelector, or toleration logic was added.
Ote Binary Stdout Contract ✅ Passed Context threading refactor. No stdout writes detected. Uses logr.Logger which writes to stderr. No fmt.Print or log operations. All changes are signature updates.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests added. PR refactors context propagation in pkg/controller/. Check only applies when e2e tests are added.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@openshift-ci openshift-ci Bot requested review from mytreya-rh and swghosh May 6, 2026 17:14
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 6, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: sebrandon1
Once this PR has been reviewed and has the lgtm label, please assign swghosh for approval. For more information see the Code Review Process.

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/controller/istiocsr/utils.go (1)

481-486: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Preserve the original reconciliation error in the aggregate.

When updateStatus fails, this branch currently returns the raw status-update error twice and drops prependErr. That hides the actual root cause whenever both operations fail.

Proposed fix
 func (r *Reconciler) updateCondition(ctx context.Context, istiocsr *v1alpha1.IstioCSR, prependErr error) error {
 	if err := r.updateStatus(ctx, istiocsr); err != nil {
 		errUpdate := fmt.Errorf("failed to update %s/%s status: %w", istiocsr.GetNamespace(), istiocsr.GetName(), err)
 		if prependErr != nil {
-			return utilerrors.NewAggregate([]error{err, errUpdate})
+			return utilerrors.NewAggregate([]error{prependErr, errUpdate})
 		}
 		return errUpdate
 	}
 	return prependErr
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controller/istiocsr/utils.go` around lines 481 - 486, The updateCondition
function currently aggregates the status-update error twice and discards the
original reconciliation error (prependErr); change the aggregation so that when
updateStatus fails you return an aggregate containing the original prependErr
and the constructed errUpdate (i.e., utilerrors.NewAggregate([]error{prependErr,
errUpdate})) so the root reconciliation error is preserved; keep the existing
behavior when prependErr is nil (return errUpdate or the single status error as
before). Reference: function updateCondition, call to r.updateStatus, variable
prependErr and errUpdate.
🧹 Nitpick comments (2)
pkg/controller/istiocsr/install_instiocsr_test.go (1)

116-125: ⚡ Quick win

Assert that the reconcile context is the one reaching client calls.

This only exercises the new signature today. If reconcileIstioCSRDeployment or one of its helpers regresses to context.Background(), these tests still pass because every fake ignores ctx. Passing a sentinel context here and checking it in one mocked Get/Create/UpdateWithRetry callback would lock in the behavior this PR is meant to preserve.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controller/istiocsr/install_instiocsr_test.go` around lines 116 - 125,
The test must assert the actual context passed into controller client calls:
create a sentinel context (e.g., ctx := context.WithValue(context.Background(),
"sentinel", true)) in the subtest before calling r.reconcileIstioCSRDeployment,
pass that ctx into the call instead of context.Background(), and configure one
of the fake client callbacks on fakes.FakeCtrlClient (Get or Create or
UpdateWithRetry) to check that the incoming ctx equals the sentinel (or contains
the sentinel value) and fail the test if not; update testReconciler usage in the
subtest to use this ctx and reference reconcileIstioCSRDeployment,
FakeCtrlClient, and istiocsr so the assertion locks the intended behavior.
pkg/controller/trustmanager/webhooks_test.go (1)

227-242: ⚡ Quick win

Verify that the provided context is forwarded to Exists/Patch.

Right now this just compiles against the new API. A future fallback to context.Background() inside createOrApplyValidatingWebhookConfiguration would still pass. Using a sentinel context here and asserting it inside one fake client callback would make the context-threading change testable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controller/trustmanager/webhooks_test.go` around lines 227 - 242, The
test should verify the context is forwarded to the client methods: create a
sentinel context (e.g., ctxSentinel := context.WithValue(context.Background(),
"sentinel", struct{}{})), call r.createOrApplyValidatingWebhookConfiguration
with that ctxSentinel instead of context.Background(), and configure the fake
client (fakes.FakeCtrlClient) inside the test (via mock.ExistsStub and/or
mock.PatchStub) to assert the incoming ctx equals ctxSentinel (fail the test if
not) before returning; update the test case that exercises
createOrApplyValidatingWebhookConfiguration to set those stubs so Exists/Patch
receive and validate the sentinel context.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@pkg/controller/istiocsr/utils.go`:
- Around line 481-486: The updateCondition function currently aggregates the
status-update error twice and discards the original reconciliation error
(prependErr); change the aggregation so that when updateStatus fails you return
an aggregate containing the original prependErr and the constructed errUpdate
(i.e., utilerrors.NewAggregate([]error{prependErr, errUpdate})) so the root
reconciliation error is preserved; keep the existing behavior when prependErr is
nil (return errUpdate or the single status error as before). Reference: function
updateCondition, call to r.updateStatus, variable prependErr and errUpdate.

---

Nitpick comments:
In `@pkg/controller/istiocsr/install_instiocsr_test.go`:
- Around line 116-125: The test must assert the actual context passed into
controller client calls: create a sentinel context (e.g., ctx :=
context.WithValue(context.Background(), "sentinel", true)) in the subtest before
calling r.reconcileIstioCSRDeployment, pass that ctx into the call instead of
context.Background(), and configure one of the fake client callbacks on
fakes.FakeCtrlClient (Get or Create or UpdateWithRetry) to check that the
incoming ctx equals the sentinel (or contains the sentinel value) and fail the
test if not; update testReconciler usage in the subtest to use this ctx and
reference reconcileIstioCSRDeployment, FakeCtrlClient, and istiocsr so the
assertion locks the intended behavior.

In `@pkg/controller/trustmanager/webhooks_test.go`:
- Around line 227-242: The test should verify the context is forwarded to the
client methods: create a sentinel context (e.g., ctxSentinel :=
context.WithValue(context.Background(), "sentinel", struct{}{})), call
r.createOrApplyValidatingWebhookConfiguration with that ctxSentinel instead of
context.Background(), and configure the fake client (fakes.FakeCtrlClient)
inside the test (via mock.ExistsStub and/or mock.PatchStub) to assert the
incoming ctx equals ctxSentinel (fail the test if not) before returning; update
the test case that exercises createOrApplyValidatingWebhookConfiguration to set
those stubs so Exists/Patch receive and validate the sentinel context.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 23714fe0-8a1a-4c99-a548-c1d17e7437d7

📥 Commits

Reviewing files that changed from the base of the PR and between a2e7514 and df73b9f.

📒 Files selected for processing (37)
  • pkg/controller/istiocsr/certificates.go
  • pkg/controller/istiocsr/certificates_test.go
  • pkg/controller/istiocsr/controller.go
  • pkg/controller/istiocsr/controller_test.go
  • pkg/controller/istiocsr/deployments.go
  • pkg/controller/istiocsr/deployments_test.go
  • pkg/controller/istiocsr/install_instiocsr_test.go
  • pkg/controller/istiocsr/install_istiocsr.go
  • pkg/controller/istiocsr/networkpolicies.go
  • pkg/controller/istiocsr/rbacs.go
  • pkg/controller/istiocsr/rbacs_test.go
  • pkg/controller/istiocsr/serviceaccounts.go
  • pkg/controller/istiocsr/serviceaccounts_test.go
  • pkg/controller/istiocsr/services.go
  • pkg/controller/istiocsr/services_test.go
  • pkg/controller/istiocsr/test_utils.go
  • pkg/controller/istiocsr/utils.go
  • pkg/controller/trustmanager/certificates.go
  • pkg/controller/trustmanager/certificates_test.go
  • pkg/controller/trustmanager/configmaps.go
  • pkg/controller/trustmanager/configmaps_test.go
  • pkg/controller/trustmanager/controller.go
  • pkg/controller/trustmanager/controller_test.go
  • pkg/controller/trustmanager/deployments.go
  • pkg/controller/trustmanager/deployments_test.go
  • pkg/controller/trustmanager/install_trustmanager.go
  • pkg/controller/trustmanager/install_trustmanager_test.go
  • pkg/controller/trustmanager/rbacs.go
  • pkg/controller/trustmanager/rbacs_test.go
  • pkg/controller/trustmanager/serviceaccounts.go
  • pkg/controller/trustmanager/serviceaccounts_test.go
  • pkg/controller/trustmanager/services.go
  • pkg/controller/trustmanager/services_test.go
  • pkg/controller/trustmanager/test_utils.go
  • pkg/controller/trustmanager/utils.go
  • pkg/controller/trustmanager/webhooks.go
  • pkg/controller/trustmanager/webhooks_test.go
💤 Files with no reviewable changes (2)
  • pkg/controller/trustmanager/test_utils.go
  • pkg/controller/istiocsr/test_utils.go

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 6, 2026

@sebrandon1: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants