@@ -291,10 +291,10 @@ func (ns *nodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
291291 }
292292 defer ns .locks .Release (volumeId )
293293
294- // 1. get runtime namespace and name
294+ // 1. get runtime namespace and name from pvc
295295 // A nil volumeContext is passed because unlike csi.NodeStageVolumeRequest, csi.NodeUnstageVolumeRequest has
296296 // no volume context attribute.
297- namespace , name , err := ns . getRuntimeNamespacedName ( nil , volumeId )
297+ pvc , err := volume . GetPVCByVolumeId ( ns . apiReader , volumeId )
298298 if err != nil {
299299 if utils .IgnoreNotFound (err ) == nil {
300300 // For cases like the related persistent volume has been deleted, ignore it and return success
@@ -304,6 +304,13 @@ func (ns *nodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
304304 glog .Errorf ("NodeUnstageVolume: can't get runtime namespace and name given (volumeContext: nil, volumeId: %s): %v" , volumeId , err )
305305 return nil , errors .Wrapf (err , "NodeUnstageVolume: can't get namespace and name by volume id %s" , volumeId )
306306 }
307+ namespace , name := pvc .Namespace , pvc .Name
308+
309+ // get latestFuseImageVersion from pvc annotations
310+ var latestFuseImageVersion string
311+ if pvc .Annotations != nil {
312+ latestFuseImageVersion = pvc .Annotations [common .AnnotationRuntimeFuseImageVersion ]
313+ }
307314
308315 // 2. Check fuse clean policy. If clean policy is set to OnRuntimeDeleted, there is no
309316 // need to clean fuse eagerly.
@@ -318,6 +325,23 @@ func (ns *nodeServer) NodeUnstageVolume(ctx context.Context, req *csi.NodeUnstag
318325 }
319326
320327 var shouldCleanFuse bool
328+ defer func () {
329+ //if shouldCleanFuse == true, fuse pod will be deleted and recreate by NodeStage
330+ if ! shouldCleanFuse {
331+ updateStrategy := runtimeInfo .GetFuseUpdateStrategy ()
332+ glog .Infof ("NodeUnstage GetFuseUpdateStrategy %v" , updateStrategy )
333+ switch updateStrategy {
334+ case v1alpha1 .OnIdleFuseUpdateStrategy :
335+ if checkIfFuseNeedUpdate (namespace , name , volumeId , latestFuseImageVersion , runtimeInfo ) {
336+ if err := ns .recreateFusePodByNodeLabelModify (namespace , name , runtimeInfo ); err != nil {
337+ glog .Warningf ("NodeUnstageVolume: recreate fuse pod for %v/%v failed, err: %v" , namespace , name , err )
338+ }
339+ cleanMetadataFuseImageVersionAfterFuseClean (namespace , name , runtimeInfo .GetRuntimeType ())
340+ }
341+ }
342+ }
343+ }()
344+
321345 cleanPolicy := runtimeInfo .GetFuseCleanPolicy ()
322346 glog .Infof ("NodeUnstageVolume: Using %s clean policy for runtime %s in namespace %s" , cleanPolicy , runtimeInfo .GetName (), runtimeInfo .GetNamespace ())
323347 switch cleanPolicy {
@@ -696,3 +720,66 @@ func checkMountPathExists(ctx context.Context, mountPath string) error {
696720 }
697721 return nil
698722}
723+
724+ func checkIfFuseNeedUpdate (namespace , name , volumeId , latestFuseImageVersion string , runtimeInfo base.RuntimeInfoInterface ) (needUpdate bool ) {
725+ if len (latestFuseImageVersion ) == 0 {
726+ return
727+ }
728+
729+ inUse , err := checkMountInUse (volumeId )
730+ if err != nil {
731+ glog .Warningf ("NodeUnstage checkMountInUse failed %v, skip to update fuse pod" , err )
732+ return
733+ }
734+ glog .Infof ("NodeUnstage checkMountInUse %v" , inUse )
735+ if inUse {
736+ return
737+ }
738+
739+ currentImageVersion , found , err := utils .GetFuseImageVersionFromMetadata (namespace , name , runtimeInfo .GetRuntimeType ())
740+ glog .Infof ("NodeUnstage GetFuseImageVersionFromMetadata %v, %v, %v" , currentImageVersion , found , err )
741+ if err != nil {
742+ glog .Warningf ("NodeUnstage GetFuseImageVersionFromMetadata failed %v, skip to update fuse pod" , err )
743+ return
744+ }
745+ if ! found {
746+ return
747+ }
748+
749+ glog .Infof ("NodeUnstage checkIfFuseNeedUpdate currentImageVersion: %v, latestFuseImageVersion: %v" , currentImageVersion , latestFuseImageVersion )
750+ if currentImageVersion != latestFuseImageVersion {
751+ needUpdate = true
752+ return
753+ }
754+ return
755+ }
756+
757+ func (ns * nodeServer ) recreateFusePodByNodeLabelModify (namespace , name string , runtimeInfo base.RuntimeInfoInterface ) error {
758+ node , err := ns .getNode ()
759+ if err != nil {
760+ glog .Errorf ("NodeUnstageVolume: can't get node %s: %v" , ns .nodeId , err )
761+ return errors .Wrapf (err , "NodeUnstageVolume: can't get node %s" , ns .nodeId )
762+ }
763+
764+ fuseLabelKey := utils .GetFuseLabelName (namespace , name , runtimeInfo .GetOwnerDatasetUID ())
765+ var labelsToModify common.LabelsToModify
766+ labelsToModify .Delete (fuseLabelKey )
767+ err = ns .patchNodeWithLabel (node , labelsToModify )
768+ if err != nil {
769+ glog .Errorf ("NodeUnstageVolume: error when patching labels on node %s: %v" , ns .nodeId , err )
770+ return errors .Wrapf (err , "NodeUnstageVolume: error when patching labels on node %s" , ns .nodeId )
771+ }
772+
773+ return nil
774+ }
775+
776+ func cleanMetadataFuseImageVersionAfterFuseClean (namespace , name , runtimeType string ) {
777+ filePath := utils .GetMetadataFuseImageVersion (namespace , name , runtimeType )
778+ err := os .Remove (filePath )
779+ if err != nil {
780+ glog .Errorf ("Error deleting file %s: %v" , filePath , err )
781+ return
782+ }
783+
784+ glog .Infof ("File %s deleted successfully" , filePath )
785+ }
0 commit comments