OCPEDGE-2700: fix flaky container-kill recovery test with migration-threshold#31276
OCPEDGE-2700: fix flaky container-kill recovery test with migration-threshold#31276lucaconsalvi wants to merge 11 commits into
Conversation
When a local etcd container is killed, the peer sets force_new_cluster and etcd recovers. In rare cases (~1.9% of runs) the killed node's repeated start failures hit Pacemaker's migration-threshold before coordination completes, causing Pacemaker to stop scheduling the resource and the 10-minute Eventually to expire. The "Failed Resource Actions" evidence (which the test asserts) is captured immediately after the cluster self-heals — at that point both nodes are guaranteed to appear since the peer's force_new_cluster monitor failure and the killed node's start failures have already been recorded. After capturing the evidence, pcs resource cleanup resets the failure count so Pacemaker can retry the start action against the now-healthy peer cluster. Fixes: https://redhat.atlassian.net/browse/OCPEDGE-2700 Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
Pipeline controller notification For optional jobs, comment This repository is configured in: automatic mode |
|
Skipping CI for Draft Pull Request. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughTest adds helpers to read, set, and restore Pacemaker's ChangesEtcd disruption test robustness improvements
Sequence Diagram(s)sequenceDiagram
participant Test
participant PacemakerCLI as Pacemaker<br/>(pcs)
participant TargetNode as Target Node<br/>(etcd)
Test->>PacemakerCLI: read migration-threshold(etcd-clone)
Test->>PacemakerCLI: set migration-threshold=INFINITY
Test->>TargetNode: kill local etcd container
TargetNode->>Test: etcd recovered
Test->>PacemakerCLI: verify etcd-clone Started on both nodes
Test->>PacemakerCLI: restore migration-threshold (original or delete)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 15✅ Passed checks (15 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: lucaconsalvi The full list of commands accepted by this bot can be found here. The pull request process is described here DetailsNeeds approval from an approver in each of these files:
Approvers can indicate their approval by writing |
|
/payload-job periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ovn-two-node-fencing-recovery |
|
@lucaconsalvi: trigger 3 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/98519310-6420-11f1-85a8-bef173c7a909-0 |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
test/extended/edge_topologies/tnf_etcd_disruption.go (1)
535-543: ⚡ Quick winConsider logging cleanup output on success for consistency and diagnostics.
The AfterEach cleanup at Line 337-343 logs the
pcs resource cleanupoutput even on success (Line 342). For consistency and better observability when investigating test runs, consider logging the output here too.📝 Suggested improvement
g.By("Running pcs resource cleanup to unblock etcd-clone if Pacemaker hit migration-threshold") if output, cleanupErr := exutil.DebugNodeRetryWithOptionsAndChroot( oc, execNode.Name, "default", "bash", "-c", "sudo pcs resource cleanup etcd-clone"); cleanupErr != nil { framework.Logf("Warning: pcs resource cleanup failed: %v\noutput: %s", cleanupErr, output) +} else { + framework.Logf("PCS resource cleanup output: %s", output) }🤖 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/edge_topologies/tnf_etcd_disruption.go` around lines 535 - 543, Update the pcs resource cleanup block that calls exutil.DebugNodeRetryWithOptionsAndChroot (the call using oc, execNode.Name and "sudo pcs resource cleanup etcd-clone") to log the command output on success as well as on error; i.e., after the call, always call framework.Logf with a concise success message and the captured output when cleanupErr is nil, and keep the existing warning log when cleanupErr is non-nil so diagnostics are consistent.
🤖 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/edge_topologies/tnf_etcd_disruption.go`:
- Around line 535-543: Update the pcs resource cleanup block that calls
exutil.DebugNodeRetryWithOptionsAndChroot (the call using oc, execNode.Name and
"sudo pcs resource cleanup etcd-clone") to log the command output on success as
well as on error; i.e., after the call, always call framework.Logf with a
concise success message and the captured output when cleanupErr is nil, and keep
the existing warning log when cleanupErr is non-nil so diagnostics are
consistent.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository YAML (base), Central YAML (inherited)
Review profile: CHILL
Plan: Enterprise
Run ID: 4ffeaed2-43be-4d3e-819c-258eef5d5aab
📒 Files selected for processing (1)
test/extended/edge_topologies/tnf_etcd_disruption.go
|
/payload-job periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ovn-two-node-fencing-recovery |
|
@lucaconsalvi: trigger 3 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/dbf33f20-64a1-11f1-99be-5db787e1433a-0 |
|
Scheduling required tests: Scheduling tests matching the |
|
@lucaconsalvi: This pull request references OCPEDGE-2700 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 story to target the "5.0.0" version, but no target version was set. DetailsIn response to this:
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. |
|
/retest |
|
Job Failure Risk Analysis for sha: ff7fde9
|
|
/retest-required |
|
@lucaconsalvi We are capturing the failure, and running the necessary command to clean up the cluster so it is not left in a bad state. How do we make sure this does not result in missing failures if a real problem introduced ? |
|
@dhensel-rh Thanks for the observation! The cleanup could mask a real start-action failure. I've reworked the approach: instead of running pcs resource cleanup mid-test, I now raise migration-threshold to INFINITY on etcd-clone before the container kill, and restore it in DeferCleanup/AfterEach. |
- Parse migration-threshold in Go instead of shell grep pipeline
to stop masking pcs failures behind || true
- Add migration-threshold=INFINITY to test 5 (etcd process crash)
which had the same podman kill as test 4 but lacked the protection
- Remove unconditional restoreMigrationThreshold("") from AfterEach
so DeferCleanup can restore to the actual original value
- Drop verifyFinalClusterHealth from tests 1-6 (AfterEach covers it)
- Remove redundant recovery polling in tests 2, 3
- Simplify Failed Resource Actions check in test 4
- Extract sshTestContext struct from 58-line inline SSH setup in test 7
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
/payload-job periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ovn-two-node-fencing-recovery |
|
@lucaconsalvi: trigger 3 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/cfe00a30-7935-11f1-82e4-4a0a664b2c88-0 |
|
Scheduling required tests: Scheduling tests matching the |
pcs stonith fence prints its confirmation ("Node: X fenced") to stderr,
not stdout. runOnNode was discarding stderr, so the fence assertion
retried for 3 minutes against empty stdout then timed out — re-fencing
an already-fenced node on every retry.
Combine stdout and stderr to match oc debug behavior, which merges both
streams.
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
/payload-job periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ovn-two-node-fencing-recovery |
|
@lucaconsalvi: trigger 3 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/5fa6e5f0-79de-11f1-8826-c62118e8b5f2-0 |
|
Scheduling required tests: Scheduling tests matching the |
|
/payload-job periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ovn-two-node-fencing-recovery |
|
@lucaconsalvi: trigger 3 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/472aa000-79ea-11f1-865a-99de944fca83-0 |
|
/retest |
|
/payload-job periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ovn-two-node-fencing-recovery |
|
@lucaconsalvi: trigger 3 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/fe7bb740-7a02-11f1-8188-b03bb8928b49-0 |
|
Job Failure Risk Analysis for sha: 74acd2b
|
|
Job Failure Risk Analysis for sha: 74acd2b
|
|
/payload-job periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ovn-two-node-fencing-recovery |
|
@lucaconsalvi: trigger 3 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/51171c70-7ae3-11f1-8870-750edcbb4e67-0 |
|
/retest |
|
/payload-job periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ovn-two-node-fencing-recovery |
|
@lucaconsalvi: trigger 3 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/f94004c0-7b92-11f1-999b-7c2e23773d32-0 |
The is_standalone test (test 7) fails at the log grep assertion because pacemaker takes 4-5 minutes after unstandby to schedule a podman_start action, exceeding the 3-minute timeout. Additionally, the first start attempt after fence/reboot runs before CRM attributes are spoofed and may leave a FAILED state that delays subsequent starts. Add pcs resource cleanup before the standby/unstandby cycle to clear stale failure history, and increase the grep timeout from 3 minutes to longRecoveryTimeout (10 minutes) to match all other recovery waits. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
/payload-job periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ovn-two-node-fencing-recovery |
|
@lucaconsalvi: trigger 3 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/c07772b0-7c44-11f1-8e84-5d2ae4b525fb-0 |
|
Scheduling required tests: Scheduling tests matching the |
|
@lucaconsalvi: The following tests failed, say
Full PR test history. Your PR dashboard. DetailsInstructions 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. |
|
/payload-job periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ovn-two-node-fencing-recovery |
|
@lucaconsalvi: trigger 3 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/9a291a00-7e7e-11f1-801d-76e7db5ff51f-0 |
After fencing a node in a two-node cluster, the Kubernetes API may be unreachable for several minutes while force-new-cluster runs on the survivor. The 3-minute timeout for the NotReady check is too short when the API is temporarily unavailable — increase to longRecoveryTimeout (10 min) to match other recovery waits in the file. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
|
/payload-job periodic-ci-openshift-release-main-nightly-4.22-e2e-metal-ovn-two-node-fencing-recovery |
|
@lucaconsalvi: trigger 3 job(s) for the /payload-(with-prs|job|aggregate|job-with-prs|aggregate-with-prs) command
See details on https://pr-payload-tests.ci.openshift.org/runs/ci/b71b2110-7ea8-11f1-8f10-e5ba67306ea2-0 |
Problem
The test
should coordinate recovery with peer when local etcd container is killedflakes at ~1.9% (4 failures / 212 CI runs, seen on both PR payload runs and periodic nightlies).All failures are identical: 600s timeout waiting for etcd-clone to be Started on both nodes. The failure log shows:
Root cause
When
podman kill etcdis run on one node, thepodman-etcdresource agent coordinates recovery via the force_new_cluster protocol:force_new_cluster→ monitor fails--force-new-clusterThe race: step 3 (start action) can fail multiple times before step 1–2 completes. If it hits Pacemaker's
migration-threshold(default: 3 failures) before the peer is ready, Pacemaker stops scheduling the resource entirely. ThelongRecoveryTimeout(10 min) then expires waiting for a recovery that Pacemaker won't attempt.Fix
Raise
migration-thresholdtoINFINITYon the etcd resource before killing the container, so Pacemaker never stops retrying during the transient coordination window. The original threshold is saved and restored viaDeferCleanup.This approach is better than the previous
pcs resource cleanupmid-test because:pcs resource cleanupcould mask real start-action failuresVerification
oc debugnamespace issues in other tests, MonitorTest noise)Fixes: https://redhat.atlassian.net/browse/OCPEDGE-2700
Summary by CodeRabbit