Unverified Commit b5eb9149 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #58089 from mtanino/issue/58085

Automatic merge from submit-queue. 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>. [FC Plugin] Create proper volumeSpec during ConstructVolumeSpec **What this PR does / why we need it**: Currently, FC plugin returns volume name and empty FCVolumeSource during ConstrutVolumeSpec of filesystem volume's reconstruction. In this fix, ConstructVolumeSpec retrieves global mount path, and analyzes volume parameters such as WWN, LUN, WWID from the path. **Which issue(s) this PR fixes** : Fixes #58085 **Special notes for your reviewer**: **Release note**: ```release-note NONE ``` cc @rootfs @jsafrane /sig storage
parents 56366348 41cb533a
...@@ -235,12 +235,60 @@ func (plugin *fcPlugin) newUnmapperInternal(volName string, podUID types.UID, ma ...@@ -235,12 +235,60 @@ func (plugin *fcPlugin) newUnmapperInternal(volName string, podUID types.UID, ma
} }
func (plugin *fcPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volume.Spec, error) { func (plugin *fcPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volume.Spec, error) {
fcVolume := &v1.Volume{ // Find globalPDPath from pod volume directory(mountPath)
// examples:
// mountPath: pods/{podUid}/volumes/kubernetes.io~fc/{volumeName}
// globalPDPath : plugins/kubernetes.io/fc/50060e801049cfd1-lun-0
var globalPDPath string
mounter := plugin.host.GetMounter(plugin.GetPluginName())
paths, err := mount.GetMountRefs(mounter, mountPath)
if err != nil {
return nil, err
}
for _, path := range paths {
if strings.Contains(path, plugin.host.GetPluginDir(fcPluginName)) {
globalPDPath = path
break
}
}
// Couldn't fetch globalPDPath
if len(globalPDPath) == 0 {
return nil, fmt.Errorf("couldn't fetch globalPDPath. failed to obtain volume spec")
}
arr := strings.Split(globalPDPath, "/")
if len(arr) < 1 {
return nil, fmt.Errorf("failed to retrieve volume plugin information from globalPDPath: %v", globalPDPath)
}
volumeInfo := arr[len(arr)-1]
// Create volume from wwn+lun or wwid
var fcVolume *v1.Volume
if strings.Contains(volumeInfo, "-lun-") {
wwnLun := strings.Split(volumeInfo, "-lun-")
if len(wwnLun) < 2 {
return nil, fmt.Errorf("failed to retrieve TargetWWN and Lun. volumeInfo is invalid: %v", volumeInfo)
}
lun, err := strconv.Atoi(wwnLun[1])
if err != nil {
return nil, err
}
lun32 := int32(lun)
fcVolume = &v1.Volume{
Name: volumeName, Name: volumeName,
VolumeSource: v1.VolumeSource{ VolumeSource: v1.VolumeSource{
FC: &v1.FCVolumeSource{}, FC: &v1.FCVolumeSource{TargetWWNs: []string{wwnLun[0]}, Lun: &lun32},
}, },
} }
glog.V(5).Infof("ConstructVolumeSpec: TargetWWNs: %v, Lun: %v",
fcVolume.VolumeSource.FC.TargetWWNs, *fcVolume.VolumeSource.FC.Lun)
} else {
fcVolume = &v1.Volume{
Name: volumeName,
VolumeSource: v1.VolumeSource{
FC: &v1.FCVolumeSource{WWIDs: []string{volumeInfo}},
},
}
glog.V(5).Infof("ConstructVolumeSpec: WWIDs: %v", fcVolume.VolumeSource.FC.WWIDs)
}
return volume.NewSpecFromVolume(fcVolume), nil return volume.NewSpecFromVolume(fcVolume), nil
} }
...@@ -249,7 +297,7 @@ func (plugin *fcPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volu ...@@ -249,7 +297,7 @@ func (plugin *fcPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volu
// - If a file is found, then retreives volumePluginDependentPath from globalMapPathUUID. // - If a file is found, then retreives volumePluginDependentPath from globalMapPathUUID.
// - Once volumePluginDependentPath is obtained, store volume information to VolumeSource // - Once volumePluginDependentPath is obtained, store volume information to VolumeSource
// examples: // examples:
// mapPath: pods/{podUid}}/{DefaultKubeletVolumeDevicesDirName}/{escapeQualifiedPluginName}/{volumeName} // mapPath: pods/{podUid}/{DefaultKubeletVolumeDevicesDirName}/{escapeQualifiedPluginName}/{volumeName}
// globalMapPathUUID : plugins/kubernetes.io/{PluginName}/{DefaultKubeletVolumeDevicesDirName}/{volumePluginDependentPath}/{pod uuid} // globalMapPathUUID : plugins/kubernetes.io/{PluginName}/{DefaultKubeletVolumeDevicesDirName}/{volumePluginDependentPath}/{pod uuid}
func (plugin *fcPlugin) ConstructBlockVolumeSpec(podUID types.UID, volumeName, mapPath string) (*volume.Spec, error) { func (plugin *fcPlugin) ConstructBlockVolumeSpec(podUID types.UID, volumeName, mapPath string) (*volume.Spec, error) {
pluginDir := plugin.host.GetVolumeDevicePluginDir(fcPluginName) pluginDir := plugin.host.GetVolumeDevicePluginDir(fcPluginName)
...@@ -284,7 +332,7 @@ func (plugin *fcPlugin) ConstructBlockVolumeSpec(podUID types.UID, volumeName, m ...@@ -284,7 +332,7 @@ func (plugin *fcPlugin) ConstructBlockVolumeSpec(podUID types.UID, volumeName, m
v1.FCVolumeSource{TargetWWNs: []string{wwnLun[0]}, Lun: &lun32}) v1.FCVolumeSource{TargetWWNs: []string{wwnLun[0]}, Lun: &lun32})
glog.V(5).Infof("ConstructBlockVolumeSpec: TargetWWNs: %v, Lun: %v", glog.V(5).Infof("ConstructBlockVolumeSpec: TargetWWNs: %v, Lun: %v",
fcPV.Spec.PersistentVolumeSource.FC.TargetWWNs, fcPV.Spec.PersistentVolumeSource.FC.TargetWWNs,
fcPV.Spec.PersistentVolumeSource.FC.Lun) *fcPV.Spec.PersistentVolumeSource.FC.Lun)
} else { } else {
fcPV = createPersistentVolumeFromFCVolumeSource(volumeName, fcPV = createPersistentVolumeFromFCVolumeSource(volumeName,
v1.FCVolumeSource{WWIDs: []string{volumeInfo}}) v1.FCVolumeSource{WWIDs: []string{volumeInfo}})
......
...@@ -19,6 +19,8 @@ package fc ...@@ -19,6 +19,8 @@ package fc
import ( import (
"fmt" "fmt"
"os" "os"
"strconv"
"strings"
"testing" "testing"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
...@@ -412,3 +414,75 @@ func Test_getWwnsLunWwidsError(t *testing.T) { ...@@ -412,3 +414,75 @@ func Test_getWwnsLunWwidsError(t *testing.T) {
t.Errorf("unexpected fc disk found") t.Errorf("unexpected fc disk found")
} }
} }
func Test_ConstructVolumeSpec(t *testing.T) {
fm := &mount.FakeMounter{
MountPoints: []mount.MountPoint{
{Device: "/dev/sdb", Path: "/var/lib/kubelet/pods/some-pod/volumes/kubernetes.io~fc/fc-in-pod1"},
{Device: "/dev/sdb", Path: "/var/lib/kubelet/plugins/kubernetes.io/fc/50060e801049cfd1-lun-0"},
{Device: "/dev/sdc", Path: "/var/lib/kubelet/pods/some-pod/volumes/kubernetes.io~fc/fc-in-pod2"},
{Device: "/dev/sdc", Path: "/var/lib/kubelet/plugins/kubernetes.io/fc/volumeDevices/3600508b400105e210000900000490000"},
},
}
mountPaths := []string{
"/var/lib/kubelet/pods/some-pod/volumes/kubernetes.io~fc/fc-in-pod1",
"/var/lib/kubelet/pods/some-pod/volumes/kubernetes.io~fc/fc-in-pod2",
}
for _, path := range mountPaths {
refs, _ := mount.GetMountRefs(fm, path)
var globalPDPath string
for _, ref := range refs {
if strings.Contains(ref, "kubernetes.io/fc") {
globalPDPath = ref
break
}
}
if len(globalPDPath) == 0 {
t.Errorf("couldn't fetch mountrefs")
}
arr := strings.Split(globalPDPath, "/")
if len(arr) < 1 {
t.Errorf("failed to retrieve volume plugin information from globalPDPath: %v", globalPDPath)
}
volumeInfo := arr[len(arr)-1]
if strings.Contains(volumeInfo, "-lun-") {
wwnLun := strings.Split(volumeInfo, "-lun-")
if len(wwnLun) < 2 {
t.Errorf("failed to retrieve TargetWWN and Lun. volumeInfo is invalid: %v", volumeInfo)
}
lun, _ := strconv.Atoi(wwnLun[1])
lun32 := int32(lun)
if wwnLun[0] != "50060e801049cfd1" || lun32 != 0 {
t.Errorf("failed to retrieve TargetWWN and Lun")
}
} else {
if volumeInfo != "3600508b400105e210000900000490000" {
t.Errorf("failed to retrieve WWIDs")
}
}
}
}
func Test_ConstructVolumeSpecNoRefs(t *testing.T) {
fm := &mount.FakeMounter{
MountPoints: []mount.MountPoint{
{Device: "/dev/sdd", Path: "/var/lib/kubelet/pods/some-pod/volumes/kubernetes.io~fc/fc-in-pod1"},
},
}
mountPaths := []string{
"/var/lib/kubelet/pods/some-pod/volumes/kubernetes.io~fc/fc-in-pod1",
}
for _, path := range mountPaths {
refs, _ := mount.GetMountRefs(fm, path)
var globalPDPath string
for _, ref := range refs {
if strings.Contains(ref, "kubernetes.io/fc") {
globalPDPath = ref
break
}
}
if len(globalPDPath) != 0 {
t.Errorf("invalid globalPDPath")
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment