Skip to content

Commit 7c0cd82

Browse files
committed
Consider volumes in status also while removing finalizers from PVC
1 parent 69a18ea commit 7c0cd82

File tree

2 files changed

+52
-18
lines changed

2 files changed

+52
-18
lines changed

pkg/syncer/cnsoperator/controller/cnsnodevmbatchattachment/cnsnodevmbatchattachment_controller.go

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,16 @@ func (r *Reconciler) Reconcile(ctx context.Context,
293293
if instance.DeletionTimestamp != nil && vm == nil {
294294
log.Infof("Instance %s is being deleted and VM object is also deleted from VC", request.NamespacedName.String())
295295

296-
// For every PVC mentioned in instance.Spec, remove finalizer from its PVC.
297-
for _, volume := range instance.Spec.Volumes {
298-
err := removePvcFinalizer(ctx, r.client, k8sClient, volume.PersistentVolumeClaim.ClaimName, instance.Namespace,
296+
pvcsInSpecAndStatus := getPvcsFromSpecAndStatus(ctx, instance)
297+
298+
// For every PVC mentioned in instance.Spec and in instance.Status, remove finalizer from it.
299+
// It is important to remove the finalizer from PVCs in instance.Status also as it is possible
300+
// that someone removes the PVC from spec after trriggering deletion of VM.
301+
for pvcName := range pvcsInSpecAndStatus {
302+
err := removePvcFinalizer(ctx, r.client, k8sClient, pvcName, instance.Namespace,
299303
instance.Spec.InstanceUUID)
300304
if err != nil {
301-
log.Errorf("failed to remove finalizer from PVC %s. Err: %s", volume.PersistentVolumeClaim.ClaimName,
305+
log.Errorf("failed to remove finalizer from PVC %s. Err: %s", pvcName,
302306
err)
303307
return r.completeReconciliationWithError(batchAttachCtx, instance, request.NamespacedName, timeout, err)
304308
}
@@ -307,7 +311,7 @@ func (r *Reconciler) Reconcile(ctx context.Context,
307311
patchErr := removeFinalizerFromCRDInstance(batchAttachCtx, instance, r.client)
308312
if patchErr != nil {
309313
log.Errorf("failed to update CnsNodeVMBatchAttachment %s. Err: +%v", instance.Name, patchErr)
310-
return r.completeReconciliationWithError(batchAttachCtx, instance, request.NamespacedName, timeout, err)
314+
return r.completeReconciliationWithError(batchAttachCtx, instance, request.NamespacedName, timeout, patchErr)
311315
}
312316
log.Infof("Successfully removed finalizer %s from instance %s",
313317
cnsoperatortypes.CNSFinalizer, request.NamespacedName.String())

pkg/syncer/cnsoperator/controller/cnsnodevmbatchattachment/cnsnodevmbatchattachment_helper.go

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,25 @@ func getVolumeMetadataMaps(ctx context.Context,
454454
return
455455
}
456456

457+
// getAllPvcsAttachedToVM returns PVC name to volumeID map for all the FCDs which are attached to the VM.
458+
func getAllPvcsAttachedToVM(ctx context.Context,
459+
attachedFCDList map[string]FCDBackingDetails) map[string]string {
460+
log := logger.GetLogger(ctx)
461+
pvcsAttachedToVM := make(map[string]string)
462+
463+
for volumeID := range attachedFCDList {
464+
pvcName, _, found := commonco.ContainerOrchestratorUtility.GetPVCNameFromCSIVolumeID(volumeID)
465+
if !found {
466+
// Do not fail if volumeID is not found to avoid cases where cache is not refreshed.
467+
// Clean up routine in syncer will take care of the cases where finalizer was not removed from such PVCs.
468+
log.Warnf("failed to find PVC name for volumeID %s", volumeID)
469+
continue
470+
}
471+
pvcsAttachedToVM[pvcName] = volumeID
472+
}
473+
return pvcsAttachedToVM
474+
}
475+
457476
// getPvcsInSpec returns map of PVCs and their volumeIDs.
458477
func getPvcsInSpec(ctx context.Context, instance *v1alpha1.CnsNodeVMBatchAttachment,
459478
k8sClient kubernetes.Interface) (map[string]string, error) {
@@ -480,7 +499,6 @@ func getPvcsInSpec(ctx context.Context, instance *v1alpha1.CnsNodeVMBatchAttachm
480499
}
481500

482501
return pvcsInSpec, nil
483-
484502
}
485503

486504
// listAttachedFcdsForVM returns list of FCDs (present in the K8s cluster)
@@ -602,6 +620,21 @@ func constructBatchAttachRequest(ctx context.Context,
602620
return pvcsInSpec, volumeIdsInSpec, batchAttachRequest, nil
603621
}
604622

623+
// getPvcsFromSpecAndStatus returns all the PVCs in spec as well as in status of the given instance.
624+
func getPvcsFromSpecAndStatus(ctx context.Context,
625+
instance *v1alpha1.CnsNodeVMBatchAttachment) map[string]bool {
626+
627+
listOfPvcsToRemoveFinalzer := make(map[string]bool, 0)
628+
629+
for _, volume := range instance.Spec.Volumes {
630+
listOfPvcsToRemoveFinalzer[volume.PersistentVolumeClaim.ClaimName] = true
631+
}
632+
for _, volume := range instance.Status.VolumeStatus {
633+
listOfPvcsToRemoveFinalzer[volume.PersistentVolumeClaim.ClaimName] = true
634+
}
635+
return listOfPvcsToRemoveFinalzer
636+
}
637+
605638
// isPvcEncrypted returns true if annotation csi.vsphere.encryption-class
606639
// is present on the PVC.
607640
func isPvcEncrypted(pvcAnnotations map[string]string) bool {
@@ -645,17 +678,6 @@ func getVolumesToAttachAndDetach(ctx context.Context, instance *v1alpha1.CnsNode
645678
pvcsToAttach := make(map[string]string, 0)
646679
pvcsToDetach := make(map[string]string, 0)
647680

648-
if instance.DeletionTimestamp != nil {
649-
log.Debugf("Instance %s is being deleted, adding all volumes in spec to volumesToDetach list.", instance.Name)
650-
volumesToDetach, err := getPvcsInSpec(ctx, instance, k8sClient)
651-
if err != nil {
652-
log.Errorf("failed to get volumes to detach from instance spec. Err: %s", err)
653-
return pvcsToAttach, volumesToDetach, err
654-
}
655-
log.Debugf("Volumes to detach list %+v for instance %s", volumesToDetach, instance.Name)
656-
return pvcsToAttach, volumesToDetach, nil
657-
}
658-
659681
// Query vCenter to find the list of FCDs which are attached to the VM.
660682
attachedFcdList, err := listAttachedFcdsForVM(ctx, vm)
661683
if err != nil {
@@ -664,6 +686,14 @@ func getVolumesToAttachAndDetach(ctx context.Context, instance *v1alpha1.CnsNode
664686
}
665687
log.Infof("List of attached FCDs %+v to VM %s", attachedFcdList, instance.Spec.InstanceUUID)
666688

689+
if instance.DeletionTimestamp != nil {
690+
log.Debugf("Instance %s is being deleted, adding all volumes attached to the VM to volumesToDetach list.",
691+
instance.Name)
692+
volumesToDetach := getAllPvcsAttachedToVM(ctx, attachedFcdList)
693+
log.Debugf("Volumes to detach list %+v for instance %s", volumesToDetach, instance.Name)
694+
return pvcsToAttach, volumesToDetach, nil
695+
}
696+
667697
// Get all PVCs and their corresponding volumeID mapping from instance spec.
668698
volumeIdsInSpec, volumeNamesInSpec, pvcNameToVolumeIDInSpec, err := getVolumeMetadataMaps(ctx, instance)
669699
if err != nil {
@@ -923,7 +953,7 @@ func removePvcFinalizer(ctx context.Context, client client.Client,
923953
return nil
924954
}
925955

926-
log.Infof("VM %s was the last attached VM for the PVC %s. Finalizer %s can be safely removed fromt the PVC",
956+
log.Infof("VM %s was the last attached VM for the PVC %s. Finalizer %s can be safely removed from the PVC",
927957
vmInstanceUUID, pvcName, cnsoperatortypes.CNSPvcFinalizer)
928958

929959
if !controllerutil.ContainsFinalizer(pvc, cnsoperatortypes.CNSPvcFinalizer) {

0 commit comments

Comments
 (0)