Skip to content

Use reflector for all repeated read operations, set read timeout & a test timeout greater than that, CI stress edition - #330

Open
Jakob-Naucke wants to merge 9 commits into
trusted-execution-clusters:mainfrom
Jakob-Naucke:get-cached-ci
Open

Use reflector for all repeated read operations, set read timeout & a test timeout greater than that, CI stress edition#330
Jakob-Naucke wants to merge 9 commits into
trusted-execution-clusters:mainfrom
Jakob-Naucke:get-cached-ci

Conversation

@Jakob-Naucke

@Jakob-Naucke Jakob-Naucke commented Aug 10, 2026

Copy link
Copy Markdown
Member

Summary by Sourcery

Consolidate Kubernetes resource caching and timeout handling to make controller read operations resilient under stressed conditions.

New Features:

  • Use reflector-backed caches through a shared operator context for repeated Kubernetes reads across controllers.
  • Add bounded retry behavior to register-server operations to tolerate operator read timeouts.

Bug Fixes:

  • Avoid stale or repeated ConfigMap reads when updating PCR and reference values by using cached data and server-side patches.

Enhancements:

  • Configure a five-minute Kubernetes API read timeout and consolidate controller cache initialization and synchronization.
  • Filter attestation-key secret reconciliation by labels and use cached resources for deployment and cluster lookups.

CI:

  • Increase integration-test timeout allowance in CI to accommodate a read timeout and retry.

Tests:

  • Update controller tests to exercise reflector-backed reads, reduced API interactions, and patch-based updates.

@openshift-ci

openshift-ci Bot commented Aug 10, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Jakob-Naucke

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

@sourcery-ai

sourcery-ai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

Centralizes Kubernetes operator controller state into a shared reflector-backed OperatorContext with a configured 5-minute read timeout, refactors reference-value and trustee logic to use cached data and server-side patches, tightens attestation secret scoping via labels, and adjusts CI/test timeouts and tests to reflect reduced API interactions and new behaviors.

Sequence diagram for ApprovedImage reconciliation using cached PCR ConfigMap

sequenceDiagram
    participant ImageController
    participant OperatorContext
    participant Trustee

    ImageController->>OperatorContext: image_reconcile(image, ctx)
    ImageController->>OperatorContext: get_opt_tec()
    alt TrustedExecutionCluster available
        ImageController->>OperatorContext: handle_new_image(ctx, image)
        note over OperatorContext: may call cached_image_pcrs()
        alt PCRs need update
            ImageController->>OperatorContext: apply_image_pcrs(ctx, image_pcrs)
            OperatorContext->>Trustee: update_reference_values(client, image_pcrs)
        else no PCR change
            ImageController-->>OperatorContext: return NOT_COMMITTED_REASON_PENDING or existing
        end
    else no cluster
        ImageController-->>OperatorContext: return LONG_REQUEUE
    end
Loading

File-Level Changes

Change Details Files
Introduce shared reflector-backed OperatorContext and use it across all controllers instead of per-controller contexts and direct API reads.
  • Add OperatorContext struct with shared kube::Client and Store caches for key resource types and helper to read the single TrustedExecutionCluster from cache.
  • Initialize all reflectors and stores in operator main, wire them into OperatorContext, and perform best-effort cache sync on startup.
  • Update TEC, attestation-key, reference-values, and keygen controllers to accept Arc instead of bespoke contexts or raw Clients, and adjust tests to construct OperatorContext-based fixtures.
operator/src/lib.rs
operator/src/main.rs
operator/src/attestation_key_register.rs
operator/src/reference_values.rs
operator/src/register_server.rs
Use cached ConfigMap and Deployment data plus server-side apply patches instead of read-modify-write updates for PCR/Trustee ConfigMaps and trustee Deployment secret mounts.
  • Replace the update_image_pcrs! macro with explicit JSON construction and API replace/patch calls in compute-pcrs and operator reference_values.
  • Refactor trustee::update_reference_values to take pre-fetched ImagePcrs and apply a server-side patch to TRUSTEE_DATA_MAP.
  • Change trustee mount_secret/unmount_secret to read Deployment from cache, compute new volumes/volumeMounts, and apply them via server-side apply patch instead of replace.
  • Update reference_values job/image reconcile paths to reuse cached PCR ConfigMaps and call trustee::update_reference_values with the in-memory ImagePcrs, and adjust tests to assert reduced API traffic and new patch semantics.
compute-pcrs/src/main.rs
lib/src/reference_values.rs
operator/src/reference_values.rs
operator/src/trustee.rs
Scope attestation-key related Secrets via labels and cache-backed filtering, and adjust AK controllers to use shared context and improved selectors.
  • Remove AkContextData in favor of OperatorContext and reuse shared secret and deployment stores in attestation_key_register.
  • Label attestation-key Secrets with a stable kind label and introduce KIND_LABEL_KEY/ATTESTATION_KEY_LABEL_VALUE constants for consistent labeling.
  • Change the secret controller to watch only labeled attestation-key Secrets using a label selector instead of inspecting ownerReferences in reconcile.
  • Use cached Secret/Deployment lookups via ObjectRef when checking for existing Secrets and when updating attestation key volumes in trustee::update_attestation_keys.
operator/src/attestation_key_register.rs
operator/src/lib.rs
operator/src/reference_values.rs
operator/src/trustee.rs
Make PCR-computation Jobs and ApprovedImage handling more cache-aware and Job-owned, including controller ownership and requeue behavior.
  • Introduce cached_image_pcrs helper in reference_values to read PCR ConfigMap from OperatorContext cache and use it in Job and image reconcile paths.
  • Change the Job controller to delete completed Jobs, update reference values based on cached PCRs, and requeue with LONG_REQUEUE instead of await_change.
  • Make the ApprovedImage controller own PCR-computation Jobs via .owns and label-based watcher config, and drive image adoption/removal via cached ApprovedImage lists instead of GET/list calls.
  • Refactor handle_new_image/disallow_image to operate on OperatorContext, use cached image PCRs, and rely on compute_fresh_pcrs plus apply_image_pcrs for updates, with tests updated for the new interaction patterns.
operator/src/reference_values.rs
Configure a Kubernetes client read timeout and align register-server retries and CI integration test timeouts to tolerate long read hangs with retries.
  • Set KUBE_READ_TIMEOUT (~5 minutes) on the inferred kube::Config in operator main before constructing the Client, documenting exec/attach impact.
  • Update register-server to configure Clevis NumRetries::Finite based on a RETRIES constant sized to cover one operator read-timeout window plus slack.
  • Adjust GitHub Actions integration-tests workflow to export TEST_TIMEOUT_MULTIPLIER=6 so the tests can survive a full read-timeout+retry cycle.
operator/src/main.rs
.github/workflows/integration-tests.yml
register-server/src/main.rs

Possibly linked issues

  • #N/A: PR implements reflector-backed caches for listed resources, replacing direct get/list calls and reducing API traffic as requested.
  • #0: They address the same problem: attestation key approval delays causing clevis to give up, via cache/timeout and retry changes.

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@Jakob-Naucke Jakob-Naucke changed the title Use reflector for all repeated read operations & set write timeout less than test timeouts, CI stress edition Use reflector for all repeated read operations & set kube timeouts less than test timeouts, CI stress edition Aug 11, 2026
@Jakob-Naucke Jakob-Naucke changed the title Use reflector for all repeated read operations & set kube timeouts less than test timeouts, CI stress edition Use reflector for all repeated read operations, set read timeout & a test timeout greater than that, CI stress edition Aug 18, 2026
@Jakob-Naucke

Copy link
Copy Markdown
Member Author

Had one VM that didn't boot up, cause cannot be uncovered from logs (from dmesg one can only tell it has failed, and Trustee was restarted). We are working on improving observability of Trustee, but should also log failures from trustee-attester without leaking secrets.

FWIW, the failure could be explained by a missing secret which has been seen on Azure and should improve with #248. For now, rerun.

Comment thread operator/src/trustee.rs
"metadata": { "name": TRUSTEE_DATA_MAP },
"data": { REFERENCE_VALUES_FILE: rv_json }
}));
let pp = PatchParams::apply("trusted-cluster-operator").force();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

is the force necessary?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, this is an apply patch, not a merge patch:

[2026-08-19T13:28:45Z WARN  operator::reference_values] PCR computation for coreos-approved-primary failed: ApiError: PatchOptions.meta.k8s.io "" is invalid: fieldManager: Required value: is required for apply patch: Invalid (Status { status: Some(Failure), code: 422, message: "PatchOptions.meta.k8s.io \"\" is invalid: fieldManager: Required value: is required for apply patch", metadata: Some(ListMeta { continue_: None, remaining_item_count: None, resource_version: None, self_link: None }), reason: "Invalid", details: Some(StatusDetails { name: "", group: "meta.k8s.io", kind: "PatchOptions", uid: "", causes: [StatusCause { reason: "FieldValueRequired", message: "Required value: is required for apply patch", field: "fieldManager" }], retry_after_seconds: 0 }) })

Comment thread operator/src/trustee.rs
}
}));
let deployments: Api<Deployment> = Api::default_namespaced(client.clone());
let pp = PatchParams::apply("trusted-cluster-operator").force();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

same is the force necessary?

}],
path: format!("default/{id}/root"),
num_retries: None,
num_retries: Some(NumRetries::Finite(RETRIES)),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We can also set it to infinite, not sure we are ready for this though. If not can you please add a todo so we don't forget it

Comment thread Makefile Outdated
ATTESTATION_KEY_REGISTER_IMAGE=$(REGISTRY)/attestation-key-register:$(TAG)
TRUSTEE_IMAGE ?= quay.io/trusted-execution-clusters/key-broker-service:v0.17.0
TEST_IMAGE ?= quay.io/trusted-execution-clusters/fedora-coreos-kubevirt:42.20260622
TEST_IMAGE ?= quay.io/trusted-execution-clusters/fedora-coreos-kubevirt:42.20251012.2.0-console-fwd

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

which image is it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I want to mention I only meant this for the CI debugging and would have removed before moving out of draft, but I built this with

[Journal]
ForwardToConsole=yes

in /usr/lib/systemd/journald.conf.d

@alicefr

alicefr commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

@Jakob-Naucke do we plan to merge this after #248 ? It will cause /again) a lot of rebase otherwise

@Jakob-Naucke

Copy link
Copy Markdown
Member Author

@Jakob-Naucke do we plan to merge this after #248 ? It will cause /again) a lot of rebase otherwise

I'll respond to your other comments later but I have no objections against merging #248 first and rebasing this

Comment thread operator/src/trustee.rs
deployments
.patch(
TRUSTEE_DEPLOYMENT,
&PatchParams::apply("trusted-cluster-operator").force(),

@Jakob-Naucke Jakob-Naucke Aug 19, 2026

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Is the force necessary?

@alicefr I'll test without but I'd also like to ask why you added it here itfp see other response

Comment thread Makefile Outdated
ATTESTATION_KEY_REGISTER_IMAGE=$(REGISTRY)/attestation-key-register:$(TAG)
TRUSTEE_IMAGE ?= quay.io/trusted-execution-clusters/key-broker-service:v0.17.0
TEST_IMAGE ?= quay.io/trusted-execution-clusters/fedora-coreos-kubevirt:42.20260622
TEST_IMAGE ?= quay.io/trusted-execution-clusters/fedora-coreos-kubevirt:42.20251012.2.0-console-fwd

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I want to mention I only meant this for the CI debugging and would have removed before moving out of draft, but I built this with

[Journal]
ForwardToConsole=yes

in /usr/lib/systemd/journald.conf.d

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Extend the use of a reflector cache from attestation keys to the
entire operator. Replace AkContextData with OperatorContext to pass
caches. Use server-side apply patches instead of get+replace.

- Updating image-pcrs without the cache is only used in compute-pcrs
  now, thus inline the macro
- trustee::update_reference_values receives PCRs from argument, it is
  sometimes available from the call site anyhow

Fixes: trusted-execution-clusters#251

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Assisted-by: AI
so that status is updated in a timely manner

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
for reuse

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Add a label to secrets and watch only by the label

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Set read timeout of 295s (same as write) so that hanging operations
can retry.

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
Local network on GHA has been seen to be less reliable than local
development and production clusters. Set a test timeout multiplier
large enough to let one read time out and retry.

Signed-off-by: Jakob Naucke <jnaucke@redhat.com>
@Jakob-Naucke

Jakob-Naucke commented Aug 21, 2026

Copy link
Copy Markdown
Member Author

This was going to be the PR to let CI spin on it for a while (hence the head name get-cached-ci), and then I was going to make a separate PR, but now that @alicefr has already reviewed here, I won't kill the context and instead just remove the CI-only commits here.

  • GHA CI was successful for 6h (its timeout)
  • The errors in focus here (resources staying behind, KBS missing a resource) have not been seen on OpenShift CI, however, OpenShift CI is recording a new class of flake, independent of the changes proposed here:
2026-08-20T08:43:09Z INFO: test_vm_restart_operator_existing: Waiting for deployment trustee-deployment to be ready
[2026-08-20T08:43:19Z ERROR kube_client::client::builder] failed with error client error (Connect)
Error: failed to probe for whether the condition is fulfilled yet: failed to perform initial object list: ServiceError: client error (Connect)
Caused by:
    0: failed to perform initial object list: ServiceError: client error (Connect)
    1: ServiceError: client error (Connect)
    2: client error (Connect)
    3: dns error
    4: failed to lookup address information: Name or service not known
test test_vm_restart_operator_existing ... FAILED

(see openshift/release#82662 for more information)

My hunch is that we merge these changes here (edit: but I'm open to merging #248 first), and consider this DNS failure separately. OpenShift CI will not extend to more tests for now. Something that we could do there already is set the test timeout multiplier like in HEAD here.

@Jakob-Naucke
Jakob-Naucke marked this pull request as ready for review August 21, 2026 10:15

@sourcery-ai sourcery-ai Bot 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.

Hey - I've found 2 issues, and left some high level feedback:

  • In trustee::do_mount_secret the server-side apply payload hardcodes the container name to "kbs"; this will break if the trustee deployment uses a different container name, so consider deriving the name from the existing pod spec (e.g., the first container) or threading a shared constant instead of duplicating it here.
  • The OperatorContext::new constructor currently creates fresh reflector stores that are immediately overwritten in main; introducing a constructor that takes all pre-created stores (or a builder) would avoid this double-initialization pattern and make it harder to accidentally use an OperatorContext with uninitialized/empty stores in other call sites.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `trustee::do_mount_secret` the server-side apply payload hardcodes the container name to `"kbs"`; this will break if the trustee deployment uses a different container name, so consider deriving the name from the existing pod spec (e.g., the first container) or threading a shared constant instead of duplicating it here.
- The `OperatorContext::new` constructor currently creates fresh reflector stores that are immediately overwritten in `main`; introducing a constructor that takes all pre-created stores (or a builder) would avoid this double-initialization pattern and make it harder to accidentally use an `OperatorContext` with uninitialized/empty stores in other call sites.

## Individual Comments

### Comment 1
<location path="operator/src/lib.rs" line_range="45-54" />
<code_context>
+    pub image_store: Store<ApprovedImage>,
+}
+
+impl OperatorContext {
+    pub fn new(client: Client) -> Self {
+        Self {
+            client,
+            tec_store: reflector::store().0,
+            cm_store: reflector::store().0,
+            deployment_store: reflector::store().0,
+            machine_store: reflector::store().0,
+            ak_store: reflector::store().0,
+            secret_store: reflector::store().0,
+            image_store: reflector::store().0,
+        }
+    }
</code_context>
<issue_to_address>
**suggestion (bug_risk):** OperatorContext::new creates unused reflector stores that never receive events

`reflector::store()` returns a `(Store, Writer)` pair, but `OperatorContext::new` keeps only the `Store` and drops the `Writer`, so these stores will never receive events unless replaced later (as in `main`). Any code that constructs `OperatorContext` directly (e.g. tests or future controllers) will get empty, never-updated caches. Consider either requiring callers to pass in the stores, or making `new` private and exposing a constructor that takes the pre-wired stores, so every `OperatorContext` either has an active cache or opts into a no-cache mode explicitly.

Suggested implementation:

```rust
impl OperatorContext {
    pub fn new(
        client: Client,
        tec_store: Store<TrustedExecutionCluster>,
        cm_store: Store<ConfigMap>,
        deployment_store: Store<Deployment>,
        machine_store: Store<Machine>,
        ak_store: Store<AttestationKey>,
        secret_store: Store<Secret>,
        image_store: Store<ApprovedImage>,
    ) -> Self {
        Self {
            client,
            tec_store,
            cm_store,
            deployment_store,
            machine_store,
            ak_store,
            secret_store,
            image_store,
        }
    }

```

1. Update all call sites (e.g. in `main` and tests) that currently call `OperatorContext::new(client)` to instead:
   - Create each `(Store<T>, Writer<T>)` via `reflector::store()` (or whatever helper is used).
   - Wire the `Writer` into the appropriate reflector/controller.
   - Pass the `Store` halves into `OperatorContext::new(client, tec_store, cm_store, deployment_store, machine_store, ak_store, secret_store, image_store)`.
2. If you want a no-cache mode for tests, consider adding an explicit `OperatorContext::without_caches(client: Client) -> Self` constructor that clearly documents that it uses empty/non-updating stores, instead of implicitly constructing unused reflectors.
</issue_to_address>

### Comment 2
<location path="operator/src/trustee.rs" line_range="199-207" />
<code_context>
-    deployments
-        .replace(TRUSTEE_DEPLOYMENT, &Default::default(), &deployment)
-        .await?;
+    let patch = Patch::Apply(json!({
+        "apiVersion": "apps/v1",
+        "kind": "Deployment",
+        "metadata": { "name": TRUSTEE_DEPLOYMENT },
+        "spec": {
+            "template": {
+                "spec": {
+                    "volumes": volumes,
+                    "containers": [{ "name": "kbs", "volumeMounts": vol_mounts }]
+                }
+            }
</code_context>
<issue_to_address>
**issue (bug_risk):** Hard-coding container name "kbs" in the patch may break deployments with different names or multiple containers

The previous code mutated `containers[0]` from the live `Deployment`, so it worked regardless of the container name. The new patch assumes a single container named `kbs`, which will break if the deployment is renamed or has multiple containers (e.g., patch failing or affecting the wrong container). Instead, derive the container name from the existing deployment (e.g., reuse `container.name`) and patch only the relevant container’s `volumeMounts`, rather than constructing a new `containers` array with a fixed name.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread operator/src/lib.rs
Comment on lines +45 to +54
impl OperatorContext {
pub fn new(client: Client) -> Self {
Self {
client,
tec_store: reflector::store().0,
cm_store: reflector::store().0,
deployment_store: reflector::store().0,
machine_store: reflector::store().0,
ak_store: reflector::store().0,
secret_store: reflector::store().0,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion (bug_risk): OperatorContext::new creates unused reflector stores that never receive events

reflector::store() returns a (Store, Writer) pair, but OperatorContext::new keeps only the Store and drops the Writer, so these stores will never receive events unless replaced later (as in main). Any code that constructs OperatorContext directly (e.g. tests or future controllers) will get empty, never-updated caches. Consider either requiring callers to pass in the stores, or making new private and exposing a constructor that takes the pre-wired stores, so every OperatorContext either has an active cache or opts into a no-cache mode explicitly.

Suggested implementation:

impl OperatorContext {
    pub fn new(
        client: Client,
        tec_store: Store<TrustedExecutionCluster>,
        cm_store: Store<ConfigMap>,
        deployment_store: Store<Deployment>,
        machine_store: Store<Machine>,
        ak_store: Store<AttestationKey>,
        secret_store: Store<Secret>,
        image_store: Store<ApprovedImage>,
    ) -> Self {
        Self {
            client,
            tec_store,
            cm_store,
            deployment_store,
            machine_store,
            ak_store,
            secret_store,
            image_store,
        }
    }
  1. Update all call sites (e.g. in main and tests) that currently call OperatorContext::new(client) to instead:
    • Create each (Store<T>, Writer<T>) via reflector::store() (or whatever helper is used).
    • Wire the Writer into the appropriate reflector/controller.
    • Pass the Store halves into OperatorContext::new(client, tec_store, cm_store, deployment_store, machine_store, ak_store, secret_store, image_store).
  2. If you want a no-cache mode for tests, consider adding an explicit OperatorContext::without_caches(client: Client) -> Self constructor that clearly documents that it uses empty/non-updating stores, instead of implicitly constructing unused reflectors.

Comment thread operator/src/trustee.rs
Comment on lines +199 to +207
let patch = Patch::Apply(json!({
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": { "name": TRUSTEE_DEPLOYMENT },
"spec": {
"template": {
"spec": {
"volumes": volumes,
"containers": [{ "name": "kbs", "volumeMounts": vol_mounts }]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): Hard-coding container name "kbs" in the patch may break deployments with different names or multiple containers

The previous code mutated containers[0] from the live Deployment, so it worked regardless of the container name. The new patch assumes a single container named kbs, which will break if the deployment is renamed or has multiple containers (e.g., patch failing or affecting the wrong container). Instead, derive the container name from the existing deployment (e.g., reuse container.name) and patch only the relevant container’s volumeMounts, rather than constructing a new containers array with a fixed name.

@openshift-ci

openshift-ci Bot commented Aug 21, 2026

Copy link
Copy Markdown

PR needs rebase.

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.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants