Skip to content

Commit 2dcfa67

Browse files
authored
Merge pull request #182 from red-hat-storage/sync_us--main
Syncing latest changes from upstream main for ramen
2 parents aead403 + 9320b5e commit 2dcfa67

6 files changed

+85
-63
lines changed

controllers/drplacementcontrol.go

+1
Original file line numberDiff line numberDiff line change
@@ -1524,6 +1524,7 @@ func (d *DRPCInstance) generateVRG(dstCluster string, repState rmn.ReplicationSt
15241524
Namespace: d.vrgNamespace,
15251525
Annotations: map[string]string{
15261526
DestinationClusterAnnotationKey: dstCluster,
1527+
DoNotDeletePVCAnnotation: d.instance.GetAnnotations()[DoNotDeletePVCAnnotation],
15271528
},
15281529
},
15291530
Spec: rmn.VolumeReplicationGroupSpec{

controllers/drplacementcontrol_controller.go

+3
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,9 @@ const (
5959
MaxPlacementDecisionConflictCount = 5
6060

6161
DestinationClusterAnnotationKey = "drplacementcontrol.ramendr.openshift.io/destination-cluster"
62+
63+
DoNotDeletePVCAnnotation = "drplacementcontrol.ramendr.openshift.io/do-not-delete-pvc"
64+
DoNotDeletePVCAnnotationVal = "true"
6265
)
6366

6467
var InitialWaitTimeForDRPCPlacementRule = errorswrapper.New("Waiting for DRPC Placement to produces placement decision")

controllers/volsync/vshandler.go

+57-44
Original file line numberDiff line numberDiff line change
@@ -505,11 +505,8 @@ func (v *VSHandler) PreparePVC(pvcName string, prepFinalSync, copyMethodDirect b
505505
return nil
506506
}
507507

508-
// This doesn't need to specifically be in VSHandler - could be useful for non-volsync scenarios?
509-
// Will look at annotations on the PVC, make sure the reconcile option from ACM is set to merge (or not exists)
510-
// and then will remove ACM annotations and also add VRG as the owner. This is to break the connection between
511-
// the appsub and the PVC itself. This way we can proceed to remove the app without the PVC being removed.
512-
// We need the PVC left behind for running the final sync or for CopyMethod Direct.
508+
// TakePVCOwnership adds do-not-delete annotation to indicate that ACM should not delete/cleanup this pvc
509+
// when the appsub is removed and adds VRG as owner so the PVC is garbage collected when the VRG is deleted.
513510
func (v *VSHandler) TakePVCOwnership(pvcName string) (bool, error) {
514511
l := v.log.WithValues("pvcName", pvcName)
515512

@@ -521,22 +518,6 @@ func (v *VSHandler) TakePVCOwnership(pvcName string) (bool, error) {
521518
return false, err
522519
}
523520

524-
// Remove acm annotations from the PVC just as a precaution - ACM uses the annotations to track that the
525-
// pvc is owned by an application. Removing them should not be necessary now that we are adding
526-
// the do-not-delete annotation. With the do-not-delete annotation (see ACMAppSubDoNotDeleteAnnotation), ACM
527-
// should not delete the pvc when the application is removed.
528-
updatedAnnotations := map[string]string{}
529-
530-
for currAnnotationKey, currAnnotationValue := range pvc.Annotations {
531-
// We want to only preserve annotations not from ACM (i.e. remove all ACM annotations to break ownership)
532-
if !strings.HasPrefix(currAnnotationKey, "apps.open-cluster-management.io") ||
533-
currAnnotationKey == ACMAppSubDoNotDeleteAnnotation {
534-
updatedAnnotations[currAnnotationKey] = currAnnotationValue
535-
}
536-
}
537-
538-
pvc.Annotations = updatedAnnotations
539-
540521
err = v.client.Update(v.ctx, pvc)
541522
if err != nil {
542523
l.Error(err, "Error updating annotations on PVC to break appsub ownership")
@@ -578,23 +559,6 @@ func (v *VSHandler) pvcExistsAndInUse(pvcName string, inUsePodMustBeReady bool)
578559
return util.IsPVAttachedToNode(v.ctx, v.client, v.log, pvc)
579560
}
580561

581-
func (v *VSHandler) pvcExists(pvcName string) (bool, error) {
582-
_, err := v.getPVC(pvcName)
583-
if err != nil {
584-
if !kerrors.IsNotFound(err) {
585-
v.log.V(1).Info("failed to get PVC")
586-
587-
return false, err
588-
}
589-
590-
return false, nil
591-
}
592-
593-
v.log.V(1).Info("PVC found")
594-
595-
return true, nil
596-
}
597-
598562
func (v *VSHandler) getPVC(pvcName string) (*corev1.PersistentVolumeClaim, error) {
599563
pvc := &corev1.PersistentVolumeClaim{}
600564

@@ -604,7 +568,7 @@ func (v *VSHandler) getPVC(pvcName string) (*corev1.PersistentVolumeClaim, error
604568
Namespace: v.owner.GetNamespace(),
605569
}, pvc)
606570
if err != nil {
607-
return pvc, fmt.Errorf("%w", err)
571+
return nil, fmt.Errorf("%w", err)
608572
}
609573

610574
return pvc, nil
@@ -933,6 +897,7 @@ func (v *VSHandler) EnsurePVCfromRD(rdSpec ramendrv1alpha1.VolSyncReplicationDes
933897
return v.validateSnapshotAndEnsurePVC(rdSpec, *vsImageRef, failoverAction)
934898
}
935899

900+
//nolint:cyclop
936901
func (v *VSHandler) EnsurePVCforDirectCopy(ctx context.Context,
937902
rdSpec ramendrv1alpha1.VolSyncReplicationDestinationSpec,
938903
) error {
@@ -946,16 +911,16 @@ func (v *VSHandler) EnsurePVCforDirectCopy(ctx context.Context,
946911
return fmt.Errorf("capacity must be provided %v", rdSpec.ProtectedPVC)
947912
}
948913

949-
exists, err := v.pvcExists(rdSpec.ProtectedPVC.Name)
950-
if err != nil {
914+
pvc, err := v.getPVC(rdSpec.ProtectedPVC.Name)
915+
if err != nil && !kerrors.IsNotFound(err) {
951916
return err
952917
}
953918

954-
if exists {
955-
return nil
919+
if pvc != nil {
920+
return v.removeOCMAnnotationsAndUpdate(pvc)
956921
}
957922

958-
pvc := &corev1.PersistentVolumeClaim{
923+
pvc = &corev1.PersistentVolumeClaim{
959924
ObjectMeta: metav1.ObjectMeta{
960925
Name: rdSpec.ProtectedPVC.Name,
961926
Namespace: v.owner.GetNamespace(),
@@ -1043,6 +1008,17 @@ func (v *VSHandler) validateSnapshotAndEnsurePVC(rdSpec ramendrv1alpha1.VolSyncR
10431008
}
10441009
}
10451010

1011+
pvc, err := v.getPVC(rdSpec.ProtectedPVC.Name)
1012+
if err != nil {
1013+
return err
1014+
}
1015+
1016+
// Once the PVC is restored/rolled back, need to re-add the annotations from old Primary
1017+
err = v.addBackOCMAnnotationsAndUpdate(pvc, rdSpec.ProtectedPVC.Annotations)
1018+
if err != nil {
1019+
return err
1020+
}
1021+
10461022
// Add ownerRef on snapshot pointing to the vrg - if/when the VRG gets cleaned up, then GC can cleanup the snap
10471023
return v.addOwnerReferenceAndUpdate(snap, v.owner)
10481024
}
@@ -2110,3 +2086,40 @@ func (v *VSHandler) checkLastSnapshotSyncStatus(lrs *volsyncv1alpha1.Replication
21102086

21112087
return !completed
21122088
}
2089+
2090+
func (v *VSHandler) DisownVolSyncManagedPVC(pvc *corev1.PersistentVolumeClaim) error {
2091+
// TODO: Remove just the VRG ownerReference instead of blindly removing all ownerreferences.
2092+
// For now, this is fine, given that the VRG is the sole owner of the PVC after DR is enabled.
2093+
pvc.ObjectMeta.OwnerReferences = nil
2094+
delete(pvc.Annotations, ACMAppSubDoNotDeleteAnnotation)
2095+
2096+
return v.client.Update(v.ctx, pvc)
2097+
}
2098+
2099+
func (v *VSHandler) addBackOCMAnnotationsAndUpdate(obj client.Object, annotations map[string]string) error {
2100+
updatedAnnotations := obj.GetAnnotations()
2101+
2102+
for key, val := range annotations {
2103+
if strings.HasPrefix(key, "apps.open-cluster-management.io") {
2104+
updatedAnnotations[key] = val
2105+
}
2106+
}
2107+
2108+
obj.SetAnnotations(updatedAnnotations)
2109+
2110+
return v.client.Update(v.ctx, obj)
2111+
}
2112+
2113+
func (v *VSHandler) removeOCMAnnotationsAndUpdate(obj client.Object) error {
2114+
updatedAnnotations := map[string]string{}
2115+
2116+
for key, val := range obj.GetAnnotations() {
2117+
if !strings.HasPrefix(key, "apps.open-cluster-management.io") {
2118+
updatedAnnotations[key] = val
2119+
}
2120+
}
2121+
2122+
obj.SetAnnotations(updatedAnnotations)
2123+
2124+
return v.client.Update(v.ctx, obj)
2125+
}

controllers/volsync/vshandler_test.go

-19
Original file line numberDiff line numberDiff line change
@@ -1807,25 +1807,6 @@ var _ = Describe("VolSync_Handler", func() {
18071807
Expect(pvcPreparationErr).ToNot(HaveOccurred())
18081808
Expect(pvcPreparationComplete).To(BeTrue())
18091809

1810-
Eventually(func() int {
1811-
err := k8sClient.Get(ctx, client.ObjectKeyFromObject(testPVC), testPVC)
1812-
if err != nil {
1813-
return 0
1814-
}
1815-
1816-
return len(testPVC.Annotations)
1817-
}, maxWait, interval).Should(Equal(len(initialAnnotations) - 2))
1818-
// We had 2 acm annotations in initialAnnotations
1819-
1820-
for key, val := range testPVC.Annotations {
1821-
if key != volsync.ACMAppSubDoNotDeleteAnnotation {
1822-
// Other ACM annotations should be deleted
1823-
Expect(strings.HasPrefix(key, "apps.open-cluster-management.io")).To(BeFalse())
1824-
1825-
Expect(initialAnnotations[key]).To(Equal(val)) // Other annotations should still be there
1826-
}
1827-
}
1828-
18291810
// ACM do-not-delete annotation should be added to the PVC
18301811
pvcAnnotations := testPVC.GetAnnotations()
18311812
val, ok := pvcAnnotations[volsync.ACMAppSubDoNotDeleteAnnotation]

controllers/volumereplicationgroup_controller.go

+6
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,12 @@ func (v *VRGInstance) processForDeletion() ctrl.Result {
774774

775775
defer v.log.Info("Exiting processing VolumeReplicationGroup")
776776

777+
if err := v.disownPVCs(); err != nil {
778+
v.log.Info("Disowning PVCs failed", "error", err)
779+
780+
return ctrl.Result{Requeue: true}
781+
}
782+
777783
if !containsString(v.instance.ObjectMeta.Finalizers, vrgFinalizerName) {
778784
v.log.Info("Finalizer missing from resource", "finalizer", vrgFinalizerName)
779785

controllers/vrg_volsync.go

+18
Original file line numberDiff line numberDiff line change
@@ -402,3 +402,21 @@ func (v *VRGInstance) pvcUnprotectVolSync(pvc corev1.PersistentVolumeClaim, log
402402
// TODO Delete ReplicationSource, ReplicationDestination, etc.
403403
v.pvcStatusDeleteIfPresent(pvc.Namespace, pvc.Name, log)
404404
}
405+
406+
// disownPVCs this function is disassociating all PVCs (targeted for VolSync replication) from its owner (VRG)
407+
func (v *VRGInstance) disownPVCs() error {
408+
if v.instance.GetAnnotations()[DoNotDeletePVCAnnotation] != DoNotDeletePVCAnnotationVal {
409+
return nil
410+
}
411+
412+
for idx := range v.volSyncPVCs {
413+
pvc := &v.volSyncPVCs[idx]
414+
415+
err := v.volSyncHandler.DisownVolSyncManagedPVC(pvc)
416+
if err != nil {
417+
return err
418+
}
419+
}
420+
421+
return nil
422+
}

0 commit comments

Comments
 (0)