diff --git a/internal/controller/drplacementcontrol_controller.go b/internal/controller/drplacementcontrol_controller.go index bfd8a862b..f3399490a 100644 --- a/internal/controller/drplacementcontrol_controller.go +++ b/internal/controller/drplacementcontrol_controller.go @@ -724,15 +724,15 @@ func (r *DRPlacementControlReconciler) cleanupVRGs( return fmt.Errorf("failed to retrieve VRGs. We'll retry later. Error (%w)", err) } - if !ensureVRGsManagedByDRPC(r.Log, mwu, vrgs, drpc, vrgNamespace) { - return fmt.Errorf("VRG adoption in progress") + // We have to ensure the secondary VRG is deleted before deleting the primary VRG. This will fail until there + // is no secondary VRG in the vrgs list. + if err := r.ensureVRGsDeleted(mwu, vrgs, drpc, vrgNamespace, rmn.Secondary); err != nil { + return err } - // delete VRG manifestwork - for _, drClusterName := range rmnutil.DRPolicyClusterNames(drPolicy) { - if err := mwu.DeleteManifestWork(mwu.BuildManifestWorkName(rmnutil.MWTypeVRG), drClusterName); err != nil { - return fmt.Errorf("%w", err) - } + // This will fail until there is no primary VRG in the vrgs list. + if err := r.ensureVRGsDeleted(mwu, vrgs, drpc, vrgNamespace, rmn.Primary); err != nil { + return err } if len(vrgs) != 0 { @@ -747,6 +747,38 @@ func (r *DRPlacementControlReconciler) cleanupVRGs( return nil } +// ensureVRGsDeleted ensure that secondary or primary VRGs are deleted. Return an error if a vrg could not be deleted, +// or deletion is in progress. Return nil if vrg of specified type was not found. +func (r *DRPlacementControlReconciler) ensureVRGsDeleted( + mwu rmnutil.MWUtil, + vrgs map[string]*rmn.VolumeReplicationGroup, + drpc *rmn.DRPlacementControl, + vrgNamespace string, + replicationState rmn.ReplicationState, +) error { + var inProgress bool + + for cluster, vrg := range vrgs { + if vrg.Spec.ReplicationState == replicationState { + if !ensureVRGsManagedByDRPC(r.Log, mwu, vrgs, drpc, vrgNamespace) { + return fmt.Errorf("%s VRG adoption in progress", replicationState) + } + + if err := mwu.DeleteManifestWork(mwu.BuildManifestWorkName(rmnutil.MWTypeVRG), cluster); err != nil { + return fmt.Errorf("failed to delete %s VRG manifestwork for cluster %q: %w", replicationState, cluster, err) + } + + inProgress = true + } + } + + if inProgress { + return fmt.Errorf("%s VRG manifestwork deletion in progress", replicationState) + } + + return nil +} + func (r *DRPlacementControlReconciler) deleteAllManagedClusterViews( drpc *rmn.DRPlacementControl, clusterNames []string, ) error {