Skip to content

CNTRLPLANE-3145: refactor(hostedcluster): segregate reconcile loop into error-collecting blocks - #7908

Merged
openshift-merge-bot[bot] merged 3 commits into
openshift:mainfrom
muraee:refactor/hostedcluster-reconcile-error-collecting
Jun 23, 2026
Merged

CNTRLPLANE-3145: refactor(hostedcluster): segregate reconcile loop into error-collecting blocks#7908
openshift-merge-bot[bot] merged 3 commits into
openshift:mainfrom
muraee:refactor/hostedcluster-reconcile-error-collecting

Conversation

@muraee

@muraee muraee commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Refactors reconcile() in the HostedCluster controller to use categorized error handling with critical/non-critical operations instead of sequential short-circuiting. Previously, any single failure among ~50 operations would block all subsequent work — e.g., a missing SSH key secret prevented CPO deployment and HCP creation.
  • Introduces a reconcileReport struct (reconcile_report.go) that classifies operations as critical (blocks downstream Phase 8) or nonCritical (errors collected, never blocks). When critical operations fail, Phase 8 components are automatically skipped with clear reporting of what failed and what was blocked.
  • Extracts inline code blocks into named methods and introduces wrapper methods (reconcileOperatorDeployments, reconcileRBACAndPolicies, reconcileKubeconfigAndPasswordSync, reconcileAuxiliary, reconcilePlatformSpecific) that collect errors independently.
  • The ReconciliationSucceeded condition now reflects the structured report: when critical failures exist, the condition message surfaces which operations failed and which were blocked (e.g., critical failures: [PullSecretSync]; blocked operations: [OperatorDeployments, RBACAndPolicies, ...]).

Key changes

Error categorization

Category Behavior Operations
critical Failures block Phase 8 components PlatformCredentials, PullSecretSync, SecretEncryptionSync, CoreHCPChain
nonCritical Errors collected, never blocks SSHKeySync, AuditWebhookSync, AdditionalTrustBundle, all Phase 8 groups

Phase structure

Phase Behavior Operations
0–5 Short-circuit (prerequisites) HCP get, deletion, platform defaults, status, finalizers, namespace, platform
6a Critical sync (error-collecting) PlatformCredentials, PullSecretSync, SecretEncryptionSync
6b Non-critical sync (error-collecting, never blocked) RestoredFromBackup, AuditWebhookSync, SSHKeySync, AdditionalTrustBundle, SA signing key, etcd MTLS, ETCDMemberRecovery, GlobalConfigSync
7 Core HCP chain (always runs regardless of 6a) HCP object → CAPI InfraCR → CAPI Cluster
8 Components — blocked if any critical failure KubeconfigAndPasswordSync, OperatorDeployments, RBACAndPolicies, PlatformOIDCAndCSI, MonitoringAndCLISecrets

Condition reporting

The ReconciliationSucceeded condition now reflects the structured error report:

  • When critical failures exist, the condition message includes which operations failed and which were blocked
  • When only non-critical failures exist, the condition reports the aggregate error as before
  • Example condition message: critical failures: [PullSecretSync]; blocked operations: [KubeconfigAndPasswordSync, OperatorDeployments, RBACAndPolicies, PlatformOIDCAndCSI, MonitoringAndCLISecrets]

Structured error aggregation

When critical failures exist, aggregate() returns only critical errors with blocked operation list — non-critical errors are suppressed since the user should fix the critical issue first:

critical error: failed to get pull secret...; blocked operations: [KubeconfigAndPasswordSync, OperatorDeployments, RBACAndPolicies, PlatformOIDCAndCSI, MonitoringAndCLISecrets]

When no critical failures exist, all errors are returned as-is.

reconcileReport API

Two public methods on the report:

  • execute(name, category, func() error) — always runs the operation and records the result
  • executeOrBlock(name, func() error) — automatically checks hasCriticalFailure() and either runs the operation or records it as blocked

Analysis

See docs/design/hostedcluster-reconcile-segregation-analysis.md for the full design.

Test plan

  • All existing unit tests pass (go test -count=1 -race ./hypershift-operator/controllers/hostedcluster/)
  • make lint passes with 0 issues
  • New unit tests for reconcileReport methods (TestReconcileReport, TestConditionMessage, TestAggregate, TestExecuteOrBlock)
  • New unit tests for wrapper method isolation (TestReconcileKubeconfigAndPasswordSync_*, TestReconcileRBACAndPolicies_*)
  • New integration tests verifying blocking behavior:
    • Phase 6a critical failure → Phase 8 blocked, Phase 7 still runs
    • Phase 7 HCP creation failure → Phase 8 blocked
    • Phase 6b non-critical failure → nothing blocked

@openshift-ci-robot

Copy link
Copy Markdown

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

@coderabbitai

coderabbitai Bot commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The head commit changed during the review from 717ef22 to 7e6260d.

📝 Walkthrough

Walkthrough

This pull request introduces a phased, modular refactoring of the HostedCluster reconciliation loop. It adds a design document analyzing reconciliation segregation, restructures the controller into nine sequential phases with independent error aggregation, and introduces multiple helper functions to isolate functionality. A signature change removes the defaultIngressDomain parameter from reconcileControlPlaneOperator, and new tests validate partial progress when operations fail.

Changes

Cohort / File(s) Summary
Design Documentation
docs/design/hostedcluster-reconcile-segregation-analysis.md
New design document detailing reconciliation segregation analysis, including operation map splits (Pre-requisite, Part One, Part Two), dependency graphs, identified blocking issues, and impact assessment showing partial progress scenarios.
Controller Refactoring
hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
Major restructuring into 9 phases: initialization, pre-deletion propagation, deletion handling, conversion fixes, status updates, prerequisites, and three independent phase blocks. Introduces 15+ new modular helper functions (e.g., reconcileCoreHCPChain, reconcileOperatorDeployments, reconcilePlatformCredentialsWithStatus), changes reconcileControlPlaneOperator signature (removes defaultIngressDomain parameter), and implements aggregated error collection across independent syncs.
Test Coverage
hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go
Adds three new tests validating resilient reconciliation: kubeconfig sync failure with continued kubeadmin-password sync, RBAC failure with continued Prometheus RBAC creation, and Phase 6 SSH key failure with continued Phase 7–8 completion. Includes rbacv1 import for RBAC assertions.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Structure And Quality ⚠️ Warning Three new tests lack context timeouts, have incomplete coverage for failure scenarios, and include inconsistent assertion messages. Add context timeouts using context.WithTimeout(), mock dependencies to force failures in the PKI RBAC test, and add meaningful messages to all assertions.
✅ Passed checks (3 passed)
Check name Status Explanation
Stable And Deterministic Test Names ✅ Passed Pull request uses Go's standard testing package (func TestXxx) rather than Ginkgo, so the Ginkgo test title stability check does not apply. Test function names are descriptive and static with no dynamic values.
Title check ✅ Passed The title accurately describes the primary refactoring—segregating the reconcile loop into error-collecting blocks with clearer phase separation.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

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

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

@muraee

muraee commented Mar 10, 2026

Copy link
Copy Markdown
Contributor Author

/test e2e-aws

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/design/hostedcluster-reconcile-segregation-analysis.md`:
- Around line 112-190: The markdown fenced block containing the ASCII diagram
(the block that begins with
"+-----------------------------------------------------+" and includes "CRITICAL
PREREQUISITES (must succeed first)") needs a language label to satisfy
markdownlint: change the opening fence from ``` to ```text so the diagram is
fenced as a text block; update the single fenced block in the file (the ASCII
diagram between the backticks) accordingly.

In `@hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go`:
- Around line 1726-1728: The code currently checks and then removes the
HostedClusterRestoredFromBackupAnnotation from hcluster before writing the
durable status (ReconciliationSucceeded/HostedClusterRestoredFromBackup
condition), which can lose the trigger if the status update fails; change the
flow so you do not consume/remove HostedClusterRestoredFromBackupAnnotation
until after the status write is confirmed: first set the
HostedClusterRestoredFromBackup condition on the HostedCluster status and
perform the status update (updateStatus on hcluster), retrying on conflict as
needed, and only after the status update succeeds remove the
HostedClusterRestoredFromBackupAnnotation (or perform the annotation removal in
a separate patch/update with proper conflict handling) so the reconcile will
retry if the status write failed.
- Around line 1456-1483: If reconcileCoreHCPChain failed and hcp is nil, phase‑8
helpers will dereference hcp and panic; guard the entire phase‑8 block by
checking if hcp == nil and, if so, append a recoverable error to componentErrs
(e.g. fmt.Errorf("skipping phase 8: HostedControlPlane is nil due to earlier
error")) and skip calling reconcileKubeconfigAndPasswordSync,
reconcileOperatorDeployments, reconcileRBACAndPolicies,
reconcilePlatformSpecific, and reconcileAuxiliary; otherwise run the existing
calls as before.
- Around line 2161-2174: The status fields holding secret references
(hcluster.Status.CustomKubeconfig and hcluster.Status.KubeadminPassword) are
only being cleared in memory; after deleting the Secrets you must also persist
those changes to the API by clearing the fields on the HostedCluster status and
calling the Status().Update (or Client.Status().Update) to save them. Modify the
branch that deletes the custom kubeconfig (and the other branch mentioned around
the KubeadminPassword) to set hcluster.Status.CustomKubeconfig = nil and/or
hcluster.Status.KubeadminPassword = nil as appropriate and then call
r.Status().Update(ctx, hcluster) (handling and returning any error) so the API
no longer holds dangling secret refs; use the existing DeleteIfNeeded flow and
ensure both branches behave the same way.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro

Run ID: 33f6ef88-9d24-48cc-8609-666d2cca5d82

📥 Commits

Reviewing files that changed from the base of the PR and between cc479bc and 04ede4b.

📒 Files selected for processing (3)
  • docs/design/hostedcluster-reconcile-segregation-analysis.md
  • hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go
  • hypershift-operator/controllers/hostedcluster/hostedcluster_controller_test.go

Comment thread docs/design/hostedcluster-reconcile-segregation-analysis.md Outdated
Comment thread hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go Outdated
Comment thread hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go Outdated
@openshift-ci
openshift-ci Bot requested review from enxebre and sjenning March 10, 2026 16:26
@openshift-ci openshift-ci Bot added the area/documentation Indicates the PR includes changes for documentation label Mar 10, 2026
@openshift-ci

openshift-ci Bot commented Mar 10, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: muraee

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

@openshift-ci openshift-ci Bot added area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release approved Indicates a PR has been approved by an approver from all required OWNERS files. and removed do-not-merge/needs-area labels Mar 10, 2026
Comment thread docs/design/hostedcluster-reconcile-segregation-analysis.md Outdated
Comment thread docs/design/hostedcluster-reconcile-segregation-analysis.md Outdated
@enxebre

enxebre commented Mar 12, 2026

Copy link
Copy Markdown
Member

was there jira bug we can ref reporting the scenario where this was being problematic for managed?

Comment thread docs/design/hostedcluster-reconcile-segregation-analysis.md Outdated
@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 15, 2026
@openshift-merge-robot

Copy link
Copy Markdown
Contributor

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.

@muraee
muraee force-pushed the refactor/hostedcluster-reconcile-error-collecting branch from 04ede4b to 168e67a Compare March 31, 2026 11:16
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Mar 31, 2026
@muraee
muraee force-pushed the refactor/hostedcluster-reconcile-error-collecting branch from 168e67a to 15e6a0c Compare March 31, 2026 11:23
@muraee
muraee force-pushed the refactor/hostedcluster-reconcile-error-collecting branch from 15e6a0c to e7bc83c Compare March 31, 2026 11:27
@muraee
muraee force-pushed the refactor/hostedcluster-reconcile-error-collecting branch from e7bc83c to 5bc8ca5 Compare March 31, 2026 11:40
@muraee
muraee force-pushed the refactor/hostedcluster-reconcile-error-collecting branch from 5bc8ca5 to 922ef75 Compare March 31, 2026 11:47
@codecov

codecov Bot commented Mar 31, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 51.17493% with 374 lines in your changes missing coverage. Please review.
✅ Project coverage is 42.41%. Comparing base (95f7017) to head (0983a82).
⚠️ Report is 23 commits behind head on main.

Files with missing lines Patch % Lines
...trollers/hostedcluster/hostedcluster_controller.go 46.49% 322 Missing and 44 partials ⚠️
...ator/controllers/hostedcluster/reconcile_report.go 95.94% 3 Missing ⚠️
hypershift-operator/main.go 0.00% 2 Missing ⚠️
support/util/util.go 60.00% 1 Missing and 1 partial ⚠️
...rollers/hostedcluster/internal/platform/aws/aws.go 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7908      +/-   ##
==========================================
+ Coverage   42.09%   42.41%   +0.31%     
==========================================
  Files         766      767       +1     
  Lines       95047    95217     +170     
==========================================
+ Hits        40012    40383     +371     
+ Misses      52221    52032     -189     
+ Partials     2814     2802      -12     
Files with missing lines Coverage Δ
...rollers/hostedcluster/internal/platform/aws/aws.go 14.09% <0.00%> (ø)
hypershift-operator/main.go 0.00% <0.00%> (ø)
support/util/util.go 39.71% <60.00%> (+0.16%) ⬆️
...ator/controllers/hostedcluster/reconcile_report.go 95.94% <95.94%> (ø)
...trollers/hostedcluster/hostedcluster_controller.go 51.99% <46.49%> (+5.92%) ⬆️

... and 1 file with indirect coverage changes

Flag Coverage Δ
cmd-support 35.42% <60.00%> (+<0.01%) ⬆️
cpo-hostedcontrolplane 44.48% <ø> (ø)
cpo-other 44.25% <ø> (ø)
hypershift-operator 53.05% <51.11%> (+1.13%) ⬆️
other 31.56% <ø> (ø)

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.

@muraee
muraee force-pushed the refactor/hostedcluster-reconcile-error-collecting branch from ba3485a to 717ef22 Compare June 18, 2026 10:33
@openshift-ci openshift-ci Bot added the area/ai Indicates the PR includes changes related to AI - Claude agents, Cursor rules, etc. label Jun 18, 2026
@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-7908 June 18, 2026 10:35 Inactive
@muraee
muraee force-pushed the refactor/hostedcluster-reconcile-error-collecting branch from 717ef22 to 7e6260d Compare June 18, 2026 10:36
@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-7908 June 18, 2026 10:38 Inactive

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

Reviewed the behavioral changes between the legacy and new reconcile paths. Two items worth addressing before merge.

Comment thread hypershift-operator/controllers/hostedcluster/hostedcluster_controller.go Outdated
@muraee
muraee force-pushed the refactor/hostedcluster-reconcile-error-collecting branch from 7e6260d to 484a1c1 Compare June 19, 2026 10:15
@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 19, 2026
@muraee
muraee force-pushed the refactor/hostedcluster-reconcile-error-collecting branch from 484a1c1 to 6d8244d Compare June 19, 2026 10:22
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jun 19, 2026
@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-7908 June 19, 2026 10:27 Inactive
@muraee
muraee force-pushed the refactor/hostedcluster-reconcile-error-collecting branch from 6d8244d to d341729 Compare June 19, 2026 10:28
@github-actions
github-actions Bot temporarily deployed to docs-preview/pr-7908 June 19, 2026 10:32 Inactive
muraee and others added 2 commits June 22, 2026 16:23
…ng blocks

The reconcile() method executes ~50 sequential operations where every
error causes an early return, short-circuiting all remaining work. An
unrelated failure (e.g., missing SSH key secret) prevents critical
operations like deploying the CPO or reconciling the HCP object.

This refactoring:

- Extracts 12 inline blocks into named methods
- Groups operations into phased error-collecting blocks
- Aggregates all errors with utilerrors.NewAggregate at the end
- Introduce reconcileReport struct that classifies reconcile operations as
critical (blocks Phase 8) or non-critical (error-collecting, never blocks).
Replace the sequential error chain where any failure short-circuits the
entire loop with structured error collection and blocking rules.

After this change, failures in one phase no longer block unrelated
phases. For example, a missing SSH key no longer prevents CPO deployment
or HCP object creation.

Includes the analysis document and integration tests that verify
non-blocking behavior across phases.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rror-collection framework

Replace the ad-hoc early-return pull-secret recovery path (PR openshift#8352) with
the error-collection framework. Instead of inline HCP reconciliation when
GetPullSecretBytes fails, the reconciliation now flows through the framework
where PullSecretSync captures the error as critical and CoreHCPChain
reconciles the HCP with full cert resolution.

Key changes:
- Move GetPullSecretBytes, CPO image/label resolution, and namespace
  reconciliation into a single report.execute("CPOImageAndNamespace")
  block. This prevents namespace PSA label downgrades when CPO labels
  are unavailable.
- Make DetermineHostedClusterPayloadArch and lookupReleaseImage non-fatal
  so reconciliation continues to the framework.
- Make cpoSupportsKASCustomKubeconfig status check unconditional — all
  supported CPO versions expose custom kubeconfig.
- Wrap releaseImageVersion parsing in report.execute(critical) to block
  OperatorDeployments and RBACAndPolicies on failure instead of hard-returning.
- Extract reconcileControlPlaneNamespace into its own method.
- Update pull-secret-missing tests with valid fixtures (NonePlatform, Route,
  valid UUID) so reconciliation reaches the framework.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@csrwng

csrwng commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@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

Move the original reconcile method into reconcile_legacy.go as
reconcileLegacy, activated by HYPERSHIFT_RECONCILE_LEGACY=1. This
replaces the legacy flag in reconcileReport — the changes to the v2
reconciler are too deep for a flag to faithfully reproduce the old
behavior.

- Extract pre-refactor reconcile into reconcile_legacy.go
- Remove legacy field from reconcileReport and simplify shouldBlock
- Dispatch via ReconcileLegacy flag in the Reconcile entry point
- Fix reconcileOpenShiftTrustedCAs unused bool return (unparam lint)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@hypershift-jira-solve-ci

Copy link
Copy Markdown
Contributor

AI Test Failure Analysis

Job: pull-ci-openshift-hypershift-main-e2e-aks | Build: 2069066229867352064 | Cost: $2.14710425 | Failed step: hypershift-azure-run-e2e

View full analysis report


Generated by hypershift-analyze-e2e-failure post-step using Claude claude-opus-4-6

@csrwng

csrwng commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

/lgtm

@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

@muraee

muraee commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

/verified by unit

@openshift-ci-robot

Copy link
Copy Markdown

@muraee: This PR has been marked as verified by unit.

Details

In response to this:

/verified by unit

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.

@muraee

muraee commented Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

/retest-required

@openshift-ci

openshift-ci Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

@muraee: The following tests failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/docs-preview 6805539 link false /test docs-preview
ci/prow/verify-workflows 6805539 link true /test verify-workflows
ci/prow/okd-scos-images 0983a82 link unknown /test okd-scos-images

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.

@hypershift-jira-solve-ci

hypershift-jira-solve-ci Bot commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

Test Failure Analysis Complete

Job Information

  • Prow Job: pull-ci-openshift-hypershift-main-okd-scos-images
  • Build ID: 2069422325370982400
  • Target: [images]
  • Variant: okd-scos
  • PR: #7908CNTRLPLANE-3145: refactor(hostedcluster): segregate reconcile loop into error-collecting blocks
  • Duration: 6m41s (14:08:24Z → 14:15:21Z)
  • Cluster: build01

Test Failure Analysis

Error

step hypershift failed: error occurred handling build hypershift-amd64: the build hypershift-amd64 
failed after 4m2s with reason DockerBuildFailed: Dockerfile build strategy has failed.

Summary

The okd-scos-images job failed during the Docker image build of the hypershift image using Dockerfile.control-plane. Stage 1 (Go compilation of control-plane-operator and control-plane-pki-operator) completed successfully — both go build commands finished without errors and Buildah proceeded to Stage 2. The failure occurred in Stage 2 (base image pull + binary COPY + labels) but the actual error output from Buildah was not captured in any CI artifact — the build log stream was cut off between the base image pull initiation and the ci-operator error report. The same job passes consistently for other PRs (SUCCESS runs immediately before and after this failure), and the PR's code changes do not affect the binaries being built by this Dockerfile. This is a transient CI infrastructure failure, not a code defect.

Root Cause

Transient Docker build infrastructure failure (flaky).

The hypershift-amd64 OpenShift Build failed during Docker Stage 2 with the generic DockerBuildFailed reason, but the specific error was lost due to build log streaming limitations. The evidence points to an infrastructure-level issue:

  1. Go compilation succeeded: Both control-plane-operator and control-plane-pki-operator were compiled without errors in Stage 1 (confirmed by [2/2] STEP 1/22 appearing in the log — Buildah only proceeds to Stage 2 if Stage 1's RUN exits 0).

  2. PR changes are irrelevant to the built artifacts: The Dockerfile builds control-plane-operator and control-plane-pki-operator. The PR modifies hypershift-operator/ code (new files reconcile_legacy.go, reconcile_report.go, controller refactoring) and two shared support packages (support/config/constants.go — one new constant; support/util/util.go — new error variable and GetPullSecretBytes refactoring). While control-plane-operator imports support/util and support/config, the changes are trivially Go 1.24-compatible (stdlib errors.New(), fmt.Errorf with %w).

  3. Job passes consistently for other PRs: Checking the job history, the runs immediately before (PR CNTRLPLANE-3276: Add Azure ExternalPrivateService and endpoint access transition test #8718, SUCCESS at 14:00) and after (PR CNTRLPLANE-3276: Add Azure ExternalPrivateService and endpoint access transition test #8718 again, multiple pending/success) all pass. The only other recent failure (PR fix(ci): add missing plugin marketplaces for GHA workflows #8810 at 12:25) was due to a merge conflict — a completely unrelated issue.

  4. Build log truncation: The actual Buildah error output between "Trying to pull [base-image]..." and ci-operator's error report is missing. The build pod's resource snapshot was captured while the container was still in Running state, so no exit code is available. This is a known ci-operator log streaming limitation where failed build output can be lost.

  5. Resource constraints possible: The build pod had only 430MB memory request with Burstable QoS (no memory limit), which is low for a Go compilation producing multiple binaries in a Buildah build context.

Recommendations
  1. Retest the PR — This appears to be a transient failure. Run /retest or /test okd-scos-images on the PR to trigger a new run. The job is expected to pass on retry.

  2. If it fails again on retry, investigate:

    • Check if the origin/scos-4.21:base-stream9 base image is healthy (image stream import status)
    • Check build pod memory usage — the 430MB request may need increase if the repo is growing
    • Compare the build duration with the successful PR CNTRLPLANE-3276: Add Azure ExternalPrivateService and endpoint access transition test #8718 run (3m43s success vs 4m2s failure — the extra ~20s from the new 1806-line reconcile_legacy.go is within normal variance but increases memory/disk pressure)
  3. No code changes needed — The PR's modifications to support/util/util.go and support/config/constants.go are correct and Go 1.24-compatible.

Evidence
Evidence Detail
Build failure reason DockerBuildFailed: Dockerfile build strategy has failed. — generic, no specific cause captured
Stage 1 (Go compilation) ✅ Succeeded — both control-plane-operator and control-plane-pki-operator compiled; Buildah proceeded to Stage 2
Stage 2 (base image + COPY) ❌ Failed — log shows [2/2] STEP 1/22: FROM ... then Trying to pull ... then log ends
Build log completeness Truncated — 8,302 bytes; Buildah error output between base image pull and ci-operator error is missing
Build duration 4m2s (DockerBuild stage: 88s); comparable to successful 3m43s on PR #8718
Build pod resources 4 CPU request, 430MB memory request, Burstable QoS (no memory limit)
Build pod exit code Not captured — pod snapshot taken while still Running
Job history 12 of 14 recent runs succeeded; our failure + one merge conflict failure are the only failures
PR code impact on built binary None — PR modifies hypershift-operator/ (not compiled by this Dockerfile) and two trivial support/ changes (Go 1.24-compatible)
Go version compatibility go.mod requires go 1.25.7; OKD builder uses Go 1.24; -mod=vendor allows compilation despite version mismatch; no Go 1.25-specific syntax in changed files
Other failure (PR #8810) Unrelated — merge conflict in .github/workflows/reusable-claude-on-pr.yaml

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

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. area/ai Indicates the PR includes changes related to AI - Claude agents, Cursor rules, etc. area/control-plane-operator Indicates the PR includes changes for the control plane operator - in an OCP release area/documentation Indicates the PR includes changes for documentation area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/aws PR/issue for AWS (AWSPlatform) platform 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. verified Signifies that the PR passed pre-merge verification criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants