Skip to content

OCPBUGS-98464: handle stale DaemonSet in GlobalPullSecret test#8990

Open
jparrill wants to merge 1 commit into
openshift:mainfrom
jparrill:OCPBUGS-98464
Open

OCPBUGS-98464: handle stale DaemonSet in GlobalPullSecret test#8990
jparrill wants to merge 1 commit into
openshift:mainfrom
jparrill:OCPBUGS-98464

Conversation

@jparrill

@jparrill jparrill commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Delete any stale kubelet-config-verifier DaemonSet before creating a new one in CreateKubeletConfigVerifierDaemonSet
  • Move resource cleanup to t.Cleanup() in VerifyKubeletConfigWithDaemonSet so it runs even when the test fails or times out

Fixes

Root Cause

The EnsureGlobalPullSecret test creates a kubelet-config-verifier DaemonSet to verify pull secret propagation. Two issues caused intermittent 409 errors and cascading failures:

  1. No stale resource handling: CreateKubeletConfigVerifierDaemonSet used a raw client.Create() with no AlreadyExists handling. If a previous test run left the DaemonSet behind (e.g., after a timeout), the next run got a 409 and failed.

  2. Cleanup dependent on test success: Resource cleanup ran inline after the readiness wait using g.Expect().To(Succeed()). If the readiness wait timed out, cleanup never executed — leaving stale resources for the next run.

Changes

What Before After
Stale DS 409 AlreadyExists → test fails Delete stale DS (ignore NotFound) → create fresh
Cleanup Inline after readiness wait (skipped on failure) t.Cleanup() — always runs
Cleanup errors g.Expect (fails the test on cleanup error) t.Logf warning (non-fatal)

Test plan

  • Unit tested all scenarios locally (stale DS, no DS, stale pull secret, cleanup after failure)
  • e2e-aws-ovn periodic should no longer hit 409 errors on the kubelet-config-verifier DaemonSet

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved kubelet configuration verification test cleanup, including automatic removal of temporary resources when tests fail or time out.
    • Prevented conflicts from stale verifier resources by removing existing resources before creating new ones.

The kubelet-config-verifier DaemonSet was created with a raw Create
call that failed with 409 AlreadyExists when a previous test run left
it behind (e.g., after a timeout before cleanup). The cleanup also
used g.Expect which could fail the test during teardown, preventing
resource removal.

Delete any stale DaemonSet before creating a new one, and move
cleanup to t.Cleanup so it always runs regardless of test outcome.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Juan Manuel Parrilla Madrid <jparrill@redhat.com>
@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: LGTM mode

@jparrill

Copy link
Copy Markdown
Contributor Author

/area ci

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The kubelet config verifier now deletes an existing DaemonSet before creating a new one, ignoring not-found errors and reporting other deletion failures. Resource cleanup is registered through t.Cleanup, so the verifier DaemonSet and pull-secret are removed regardless of test outcome. The previous explicit post-verification deletion block was removed.

🚥 Pre-merge checks | ✅ 10 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Test Structure And Quality ⚠️ Warning Cleanup was added, but setup is still flaky: the verifier pull-secret isn’t refreshed when it already exists, and DaemonSet deletion doesn’t wait for NotFound before recreate. Refresh or replace the verifier pull-secret on every run, and poll the DaemonSet until NotFound before creating a replacement; keep the t.Cleanup teardown.
✅ Passed checks (10 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 changed file only updates helper functions and contains no Ginkgo titles; the only test name found is the static t.Run("EnsureGlobalPullSecret").
Topology-Aware Scheduling Compatibility ✅ Passed Only test cleanup/stale-resource logic changed; no node selectors, affinity, spread constraints, replica math, or topology assumptions were introduced.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The changed code is a test helper, not a new Ginkgo body; it uses cluster APIs and on-node file checks only, with no IPv4 literals or public-internet connectivity.
No-Weak-Crypto ✅ Passed Patch only changes DaemonSet cleanup; no new weak-crypto, custom crypto, or secret comparison code was added.
Container-Privileges ✅ Passed PASS: The PR only changes stale DaemonSet cleanup and t.Cleanup; no new privileged/hostPID/hostNetwork/SYS_ADMIN/allowPrivilegeEscalation settings are added.
No-Sensitive-Data-In-Logs ✅ Passed Diff only adds generic cleanup t.Log/t.Logf messages; no passwords, tokens, PII, or other sensitive values are logged.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: handling stale DaemonSet cleanup in the GlobalPullSecret test.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci

openshift-ci Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

@jparrill: The label(s) area/ci cannot be applied, because the repository doesn't have them.

Details

In response to this:

/area ci

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.

@openshift-ci openshift-ci Bot added the area/testing Indicates the PR includes changes for e2e testing label Jul 13, 2026
@openshift-ci openshift-ci Bot requested review from clebs and ironcladlou July 13, 2026 14:19
@openshift-ci

openshift-ci Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: jparrill

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

The pull request process is described 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

@jparrill

Copy link
Copy Markdown
Contributor Author

/area ci-tooling

@openshift-ci openshift-ci Bot added approved Indicates a PR has been approved by an approver from all required OWNERS files. area/ci-tooling Indicates the PR includes changes for CI or tooling labels Jul 13, 2026
@jparrill jparrill changed the title fix(OCPBUGS-98464): handle stale DaemonSet in GlobalPullSecret test OCPBUGS-98464: handle stale DaemonSet in GlobalPullSecret test Jul 13, 2026
@openshift-ci-robot openshift-ci-robot added jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. jira/valid-bug Indicates that a referenced Jira bug is valid for the branch this PR is targeting. labels Jul 13, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@jparrill: This pull request references Jira Issue OCPBUGS-98464, 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)

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

Details

In response to this:

Summary

  • Delete any stale kubelet-config-verifier DaemonSet before creating a new one in CreateKubeletConfigVerifierDaemonSet
  • Move resource cleanup to t.Cleanup() in VerifyKubeletConfigWithDaemonSet so it runs even when the test fails or times out

Fixes

Root Cause

The EnsureGlobalPullSecret test creates a kubelet-config-verifier DaemonSet to verify pull secret propagation. Two issues caused intermittent 409 errors and cascading failures:

  1. No stale resource handling: CreateKubeletConfigVerifierDaemonSet used a raw client.Create() with no AlreadyExists handling. If a previous test run left the DaemonSet behind (e.g., after a timeout), the next run got a 409 and failed.

  2. Cleanup dependent on test success: Resource cleanup ran inline after the readiness wait using g.Expect().To(Succeed()). If the readiness wait timed out, cleanup never executed — leaving stale resources for the next run.

Changes

What Before After
Stale DS 409 AlreadyExists → test fails Delete stale DS (ignore NotFound) → create fresh
Cleanup Inline after readiness wait (skipped on failure) t.Cleanup() — always runs
Cleanup errors g.Expect (fails the test on cleanup error) t.Logf warning (non-fatal)

Test plan

  • Unit tested all scenarios locally (stale DS, no DS, stale pull secret, cleanup after failure)
  • e2e-aws-ovn periodic should no longer hit 409 errors on the kubelet-config-verifier DaemonSet

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
  • Improved kubelet configuration verification test cleanup, including automatic removal of temporary resources when tests fail or time out.
  • Prevented conflicts from stale verifier resources by removing existing resources before creating new ones.

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
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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/e2e/util/globalps.go`:
- Around line 29-30: Update the pull-secret setup flow in the verifier creation
logic to reconcile or replace the existing kube-system/pull-secret before
creating the DaemonSet. Ensure stale credentials from prior runs are refreshed
from the current cluster pull secret, rather than accepting an existing Secret
unchanged, while preserving the subsequent node-file comparison behavior.
- Around line 54-64: Update the stale DaemonSet cleanup using the existing
`staleDS` and `guestClient` flow so deletion waits for confirmed completion:
after `Delete` succeeds, poll `Get` until it returns `NotFound`, propagating
other errors and honoring the context before proceeding to create the
replacement.
🪄 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: 467ef7e9-22e8-4b4c-86fe-9c50dc753ee6

📥 Commits

Reviewing files that changed from the base of the PR and between 845ed6f and cf88672.

📒 Files selected for processing (1)
  • test/e2e/util/globalps.go

Comment thread test/e2e/util/globalps.go
Comment on lines +29 to +30
// on all nodes of the cluster, comparing it with the cluster's pull secret.
// Stale resources from a previous failed run are cleaned up before creation.

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Refresh the replicated pull-secret before creating the verifier.

The new comment claims stale resources are cleaned before creation, but an existing kube-system/pull-secret is still accepted unchanged. A previous interrupted run can leave stale data, causing the verifier to compare the node file against old credentials and produce false failures or passes. Reconcile or replace the Secret before creating the DaemonSet.

🤖 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/e2e/util/globalps.go` around lines 29 - 30, Update the pull-secret setup
flow in the verifier creation logic to reconcile or replace the existing
kube-system/pull-secret before creating the DaemonSet. Ensure stale credentials
from prior runs are refreshed from the current cluster pull secret, rather than
accepting an existing Secret unchanged, while preserving the subsequent
node-file comparison behavior.

Comment thread test/e2e/util/globalps.go
Comment on lines +54 to +64
// Clean up any stale DaemonSet left by a previous failed run
staleDS := &appsv1.DaemonSet{
ObjectMeta: metav1.ObjectMeta{
Name: KubeletConfigVerifierDaemonSetName,
Namespace: KubeletConfigVerifierNamespace,
},
}
if err := guestClient.Delete(ctx, staleDS); err != nil && !apierrors.IsNotFound(err) {
return fmt.Errorf("failed to delete stale DaemonSet: %w", err)
}

@coderabbitai coderabbitai Bot Jul 13, 2026

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.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- file outline ---'
ast-grep outline test/e2e/util/globalps.go --view expanded || true

echo '--- relevant lines 1-280 ---'
nl -ba test/e2e/util/globalps.go | sed -n '1,280p'

echo '--- search for daemonset name and wait/retry logic ---'
rg -n "KubeletConfigVerifierDaemonSetName|Delete\\(|AlreadyExists|NotFound|WaitFor|poll|Eventually|Create\\(" test/e2e/util/globalps.go test/e2e -g '!**/vendor/**'

Repository: openshift/hypershift

Length of output: 742


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- relevant lines 1-280 ---'
sed -n '1,280p' test/e2e/util/globalps.go | cat -n

echo '--- focused search for waiting/retry logic ---'
rg -n "AlreadyExists|NotFound|WaitFor|Eventually|Poll|Create\\(|Delete\\(" test/e2e/util/globalps.go

Repository: openshift/hypershift

Length of output: 11853


Wait for the DaemonSet to be fully deleted before recreating it. Delete only requests removal; if a previous run left kubelet-config-verifier terminating, the subsequent Create can still fail with AlreadyExists. Poll Get until NotFound before creating the replacement.

🤖 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/e2e/util/globalps.go` around lines 54 - 64, Update the stale DaemonSet
cleanup using the existing `staleDS` and `guestClient` flow so deletion waits
for confirmed completion: after `Delete` succeeds, poll `Get` until it returns
`NotFound`, propagating other errors and honoring the context before proceeding
to create the replacement.

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.

The robot is right about this; I would suggest we make a guard / precondition to fail the test immediately if the DaemonSet unexpectedly exists per #8990 (comment)

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.

@ironcladlou, agreed — that's a cleaner approach than delete-and-poll. Since cleanup is now guaranteed via t.Cleanup, an existing DaemonSet at creation time signals a real problem (e.g., a previous run's cleanup failed), so failing fast with a clear error is more useful than silently deleting and racing a recreate.

I'll plan the change to replace the stale-delete logic in CreateKubeletConfigVerifierDaemonSet with a Get-based precondition that errors out immediately if the DaemonSet already exists.

  • Replace the "delete stale DaemonSet" block in CreateKubeletConfigVerifierDaemonSet (test/e2e/util/globalps.go) with a precondition check using Get
  • If the DaemonSet already exists, return a descriptive error causing the test to fail immediately (via the g.Expect(err).NotTo(HaveOccurred()) call in VerifyKubeletConfigWithDaemonSet) instead of deleting and recreating it
  • Propagate any non-NotFound Get error as a failure too

Failed to handle agent chat message. Please try again.

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 43.79%. Comparing base (845ed6f) to head (cf88672).
⚠️ Report is 15 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8990   +/-   ##
=======================================
  Coverage   43.79%   43.79%           
=======================================
  Files         772      772           
  Lines       96037    96037           
=======================================
  Hits        42061    42061           
  Misses      51061    51061           
  Partials     2915     2915           
Flag Coverage Δ
cmd-support 37.43% <ø> (ø)
cpo-hostedcontrolplane 45.91% <ø> (ø)
cpo-other 45.11% <ø> (ø)
hypershift-operator 54.07% <ø> (ø)
other 32.08% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Comment thread test/e2e/util/globalps.go
}
}

// Clean up any stale DaemonSet left by a previous failed run

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.

Is it really needed to have the deletion in 2 places? IIUC the cleanup below always runs so this should not be necessary.
Are there cases in which the cleanup could not run?
Are the cases in which the cleanup could fail but this deletion succeed?

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.

If the test can't tolerate the leaked/existing DaemonSet, and we have what should be a reliable cleanup function in place (below), what if instead of the duplicated cleanup logic here we added an additional precondition guard which fails the test immediately if the unexpected DaemonSet already exists in order to send a clear signal that we've got a cleanup bug?

@ironcladlou

Copy link
Copy Markdown
Contributor

Despite the feedback above I think if the PR's current state w/ the primary deletion lifecycle change makes the test more reliable we should merge it ASAP and incorporate the feedback into a followup

@ironcladlou

Copy link
Copy Markdown
Contributor

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 13, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks-4-22
/test e2e-aws-4-22
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-azure-v2-self-managed
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws
/test e2e-v2-gke

@cwbotbot

cwbotbot commented Jul 13, 2026

Copy link
Copy Markdown

Test Results

e2e-aws

e2e-aks

@hypershift-jira-solve-ci

Copy link
Copy Markdown
Contributor

Now I have all the evidence needed. Let me produce the final report:

Test Failure Analysis Complete

Job Information

  • Prow Job: pull-ci-openshift-hypershift-main-e2e-aws
  • Build ID: 2076767540909969408
  • Target: e2e-aws
  • Failed Test: TestCreateCluster/Main/EnsureGlobalPullSecret/When_management-cluster_hostedCluster.Spec.PullSecret_is_updated_in-place_it_should_propagate_to_guest_without_rollout
  • PR: #8990 — OCPBUGS-98464: handle stale DaemonSet in GlobalPullSecret test

Test Failure Analysis

Error

globalps.go:252:
    Expected success, but got an error:
        <*fmt.wrapError | 0xc00a87ff00>:
        failed to wait for DaemonSet global-pull-secret-syncer to be ready: context deadline exceeded
        {
            msg: "failed to wait for DaemonSet global-pull-secret-syncer to be ready: context deadline exceeded",
            err: <context.deadlineExceededError>{},
        }
--- FAIL: TestCreateCluster/Main/EnsureGlobalPullSecret/When_management-cluster_hostedCluster.Spec.PullSecret_is_updated_in-place_it_should_propagate_to_guest_without_rollout (1205.10s)

Summary

The EnsureGlobalPullSecret test failed because the global-pull-secret-syncer DaemonSet remained stuck at 2/3 pods ready for the entire 20-minute timeout after the management-cluster pull secret was patched. The hosted cluster has 3 nodes (one NodePool per AZ: us-east-1a, us-east-1b, us-east-1c), so the DaemonSet's DesiredNumberScheduled=3, but one pod never reached Ready state. This is not the stale kubelet-config-verifier DaemonSet issue that PR #8990 addresses — it is the global-pull-secret-syncer DaemonSet itself failing to complete its rolling update after the pull secret propagation. The PR's fix (deleting stale kubelet-config-verifier before creation + moving cleanup to t.Cleanup()) does not prevent this failure mode.

Root Cause

The EnsureGlobalPullSecret test patches the management-cluster pull secret, which triggers the HyperShift control plane to propagate the change to the hosted cluster's global-pull-secret-syncer DaemonSet. This propagation causes a rolling update of the DaemonSet (generation change). During this rolling update, one of the three global-pull-secret-syncer pods fails to reach Ready state, leaving the DaemonSet permanently stuck at 2/3 pods ready.

Key evidence of the rolling update race:

  • In the "first check" subtest (line 3305), the same global-pull-secret-syncer DaemonSet also shows status has not observed generation 4 yet (current 2), goes to 2/3 pods ready, then recovers to 3/3 pods ready — proving the DaemonSet does undergo a rolling update when the pull secret changes.
  • In the failing "When_management-cluster" subtest (line 2432), the DaemonSet immediately reports 2/3 pods ready with no generation mismatch log — the controller has already observed the new generation but one pod is stuck not-ready.

Why 2/3: The hosted cluster create-cluster-gp8z8 has 3 nodes across 3 AZs (us-east-1a, us-east-1b, us-east-1c) each with 1 NodePool replica. All 3 nodes are healthy (ovnkube-node reports 3/3). The global-pull-secret-syncer DaemonSet targets all 3 nodes but one pod consistently fails to reach readiness during the rolling update triggered by the pull secret patch.

Why PR #8990 does not fix this: The PR addresses a different issue — it handles stale kubelet-config-verifier DaemonSets left by previous failed runs (409 AlreadyExists on client.Create()). The actual failure is the global-pull-secret-syncer DaemonSet (a separate, system-managed DaemonSet) being stuck at 2/3 ready. The waitForDaemonSetReady function requires exact equality (ready == desired), and with one pod unhealthy the 20-minute timeout expires.

The test ran the EnsureGlobalPullSecret flow twice on the same hosted cluster. Both invocations failed identically at the global-pull-secret-syncer readiness check, confirming this is a persistent condition on the cluster rather than a transient race.

Recommendations
  1. Investigate the stuck global-pull-secret-syncer pod: The DaemonSet consistently has one pod not reaching Ready on one of the 3 nodes. The test should log which node/pod is not ready and the pod's conditions/events to diagnose whether it's a scheduling issue, image pull failure, readiness probe failure, or resource constraint.

  2. Add tolerance for transient DaemonSet rolling updates: The waitForDaemonSetReady function could be made more resilient by:

    • Adding a longer settling period after pull secret patches before checking DaemonSet readiness (the rolling update needs time to propagate).
    • Detecting when a DaemonSet is mid-rollout (generation != observedGeneration) and waiting for the rollout to complete before evaluating readiness.
  3. Consider the minExpected check: The test sets minExpected=1 (NodePool replicas) but the cluster has 3 nodes. The readiness check still requires ready == desired (3/3), making minExpected ineffective. If the intent is to tolerate partial readiness, the check logic should be adjusted.

  4. Re-scope PR OCPBUGS-98464: handle stale DaemonSet in GlobalPullSecret test #8990: The PR's current changes (stale kubelet-config-verifier cleanup + t.Cleanup()) are valid improvements but do not address the root failure seen in this CI run. Either:

    • Extend the PR to also add resilience to global-pull-secret-syncer readiness checks (e.g., retry/backoff after generation changes), or
    • Open a separate bug for the global-pull-secret-syncer rolling update failure.
Evidence
Evidence Detail
Failed test TestCreateCluster/Main/EnsureGlobalPullSecret/When_management-cluster_hostedCluster.Spec.PullSecret_is_updated_in-place_it_should_propagate_to_guest_without_rollout
Duration 1205.10s (20 min timeout)
Failure location globalps.go:252waitForDaemonSetReady for global-pull-secret-syncer
DaemonSet status 2/3 pods ready — stuck for 20 minutes, never recovered
Hosted cluster e2e-clusters-rr9kf/create-cluster-gp8z8 — 3 nodes across 3 AZs
NodePool replicas 1 per AZ (3 total nodes)
ovnkube-node 3/3 ready (nodes are healthy)
Generation check "first check" subtest showed generation 4 yet (current 2) → 2/3 → 3/3 (recovered); failing subtest showed 2/3 immediately (no recovery)
Test ran twice Both invocations of EnsureGlobalPullSecret failed identically at global-pull-secret-syncer 2/3
PR #8990 scope Fixes stale kubelet-config-verifier DaemonSet cleanup — does not address global-pull-secret-syncer readiness
Total failures 4 (all parent-child of the same leaf test: TestCreateCluster > Main > EnsureGlobalPullSecret > When_management-cluster...)
Other tests 623 tests total, 30 skipped, only this one chain failed

@jparrill

Copy link
Copy Markdown
Contributor Author

/label acknowledge-critical-fixes-only

@openshift-ci openshift-ci Bot added the acknowledge-critical-fixes-only Indicates if the issuer of the label is OK with the policy. label Jul 14, 2026
@jparrill

Copy link
Copy Markdown
Contributor Author

/retest-required

@openshift-ci

openshift-ci Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

@jparrill: 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

acknowledge-critical-fixes-only Indicates if the issuer of the label is OK with the policy. approved Indicates a PR has been approved by an approver from all required OWNERS files. area/ci-tooling Indicates the PR includes changes for CI or tooling area/testing Indicates the PR includes changes for e2e testing 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. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants