Skip to content

Add DR migration labels and annotations for ZTP resources#2388

Open
ldpliu wants to merge 1 commit intostolostron:mainfrom
ldpliu:fix-dr-migration
Open

Add DR migration labels and annotations for ZTP resources#2388
ldpliu wants to merge 1 commit intostolostron:mainfrom
ldpliu:fix-dr-migration

Conversation

@ldpliu
Copy link
Copy Markdown
Contributor

@ldpliu ldpliu commented Apr 8, 2026

Summary

  • Add velero.io/restore-status annotation to ImageClusterInstall resources
  • Add cluster.open-cluster-management.io/backup label to BareMetalHost resources
  • Validate both key and value when setting labels/annotations during migration

Changes

Agent (agent/pkg/spec/migration/migration_from_syncer.go)

Constants Added:

  • VeleroRestoreStatusAnnotation = "velero.io/restore-status"
  • ClusterBackupLabel = "cluster.open-cluster-management.io/backup"
  • ClusterActivationBackup = "cluster-activation"

ImageClusterInstall Processing:

  • Add velero.io/restore-status: "true" annotation to prevent image-based-install-operator reconciliation
  • Add velero.io/restore-name: globalhub label (existing, now validates value)
  • Check both key existence AND value correctness

BareMetalHost Processing:

  • Add cluster.open-cluster-management.io/backup: cluster-activation label
  • Ensures resources are included in cluster activation backups
  • Separated from DataImage case for clearer logic
  • Check label value, not just existence

Why These Changes

velero.io/restore-status annotation:
The image-based-install-operator checks for this annotation to determine if a resource was restored by Velero during DR recovery. Without it, the operator may attempt to reconcile ImageClusterInstall resources inappropriately during migration, causing conflicts.

cluster.open-cluster-management.io/backup label:
This label marks BareMetalHost resources for inclusion in cluster activation backup workflows, ensuring they're properly captured during DR scenarios.

Value validation:
Previously, the code only checked if keys existed. Now it validates values match expected constants, preventing issues where resources have the annotation/label but with incorrect values.

Test plan

  • Unit tests pass: make unit-tests-agent
  • Migration E2E tests verify labels/annotations are set correctly
  • ImageClusterInstall resources have both label and annotation
  • BareMetalHost resources have backup label with correct value
  • Existing migrations continue to work without issues

Related Issues

https://issues.redhat.com/browse/ACM-32454

🤖 Generated with Claude Code

Signed-off-by: daliu@redhat.com

Summary by CodeRabbit

  • Bug Fixes

    • Improved migration handling to correctly set/remove backup labels and pause annotations per resource type.
    • Consistently enforce the standardized restore name and add a restore-status annotation to improve restore tracking and visibility.
  • Tests

    • Updated unit tests to reflect the revised migration behaviors and annotation/label expectations.

@openshift-ci
Copy link
Copy Markdown

openshift-ci bot commented Apr 8, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

@ldpliu
Copy link
Copy Markdown
Contributor Author

ldpliu commented Apr 8, 2026

Related Jira Issues:

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 8, 2026

📝 Walkthrough

Walkthrough

Split combined handling of BareMetalHost/DataImage into separate cases; BareMetalHost now ensures a cluster-backup label and both kinds remove pause annotation; ImageClusterInstall now sets Velero restore name and a velero restore-status annotation; three new constants were added.

Changes

Cohort / File(s) Summary
Migration Logic Updates
agent/pkg/spec/migration/migration_from_syncer.go
Split BareMetalHost and DataImage handling into separate cases. Both remove Metal3PauseAnnotation when present. BareMetalHost ensures label cluster.open-cluster-management.io/backup = cluster-activation if not already set. ImageClusterInstall sets VeleroRestoreNameLabel to globalhub unless already equal and sets velero.io/restore-status = "true" (initializes annotations map if nil). Added constants: VeleroRestoreStatusAnnotation, ClusterBackupLabel, ClusterActivationBackup.
Tests Updated
agent/pkg/spec/migration/migration_from_syncer_test.go
Updated TestProcessResourceByType expectations: added backup label expectation for BareMetalHost; extended ImageClusterInstall cases to expect velero.io/restore-status and adjustments to restore-name handling and preservation of user-provided fields.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐇 I nudged some labels, nudged annotations true,

Split hosts from images in a hop or two,
Backups now wear tidy names,
Restores glow with tiny claims —
A rabbit's patch, clean and new 🌱

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Add DR migration labels and annotations for ZTP resources' is directly related to the main change in the changeset, which adds labels and annotations for disaster-recovery migration.
Description check ✅ Passed The description covers the main changes, includes a detailed summary, explains the rationale, provides a test plan, and references the related issue, though it doesn't follow the repository template structure.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ 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.

@ldpliu ldpliu force-pushed the fix-dr-migration branch from e285540 to 46f87e0 Compare April 8, 2026 08:52
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

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

Inline comments:
In `@agent/pkg/spec/migration/migration_from_syncer.go`:
- Around line 65-72: The const block with VeleroRestoreStatusAnnotation,
ClusterBackupLabel, GlobalHubRestoreName, and ClusterActivationBackup is not
formatted to gofumpt's rules; run gofumpt (or make strict-fmt) on
agent/pkg/spec/migration/migration_from_syncer.go to reformat that const block
so the constants and their values follow gofumpt alignment/spacing rules (or
manually adjust the spacing within the const (...) group to match gofumpt's
output). Ensure the names VeleroRestoreStatusAnnotation, ClusterBackupLabel,
GlobalHubRestoreName, and ClusterActivationBackup remain unchanged.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: ce1cb351-9a06-4623-abf1-21b25f95ec5b

📥 Commits

Reviewing files that changed from the base of the PR and between a77c35a and e285540.

📒 Files selected for processing (1)
  • agent/pkg/spec/migration/migration_from_syncer.go

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
agent/pkg/spec/migration/migration_from_syncer.go (2)

68-72: Reuse the shared backup label constants.

pkg/constants/constants.go:38-42 already defines this backup key/value pair. Re-declaring it here creates a second contract to keep in sync in a path that now depends on exact string matches.

♻️ Proposed cleanup
-	// ClusterBackupLabel marks resources for cluster activation backup.
-	ClusterBackupLabel = "cluster.open-cluster-management.io/backup"
-
-	GlobalHubRestoreName    = "globalhub"
-	ClusterActivationBackup = "cluster-activation"
+	GlobalHubRestoreName = "globalhub"
-		if labels[ClusterBackupLabel] != ClusterActivationBackup {
-			labels[ClusterBackupLabel] = ClusterActivationBackup
+		if labels[constants.BackupKey] != constants.BackupActivationValue {
+			labels[constants.BackupKey] = constants.BackupActivationValue
 		}

Also applies to: 458-465

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@agent/pkg/spec/migration/migration_from_syncer.go` around lines 68 - 72,
Remove the duplicate ClusterBackupLabel constant declaration in
migration_from_syncer.go and any other re-declared backup key/value (e.g.,
ClusterBackupLabel and ClusterActivationBackup at the other location) and
replace usages with the shared definitions from the package that holds the
canonical constants (pkg/constants/constants.go); update imports to reference
that constants package and use constants.ClusterBackupLabel (and the
corresponding shared name for the activation backup constant) throughout so
there is a single source of truth.

450-466: Add regression tests for the exact-value cases.

This change is only different when labels/annotations are nil or when the key already exists with the wrong value. A small table-driven test around processResourceByType would lock down the new BareMetalHost and ImageClusterInstall behavior.

Also applies to: 474-493

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@agent/pkg/spec/migration/migration_from_syncer.go` around lines 450 - 466,
Add table-driven regression tests for processResourceByType covering
BareMetalHost and ImageClusterInstall to lock behavior when annotations/labels
are nil, when keys already exist with correct values, and when keys exist with
wrong values; for each case create a resource object with initial Annotations
and Labels (nil, correct, wrong), call processResourceByType (or the exposed
wrapper that applies the migration), then assert that Metal3PauseAnnotation is
removed from Annotations and that ClusterBackupLabel equals
ClusterActivationBackup (or remains correct) and other keys are unchanged.
Include cases where annotations/labels are nil to ensure
SetAnnotations/SetLabels are called and existing wrong values are overwritten
while correct values are preserved.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@agent/pkg/spec/migration/migration_from_syncer.go`:
- Around line 68-72: Remove the duplicate ClusterBackupLabel constant
declaration in migration_from_syncer.go and any other re-declared backup
key/value (e.g., ClusterBackupLabel and ClusterActivationBackup at the other
location) and replace usages with the shared definitions from the package that
holds the canonical constants (pkg/constants/constants.go); update imports to
reference that constants package and use constants.ClusterBackupLabel (and the
corresponding shared name for the activation backup constant) throughout so
there is a single source of truth.
- Around line 450-466: Add table-driven regression tests for
processResourceByType covering BareMetalHost and ImageClusterInstall to lock
behavior when annotations/labels are nil, when keys already exist with correct
values, and when keys exist with wrong values; for each case create a resource
object with initial Annotations and Labels (nil, correct, wrong), call
processResourceByType (or the exposed wrapper that applies the migration), then
assert that Metal3PauseAnnotation is removed from Annotations and that
ClusterBackupLabel equals ClusterActivationBackup (or remains correct) and other
keys are unchanged. Include cases where annotations/labels are nil to ensure
SetAnnotations/SetLabels are called and existing wrong values are overwritten
while correct values are preserved.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 03fd5fbd-79e9-4ff6-9851-ab1cae5f10e5

📥 Commits

Reviewing files that changed from the base of the PR and between e285540 and 46f87e0.

📒 Files selected for processing (1)
  • agent/pkg/spec/migration/migration_from_syncer.go

Enhance migration support for disaster recovery scenarios:
- Add velero.io/restore-status annotation to ImageClusterInstall
- Add cluster.open-cluster-management.io/backup label to BareMetalHost
- Validate both key and value when setting labels/annotations

The velero.io/restore-status annotation prevents the image-based-install-operator
from reconciling ImageClusterInstall resources during DR recovery. The backup label
ensures BareMetalHost resources are included in cluster activation backups.

Both checks now validate the value matches expected constants, not just key existence,
ensuring correct DR configuration even if resources have incorrect values.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Signed-off-by: daliu@redhat.com
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@ldpliu ldpliu force-pushed the fix-dr-migration branch from 46f87e0 to f3b3e96 Compare April 8, 2026 10:21
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
agent/pkg/spec/migration/migration_from_syncer.go (1)

68-72: Use existing constants from pkg/constants/constants.go instead of redefining them.

ClusterBackupLabel and ClusterActivationBackup duplicate BackupKey and BackupActivationValue already defined in pkg/constants/constants.go. Having two sources of truth for the same values creates maintenance burden and risks drift if one is updated but not the other.

Replace the local definitions with an import and use constants.BackupKey and constants.BackupActivationValue at lines 463-464, consistent with how the rest of the codebase handles these constants.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@agent/pkg/spec/migration/migration_from_syncer.go` around lines 68 - 72,
Remove the duplicated local constants ClusterBackupLabel and
ClusterActivationBackup and replace all uses with the canonical constants from
the shared package: import the constants package (e.g., import "pkg/constants"
as constants) and use constants.BackupKey instead of ClusterBackupLabel and
constants.BackupActivationValue instead of ClusterActivationBackup; also delete
the local constant declarations so there is a single source of truth.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@agent/pkg/spec/migration/migration_from_syncer.go`:
- Around line 68-72: Remove the duplicated local constants ClusterBackupLabel
and ClusterActivationBackup and replace all uses with the canonical constants
from the shared package: import the constants package (e.g., import
"pkg/constants" as constants) and use constants.BackupKey instead of
ClusterBackupLabel and constants.BackupActivationValue instead of
ClusterActivationBackup; also delete the local constant declarations so there is
a single source of truth.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 378bb1cc-b150-4e86-a900-2176d00dcb0b

📥 Commits

Reviewing files that changed from the base of the PR and between 46f87e0 and f3b3e96.

📒 Files selected for processing (2)
  • agent/pkg/spec/migration/migration_from_syncer.go
  • agent/pkg/spec/migration/migration_from_syncer_test.go

@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 8, 2026

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant