Skip to content

OCPBUGS-97592: skip plugin execution when backup does not target HCP resources#293

Draft
Alcamech wants to merge 1 commit into
openshift:mainfrom
Alcamech:OCPBUGS-97592-fix-mc-wide-backup-errors
Draft

OCPBUGS-97592: skip plugin execution when backup does not target HCP resources#293
Alcamech wants to merge 1 commit into
openshift:mainfrom
Alcamech:OCPBUGS-97592-fix-mc-wide-backup-errors

Conversation

@Alcamech

@Alcamech Alcamech commented Jul 7, 2026

Copy link
Copy Markdown

Summary

  • Remove the CRD-existence fallback from ShouldEndPluginExecution. The plugin now requires includedResources to list HCP types (hostedcontrolplane, hostedcluster, or nodepool) to proceed.
  • MC-wide backups (includedResources: null) are correctly skipped, eliminating ~16K spurious errors and the misleading PartiallyFailed status. Backup data was never affected.
  • Update test backup specs to include HCP resource types, matching real-world HC backup configurations.

Context

ShouldEndPluginExecution falls back to a CRD-existence check when includedResources is empty. On management clusters the HCP CRD is always present, so MC-wide backups (daily-full/weekly-full) are never skipped. The plugin runs on every item (~16K), errors on each because no HostedControlPlane can be associated, and marks the backup PartiallyFailed.

Every HC backup schedule on the staging MC (240 schedules) and every example in this repo specifies includedResources with HCP types. MC-wide schedules have includedResources: null.

Open question for the team: Can we require includedResources to list HCP types for the plugin to run? If an HC backup omits includedResources, the plugin would silently skip. All current schedules and examples already include them.

Test plan

  • make verify passes
  • MC-wide backup completes as Completed (not PartiallyFailed)
  • HC backup with includedResources containing HCP types proceeds normally
  • HC restore from a backup with includedResources proceeds normally

Summary by CodeRabbit

  • Bug Fixes
    • Improved backup and restore handling for environments that include hosted control plane-related resources.
    • Updated stop conditions so plugin execution now ends based on selected included resources, with clearer errors when required namespaces or resources are missing.
  • Tests
    • Refreshed backup and restore test data to reflect the updated resource selection behavior.

…resources

Signed-off-by: Lawton Mizell <lmizell@redhat.com>
@openshift-ci

openshift-ci Bot commented Jul 7, 2026

Copy link
Copy Markdown

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 added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 7, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 7, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@Alcamech: This pull request references Jira Issue OCPBUGS-97592, 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:

Summary

  • Remove the CRD-existence fallback from ShouldEndPluginExecution. The plugin now requires includedResources to list HCP types (hostedcontrolplane, hostedcluster, or nodepool) to proceed.
  • MC-wide backups (includedResources: null) are correctly skipped, eliminating ~16K errors and PartiallyFailed status.
  • Update test backup specs to include HCP resource types, matching real-world HC backup configurations.

Context

ShouldEndPluginExecution falls back to a CRD-existence check when includedResources is empty. On management clusters the HCP CRD is always present, so MC-wide backups (daily-full/weekly-full) are never skipped. The plugin runs on every item (~16K), errors on each because no HostedControlPlane can be associated, and marks the backup PartiallyFailed.

Every HC backup schedule on the staging MC (240 schedules) and every example in this repo specifies includedResources with HCP types. MC-wide schedules have includedResources: null.

Open question for the team: Can we require includedResources to list HCP types for the plugin to run? If an HC backup omits includedResources, the plugin would silently skip. All current schedules and examples already include them.

Test plan

  • make verify passes
  • MC-wide backup completes as Completed (not PartiallyFailed)
  • HC backup with includedResources containing HCP types proceeds normally
  • HC restore from a backup with includedResources proceeds normally

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-ci-robot openshift-ci-robot added the jira/invalid-bug Indicates that a referenced Jira bug is invalid for the branch this PR is targeting. label Jul 7, 2026
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Walkthrough

The ShouldEndPluginExecution function in pkg/common/utils.go was changed to determine execution termination by checking backup.Spec.IncludedResources for hypershift-related substrings (hostedcluster, hostedcontrolplane, nodepool) instead of checking for HostedControlPlane CRD existence. Test fixtures in backup_test.go and restore_test.go were updated to include these resources.

Changes

IncludedResources-based execution gating

Layer / File(s) Summary
Replace CRD check with IncludedResources substring check
pkg/common/utils.go
ShouldEndPluginExecution now inspects backup.Spec.IncludedResources for hostedcluster, hostedcontrolplane, or nodepool substrings instead of checking for the HostedControlPlane CRD; error messages and comments were updated accordingly, with minor whitespace adjustments elsewhere in the file.
Update test fixtures to include HCP resources
pkg/core/backup_test.go, pkg/core/restore_test.go
Test backup specs now set IncludedResources to include hostedcontrolplane, hostedcluster, and nodepool so existing tests remain consistent with the new gating logic.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 15
✅ Passed checks (15 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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 PR only changes backup spec fixtures; the touched test titles are static tt.name strings and contain no dynamic values.
Test Structure And Quality ✅ Passed PASS: The PR only adds IncludedResources fixtures and rewrites a pure helper; no new Ginkgo specs, waits, or resource-lifecycle issues were introduced.
Microshift Test Compatibility ✅ Passed PASS: The changed tests are standard Go unit tests (testing.T), not Ginkgo e2e tests, and they contain no MicroShift-blocked APIs or features.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the changes are utility code plus standard unit tests, with no SNO-assumption patterns present.
Topology-Aware Scheduling Compatibility ✅ Passed Only utility/test files changed; the PR removes a CRD check and updates backup fixtures, with no manifests, replicas, selectors, or scheduling constraints added.
Ote Binary Stdout Contract ✅ Passed Diff only changes backup-resource gating and test fixtures; no main/init/TestMain/RunSpecs or stdout-printing calls in touched files.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the touched files are unit tests and utility logic only, with no IPv4-only assumptions or external connectivity.
No-Weak-Crypto ✅ Passed Touched files only adjust backup selection and test fixtures; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret comparisons were introduced.
Container-Privileges ✅ Passed PR only changes Go logic/tests; diff has no privileged, hostPID, hostNetwork, hostIPC, SYS_ADMIN, or allowPrivilegeEscalation settings.
No-Sensitive-Data-In-Logs ✅ Passed PR only changes HCP resource gating and test fixtures; no new log statements or secret-bearing messages were added.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: skipping plugin execution unless the backup includes HCP resources.
✨ 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.

@openshift-ci

openshift-ci Bot commented Jul 7, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
pkg/common/utils.go (1)

212-221: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Treat * as a match here. Backup.Spec.IncludedResources can legally be ["*"], but this loop only recognizes explicit HCP resource names, so those backups fall through and get skipped. Short-circuit on * (or otherwise handle the all-resources case) so HCP restores still run.

🤖 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 `@pkg/common/utils.go` around lines 212 - 221, The resource filter in the
IncludedResources check currently only matches explicit hostedcluster,
hostedcontrolplane, and nodepool names, so backups configured with "*" are
incorrectly skipped. Update the logic in the loop inside the relevant utils
helper to treat "*" as a valid match for all resources and short-circuit to
allow the restore path, while keeping the existing explicit resource-name checks
intact.
🤖 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.

Outside diff comments:
In `@pkg/common/utils.go`:
- Around line 212-221: The resource filter in the IncludedResources check
currently only matches explicit hostedcluster, hostedcontrolplane, and nodepool
names, so backups configured with "*" are incorrectly skipped. Update the logic
in the loop inside the relevant utils helper to treat "*" as a valid match for
all resources and short-circuit to allow the restore path, while keeping the
existing explicit resource-name checks intact.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 8a6b9ffa-d7bc-4df2-9ee3-9a79cf7e776d

📥 Commits

Reviewing files that changed from the base of the PR and between e9dbba8 and 5fccb61.

📒 Files selected for processing (3)
  • pkg/common/utils.go
  • pkg/core/backup_test.go
  • pkg/core/restore_test.go

@jparrill

Copy link
Copy Markdown
Contributor

/uncc @enxebre

@jparrill

Copy link
Copy Markdown
Contributor

/uncc @sjenning

@jparrill

Copy link
Copy Markdown
Contributor

/cc @jparrill

@openshift-ci openshift-ci Bot requested a review from jparrill July 13, 2026 16:15

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

Dropped some comments. Thanks!

Comment thread pkg/common/utils.go
@@ -222,16 +218,7 @@ func ShouldEndPluginExecution(ctx context.Context, backup *veleroapiv1.Backup, c
}
}

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.

[blocking] The for loop above doesn't handle Velero's wildcard includedResources: ["*"]. The string "*" doesn't contain "hostedcluster", "hostedcontrolplane", or "nodepool", so a backup configured with ["*"] scoped to HC namespaces would be silently skipped.

for _, resource := range backup.Spec.IncludedResources {
    if resource == "*" ||
        strings.Contains(resource, "hostedcluster") ||
        strings.Contains(resource, "hostedcontrolplane") ||
        strings.Contains(resource, "nodepool") {
        return false, nil
    }
}

Comment thread pkg/common/utils.go
}

return true, fmt.Errorf("no HostedControlPlane CRD found")
return true, fmt.Errorf("backup does not include hostedcontrolplane resources")

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.

[suggestion] This returns an error for a normal operational path — an MC-wide backup not targeting HCP resources is expected behavior, not an error condition. Both callers already swallow the error and return nil to Velero, so this doesn't cause PartiallyFailed, but semantically it's cleaner to return nil:

return true, nil

The callers at backup.go:142 and restore.go:167 already log the skip at Info level, so observability is preserved.

Also, after removing the CRD check, ctx, c, and log are unused in this function. Worth simplifying the signature to func ShouldEndPluginExecution(backup *veleroapiv1.Backup) (bool, error) and updating the two callers.

Comment thread pkg/common/utils.go
// Returns true if the plugin should end execution (i.e., if this is not a Hypershift cluster).
// ShouldEndPluginExecution checks whether this backup targets a hosted control
// plane by looking for HCP resource types in the backup's includedResources.
// Returns true (skip) when the backup does not target an HCP.

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.

[nit] The updated comment doesn't mention the namespace-empty check (first guard). Suggestion:

// ShouldEndPluginExecution checks whether this backup targets a hosted control
// plane. It returns true (skip) when no namespaces are provided or when the
// backup's includedResources does not contain HCP resource types.

Comment thread pkg/core/backup_test.go
ObjectMeta: metav1.ObjectMeta{Name: "test-backup", Namespace: "openshift-adp"},
Spec: velerov1.BackupSpec{
IncludedNamespaces: []string{"clusters", "clusters-test"},
IncludedResources: []string{"hostedcontrolplane", "hostedcluster", "nodepool"},

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.

[suggestion] The dedicated tests in utils_test.go:TestShouldEndPluginExecution aren't updated by this PR. The existing test names ("CRD exists", "CRD does not exist") reference removed behavior, and the key scenario — CRD present but includedResources has no HCP types, which is the actual bug — has no coverage.

Worth adding cases for:

  • includedResources with no HCP types (the fix) → returns true
  • includedResources: ["*"] (wildcard) → returns false
  • includedResources: ["nodepool"] alone → returns false
  • includedResources: ["hostedcontrolplanes.hypershift.openshift.io"] (full GVR) → returns false

Also, the []string{"hostedcontrolplane", "hostedcluster", "nodepool"} slice is repeated 4 times across backup and restore tests — a shared test-level var would reduce duplication.

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

Labels

do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. jira/invalid-bug Indicates that a referenced Jira bug is invalid 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.

3 participants