Change:
/kind bug /sig storage What happened: When using a CSI driver that does not support NODESTAGE, I can see orphan json files in that are never cleaned up. What you expected to happen: No orphan file /assign

Discussion:
return deviceMountPath, nil } <del> func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error { </del> <ins> func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (err error) { </ins> glog.V(4).Infof(log("attacher.MountDevice(%s, %s)", devicePath, deviceMountPath)) mounted, err := isDirMounted(c.plugin, deviceMountPath)

return err } <del> dataDir := filepath.Dir(deviceMountPath) if err := os.MkdirAll(dataDir, 0750); err != nil { glog.Error(log("attacher.MountDevice failed to create dir %#v:  %v", dataDir, err)) </del> <ins> // Store volume metadata for UnmountDevice. Keep it around even if the // driver does not support NodeStage, UnmountDevice still needs it. if err = os.MkdirAll(deviceMountPath, 0750); err != nil { glog.Error(log("attacher.MountDevice failed to create dir %#v:  %v", deviceMountPath, err)) </ins> return err } <ins> glog.V(4).Info(log("created target path successfully [%s]", deviceMountPath)) dataDir := filepath.Dir(deviceMountPath) </ins> data := map[string]string{ volDataKey.volHandle:  csiSource.VolumeHandle, volDataKey.driverName: csiSource.Driver, } <del> if err := saveVolumeData(dataDir, volDataFileName, data); err != nil { </del> <ins> if err = saveVolumeData(dataDir, volDataFileName, data); err != nil { </ins> glog.Error(log("failed to save volume info data: %v", err)) <del> if err := os.RemoveAll(dataDir); err != nil { glog.Error(log("failed to remove dir after error [%s]: %v", dataDir, err)) return err </del> <ins> if cleanerr := os.RemoveAll(dataDir); err != nil { glog.Error(log("failed to remove dir after error [%s]: %v", dataDir, cleanerr)) </ins> } return err } <ins> defer func() { if err != nil { // clean up metadata glog.Errorf(log("attacher.MountDevice failed: %v", err)) if err := removeMountDir(c.plugin, deviceMountPath); err != nil { glog.Error(log("attacher.MountDevice failed to remove mount dir after errir [%s]: %v", deviceMountPath, err)) } } }() </ins> if c.csiClient == nil { c.csiClient = newCsiDriverClient(csiSource.Driver)

// Check whether "STAGE_UNSTAGE_VOLUME" is set stageUnstageSet, err := hasStageUnstageCapability(ctx, csi) if err != nil { <del> glog.Error(log("attacher.MountDevice failed to check STAGE_UNSTAGE_VOLUME: %v", err)) </del> return err } if !stageUnstageSet { glog.Infof(log("attacher.MountDevice STAGE_UNSTAGE_VOLUME capability not set. Skipping MountDevice...")) <ins> // defer does *not* remove the metadata file and it's correct - UnmountDevice needs it there. </ins> return nil } // Start MountDevice if deviceMountPath == "" { <del> return fmt.Errorf("attacher.MountDevice failed, deviceMountPath is empty") </del> <ins> err = fmt.Errorf("attacher.MountDevice failed, deviceMountPath is empty") return err </ins> } nodeName := string(c.plugin.host.GetNodeName())

// search for attachment by VolumeAttachment.Spec.Source.PersistentVolumeName attachment, err := c.k8s.StorageV1beta1().VolumeAttachments().Get(attachID, meta.GetOptions{}) if err != nil { <del> glog.Error(log("attacher.MountDevice failed while getting volume attachment [id=%v]: %v", attachID, err)) return err </del> <ins> return err // This err already has enough context ("VolumeAttachment xyz not found") </ins> } if attachment == nil { <del> glog.Error(log("unable to find VolumeAttachment [id=%s]", attachID)) return errors.New("no existing VolumeAttachment found") </del> <ins> err = errors.New("no existing VolumeAttachment found") return err </ins> } publishVolumeInfo := attachment.Status.AttachmentMetadata

if csiSource.NodeStageSecretRef != nil { nodeStageSecrets, err = getCredentialsFromSecret(c.k8s, csiSource.NodeStageSecretRef) if err != nil { <del> return fmt.Errorf("fetching NodeStageSecretRef %s/%s failed: %v", </del> <ins> err = fmt.Errorf("fetching NodeStageSecretRef %s/%s failed: %v", </ins> csiSource.NodeStageSecretRef.Namespace, csiSource.NodeStageSecretRef.Name, err) <ins> return err </ins> } } <del> // create target_dir before call to NodeStageVolume if err := os.MkdirAll(deviceMountPath, 0750); err != nil { glog.Error(log("attacher.MountDevice failed to create dir %#v:  %v", deviceMountPath, err)) return err } glog.V(4).Info(log("created target path successfully [%s]", deviceMountPath)) </del> //TODO (vladimirvivien) implement better AccessModes mapping between k8s and CSI accessMode := v1.ReadWriteOnce if spec.PersistentVolume.Spec.AccessModes != nil {

csiSource.VolumeAttributes) if err != nil { <del> glog.Errorf(log("attacher.MountDevice failed: %v", err)) if removeMountDirErr := removeMountDir(c.plugin, deviceMountPath); removeMountDirErr != nil { glog.Error(log("attacher.MountDevice failed to remove mount dir after a NodeStageVolume() error [%s]: %v", deviceMountPath, removeMountDirErr)) } </del> return err }

deviceMountPath: "path2", stageUnstageSet: false, }, <del> { testName:        "stage_unstage not set no vars should not fail", stageUnstageSet: false, }, </del> } for _, tc := range testCases {