Merge pull request #65323 from jsafrane/fix-csi-json

Automatic merge from submit-queue (batch tested with PRs 65404, 65323, 65468). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Fix cleanup of volume metadata json file.

Create the json file with metadata as the last item, when everything else is ready, so we don't need to clean up the file in all error cases in this function.

Fixes #65322

**Release note**:
```release-note
Fixed cleanup of CSI metadata files.
```

/assign @saad-ali @vladimirvivien
pull/8/head
Kubernetes Submit Queue 2018-06-26 17:33:05 -07:00 committed by GitHub
commit e55ea1608a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 27 additions and 31 deletions

View File

@ -245,7 +245,7 @@ func (c *csiAttacher) GetDeviceMountPath(spec *volume.Spec) (string, error) {
return deviceMountPath, nil return deviceMountPath, nil
} }
func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error { func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) (err error) {
glog.V(4).Infof(log("attacher.MountDevice(%s, %s)", devicePath, deviceMountPath)) glog.V(4).Infof(log("attacher.MountDevice(%s, %s)", devicePath, deviceMountPath))
mounted, err := isDirMounted(c.plugin, deviceMountPath) mounted, err := isDirMounted(c.plugin, deviceMountPath)
@ -269,24 +269,34 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
return err return err
} }
dataDir := filepath.Dir(deviceMountPath) // Store volume metadata for UnmountDevice. Keep it around even if the
if err := os.MkdirAll(dataDir, 0750); err != nil { // driver does not support NodeStage, UnmountDevice still needs it.
glog.Error(log("attacher.MountDevice failed to create dir %#v: %v", dataDir, err)) if err = os.MkdirAll(deviceMountPath, 0750); err != nil {
glog.Error(log("attacher.MountDevice failed to create dir %#v: %v", deviceMountPath, err))
return err return err
} }
glog.V(4).Info(log("created target path successfully [%s]", deviceMountPath))
dataDir := filepath.Dir(deviceMountPath)
data := map[string]string{ data := map[string]string{
volDataKey.volHandle: csiSource.VolumeHandle, volDataKey.volHandle: csiSource.VolumeHandle,
volDataKey.driverName: csiSource.Driver, volDataKey.driverName: csiSource.Driver,
} }
if err := saveVolumeData(dataDir, volDataFileName, data); err != nil { if err = saveVolumeData(dataDir, volDataFileName, data); err != nil {
glog.Error(log("failed to save volume info data: %v", err)) glog.Error(log("failed to save volume info data: %v", err))
if err := os.RemoveAll(dataDir); err != nil { if cleanerr := os.RemoveAll(dataDir); err != nil {
glog.Error(log("failed to remove dir after error [%s]: %v", dataDir, err)) glog.Error(log("failed to remove dir after error [%s]: %v", dataDir, cleanerr))
return err
} }
return err return err
} }
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))
}
}
}()
if c.csiClient == nil { if c.csiClient == nil {
c.csiClient = newCsiDriverClient(csiSource.Driver) c.csiClient = newCsiDriverClient(csiSource.Driver)
@ -298,17 +308,18 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
// Check whether "STAGE_UNSTAGE_VOLUME" is set // Check whether "STAGE_UNSTAGE_VOLUME" is set
stageUnstageSet, err := hasStageUnstageCapability(ctx, csi) stageUnstageSet, err := hasStageUnstageCapability(ctx, csi)
if err != nil { if err != nil {
glog.Error(log("attacher.MountDevice failed to check STAGE_UNSTAGE_VOLUME: %v", err))
return err return err
} }
if !stageUnstageSet { if !stageUnstageSet {
glog.Infof(log("attacher.MountDevice STAGE_UNSTAGE_VOLUME capability not set. Skipping MountDevice...")) glog.Infof(log("attacher.MountDevice STAGE_UNSTAGE_VOLUME capability not set. Skipping MountDevice..."))
// defer does *not* remove the metadata file and it's correct - UnmountDevice needs it there.
return nil return nil
} }
// Start MountDevice // Start MountDevice
if deviceMountPath == "" { if deviceMountPath == "" {
return fmt.Errorf("attacher.MountDevice failed, deviceMountPath is empty") err = fmt.Errorf("attacher.MountDevice failed, deviceMountPath is empty")
return err
} }
nodeName := string(c.plugin.host.GetNodeName()) nodeName := string(c.plugin.host.GetNodeName())
@ -317,13 +328,12 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
// search for attachment by VolumeAttachment.Spec.Source.PersistentVolumeName // search for attachment by VolumeAttachment.Spec.Source.PersistentVolumeName
attachment, err := c.k8s.StorageV1beta1().VolumeAttachments().Get(attachID, meta.GetOptions{}) attachment, err := c.k8s.StorageV1beta1().VolumeAttachments().Get(attachID, meta.GetOptions{})
if err != nil { if err != nil {
glog.Error(log("attacher.MountDevice failed while getting volume attachment [id=%v]: %v", attachID, err)) return err // This err already has enough context ("VolumeAttachment xyz not found")
return err
} }
if attachment == nil { if attachment == nil {
glog.Error(log("unable to find VolumeAttachment [id=%s]", attachID)) err = errors.New("no existing VolumeAttachment found")
return errors.New("no existing VolumeAttachment found") return err
} }
publishVolumeInfo := attachment.Status.AttachmentMetadata publishVolumeInfo := attachment.Status.AttachmentMetadata
@ -331,18 +341,12 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
if csiSource.NodeStageSecretRef != nil { if csiSource.NodeStageSecretRef != nil {
nodeStageSecrets, err = getCredentialsFromSecret(c.k8s, csiSource.NodeStageSecretRef) nodeStageSecrets, err = getCredentialsFromSecret(c.k8s, csiSource.NodeStageSecretRef)
if err != nil { if err != nil {
return fmt.Errorf("fetching NodeStageSecretRef %s/%s failed: %v", err = fmt.Errorf("fetching NodeStageSecretRef %s/%s failed: %v",
csiSource.NodeStageSecretRef.Namespace, csiSource.NodeStageSecretRef.Name, err) csiSource.NodeStageSecretRef.Namespace, csiSource.NodeStageSecretRef.Name, err)
return err
} }
} }
// 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))
//TODO (vladimirvivien) implement better AccessModes mapping between k8s and CSI //TODO (vladimirvivien) implement better AccessModes mapping between k8s and CSI
accessMode := v1.ReadWriteOnce accessMode := v1.ReadWriteOnce
if spec.PersistentVolume.Spec.AccessModes != nil { if spec.PersistentVolume.Spec.AccessModes != nil {
@ -364,10 +368,6 @@ func (c *csiAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMo
csiSource.VolumeAttributes) csiSource.VolumeAttributes)
if err != nil { if err != nil {
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))
}
return err return err
} }

View File

@ -523,10 +523,6 @@ func TestAttacherMountDevice(t *testing.T) {
deviceMountPath: "path2", deviceMountPath: "path2",
stageUnstageSet: false, stageUnstageSet: false,
}, },
{
testName: "stage_unstage not set no vars should not fail",
stageUnstageSet: false,
},
} }
for _, tc := range testCases { for _, tc := range testCases {