@@ -26,6 +26,7 @@ import (
2626 "sync"
2727
2828 v1 "k8s.io/api/core/v1"
29+ apierrors "k8s.io/apimachinery/pkg/api/errors"
2930 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
3031 "k8s.io/apimachinery/pkg/types"
3132 "k8s.io/client-go/kubernetes"
@@ -162,6 +163,9 @@ func removeStaleEntriesFromInstanceStatus(ctx context.Context,
162163 pvcsToDetach map [string ]string , volumeNamesInSpec map [string ]string ) error {
163164 log := logger .GetLogger (ctx )
164165
166+ // Add the stale PVCs which need to be removed to this list.
167+ pvcsEntriesToRemove := make ([]string , 0 )
168+
165169 // Remove entries them from instance status and update the instance.
166170 // For each entry in status, find corresponding entry in Spec and in pvcsToDetach.
167171 for _ , volumeStatus := range instance .Status .VolumeStatus {
@@ -182,10 +186,17 @@ func removeStaleEntriesFromInstanceStatus(ctx context.Context,
182186
183187 log .Infof ("Status for a PVC %s found in instance %s but it is not present in Spec. " +
184188 "Removing it from instance" , volumeStatus .PersistentVolumeClaim .ClaimName , instance .Name )
185- deleteVolumeFromStatus ( volumeStatus .PersistentVolumeClaim .ClaimName , instance )
189+ pvcsEntriesToRemove = append ( pvcsEntriesToRemove , volumeStatus .PersistentVolumeClaim .ClaimName )
186190 }
187191 }
188192 }
193+
194+ // Go does not support in slice mutation as it shifts the indices.
195+ // Hence, it is important to delete the entries separately.
196+ for _ , pvcToDeleteFromStatus := range pvcsEntriesToRemove {
197+ deleteVolumeFromStatus (pvcToDeleteFromStatus , instance )
198+ }
199+
189200 return nil
190201}
191202
@@ -347,12 +358,25 @@ func getVolumeNameVolumeIdMapsInSpec(ctx context.Context,
347358}
348359
349360// getPvcsInSpec returns map of PVCs and their volumeIDs.
350- func getPvcsInSpec (instance * v1alpha1.CnsNodeVMBatchAttachment ) (map [string ]string , error ) {
361+ func getPvcsInSpec (ctx context.Context , instance * v1alpha1.CnsNodeVMBatchAttachment ,
362+ k8sClient kubernetes.Interface ) (map [string ]string , error ) {
363+ log := logger .GetLogger (ctx )
364+
351365 pvcsInSpec := make (map [string ]string )
352366 for _ , volume := range instance .Spec .Volumes {
353367 volumeId , ok := commonco .ContainerOrchestratorUtility .GetVolumeIDFromPVCName (
354368 instance .Namespace , volume .PersistentVolumeClaim .ClaimName )
355369 if ! ok {
370+ pvcName := volume .PersistentVolumeClaim .ClaimName
371+ _ , err := k8sClient .CoreV1 ().PersistentVolumeClaims (instance .Namespace ).Get (ctx ,
372+ pvcName , metav1.GetOptions {})
373+ if err != nil {
374+ if apierrors .IsNotFound (err ) {
375+ log .Infof ("PVC %s has already been deleted. No action to be taken" , pvcName )
376+ continue
377+ }
378+ return pvcsInSpec , fmt .Errorf ("failed to find volumeID for PVC %s" , volume .PersistentVolumeClaim .ClaimName )
379+ }
356380 return pvcsInSpec , fmt .Errorf ("failed to find volumeID for PVC %s" , volume .PersistentVolumeClaim .ClaimName )
357381 }
358382 pvcsInSpec [volume .PersistentVolumeClaim .ClaimName ] = volumeId
@@ -474,7 +498,7 @@ func getVolumesToDetach(ctx context.Context, instance *v1alpha1.CnsNodeVMBatchAt
474498
475499 if instance .DeletionTimestamp != nil {
476500 log .Debugf ("Instance %s is being deleted, adding all volumes in spec to volumesToDetach list." , instance .Name )
477- volumesToDetach , err := getPvcsInSpec (instance )
501+ volumesToDetach , err := getPvcsInSpec (ctx , instance , k8sClient )
478502 if err != nil {
479503 log .Errorf ("failed to get volumes to detach from instance spec. Err: %s" , err )
480504 return volumesToDetach , err
@@ -696,8 +720,21 @@ func removePvcFinalizer(ctx context.Context, client client.Client,
696720 // Get PVC object from informer cache
697721 pvc , err := commonco .ContainerOrchestratorUtility .GetPvcObjectByName (ctx , pvcName , namespace )
698722 if err != nil {
699- log .Errorf ("failed to get PVC object for PVC %s. Err: %s" , pvcName , err )
700- return err
723+ if ! apierrors .IsNotFound (err ) {
724+ log .Errorf ("failed to get PVC object for PVC %s. Err: %s" , pvcName , err )
725+ return err
726+ }
727+
728+ // Verify if the PVC object itself has been deleted by querying the API server in case the cache is old.
729+ pvc , err = k8sClient .CoreV1 ().PersistentVolumeClaims (pvc .Namespace ).Get (ctx , pvcName , metav1.GetOptions {})
730+ if err != nil {
731+ if apierrors .IsNotFound (err ) {
732+ log .Infof ("PVC %s has already been deleted. No action to be taken" , pvcName )
733+ return nil
734+ }
735+ log .Errorf ("failed to get updated PVC %s in namespace %s" , pvcName , namespace )
736+ return err
737+ }
701738 }
702739
703740 // Remove usedby annotation
0 commit comments