Skip to content

OCPBUGS-99397: remove custom MCP from mirror-set tests to prevent PDB drain deadlock#31408

Open
Chandan9112 wants to merge 1 commit into
openshift:mainfrom
Chandan9112:fix/mirror-test-pdb-drain-deadlock
Open

OCPBUGS-99397: remove custom MCP from mirror-set tests to prevent PDB drain deadlock#31408
Chandan9112 wants to merge 1 commit into
openshift:mainfrom
Chandan9112:fix/mirror-test-pdb-drain-deadlock

Conversation

@Chandan9112

@Chandan9112 Chandan9112 commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Bug

https://redhat.atlassian.net/browse/OCPBUGS-99397

Problem

The mirror-set tests (OCP-57401, OCP-70203) used a custom single-node MachineConfigPool to isolate rollouts. However, cluster-scoped IDMS/ITMS/ICSP resources trigger config changes on all MachineConfigPools simultaneously. On 2-worker clusters (vSphere, AWS 1-of-2 split), this caused both the custom pool and the worker pool to drain nodes concurrently, leading to a PDB drain deadlock where PDB-protected pods (router, prometheus, etc.) had nowhere to reschedule — blocking the drain indefinitely and leaving the cluster degraded.

This caused the vsphere-disruptive-longrunning-techpreview and aws-disruptive-longrunning-techpreview jobs to fail consistently since 07/08/2026 when the tests were introduced via #31229.

Fix

Remove the custom MCP entirely and test directly on the worker pool. The MCO handles worker pool rollouts sequentially (maxUnavailable=1 by default), so nodes drain one at a time and PDB-protected pods can always reschedule to available nodes.

Key changes:

  • Removed mirrorTestPool struct and all associated methods (create, teardown, pause/unpause)
  • Both tests now operate directly on the worker pool using simple helpers: getWorkerSpec(), waitForWorkerRollout(), readRegistriesConfOnWorker()
  • Test assertions remain identical — same IDMS/ITMS/ICSP creation, same registries.conf verification
  • Cleanup simply deletes resources and waits for worker pool to stabilize

Test Results (vSphere, 2 workers)

OCP-57401: 749 seconds (~12.5 min) — PASSED
OCP-70203: 1162 seconds (~19.4 min) — PASSED

Both MCPs returned to Updated=True, Degraded=False after test completion:

NAME     UPDATED   UPDATING   DEGRADED
master   True      False      False
worker   True      False      False

Summary by CodeRabbit

  • Bug Fixes
    • Improved mirror-set end-to-end rollout verification by tracking changes directly against the cluster worker MachineConfigPool.
    • Enhanced cleanup behavior to delete mirror-set resources and wait for the worker pool to settle reliably.
  • Tests
    • Added polling helpers to validate MCP spec updates (and that expected non-regeneration cases remain unchanged) and to confirm registries.conf content, including blocked entries driven by NeverContactSource.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: automatic mode

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 22, 2026
@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: Chandan9112
Once this PR has been reviewed and has the lgtm label, please assign cpmeadors 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

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Walkthrough

The image mirror-set end-to-end tests now use the cluster-scoped worker MachineConfigPool for rollout tracking and validate mirror configuration changes by reading registries.conf from ready worker nodes.

Changes

Worker MCP mirror-set verification

Layer / File(s) Summary
Worker MCP helpers
test/extended/node/node_e2e/image_mirror_set.go
Replaces the custom mirror-test pool with helpers for reading worker MCP specs, waiting for rollout, reading worker registries.conf, and detecting unchanged specs.
IDMS and ITMS rollout assertions
test/extended/node/node_e2e/image_mirror_set.go
Tracks worker rollout after IDMS and ITMS changes, validates mirror and blocked-entry output, and waits for worker settling during cleanup.
ICSP coexistence and deletion checks
test/extended/node/node_e2e/image_mirror_set.go
Verifies worker spec stability and registries.conf contents across ICSP, IDMS, and ITMS creation and deletion.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Suggested reviewers: mrunalp, asahay19


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error readRegistriesConfOnWorker formats nodeName into an assertion error, which can surface internal worker hostnames in test output. Remove or redact the node name from the failure message; keep the error generic or use a sanitized node identifier.
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (13 passed)
Check name Status Explanation
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 The only Ginkgo titles in the changed test are static literals; no dynamic names or unstable values appear.
Test Structure And Quality ✅ Passed The updated tests use BeforeEach plus DeferCleanup, clean up cluster-scoped resources, bound MCP waits with timeouts, and add meaningful assertion messages while matching repo patterns.
Microshift Test Compatibility ✅ Passed The suite calls nodeutils.SkipOnMicroShift in BeforeEach, and that helper skips via exutil.IsMicroShiftCluster/g.Skip before any MicroShift-unsafe APIs run.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The tests use the worker MCP and one ready worker node, without node-counting, cross-node scheduling, or rescheduling assumptions.
Topology-Aware Scheduling Compatibility ✅ Passed PASS: The change is test-only; it removes custom MCP handling and adds worker-MCP rollout checks, with no manifests/controllers or new scheduling constraints.
Ote Binary Stdout Contract ✅ Passed No process-level stdout writes were added; the file only has helper funcs and Ginkgo It/DeferCleanup code, with no main/init/TestMain/RunSpecs or stdout logging calls.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No IPv4-only parsing or URL construction found, and the public registry names are only config values—no external network access is performed.
No-Weak-Crypto ✅ Passed Changed test code only manipulates MCP specs and registries.conf; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret/token compares found.
Container-Privileges ✅ Passed PR only edits a Go e2e test; no K8s/container manifests or securityContext fields (privileged, hostPID/Network/IPC, SYS_ADMIN, allowPrivilegeEscalation) were added.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: removing the custom MCP from mirror-set tests to avoid drain deadlocks.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/extended/node/node_e2e/image_mirror_set.go (1)

135-136: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Use a bounded, detached cleanup context instead of context.Background().

Both cleanup paths discard Ginkgo context values; the new unpause PATCH also has no explicit deadline. Thread the cleanup context into teardown and derive bounded contexts with context.WithoutCancel(ctx).

  • test/extended/node/node_e2e/image_mirror_set.go#L135-L136: use the detached, timeout-bounded context for unpauseWorkerMCP.
  • test/extended/node/node_e2e/image_mirror_set.go#L279-L279: derive cleanupCtx from the existing spec context rather than context.Background().

Based on learnings, deferred cleanup should preserve context values with context.WithoutCancel(ctx) and then apply an explicit timeout. As per path instructions, Go API calls must remain cancellation/timeout bounded.

🤖 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 `@test/extended/node/node_e2e/image_mirror_set.go` around lines 135 - 136, The
cleanup flow in test/extended/node/node_e2e/image_mirror_set.go must use a
detached, timeout-bounded context for both cleanup paths: at lines 135-136, pass
the derived cleanup context to unpauseWorkerMCP; at line 279, derive cleanupCtx
from the existing spec context with context.WithoutCancel(ctx) and apply an
explicit timeout instead of using context.Background().

Sources: Path instructions, Learnings

🤖 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.

Inline comments:
In `@test/extended/node/node_e2e/image_mirror_set.go`:
- Around line 117-123: Update mirrorTestPool.unpauseWorkerMCP to retry the
worker MCP patch and verify that the resulting MachineConfigPool has
spec.paused=false. If restoration still fails, record a cleanup failure and
prevent teardown from continuing in a way that could leave the cluster-scoped
worker MCP paused; retain the success log only after verification passes.

---

Nitpick comments:
In `@test/extended/node/node_e2e/image_mirror_set.go`:
- Around line 135-136: The cleanup flow in
test/extended/node/node_e2e/image_mirror_set.go must use a detached,
timeout-bounded context for both cleanup paths: at lines 135-136, pass the
derived cleanup context to unpauseWorkerMCP; at line 279, derive cleanupCtx from
the existing spec context with context.WithoutCancel(ctx) and apply an explicit
timeout instead of using context.Background().
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 1b5e0a66-a84d-4a2e-b23e-fad269433ea5

📥 Commits

Reviewing files that changed from the base of the PR and between c367745 and 0b62ca0.

📒 Files selected for processing (1)
  • test/extended/node/node_e2e/image_mirror_set.go

Comment thread test/extended/node/node_e2e/image_mirror_set.go Outdated
@Chandan9112 Chandan9112 changed the title fix: pause worker MCP during mirror-set tests to prevent PDB drain deadlock Bug OCPBUGS-99397: pause worker MCP during mirror-set tests to prevent PDB drain deadlock Jul 22, 2026
@openshift-ci-robot openshift-ci-robot added jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Jul 22, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@Chandan9112: This pull request references Jira Issue OCPBUGS-99397, which is invalid:

  • expected the bug to target the "5.0.0" version, but no target version was set

Comment /jira refresh to re-evaluate validity if changes to the Jira bug are made, or edit the title of this pull request to link to a different bug.

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Bug

On 2-worker clusters (vSphere CI, AWS 1of2 splits), the [OCP-57401] and [OCP-70203] mirror-set tests cause a PDB drain deadlock during MCP rollouts. The vsphere-disruptive-longrunning-techpreview job has been consistently failing since 07/08/2026 when PR #31229 introduced the [OCP-57401] test.

Root Cause

The tests create cluster-scoped IDMS/ITMS/ICSP resources which trigger a MachineConfig update on all pools simultaneously. Since mirrorTestPool moves one worker into a custom MCP, only one worker remains in the worker pool. When both pools drain their nodes at the same time, PDB-protected pods (router, prometheus, ingress) have zero available nodes to reschedule onto — causing a drain deadlock. The worker MCP gets stuck in Updating state, cleanup times out, and subsequent tests fail on a degraded cluster.

Fix

Pause the worker MCP when creating the custom mirror test pool, and unpause it at the start of Teardown() before the node transitions back. This ensures only the custom pool node is drained during the test while the other worker remains available for PDB-protected pod scheduling.

Changes (+24 lines, -2 lines):

  • Add pauseWorkerMCP() / unpauseWorkerMCP() helper methods on mirrorTestPool
  • Call pauseWorkerMCP in newMirrorTestPool() after pool is ready
  • Call unpauseWorkerMCP at start of Teardown() before node label removal
  • Bump timeout from 10m to 15m to account for worker processing pending changes after unpause

Test Results

Tested on vSphere TechPreview cluster with 2 workers:

SUCCESS! -- 1 Passed | 0 Failed | 0 Pending | 0 Skipped

Paused worker MCP to prevent PDB drain deadlock
IDMS MCP rollout complete on custom pool mirror-test-f6cw9
Custom MCP mirror-test-f6cw9 finished rolling out after ITMS creation
Cleanup: Delete IDMS and ITMS resources
Unpaused worker MCP
Teardown: waiting for node to transition back to worker pool
Teardown: waiting for worker MCP to stabilize
MachineConfigPool worker is ready: 2/2 machines ready

Post-test cluster state — all MCPs healthy:

NAME     UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT
master   True      False      False      3              3
worker   True      False      False      2              2

All nodes Ready, no SchedulingDisabled:

ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hkv84   Ready    worker
ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hl9bd   Ready    worker

Summary by CodeRabbit

  • Bug Fixes
  • Improved mirror-set end-to-end test reliability on clusters with two workers by preventing drain deadlocks.
  • Ensured worker configuration is restored during cleanup.
  • Increased stabilization and cleanup timeouts to accommodate slower cluster operations.

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.

@Chandan9112 Chandan9112 changed the title Bug OCPBUGS-99397: pause worker MCP during mirror-set tests to prevent PDB drain deadlock OCPBUGS-99397: pause worker MCP during mirror-set tests to prevent PDB drain deadlock Jul 22, 2026
@Chandan9112
Chandan9112 force-pushed the fix/mirror-test-pdb-drain-deadlock branch from 0b62ca0 to 46e684f Compare July 22, 2026 06:24
@openshift-ci-robot openshift-ci-robot added jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. and removed jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. labels Jul 22, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@Chandan9112: This pull request references Jira Issue OCPBUGS-99397, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state New, which is one of the valid states (NEW, ASSIGNED, POST)

The bug has been updated to refer to the pull request using the external bug tracker.

Details

In response to this:

Bug

On 2-worker clusters (vSphere CI, AWS 1of2 splits), the [OCP-57401] and [OCP-70203] mirror-set tests cause a PDB drain deadlock during MCP rollouts. The vsphere-disruptive-longrunning-techpreview job has been consistently failing since 07/08/2026 when PR #31229 introduced the [OCP-57401] test.

Root Cause

The tests create cluster-scoped IDMS/ITMS/ICSP resources which trigger a MachineConfig update on all pools simultaneously. Since mirrorTestPool moves one worker into a custom MCP, only one worker remains in the worker pool. When both pools drain their nodes at the same time, PDB-protected pods (router, prometheus, ingress) have zero available nodes to reschedule onto — causing a drain deadlock. The worker MCP gets stuck in Updating state, cleanup times out, and subsequent tests fail on a degraded cluster.

Fix

Pause the worker MCP when creating the custom mirror test pool, and unpause it at the start of Teardown() before the node transitions back. This ensures only the custom pool node is drained during the test while the other worker remains available for PDB-protected pod scheduling.

Changes (+24 lines, -2 lines):

  • Add pauseWorkerMCP() / unpauseWorkerMCP() helper methods on mirrorTestPool
  • Call pauseWorkerMCP in newMirrorTestPool() after pool is ready
  • Call unpauseWorkerMCP at start of Teardown() before node label removal
  • Bump timeout from 10m to 15m to account for worker processing pending changes after unpause

Test Results

Tested on vSphere TechPreview cluster with 2 workers:

SUCCESS! -- 1 Passed | 0 Failed | 0 Pending | 0 Skipped

Paused worker MCP to prevent PDB drain deadlock
IDMS MCP rollout complete on custom pool mirror-test-f6cw9
Custom MCP mirror-test-f6cw9 finished rolling out after ITMS creation
Cleanup: Delete IDMS and ITMS resources
Unpaused worker MCP
Teardown: waiting for node to transition back to worker pool
Teardown: waiting for worker MCP to stabilize
MachineConfigPool worker is ready: 2/2 machines ready

Post-test cluster state — all MCPs healthy:

NAME     UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT
master   True      False      False      3              3
worker   True      False      False      2              2

All nodes Ready, no SchedulingDisabled:

ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hkv84   Ready    worker
ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hl9bd   Ready    worker

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes
  • Improved mirror-set end-to-end test reliability on two-worker clusters by avoiding drain deadlocks.
  • Ensured worker configuration is restored during cleanup.
  • Increased stabilization and resource cleanup timeouts to better handle slower cluster operations.

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.

@Chandan9112
Chandan9112 marked this pull request as ready for review July 22, 2026 06:33
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 22, 2026
@openshift-ci
openshift-ci Bot requested review from asahay19 and mrunalp July 22, 2026 06:34
@openshift-ci-robot

Copy link
Copy Markdown

@Chandan9112: This pull request references Jira Issue OCPBUGS-99397, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)
Details

In response to this:

Bug

On 2-worker clusters (vSphere CI, AWS 1of2 splits), the [OCP-57401] and [OCP-70203] mirror-set tests cause a PDB drain deadlock during MCP rollouts. The vsphere-disruptive-longrunning-techpreview job has been consistently failing since 07/08/2026 when PR #31229 introduced the [OCP-57401] test.

Root Cause

The tests create cluster-scoped IDMS/ITMS/ICSP resources which trigger a MachineConfig update on all pools simultaneously. Since mirrorTestPool moves one worker into a custom MCP, only one worker remains in the worker pool. When both pools drain their nodes at the same time, PDB-protected pods (router, prometheus, ingress) have zero available nodes to reschedule onto — causing a drain deadlock. The worker MCP gets stuck in Updating state, cleanup times out, and subsequent tests fail on a degraded cluster.

Fix

Pause the worker MCP when creating the custom mirror test pool, and unpause it at the start of Teardown() before the node transitions back. This ensures only the custom pool node is drained during the test while the other worker remains available for PDB-protected pod scheduling.

Changes (+24 lines, -2 lines):

  • Add pauseWorkerMCP() / unpauseWorkerMCP() helper methods on mirrorTestPool
  • Call pauseWorkerMCP in newMirrorTestPool() after pool is ready
  • Call unpauseWorkerMCP at start of Teardown() before node label removal
  • Bump timeout from 10m to 15m to account for worker processing pending changes after unpause

Test Results

Tested on vSphere TechPreview cluster with 2 workers:

 Running Suite:  - /Users/cmaurya/go/src/github.com/openshift/origin
 ===================================================================
 Random Seed: 1784701586 - will randomize all specs

 Will run 1 of 1 specs
 ------------------------------
 [sig-node][Suite:openshift/disruptive-longrunning][Disruptive][Serial] ImageTagMirrorSet and ImageDigestMirrorSet [OTP] Create ImageDigestMirrorSet and ImageTagMirrorSet and verify registries.conf [OCP-57401]
 github.com/openshift/origin/test/extended/node/node_e2e/image_mirror_set.go:236
   STEP: Creating a kubernetes client @ 07/22/26 11:56:38.879
 I0722 11:56:38.880515   93116 discovery.go:214] Invalidating discovery information
 I0722 11:56:38.881364 93116 framework.go:2330] [precondition-check] checking if cluster is MicroShift
 I0722 11:56:39.183964 93116 framework.go:2353] IsMicroShiftCluster: microshift-version configmap not found, not MicroShift
 I0722 11:57:11.360996 93116 image_mirror_set.go:93] Custom mirror test pool mirror-test-psrq6 ready on node ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hkv84
 I0722 11:57:11.679147 93116 image_mirror_set.go:114] Paused worker MCP to prevent PDB drain deadlock
   STEP: Step 1: Create an ImageDigestMirrorSet @ 07/22/26 11:57:11.679
 I0722 11:57:12.288861 93116 image_mirror_set.go:274] ImageDigestMirrorSet "digest-mirror-t2llr" created successfully
 I0722 11:57:12.288970 93116 imagepolicy.go:689] Waiting for pool mirror-test-psrq6 to complete
 I0722 11:57:43.754080 93116 image_mirror_set.go:291] IDMS MCP rollout complete on custom pool mirror-test-psrq6
   STEP: Step 2: Create an ImageTagMirrorSet @ 07/22/26 11:57:43.754
 I0722 11:57:44.373342 93116 image_mirror_set.go:323] ImageTagMirrorSet "tag-mirror-t2llr" created successfully
   STEP: Step 3: Wait for custom MCP to finish rolling out @ 07/22/26 11:57:44.373
 I0722 11:57:44.373417 93116 imagepolicy.go:689] Waiting for pool mirror-test-psrq6 to complete
 I0722 11:59:17.510904 93116 image_mirror_set.go:327] Custom MCP mirror-test-psrq6 finished rolling out after ITMS creation
   STEP: Step 4: Verify /etc/containers/registries.conf on the custom pool node @ 07/22/26 11:59:17.511
 I0722 11:59:31.061383 93116 image_mirror_set.go:331] registries.conf on ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hkv84: read 1177 bytes, asserting expected entries
   STEP: Verify IDMS entries (digest-only mirrors) @ 07/22/26 11:59:31.061
   STEP: Verify ITMS entries (tag-only mirrors) @ 07/22/26 11:59:31.061
   STEP: Verify NeverContactSource entries are blocked @ 07/22/26 11:59:31.061
   STEP: Cleanup: Delete IDMS and ITMS resources @ 07/22/26 11:59:31.064
 I0722 11:59:31.978508 93116 imagepolicy.go:689] Waiting for pool mirror-test-psrq6 to complete
 I0722 12:01:06.240014 93116 image_mirror_set.go:121] Unpaused worker MCP
 I0722 12:01:06.240104 93116 image_mirror_set.go:135] Teardown: removing label node-role.kubernetes.io/mirror-test-psrq6 from node ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hkv84
 I0722 12:01:06.575588 93116 image_mirror_set.go:142] Teardown: waiting for node ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hkv84 to transition back to worker pool
 I0722 12:01:37.589452 93116 image_mirror_set.go:162] Teardown: waiting for worker MCP to stabilize
 I0722 12:01:37.589550 93116 node_utils.go:611] Waiting for MCP worker to be ready (timeout: 15m0s)...
 I0722 12:01:37.894104 93116 node_utils.go:685] MachineConfigPool worker is ready: 2/2 machines ready
 • [299.039 seconds]
 ------------------------------

 Ran 1 of 1 Specs in 299.040 seconds
 SUCCESS! -- 1 Passed | 0 Failed | 0 Pending | 0 Skipped

Post-test cluster state — all MCPs healthy:

NAME     UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT
master   True      False      False      3              3
worker   True      False      False      2              2

All nodes Ready, no SchedulingDisabled:

ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hkv84   Ready    worker
ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hl9bd   Ready    worker

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes
  • Improved mirror-set end-to-end test reliability on two-worker clusters by avoiding drain deadlocks.
  • Ensured worker configuration is restored during cleanup.
  • Increased stabilization and resource cleanup timeouts to better handle slower cluster operations.

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.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling required tests:
/test e2e-aws-csi
/test e2e-aws-ovn-fips
/test e2e-aws-ovn-microshift
/test e2e-aws-ovn-microshift-serial
/test e2e-aws-ovn-serial-1of2
/test e2e-aws-ovn-serial-2of2
/test e2e-gcp-csi
/test e2e-gcp-ovn
/test e2e-gcp-ovn-upgrade
/test e2e-metal-ipi-ovn-ipv6
/test e2e-vsphere-ovn
/test e2e-vsphere-ovn-upi

@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@Chandan9112: 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.

@BhargaviGudi

Copy link
Copy Markdown
Contributor

/payload-job periodic-ci-openshift-release-main-nightly-5.0-e2e-vsphere-disruptive-longrunning-techpreview

@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@BhargaviGudi: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command

  • periodic-ci-openshift-release-main-nightly-5.0-e2e-vsphere-disruptive-longrunning-techpreview

See details on https://pr-payload-tests.ci.openshift.org/runs/ci/c57ee790-85b1-11f1-839f-e365ebbac51d-0

@BhargaviGudi

Copy link
Copy Markdown
Contributor

/payload-job periodic-ci-openshift-release-main-nightly-5.0-e2e-azure-disruptive-longrunning-techpreview-1of2

@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@BhargaviGudi: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command

  • periodic-ci-openshift-release-main-nightly-5.0-e2e-azure-disruptive-longrunning-techpreview-1of2

See details on https://pr-payload-tests.ci.openshift.org/runs/ci/79743d90-85b2-11f1-837f-5e32378ade18-0

@ngopalak-redhat

Copy link
Copy Markdown
Contributor

@Chandan9112 Pause is useful to prevent the MCO from changing node config, or when you want to stack up a whole bunch of changes and only take a single reboot. Have you thought of other ways to solve this?

@Chandan9112

Copy link
Copy Markdown
Contributor Author

@Chandan9112 Pause is useful to prevent the MCO from changing node config, or when you want to stack up a whole bunch of changes and only take a single reboot. Have you thought of other ways to solve this?

@ngopalak-redhat I thought of removing the custom MCP entirely and testing on the worker pool directly (sequential drain via default maxUnavailable=1), but that's a larger refactor. For now, pause is the lightest fix to unblock CI — worker nodes stay fully schedulable, only config updates are deferred, and it's cleanly reversed in Teardown.

@ngopalak-redhat

Copy link
Copy Markdown
Contributor

@Chandan9112 Can we try removing custom MCP for cluster level resources? Will be helpful on a long term.

@openshift-ci-robot

Copy link
Copy Markdown

@Chandan9112: This pull request references Jira Issue OCPBUGS-99397, which is valid. The bug has been moved to the POST state.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state ASSIGNED, which is one of the valid states (NEW, ASSIGNED, POST)
Details

In response to this:

Bug

On 2-worker clusters (vSphere CI, AWS 1of2 splits), the [OCP-57401] and [OCP-70203] mirror-set tests cause a PDB drain deadlock during MCP rollouts. The vsphere-disruptive-longrunning-techpreview job has been consistently failing since 07/08/2026 when PR #31229 introduced the [OCP-57401] test.

Root Cause

The tests create cluster-scoped IDMS/ITMS/ICSP resources which trigger a MachineConfig update on all pools simultaneously. Since mirrorTestPool moves one worker into a custom MCP, only one worker remains in the worker pool. When both pools drain their nodes at the same time, PDB-protected pods (router, prometheus, ingress) have zero available nodes to reschedule onto — causing a drain deadlock. The worker MCP gets stuck in Updating state, cleanup times out, and subsequent tests fail on a degraded cluster.

Fix

Pause the worker MCP when creating the custom mirror test pool, and unpause it at the start of Teardown() before the node transitions back. This ensures only the custom pool node is drained during the test while the other worker remains available for PDB-protected pod scheduling.

Changes (+24 lines, -2 lines):

  • Add pauseWorkerMCP() / unpauseWorkerMCP() helper methods on mirrorTestPool
  • Call pauseWorkerMCP in newMirrorTestPool() after pool is ready
  • Call unpauseWorkerMCP at start of Teardown() before node label removal
  • Bump timeout from 10m to 15m to account for worker processing pending changes after unpause

Test Results

Tested on vSphere TechPreview cluster with 2 workers:

 Running Suite:  - /Users/cmaurya/go/src/github.com/openshift/origin
 ===================================================================
 Random Seed: 1784726830 - will randomize all specs

 Will run 1 of 1 specs
 ------------------------------
 [sig-node][Suite:openshift/disruptive-longrunning][Disruptive][Serial] ImageTagMirrorSet and ImageDigestMirrorSet [OTP] Create ImageDigestMirrorSet and ImageTagMirrorSet and verify registries.conf [OCP-57401]
 github.com/openshift/origin/test/extended/node/node_e2e/image_mirror_set.go:66
   STEP: Creating a kubernetes client @ 07/22/26 18:57:19.332
 I0722 18:57:19.332854   11561 discovery.go:214] Invalidating discovery information
 I0722 18:57:19.334055 11561 framework.go:2330] [precondition-check] checking if cluster is MicroShift
 I0722 18:57:19.632628 11561 framework.go:2353] IsMicroShiftCluster: microshift-version configmap not found, not MicroShift
   STEP: Step 1: Create an ImageDigestMirrorSet @ 07/22/26 18:57:20.284
 I0722 18:57:20.593220 11561 image_mirror_set.go:100] ImageDigestMirrorSet "digest-mirror-gwghg" created successfully
   STEP: Step 2: Wait for worker MCP rollout and verify IDMS entries in registries.conf @ 07/22/26 18:57:20.593
 I0722 18:57:20.593496 11561 imagepolicy.go:689] Waiting for pool worker to complete
 I0722 18:58:12.486015 11561 image_mirror_set.go:119] Worker MCP rollout complete after IDMS creation
 I0722 18:58:23.588885 11561 image_mirror_set.go:122] registries.conf after IDMS: read 668 bytes
   STEP: Step 3: Create an ImageTagMirrorSet @ 07/22/26 18:58:23.589
 I0722 18:58:24.204243 11561 image_mirror_set.go:163] ImageTagMirrorSet "tag-mirror-gwghg" created successfully
   STEP: Step 4: Wait for worker MCP rollout and verify ITMS entries alongside IDMS @ 07/22/26 18:58:24.204
 I0722 18:58:24.204331 11561 imagepolicy.go:689] Waiting for pool worker to complete
 I0722 19:02:52.948012 11561 image_mirror_set.go:167] Worker MCP rollout complete after ITMS creation
 I0722 19:03:05.135560 11561 image_mirror_set.go:170] registries.conf after ITMS: read 1177 bytes
   STEP: Cleanup: Delete IDMS and ITMS resources @ 07/22/26 19:03:05.139
 I0722 19:03:06.054788 11561 imagepolicy.go:689] Waiting for pool worker to complete
 • [749.476 seconds]
 ------------------------------

 Ran 1 of 1 Specs in 749.477 seconds
 SUCCESS! -- 1 Passed | 0 Failed | 0 Pending | 0 Skipped

Post-test cluster state — all MCPs healthy:

NAME     UPDATED   UPDATING   DEGRADED   MACHINECOUNT   READYMACHINECOUNT
master   True      False      False      3              3
worker   True      False      False      2              2

All nodes Ready, no SchedulingDisabled:

ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hkv84   Ready    worker
ci-ln-t5dnqcb-c1627-9bmwz-worker-0-hl9bd   Ready    worker

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes
  • Improved mirror-set end-to-end test reliability on two-worker clusters by avoiding drain deadlocks.
  • Ensured worker configuration is restored during cleanup.
  • Increased stabilization and resource cleanup timeouts to better handle slower cluster operations.

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.

…dlock

The mirror-set tests (OCP-57401, OCP-70203) used a custom single-node
MachineConfigPool to isolate rollouts. However, cluster-scoped IDMS/ITMS/ICSP
resources trigger config changes on all pools simultaneously. On 2-worker
clusters, this caused both the custom pool and worker pool to drain nodes
concurrently, leading to a PDB deadlock where PDB-protected pods had nowhere
to reschedule.

Fix: Remove the custom MCP entirely and test directly on the worker pool.
The MCO handles worker pool rollouts sequentially (maxUnavailable=1), so
nodes drain one at a time and PDB-protected pods can always reschedule.

This eliminates the ~20 min MCP setup/teardown overhead while keeping test
assertions identical.

Bug: OCPBUGS-99397
Co-authored-by: Cursor <cursoragent@cursor.com>
@Chandan9112
Chandan9112 force-pushed the fix/mirror-test-pdb-drain-deadlock branch from 46e684f to 1733cb9 Compare July 22, 2026 14:15
@openshift-ci-robot

Copy link
Copy Markdown

@Chandan9112: This pull request references Jira Issue OCPBUGS-99397, which is valid.

3 validation(s) were run on this bug
  • bug is open, matching expected state (open)
  • bug target version (5.0.0) matches configured target version for branch (5.0.0)
  • bug is in the state POST, which is one of the valid states (NEW, ASSIGNED, POST)
Details

In response to this:

Bug

https://redhat.atlassian.net/browse/OCPBUGS-99397

Problem

The mirror-set tests (OCP-57401, OCP-70203) used a custom single-node MachineConfigPool to isolate rollouts. However, cluster-scoped IDMS/ITMS/ICSP resources trigger config changes on all MachineConfigPools simultaneously. On 2-worker clusters (vSphere, AWS 1-of-2 split), this caused both the custom pool and the worker pool to drain nodes concurrently, leading to a PDB drain deadlock where PDB-protected pods (router, prometheus, etc.) had nowhere to reschedule — blocking the drain indefinitely and leaving the cluster degraded.

This caused the vsphere-disruptive-longrunning-techpreview and aws-disruptive-longrunning-techpreview jobs to fail consistently since 07/08/2026 when the tests were introduced via #31229.

Fix

Remove the custom MCP entirely and test directly on the worker pool. The MCO handles worker pool rollouts sequentially (maxUnavailable=1 by default), so nodes drain one at a time and PDB-protected pods can always reschedule to available nodes.

Key changes:

  • Removed mirrorTestPool struct and all associated methods (create, teardown, pause/unpause)
  • Both tests now operate directly on the worker pool using simple helpers: getWorkerSpec(), waitForWorkerRollout(), readRegistriesConfOnWorker()
  • Test assertions remain identical — same IDMS/ITMS/ICSP creation, same registries.conf verification
  • Cleanup simply deletes resources and waits for worker pool to stabilize

Why this is better than pausing worker MCP:

  • Simpler — no custom MCP lifecycle management
  • No risk of leaving worker MCP paused if test fails mid-way
  • Eliminates ~20 min MCP setup/teardown overhead
  • Platform independent (works on vSphere, AWS, GCP, Azure, bare-metal)

Test Results (vSphere, 2 workers)

OCP-57401: 749 seconds (~12.5 min) — PASSED
OCP-70203: 1162 seconds (~19.4 min) — PASSED

Both MCPs returned to Updated=True, Degraded=False after test completion:

NAME     UPDATED   UPDATING   DEGRADED
master   True      False      False
worker   True      False      False

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 coderabbitai 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.

🧹 Nitpick comments (2)
test/extended/node/node_e2e/image_mirror_set.go (2)

102-115: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Use a detached, bounded context for both DeferCleanup blocks instead of context.Background(). Both cleanup closures issue deletes with context.Background(), dropping context values and running unbounded. Per the repo learning, detach cancellation from the spec ctx and apply an explicit timeout so cleanup survives spec-context cancellation while staying bounded.

  • test/extended/node/node_e2e/image_mirror_set.go#L102-L115: replace the context.Background() IDMS/ITMS deletes with a ctxCleanup, cancel := context.WithTimeout(context.WithoutCancel(ctx), <timeout>) derived context (defer cancel()), and pass it to the delete calls.
  • test/extended/node/node_e2e/image_mirror_set.go#L227-L255: apply the same derived context to the ICSP/ITMS/IDMS Get/Delete calls in this cleanup block.
🤖 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 `@test/extended/node/node_e2e/image_mirror_set.go` around lines 102 - 115,
Update both cleanup closures in
test/extended/node/node_e2e/image_mirror_set.go:102-115 and
test/extended/node/node_e2e/image_mirror_set.go:227-255 to derive a bounded
cleanup context using context.WithTimeout(context.WithoutCancel(ctx), the
repository’s appropriate timeout), defer its cancellation, and use it for all
IDMS/ITMS deletes and ICSP/ITMS/IDMS Get/Delete calls. Preserve the existing
cleanup behavior while ensuring it survives spec-context cancellation and
remains time-bounded.

Source: Learnings


42-53: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Prefer context-aware polling here
wait.PollImmediate and wait.ErrWaitTimeout are legacy apimachinery APIs. Thread a context.Context through this helper and switch to wait.PollUntilContextTimeout; use wait.Interrupted(err) (or errors.Is(err, context.DeadlineExceeded)) for the timeout branch instead of comparing against wait.ErrWaitTimeout.

🤖 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 `@test/extended/node/node_e2e/image_mirror_set.go` around lines 42 - 53, The
pollMCPSpecUnchanged helper should use context-aware polling instead of legacy
wait APIs. Add a context.Context parameter, call wait.PollUntilContextTimeout
with that context, and recognize timeout via wait.Interrupted or
context.DeadlineExceeded while preserving the existing success and spec-change
error behavior.

Source: Path instructions

🤖 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.

Nitpick comments:
In `@test/extended/node/node_e2e/image_mirror_set.go`:
- Around line 102-115: Update both cleanup closures in
test/extended/node/node_e2e/image_mirror_set.go:102-115 and
test/extended/node/node_e2e/image_mirror_set.go:227-255 to derive a bounded
cleanup context using context.WithTimeout(context.WithoutCancel(ctx), the
repository’s appropriate timeout), defer its cancellation, and use it for all
IDMS/ITMS deletes and ICSP/ITMS/IDMS Get/Delete calls. Preserve the existing
cleanup behavior while ensuring it survives spec-context cancellation and
remains time-bounded.
- Around line 42-53: The pollMCPSpecUnchanged helper should use context-aware
polling instead of legacy wait APIs. Add a context.Context parameter, call
wait.PollUntilContextTimeout with that context, and recognize timeout via
wait.Interrupted or context.DeadlineExceeded while preserving the existing
success and spec-change error behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 8a364252-5db1-4e4e-8437-f10769d4778f

📥 Commits

Reviewing files that changed from the base of the PR and between 46e684f and 1733cb9.

📒 Files selected for processing (1)
  • test/extended/node/node_e2e/image_mirror_set.go

@Chandan9112 Chandan9112 changed the title OCPBUGS-99397: pause worker MCP during mirror-set tests to prevent PDB drain deadlock OCPBUGS-99397: remove custom MCP from mirror-set tests to prevent PDB drain deadlock Jul 22, 2026
@Chandan9112

Copy link
Copy Markdown
Contributor Author

/payload-job periodic-ci-openshift-release-main-nightly-5.0-e2e-vsphere-disruptive-longrunning-techpreview

@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@Chandan9112: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command

  • periodic-ci-openshift-release-main-nightly-5.0-e2e-vsphere-disruptive-longrunning-techpreview

See details on https://pr-payload-tests.ci.openshift.org/runs/ci/2fbbaf30-85da-11f1-85e7-af1285877ad2-0

@Chandan9112

Copy link
Copy Markdown
Contributor Author

/payload-job periodic-ci-openshift-release-main-nightly-5.0-e2e-azure-disruptive-longrunning-techpreview-1of2

@openshift-ci

openshift-ci Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

@Chandan9112: trigger 1 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command

  • periodic-ci-openshift-release-main-nightly-5.0-e2e-azure-disruptive-longrunning-techpreview-1of2

See details on https://pr-payload-tests.ci.openshift.org/runs/ci/481fe2d0-85da-11f1-97c6-6d5a7b3287c4-0

@Chandan9112

Copy link
Copy Markdown
Contributor Author

@Chandan9112 Can we try removing custom MCP for cluster level resources? Will be helpful on a long term.

Thanks @ngopalak-redhat ., it worked fine. Removed the custom MCP entirely — both tests now operate directly on the worker pool, which avoids the PDB drain deadlock without needing any pause/unpause logic. Tested on vSphere (2 workers), both OCP-57401 and OCP-70203 pass cleanly with cluster fully stable after cleanup.


func (p *mirrorTestPool) waitForRollout(initialSpec string) {
imagepolicy.WaitForMCPConfigSpecChangeAndUpdated(p.oc, p.PoolName, initialSpec)
func waitForWorkerRollout(oc *exutil.CLI, initialSpec string) {

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.

Could you add wait and cleanup for both work and master pool?
The CRDs ICSP/IDMS/ITMS are setting cluster wide mirror configs, not for specific labeled pools.
When verifying the test, it is ok to only check work pool.

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

Labels

jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. 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.

5 participants