fix rbd ConstructVolumeSpec bug

This commit is contained in:
mlmhl
2018-01-04 13:19:29 +08:00
parent 291b56d062
commit 2ccf22a5d0
3 changed files with 174 additions and 5 deletions

View File

@@ -357,7 +357,26 @@ func (plugin *rbdPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*vol
}
s := dstrings.Split(sourceName, "-image-")
if len(s) != 2 {
return nil, fmt.Errorf("sourceName %s wrong, should be pool+\"-image-\"+imageName", sourceName)
// The mountPath parameter is the volume mount path for a specific pod, its format
// is /var/lib/kubelet/pods/{podUID}/volumes/{volumePluginName}/{volumeName}.
// mounter.GetDeviceNameFromMount will find the device path(such as /dev/rbd0) by
// mountPath first, and then try to find the global device mount path from the mounted
// path list of this device. sourceName is extracted from this global device mount path.
// mounter.GetDeviceNameFromMount expects the global device mount path conforms to canonical
// format: /var/lib/kubelet/plugins/kubernetes.io/rbd/mounts/{pool}-image-{image}.
// If this assertion failed, it means that the global device mount path is created by
// the deprecated format: /var/lib/kubelet/plugins/kubernetes.io/rbd/rbd/{pool}-image-{image}.
// So we will try to check whether this old style global device mount path exist or not.
// If existed, extract the sourceName from this old style path, otherwise return an error.
glog.V(3).Infof("SourceName %s wrong, fallback to old format", sourceName)
sourceName, err = plugin.getDeviceNameFromOldMountPath(mounter, mountPath)
if err != nil {
return nil, err
}
s = dstrings.Split(sourceName, "-image-")
if len(s) != 2 {
return nil, fmt.Errorf("sourceName %s wrong, should be pool+\"-image-\"+imageName", sourceName)
}
}
rbdVolume := &v1.Volume{
Name: volumeName,
@@ -492,6 +511,22 @@ func (plugin *rbdPlugin) newUnmapperInternal(volName string, podUID types.UID, m
}, nil
}
func (plugin *rbdPlugin) getDeviceNameFromOldMountPath(mounter mount.Interface, mountPath string) (string, error) {
refs, err := mount.GetMountRefsByDev(mounter, mountPath)
if err != nil {
return "", err
}
// baseMountPath is the prefix of deprecated device global mounted path,
// such as: /var/lib/kubelet/plugins/kubernetes.io/rbd/rbd
baseMountPath := filepath.Join(plugin.host.GetPluginDir(rbdPluginName), "rbd")
for _, ref := range refs {
if dstrings.HasPrefix(ref, baseMountPath) {
return filepath.Rel(baseMountPath, ref)
}
}
return "", fmt.Errorf("can't find source name from mounted path: %s", mountPath)
}
func (plugin *rbdPlugin) NewDeleter(spec *volume.Spec) (volume.Deleter, error) {
if spec.PersistentVolume != nil && spec.PersistentVolume.Spec.RBD == nil {
return nil, fmt.Errorf("spec.PersistentVolumeSource.Spec.RBD is nil")