Skip to content

Conversation

@RadekManak
Copy link
Contributor

@RadekManak RadekManak commented Oct 3, 2025

Why:

Adds .status.synchronizedAPI field to Machine and MachineSet resources to enable reliable migration cancellation when migrations get stuck at status.authoritativeAPI: Migrating. Without this field, the system cannot determine which API was the migration source when users revert spec.authoritativeAPI, preventing proper rollback to the last known good state. Implements OCPCLOUD-2998.

What:

  • Adds .status.synchronizedAPI field (values: "" | MachineAPI | ClusterAPI) to track the last successfully synchronized API
  • Implements handleMigrationStatusInitialization() in migration controllers to bootstrap empty status fields with proper inference logic
  • Adds IsMigrationCancellationRequested() detection when spec.authoritativeAPI matches status.synchronizedAPI while status.authoritativeAPI == Migrating
  • Updates ApplyMigrationStatus() helpers to atomically set both authoritativeAPI and synchronizedAPI during state transitions

How can it be used:

Administrators can cancel stuck migrations by reverting spec.authoritativeAPI back to the previously synchronized state:

# Migration stuck in progress
status:
  authoritativeAPI: Migrating
  synchronizedAPI: MachineAPI  # Last good state

# Cancel by reverting spec
spec:
  authoritativeAPI: MachineAPI  # Matches synchronizedAPI

# System detects cancellation and rolls back
status:
  authoritativeAPI: MachineAPI
  synchronizedAPI: MachineAPI

The migration controller detects this pattern and transitions back to the synchronized state without requiring manual intervention.

How did you test it:

Unit tests cover status initialization scenarios (both fields empty, only one empty, mid-migration inference), migration cancellation detection logic, and rollback flows.

Adds e2e tests to verify field behavior during migrations.

Notes for the reviewer:

Requires companion PR openshift/machine-api-operator#1442 for API definition vendoring. This PR description was generated with AI assistance.

Summary by CodeRabbit

  • New Features

    • Added migration cancellation capability to rollback in-progress API migrations to the previous authoritative state
    • Enhanced tracking of API synchronization status during migration operations
  • Tests

    • Added comprehensive test coverage for migration cancellation and rollback scenarios
    • Expanded synchronization verification tests across multiple migration contexts
  • Chores

    • Updated dependencies

✏️ Tip: You can customize this high-level summary in your review settings.

@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 Oct 3, 2025
@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 3, 2025

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-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 3, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 3, 2025

Walkthrough

This PR introduces SynchronizedAPI status field tracking for machine and machineset migrations, enabling migration cancellation/rollback capabilities. Status patching methods are refactored to atomically update both AuthoritativeAPI and SynchronizedAPI fields. A migration cancellation detector and state-converter utility are added, alongside extensive test coverage for new migration scenarios including rollback, initialization, and edge cases.

Changes

Cohort / File(s) Summary
Dependency Updates
go.mod, e2e/go.mod
Bumps github.com/openshift/api to v0.0.0-20251202143230-02f6733e651c and adds replace directives for OpenShift module forks.
Machine Migration E2E Tests & Helpers
e2e/machine_migration_capi_authoritative_test.go, e2e/machine_migration_mapi_authoritative_test.go, e2e/machine_migration_helpers.go
Adds verification helpers verifyMachineMigrating and verifyMachineSynchronizedAPI; inserts synchronization API assertions across CAPI/MAPI scenarios; introduces "Machine Migration Rollback Tests" suite validating migration cancellation, state preservation, and cleanup.
MachineSet Migration E2E Tests & Helpers
e2e/machineset_migration_capi_authoritative_test.go, e2e/machineset_migration_mapi_authoritative_test.go, e2e/machineset_migration_helpers.go
Adds verifyMachineSetSynchronizedAPI helper; augments test flows with additional API synchronization assertions during authoritative API switches.
Machine Migration Controller
pkg/controllers/machinemigration/machine_migration_controller.go
Delegates initialization to handleMigrationStatusInitialization for consistent AuthoritativeAPI/SynchronizedAPI initialization; introduces migration cancellation detection and rollback steps; refactors status patching via applyMigrationStatusWithPatch and applyMigrationStatusAndResetSyncStatusWithPatch (replaces applyStatusAuthoritativeAPIWithPatch).
Machine Migration Controller Tests
pkg/controllers/machinemigration/machine_migration_controller_test.go
Expands test coverage to verify SynchronizedAPI field across all migration states; adds migration cancellation scenarios (rollback to MachineAPI/ClusterAPI); covers empty-status initialization edge cases.
MachineSet Migration Controller
pkg/controllers/machinesetmigration/machineset_migration_controller.go
Parallels machine migration controller: adds handleMigrationStatusInitialization, migration cancellation handling, and refactored status patching methods (applyMigrationStatusWithPatch, applyMigrationStatusAndResetSyncStatusWithPatch).
MachineSet Migration Controller Tests
pkg/controllers/machinesetmigration/machineset_migration_controller_test.go
Updates tests to initialize and verify SynchronizedAPI alongside AuthoritativeAPI; introduces migration cancellation contexts; validates state restoration and pausing/unpausing behavior.
Sync Controllers
pkg/controllers/machinesync/machine_sync_controller.go, pkg/controllers/machinesetsync/machineset_sync_controller.go
Preserves SynchronizedAPI field during status field synchronization (mirrors existing SynchronizedGeneration and AuthoritativeAPI preservation).
Status Application Common
pkg/controllers/synccommon/applyconfiguration.go, pkg/controllers/synccommon/migratestatus.go
Adds WithSynchronizedAPI method to syncStatusApplyConfiguration interface; renames ApplyAuthoritativeAPIApplyMigrationStatus and ApplyAuthoritativeAPIAndResetSyncStatusApplyMigrationStatusAndResetSyncStatus with new synchronizedAPI parameters; introduces IsMigrationCancellationRequested and AuthoritativeAPIToSynchronizedAPI utility functions.
Sync Common Tests
pkg/controllers/synccommon/migratestatus_test.go, pkg/controllers/synccommon/suite_test.go
Adds Ginkgo test suite for synccommon package with tabular tests for IsMigrationCancellationRequested covering multiple cancellation scenarios.
Fuzzing
pkg/conversion/test/fuzz/fuzz.go
Sets SynchronizedAPI to empty string in MAPIMachine and MachineSet fuzzers (marked as not present in CAPI).

Sequence Diagram

sequenceDiagram
    participant Reconciler as MachineMigrationReconciler
    participant OldAuth as Old Authoritative<br/>(Source)
    participant NewAuth as New Authoritative<br/>(Target)
    participant StatusPatch as Status Patch
    
    Note over Reconciler: Migration Cancellation Flow
    Reconciler->>Reconciler: Detect IsMigrationCancellationRequested()
    Reconciler->>NewAuth: ensureUnpauseRequestedOnNewAuthoritativeResource()
    NewAuth-->>Reconciler: Confirm unpause initiated
    Reconciler->>OldAuth: Capture current AuthoritativeAPI
    Reconciler->>Reconciler: AuthoritativeAPIToSynchronizedAPI(OldAuth)
    Reconciler->>StatusPatch: applyMigrationStatusWithPatch(<br/>authority=SynchronizedAPI,<br/>synchronizedAPI=OldAuth)
    StatusPatch-->>Reconciler: Status patched
    Reconciler->>Reconciler: Log: Migration cancelled,<br/>reverted to previous authority
    rect rgba(100, 200, 100, 0.2)
        Note over Reconciler,StatusPatch: Result: Resource returns to<br/>previous authoritative state
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~40 minutes

  • Migration cancellation logic in machine_migration_controller.go and machineset_migration_controller.go — verify requeue behavior, state transitions, and unpause timing
  • Status initialization handler (handleMigrationStatusInitialization) — ensure both AuthoritativeAPI and SynchronizedAPI are consistently initialized across edge cases
  • State-transition assertions in new E2E rollback tests — validate rollback semantics, AWS resource cleanup, and map consistency
  • Status patching refactor — confirm applyMigrationStatusWithPatch and applyMigrationStatusAndResetSyncStatusWithPatch correctly update both fields atomically
  • Test coverage for cancellation scenarios — review cascading contexts in controller tests for proper setup and expectation validation

Poem

🐰 A hop, skip, and a migration dance,
With synchronized states given a second chance,
When rollbacks are needed, we smoothly revert,
Both API and authority, no wires crossed or hurt! 🎉

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'OCPCLOUD-2998: implement synchronizedAPI' directly and clearly summarizes the main change: implementing a new synchronizedAPI feature, with the Jira reference providing context.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Oct 3, 2025

[APPROVALNOTIFIER] This PR is NOT APPROVED

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

@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Oct 6, 2025
@damdo damdo changed the title Draft: implement synchronizedAPI OCPCLOUD-2998: Draft: implement synchronizedAPI Oct 6, 2025
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Oct 6, 2025
@openshift-ci-robot
Copy link

openshift-ci-robot commented Oct 6, 2025

@RadekManak: This pull request references OCPCLOUD-2998 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

Details

In response to this:

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot
Copy link

openshift-ci-robot commented Dec 4, 2025

@RadekManak: This pull request references OCPCLOUD-2998 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

Details

In response to this:

Why:

Adds .status.synchronizedAPI field to Machine and MachineSet resources to enable reliable migration cancellation when migrations get stuck at status.authoritativeAPI: Migrating. Without this field, the system cannot determine which API was the migration source when users revert spec.authoritativeAPI, preventing proper rollback to the last known good state. Implements OCPCLOUD-2998.

What:

  • Adds .status.synchronizedAPI field (values: "" | MachineAPI | ClusterAPI) to track the last successfully synchronized API
  • Implements handleMigrationStatusInitialization() in migration controllers to bootstrap empty status fields with proper inference logic
  • Adds IsMigrationCancellationRequested() detection when spec.authoritativeAPI matches status.synchronizedAPI while status.authoritativeAPI == Migrating
  • Updates ApplyMigrationStatus() helpers to atomically set both authoritativeAPI and synchronizedAPI during state transitions

How can it be used:

Administrators can cancel stuck migrations by reverting spec.authoritativeAPI back to the previously synchronized state:

# Migration stuck in progress
status:
 authoritativeAPI: Migrating
 synchronizedAPI: MachineAPI  # Last good state

# Cancel by reverting spec
spec:
 authoritativeAPI: MachineAPI  # Matches synchronizedAPI

# System detects cancellation and rolls back
status:
 authoritativeAPI: MachineAPI
 synchronizedAPI: MachineAPI

The migration controller detects this pattern and transitions back to the synchronized state without requiring manual intervention.

How did you test it:

Unit tests cover status initialization scenarios (both fields empty, only one empty, mid-migration inference), migration cancellation detection logic, and rollback flows.

TODO: Add e2e tests to verify field behavior during actual migrations.

Notes for the reviewer:

Requires companion PR openshift/machine-api-operator#1442 for API definition vendoring. This PR description was generated with AI assistance.

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-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Dec 4, 2025
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Dec 5, 2025
…n cancellation

This change introduces the SynchronizedAPI status field to track the last
successfully synchronized API during migrations. The field enables:

- Migration cancellation: Users can cancel an in-progress migration by
  setting spec.AuthoritativeAPI back to match status.SynchronizedAPI,
  allowing rollback to the previously stable state
- Status initialization: Proper handling of empty AuthoritativeAPI or
  SynchronizedAPI status fields during first reconciliation
- Clear migration state tracking: The SynchronizedAPI captures which API
  was authoritative before entering the Migrating state

Key changes:
- Add handleMigrationStatusInitialization for proper status bootstrap
- Add IsMigrationCancellationRequested detection logic
- Update applyMigrationStatusWithPatch to set both status fields atomically
- Add comprehensive tests for cancellation and initialization scenarios
- Update vendor dependencies for SynchronizedAPI type support
@openshift-ci-robot
Copy link

openshift-ci-robot commented Dec 5, 2025

@RadekManak: This pull request references OCPCLOUD-2998 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

Details

In response to this:

Why:

Adds .status.synchronizedAPI field to Machine and MachineSet resources to enable reliable migration cancellation when migrations get stuck at status.authoritativeAPI: Migrating. Without this field, the system cannot determine which API was the migration source when users revert spec.authoritativeAPI, preventing proper rollback to the last known good state. Implements OCPCLOUD-2998.

What:

  • Adds .status.synchronizedAPI field (values: "" | MachineAPI | ClusterAPI) to track the last successfully synchronized API
  • Implements handleMigrationStatusInitialization() in migration controllers to bootstrap empty status fields with proper inference logic
  • Adds IsMigrationCancellationRequested() detection when spec.authoritativeAPI matches status.synchronizedAPI while status.authoritativeAPI == Migrating
  • Updates ApplyMigrationStatus() helpers to atomically set both authoritativeAPI and synchronizedAPI during state transitions

How can it be used:

Administrators can cancel stuck migrations by reverting spec.authoritativeAPI back to the previously synchronized state:

# Migration stuck in progress
status:
 authoritativeAPI: Migrating
 synchronizedAPI: MachineAPI  # Last good state

# Cancel by reverting spec
spec:
 authoritativeAPI: MachineAPI  # Matches synchronizedAPI

# System detects cancellation and rolls back
status:
 authoritativeAPI: MachineAPI
 synchronizedAPI: MachineAPI

The migration controller detects this pattern and transitions back to the synchronized state without requiring manual intervention.

How did you test it:

Unit tests cover status initialization scenarios (both fields empty, only one empty, mid-migration inference), migration cancellation detection logic, and rollback flows.

Adds e2e tests to verify field behavior during migrations.

Notes for the reviewer:

Requires companion PR openshift/machine-api-operator#1442 for API definition vendoring. This PR description was generated with AI assistance.

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.

@RadekManak RadekManak changed the title OCPCLOUD-2998: Draft: implement synchronizedAPI OCPCLOUD-2998: implement synchronizedAPI Dec 5, 2025
@RadekManak RadekManak marked this pull request as ready for review December 5, 2025 15:49
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Dec 5, 2025
@openshift-ci openshift-ci bot requested review from damdo and mdbooth December 5, 2025 15:49
@openshift-ci-robot
Copy link

openshift-ci-robot commented Dec 5, 2025

@RadekManak: This pull request references OCPCLOUD-2998 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "4.21.0" version, but no target version was set.

Details

In response to this:

Why:

Adds .status.synchronizedAPI field to Machine and MachineSet resources to enable reliable migration cancellation when migrations get stuck at status.authoritativeAPI: Migrating. Without this field, the system cannot determine which API was the migration source when users revert spec.authoritativeAPI, preventing proper rollback to the last known good state. Implements OCPCLOUD-2998.

What:

  • Adds .status.synchronizedAPI field (values: "" | MachineAPI | ClusterAPI) to track the last successfully synchronized API
  • Implements handleMigrationStatusInitialization() in migration controllers to bootstrap empty status fields with proper inference logic
  • Adds IsMigrationCancellationRequested() detection when spec.authoritativeAPI matches status.synchronizedAPI while status.authoritativeAPI == Migrating
  • Updates ApplyMigrationStatus() helpers to atomically set both authoritativeAPI and synchronizedAPI during state transitions

How can it be used:

Administrators can cancel stuck migrations by reverting spec.authoritativeAPI back to the previously synchronized state:

# Migration stuck in progress
status:
 authoritativeAPI: Migrating
 synchronizedAPI: MachineAPI  # Last good state

# Cancel by reverting spec
spec:
 authoritativeAPI: MachineAPI  # Matches synchronizedAPI

# System detects cancellation and rolls back
status:
 authoritativeAPI: MachineAPI
 synchronizedAPI: MachineAPI

The migration controller detects this pattern and transitions back to the synchronized state without requiring manual intervention.

How did you test it:

Unit tests cover status initialization scenarios (both fields empty, only one empty, mid-migration inference), migration cancellation detection logic, and rollback flows.

Adds e2e tests to verify field behavior during migrations.

Notes for the reviewer:

Requires companion PR openshift/machine-api-operator#1442 for API definition vendoring. This PR description was generated with AI assistance.

Summary by CodeRabbit

  • New Features

  • Added migration cancellation capability to rollback in-progress API migrations to the previous authoritative state

  • Enhanced tracking of API synchronization status during migration operations

  • Tests

  • Added comprehensive test coverage for migration cancellation and rollback scenarios

  • Expanded synchronization verification tests across multiple migration contexts

  • Chores

  • Updated dependencies

✏️ Tip: You can customize this high-level summary in your review settings.

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.

Copy link

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

🧹 Nitpick comments (3)
e2e/machine_migration_mapi_authoritative_test.go (1)

207-287: Excellent rollback test coverage!

The new "Machine Migration Rollback Tests" comprehensively test the cancellation workflow:

  1. Initial state verification
  2. Rollback from Migrating state back to MachineAPI
  3. Successful migration after a previous rollback
  4. Cleanup verification

One structural note: This Describe block is nested inside the "Machine Migration Round Trip Tests" Describe (line 136). While Ginkgo supports this, it may be cleaner to place this as a sibling Describe block rather than a child, for better test organization. However, this is a minor style preference and doesn't affect test execution.

Consider moving this Describe block to be a sibling of "Machine Migration Round Trip Tests" rather than nested inside it:

-	var _ = Describe("Machine Migration Round Trip Tests", Ordered, func() {
-		// ... existing round trip tests ...
-
-		var _ = Describe("Machine Migration Rollback Tests", Ordered, func() {
+	var _ = Describe("Machine Migration Round Trip Tests", Ordered, func() {
+		// ... existing round trip tests ...
+	})
+
+	var _ = Describe("Machine Migration Rollback Tests", Ordered, func() {
pkg/controllers/synccommon/migratestatus.go (1)

129-142: Consider handling unknown authority values explicitly.

The function correctly maps MachineAPI and ClusterAPI to their synchronized counterparts and returns empty string for Migrating. However, the default case silently returns empty string for any unknown values.

Consider whether logging a warning for unknown values would aid debugging, or if the empty string fallback is intentional for forward compatibility.

 	case mapiv1beta1.MachineAuthorityMigrating:
 		return ""
 	default:
+		// Unknown authority values return empty string.
+		// This provides forward compatibility if new authority values are added.
 		return ""
 	}
pkg/controllers/machinemigration/machine_migration_controller.go (1)

230-277: Consider extracting shared initialization logic to reduce duplication.

The handleMigrationStatusInitialization function is identical to the one in MachineSetMigrationReconciler. While the duplication is understandable given the different resource types and apply configurations, consider whether a shared helper could be created in synccommon package using generics, similar to the existing ApplyMigrationStatus pattern.

This is a minor refactor suggestion for future maintainability - not blocking.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between 20a3c13 and 7488790.

⛔ Files ignored due to path filters (83)
  • e2e/go.sum is excluded by !**/*.sum
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/openshift/api/config/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_insights.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_node.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_scheduling.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_00_cluster-version-operator_01_clusterversions-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_images.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_infrastructures-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_insightsdatagathers-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_insightsdatagathers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_insightsdatagathers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_schedulers-Hypershift.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_schedulers-SelfManagedHA-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_schedulers-SelfManagedHA-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_schedulers-SelfManagedHA-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.crd-manifests/0000_10_config-operator_01_schedulers-SelfManagedHA-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/types_cluster_monitoring.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1alpha1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/types.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/console/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features/features.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_awsprovider.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_machine.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/types_machineset.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.crd-manifests/0000_10_machine-api_01_machines-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.crd-manifests/0000_10_machine-api_01_machines-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.crd-manifests/0000_10_machine-api_01_machines-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.crd-manifests/0000_10_machine-api_01_machinesets-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.crd-manifests/0000_10_machine-api_01_machinesets-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.crd-manifests/0000_10_machine-api_01_machinesets-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/machine/v1beta1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/openapi/generated_openapi/zz_generated.openapi.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/types_ingress.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/awsplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/azureplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/baremetalplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/custom.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gatherconfig.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gathererconfig.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gatherers.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gcpplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/gcpserviceendpoint.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/insightsdatagather.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/insightsdatagatherspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/nutanixplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/openstackplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/ovirtplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/persistentvolumeclaimreference.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/persistentvolumeconfig.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/storage.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/config/v1/vsphereplatformstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/applyconfigurations/internal/internal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/clientset/versioned/typed/config/v1/config_client.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/clientset/versioned/typed/config/v1/generated_expansion.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/clientset/versioned/typed/config/v1/insightsdatagather.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/insightsdatagather.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/informers/externalversions/config/v1/interface.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/informers/externalversions/generic.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/listers/config/v1/expansion_generated.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/config/listers/config/v1/insightsdatagather.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/machine/applyconfigurations/machine/v1beta1/machinesetstatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/machine/applyconfigurations/machine/v1beta1/machinestatus.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/operator/applyconfigurations/internal/internal.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/ingresscontrollerspec.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/client-go/operator/applyconfigurations/operator/v1/ingresscontrollertuningoptions.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1/machine.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/cluster-api-actuator-pkg/testutils/resourcebuilder/machine/v1beta1/machineset.go is excluded by !**/vendor/**, !vendor/**
  • vendor/modules.txt is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (19)
  • e2e/go.mod (1 hunks)
  • e2e/machine_migration_capi_authoritative_test.go (3 hunks)
  • e2e/machine_migration_helpers.go (2 hunks)
  • e2e/machine_migration_mapi_authoritative_test.go (4 hunks)
  • e2e/machineset_migration_capi_authoritative_test.go (2 hunks)
  • e2e/machineset_migration_helpers.go (1 hunks)
  • e2e/machineset_migration_mapi_authoritative_test.go (3 hunks)
  • go.mod (2 hunks)
  • pkg/controllers/machinemigration/machine_migration_controller.go (4 hunks)
  • pkg/controllers/machinemigration/machine_migration_controller_test.go (16 hunks)
  • pkg/controllers/machinesetmigration/machineset_migration_controller.go (4 hunks)
  • pkg/controllers/machinesetmigration/machineset_migration_controller_test.go (16 hunks)
  • pkg/controllers/machinesetsync/machineset_sync_controller.go (1 hunks)
  • pkg/controllers/machinesync/machine_sync_controller.go (1 hunks)
  • pkg/controllers/synccommon/applyconfiguration.go (1 hunks)
  • pkg/controllers/synccommon/migratestatus.go (2 hunks)
  • pkg/controllers/synccommon/migratestatus_test.go (1 hunks)
  • pkg/controllers/synccommon/suite_test.go (1 hunks)
  • pkg/conversion/test/fuzz/fuzz.go (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
pkg/controllers/synccommon/migratestatus_test.go (1)
pkg/controllers/synccommon/migratestatus.go (1)
  • IsMigrationCancellationRequested (121-127)
pkg/controllers/machinesetmigration/machineset_migration_controller_test.go (2)
e2e/migration_common.go (1)
  • SynchronizedCondition (10-10)
pkg/controllers/common_consts.go (1)
  • SynchronizedCondition (41-41)
e2e/machine_migration_mapi_authoritative_test.go (3)
pkg/conversion/mapi2capi/interface.go (1)
  • Machine (24-26)
e2e/framework/machine.go (2)
  • GetMachine (75-86)
  • DeleteMachines (89-119)
e2e/framework/framework.go (1)
  • CAPINamespace (14-14)
pkg/controllers/machinemigration/machine_migration_controller.go (1)
pkg/controllers/synccommon/migratestatus.go (4)
  • IsMigrationCancellationRequested (121-127)
  • AuthoritativeAPIToSynchronizedAPI (131-142)
  • ApplyMigrationStatus (63-79)
  • ApplyMigrationStatusAndResetSyncStatus (42-60)
e2e/machine_migration_helpers.go (1)
e2e/framework/framework.go (2)
  • WaitMedium (24-24)
  • RetryMedium (18-18)
pkg/controllers/machinesetmigration/machineset_migration_controller.go (2)
pkg/controllers/synccommon/migratestatus.go (4)
  • IsMigrationCancellationRequested (121-127)
  • ApplyMigrationStatus (63-79)
  • AuthoritativeAPIToSynchronizedAPI (131-142)
  • ApplyMigrationStatusAndResetSyncStatus (42-60)
pkg/conversion/mapi2capi/interface.go (1)
  • MachineSet (29-31)
e2e/machineset_migration_helpers.go (2)
pkg/conversion/mapi2capi/interface.go (1)
  • MachineSet (29-31)
e2e/framework/framework.go (2)
  • WaitMedium (24-24)
  • RetryMedium (18-18)
🔇 Additional comments (58)
pkg/conversion/test/fuzz/fuzz.go (2)

736-736: LGTM! Correct handling of MAPI-only field in roundtrip testing.

The change properly clears the SynchronizedAPI field during fuzzing to ensure roundtrip conversion tests pass, since this field has no CAPI equivalent and would be lost during MAPI→CAPI→MAPI conversion. The implementation follows the established pattern for other MAPI-only fields like AuthoritativeAPI and SynchronizedGeneration.


783-783: LGTM! Consistent handling across MachineSet fuzzing.

The change correctly clears the SynchronizedAPI field for MachineSet status, mirroring the implementation for Machine status (line 736). This ensures consistent behavior across both resource types during roundtrip conversion testing.

e2e/go.mod (1)

19-19: LGTM! Dependency version aligned with root module.

The openshift/api version is correctly aligned with the root go.mod (line 26), ensuring consistency across the e2e test module and main module.

pkg/controllers/synccommon/applyconfiguration.go (1)

44-44: LGTM! Interface extension follows established pattern.

The new WithSynchronizedAPI method follows the same design pattern as the existing interface methods (WithConditions, WithSynchronizedGeneration, WithAuthoritativeAPI), maintaining consistency in the fluent API design.

pkg/controllers/machinesync/machine_sync_controller.go (1)

1547-1547: LGTM! Proper status field preservation.

The SynchronizedAPI field is correctly preserved from the existing machine status, following the same pattern as AuthoritativeAPI (line 1545) and SynchronizedGeneration (line 1546). This ensures the synchronization state is maintained during status updates.

pkg/controllers/synccommon/migratestatus_test.go (1)

26-74: LGTM! Comprehensive test coverage for migration cancellation logic.

The test table covers all the key scenarios for detecting migration cancellation:

  • Both directions of cancellation (ClusterAPI → MachineAPI and vice versa)
  • In-progress migrations that should NOT trigger cancellation
  • Pre-migration states that should NOT trigger cancellation

The test structure follows Ginkgo best practices with descriptive entry names and clear expectations.

pkg/controllers/synccommon/suite_test.go (1)

26-29: LGTM! Standard test suite setup.

The test suite follows the standard Ginkgo/Gomega pattern for test registration, correctly setting up the fail handler and naming the suite "SyncCommon Suite".

e2e/machineset_migration_helpers.go (1)

221-228: LGTM! Helper function follows established patterns.

The new verifyMachineSetSynchronizedAPI helper is well-designed:

  • Mirrors the structure of verifyMachineSetAuthoritative (lines 95-101)
  • Uses appropriate timeouts (WaitMedium, RetryMedium) consistent with similar assertions in the file
  • Provides clear assertion messages for test failures
e2e/machineset_migration_capi_authoritative_test.go (2)

169-169: LGTM! Appropriate synchronization verification after authority switch.

The addition of verifyMachineSetSynchronizedAPI correctly validates that after switching the MachineSet authority to MachineAPI (line 165), the synchronization status reflects MachineAPISynchronized. This aligns with the PR's objective of tracking the last successfully synchronized API.


208-208: LGTM! Complete test coverage for bidirectional migration.

The verification at line 208 properly validates the synchronization state after switching back to ClusterAPI authority (line 204), ensuring ClusterAPISynchronized is set. Together with the verification at line 169, this provides complete coverage for both migration directions.

go.mod (1)

5-11: Ensure temporary replace directives are tracked for removal.

The TODO comment and temporary replace directives in go.mod (lines 5-11) reference changes that should be reverted when companion PRs are merged. Verify that removal of these replacements is tracked via linked GitHub issues, PR dependencies, or a dedicated tracking mechanism beyond the inline TODO comment, to ensure they don't persist longer than necessary. Consider updating the TODO with specific issue numbers or PR links if not already linked.

e2e/machine_migration_helpers.go (2)

163-171: LGTM! Well-structured helper function.

The verifyMachineMigrating helper correctly uses SatisfyAll to verify both the Migrating state and the expected SynchronizedAPI value in a single assertion, following the established patterns in this file.


337-345: LGTM! Consistent implementation.

The verifyMachineSynchronizedAPI helper follows the same pattern as verifyMachineAuthoritative and other verification helpers in the file, using Eventually with komega.Object and appropriate timeouts.

e2e/machine_migration_capi_authoritative_test.go (3)

201-201: LGTM! Appropriate verification placement.

Adding verifyMachineSynchronizedAPI after verifyMachineSynchronizedGeneration provides complete coverage of the synchronization state, ensuring both generation and API are correctly tracked.


213-213: LGTM!

Correctly verifies MachineAPISynchronized after switching authority to MachineAPI.


225-225: LGTM!

Correctly verifies ClusterAPISynchronized after switching back to ClusterAPI.

pkg/controllers/machinesetsync/machineset_sync_controller.go (1)

1101-1104: LGTM! Correct status field preservation.

Preserving SynchronizedAPI alongside SynchronizedGeneration and AuthoritativeAPI ensures consistency during CAPI-to-MAPI synchronization, with these fields being managed separately via applySynchronizedConditionWithPatch.

e2e/machineset_migration_mapi_authoritative_test.go (3)

169-170: LGTM! Comprehensive verification added.

Adding both verifyMachineSetAuthoritative and verifyMachineSetSynchronizedAPI ensures complete state verification after the authority switch.


209-210: LGTM!

Correctly verifies MachineAPI authority and MachineAPISynchronized after switching back.


338-339: LGTM!

Consistent verification pattern for the update context after switching to ClusterAPI.

pkg/controllers/machinemigration/machine_migration_controller_test.go (5)

20-20: LGTM! Good addition for debugging.

Adding cmp package enables clearer diff output in test failure messages, improving debugging experience.


220-226: Good improvement to test assertions.

Using cmp.Diff in the failure message provides detailed comparison output when the test fails, making it easier to identify unexpected changes to the machine object.


777-903: Comprehensive migration cancellation test coverage.

The three cancellation contexts cover the essential scenarios:

  1. Cancelling back to MachineAPI
  2. Cancelling back to ClusterAPI
  3. Cancelling back to ClusterAPI with paused CAPI resources (verifying unpause behavior)

The tests correctly simulate stuck migration states and verify proper status transitions.


905-937: Good edge case coverage for status initialization.

This test verifies the handleMigrationStatusInitialization logic where SynchronizedAPI is empty but AuthoritativeAPI is set, ensuring backward compatibility and proper bootstrapping.


939-977: Important test for SynchronizedAPI preservation.

This test verifies that when transitioning from a stable state (ClusterAPI) to Migrating, the SynchronizedAPI is preserved to enable rollback detection. This is critical for the cancellation mechanism to work correctly.

e2e/machine_migration_mapi_authoritative_test.go (3)

166-166: LGTM!

Correctly verifies MachineAPISynchronized after initial synchronization.


178-178: LGTM!

Correctly verifies ClusterAPISynchronized after switching to ClusterAPI.


190-190: LGTM!

Correctly verifies MachineAPISynchronized after switching back to MachineAPI.

pkg/controllers/machinesetmigration/machineset_migration_controller_test.go (17)

200-211: LGTM - Test setup properly initializes SynchronizedAPI.

The test correctly sets both AuthoritativeAPI and SynchronizedAPI to MachineAPI in the status, matching the expected synchronized state for this scenario.


247-249: LGTM - SynchronizedAPI initialization added to migration request test.

Correctly sets SynchronizedAPI to MachineAPISynchronized when starting a migration from MachineAPI to ClusterAPI.


288-290: LGTM - Proper SynchronizedAPI tracking during MachineAPI→ClusterAPI migration.

Test correctly maintains MachineAPISynchronized as the synchronized state while in Migrating status.


323-330: LGTM - ClusterAPI→MachineAPI migration uses correct synchronized state.

Test properly uses WithSynchronizedAPIStatus(mapiv1beta1.ClusterAPISynchronized) and sets it on the status, reflecting that ClusterAPI was the last synchronized source.


374-391: LGTM - Synchronized state properly tracked during pausing phase.

Test correctly sets SynchronizedAPI to MachineAPISynchronized when testing the pausing flow during MachineAPI→ClusterAPI migration.


430-438: LGTM - ClusterAPI→MachineAPI pause flow correctly sets synchronized state.

Test properly uses ClusterAPISynchronized as the synchronized state when migrating from ClusterAPI to MachineAPI.


496-506: LGTM - Synchronized state properly set for generation mismatch test.

Test correctly uses MachineAPISynchronized when testing the scenario where synchronizedGeneration doesn't match.


537-547: LGTM - ClusterAPI generation mismatch test properly configured.

Test correctly sets ClusterAPISynchronized for the ClusterAPI→MachineAPI generation mismatch scenario.


579-597: LGTM - Complete migration prerequisites test properly configured.

Test correctly sets MachineAPISynchronized for the MachineAPI→ClusterAPI completion scenario with all prerequisites satisfied.


630-634: Verify assertion uses correct SynchronizedAPI value after migration completion.

The test asserts SynchronizedAPI equals ClusterAPISynchronized after migration completes from MachineAPI to ClusterAPI. This is correct since the new authority (ClusterAPI) should also be the new synchronized state.


660-678: LGTM - ClusterAPI→MachineAPI completion test properly configured.

Test correctly sets ClusterAPISynchronized as the starting synchronized state for migration from ClusterAPI to MachineAPI.


702-707: LGTM - Correct assertion for ClusterAPI→MachineAPI migration completion.

Test properly asserts MachineAPISynchronized as the final synchronized state after completing migration to MachineAPI.


711-742: LGTM - Migration cancellation back to MachineAPI test is well-structured.

The test correctly simulates a stuck migration (status Migrating, synchronized to MachineAPI) and verifies that when spec.AuthoritativeAPI matches the synchronized state, the controller detects cancellation and transitions back.


745-776: LGTM - Migration cancellation back to ClusterAPI test is comprehensive.

Test properly verifies rollback to ClusterAPI when spec.AuthoritativeAPI equals ClusterAPI and SynchronizedAPI is ClusterAPISynchronized.


778-820: LGTM - Migration cancellation with paused CAPI resource is well-tested.

Test verifies that when cancelling back to ClusterAPI, the paused CAPI resource gets unpaused. This is important for ensuring the rollback target becomes operational.


823-853: LGTM - Empty SynchronizedAPI initialization test covers important edge case.

Test verifies that when AuthoritativeAPI is set but SynchronizedAPI is empty, the reconciler initializes SynchronizedAPI from AuthoritativeAPI. This handles upgrade scenarios from older versions.


855-891: LGTM - Transition to Migrating preserves SynchronizedAPI correctly.

Test verifies that when transitioning from a stable state (ClusterAPI) to Migrating, the SynchronizedAPI is preserved as ClusterAPISynchronized. This is essential for enabling future cancellation/rollback.

pkg/controllers/synccommon/migratestatus.go (4)

33-60: LGTM - ApplyMigrationStatusAndResetSyncStatus correctly extended to include SynchronizedAPI.

The function now atomically sets both AuthoritativeAPI and SynchronizedAPI while resetting sync status. The call to statusAC.WithSynchronizedAPI(synchronizedAPI) at line 57 ensures the synchronized state is properly included in the patch.


62-79: LGTM - ApplyMigrationStatus correctly extended to include SynchronizedAPI.

The function now properly sets both AuthoritativeAPI and SynchronizedAPI in a single patch operation, ensuring atomicity of the status update.


100-108: LGTM - Comments clarify field ownership management.

The updated comments correctly explain the field ownership semantics and the validation rule requiring synchronizedGeneration reset when changing authoritativeAPI.


116-127: LGTM - IsMigrationCancellationRequested correctly detects rollback intent.

The function properly detects when a user wants to cancel a migration by checking:

  1. Status is Migrating
  2. Spec's AuthoritativeAPI (converted to SynchronizedAPI) matches the current SynchronizedAPI

This correctly identifies when spec.authoritativeAPI has been reverted to the last synchronized state.

pkg/controllers/machinesetmigration/machineset_migration_controller.go (5)

130-158: LGTM - Migration status initialization and cancellation handling are well-implemented.

The code correctly:

  1. Delegates to handleMigrationStatusInitialization for empty status fields
  2. Detects migration cancellation using IsMigrationCancellationRequested
  3. Ensures the rollback target is unpaused before applying the status patch
  4. Provides clear logging for cancellation scenarios

178-182: LGTM - Transition to Migrating correctly captures the source as SynchronizedAPI.

Before entering the Migrating state, the current AuthoritativeAPI is converted to SynchronizedAPI and both are patched atomically. This ensures the source of truth is preserved for potential rollback.


215-222: LGTM - Migration completion correctly updates both AuthoritativeAPI and SynchronizedAPI.

The new synchronized state is derived from the target authority, and both fields are updated atomically while resetting the sync status. The enhanced logging provides useful debugging information.


228-275: Consider potential edge case in SynchronizedAPI inference logic.

The handleMigrationStatusInitialization function handles three scenarios well. However, in the third case (lines 251-271), when SynchronizedAPI is empty but AuthoritativeAPI is set:

The logic assumes we're in a forward migration and infers the source from the opposite of spec. This could be incorrect if the controller restarts mid-cancellation. However, given this is a transitional state for upgrades from older versions, the assumption is reasonable.

Consider adding a comment explaining this assumption:

 	if mapiMachineSet.Status.SynchronizedAPI == "" {
 		// We are in a migration (Status.AuthoritativeAPI is Migrating) but we don't have SynchronizedAPI.
 		// Assuming this is a standard forward migration (not a cancellation), the Spec tells us the Target.
 		// Therefore, the Source (SynchronizedAPI) must be the opposite of the Spec.
+		// Note: This heuristic is for upgrade compatibility from older versions without SynchronizedAPI.
+		// In edge cases (e.g., controller restart mid-cancellation), this may not be perfectly accurate,
+		// but the worst case is a failed cancellation that requires re-initiating migration.
 		targetAPI := mapiMachineSet.Spec.AuthoritativeAPI

423-431: LGTM - Wrapper functions improve code readability.

The applyMigrationStatusWithPatch and applyMigrationStatusAndResetSyncStatusWithPatch wrappers encapsulate the generic function calls, making the reconciler code cleaner and more maintainable.

pkg/controllers/machinemigration/machine_migration_controller.go (4)

130-157: LGTM - Migration status initialization and cancellation handling consistent with MachineSet controller.

The implementation correctly mirrors the MachineSet controller logic:

  1. Delegates to handleMigrationStatusInitialization
  2. Detects cancellation with IsMigrationCancellationRequested
  3. Unpauses rollback target before patching
  4. Provides clear logging

177-181: LGTM - Transition to Migrating correctly captures synchronizedAPI.

Identical pattern to MachineSet controller - captures current authority as synchronized state before transitioning to Migrating.


217-224: LGTM - Migration completion correctly updates status fields.

The implementation properly derives newSynchronizedAPI from the target authority and updates both fields atomically with enhanced logging.


462-470: LGTM - Wrapper functions properly encapsulate status patching.

The wrapper functions correctly use MachineStatusApplyConfiguration type parameter and call the shared synccommon functions.

@openshift-ci
Copy link
Contributor

openshift-ci bot commented Dec 5, 2025

@RadekManak: 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/vendor 7488790 link true /test vendor
ci/prow/verify-deps 7488790 link true /test verify-deps
ci/prow/unit 7488790 link true /test unit

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

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