mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-30 15:05:27 +00:00
[FC Plugin] Create proper volumeSpec during ConstructVolumeSpec
Currently, FC plugin returns volume name and empty FCVolumeSource during ConstrutVolumeSpec during filesystem volume's reconstruction. In this fix, ConstructVolumeSpec retrieves global mount path, analyzes volume parameters such as WWN, LUN, WWID from the path. Fixes #58085
This commit is contained in:
parent
f65be3747d
commit
41cb533ad6
@ -235,11 +235,59 @@ func (plugin *fcPlugin) newUnmapperInternal(volName string, podUID types.UID, ma
|
||||
}
|
||||
|
||||
func (plugin *fcPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volume.Spec, error) {
|
||||
fcVolume := &v1.Volume{
|
||||
Name: volumeName,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
FC: &v1.FCVolumeSource{},
|
||||
},
|
||||
// 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,
|
||||
VolumeSource: v1.VolumeSource{
|
||||
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
|
||||
}
|
||||
@ -249,7 +297,7 @@ func (plugin *fcPlugin) ConstructVolumeSpec(volumeName, mountPath string) (*volu
|
||||
// - If a file is found, then retreives volumePluginDependentPath from globalMapPathUUID.
|
||||
// - Once volumePluginDependentPath is obtained, store volume information to VolumeSource
|
||||
// examples:
|
||||
// mapPath: pods/{podUid}}/{DefaultKubeletVolumeDevicesDirName}/{escapeQualifiedPluginName}/{volumeName}
|
||||
// mapPath: pods/{podUid}/{DefaultKubeletVolumeDevicesDirName}/{escapeQualifiedPluginName}/{volumeName}
|
||||
// globalMapPathUUID : plugins/kubernetes.io/{PluginName}/{DefaultKubeletVolumeDevicesDirName}/{volumePluginDependentPath}/{pod uuid}
|
||||
func (plugin *fcPlugin) ConstructBlockVolumeSpec(podUID types.UID, volumeName, mapPath string) (*volume.Spec, error) {
|
||||
pluginDir := plugin.host.GetVolumeDevicePluginDir(fcPluginName)
|
||||
@ -284,7 +332,7 @@ func (plugin *fcPlugin) ConstructBlockVolumeSpec(podUID types.UID, volumeName, m
|
||||
v1.FCVolumeSource{TargetWWNs: []string{wwnLun[0]}, Lun: &lun32})
|
||||
glog.V(5).Infof("ConstructBlockVolumeSpec: TargetWWNs: %v, Lun: %v",
|
||||
fcPV.Spec.PersistentVolumeSource.FC.TargetWWNs,
|
||||
fcPV.Spec.PersistentVolumeSource.FC.Lun)
|
||||
*fcPV.Spec.PersistentVolumeSource.FC.Lun)
|
||||
} else {
|
||||
fcPV = createPersistentVolumeFromFCVolumeSource(volumeName,
|
||||
v1.FCVolumeSource{WWIDs: []string{volumeInfo}})
|
||||
|
@ -19,6 +19,8 @@ package fc
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
@ -412,3 +414,75 @@ func Test_getWwnsLunWwidsError(t *testing.T) {
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user