k8s.io/kubernetes@v1.29.3/pkg/volume/vsphere_volume/vsphere_volume_block.go (about) 1 //go:build !providerless 2 // +build !providerless 3 4 /* 5 Copyright 2018 The Kubernetes Authors. 6 7 Licensed under the Apache License, Version 2.0 (the "License"); 8 you may not use this file except in compliance with the License. 9 You may obtain a copy of the License at 10 11 http://www.apache.org/licenses/LICENSE-2.0 12 13 Unless required by applicable law or agreed to in writing, software 14 distributed under the License is distributed on an "AS IS" BASIS, 15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 See the License for the specific language governing permissions and 17 limitations under the License. 18 */ 19 20 package vsphere_volume 21 22 import ( 23 "fmt" 24 "path/filepath" 25 "strings" 26 27 "k8s.io/klog/v2" 28 "k8s.io/mount-utils" 29 utilstrings "k8s.io/utils/strings" 30 31 v1 "k8s.io/api/core/v1" 32 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 33 "k8s.io/apimachinery/pkg/types" 34 "k8s.io/kubernetes/pkg/volume" 35 "k8s.io/kubernetes/pkg/volume/util/volumepathhandler" 36 ) 37 38 var _ volume.BlockVolumePlugin = &vsphereVolumePlugin{} 39 40 func (plugin *vsphereVolumePlugin) ConstructBlockVolumeSpec(podUID types.UID, volumeName, mapPath string) (*volume.Spec, error) { 41 42 pluginDir := plugin.host.GetPluginDir(plugin.GetPluginName()) 43 blkUtil := volumepathhandler.NewBlockVolumePathHandler() 44 globalMapPathUUID, err := blkUtil.FindGlobalMapPathUUIDFromPod(pluginDir, mapPath, podUID) 45 if err != nil { 46 klog.Errorf("Failed to find GlobalMapPathUUID from Pod: %s with error: %+v", podUID, err) 47 return nil, err 48 } 49 klog.V(5).Infof("globalMapPathUUID: %v", globalMapPathUUID) 50 globalMapPath := filepath.Dir(globalMapPathUUID) 51 if len(globalMapPath) <= 1 { 52 return nil, fmt.Errorf("failed to get volume plugin information from globalMapPathUUID: %v", globalMapPathUUID) 53 } 54 return getVolumeSpecFromGlobalMapPath(volumeName, globalMapPath) 55 } 56 57 func getVolumeSpecFromGlobalMapPath(volumeName, globalMapPath string) (*volume.Spec, error) { 58 // Construct volume spec from globalMapPath 59 // globalMapPath example: 60 // plugins/kubernetes.io/{PluginName}/{DefaultKubeletVolumeDevicesDirName}/{volumeID} 61 // plugins/kubernetes.io/vsphere-volume/volumeDevices/[datastore1]\\040volumes/myDisk 62 volPath := filepath.Base(globalMapPath) 63 volPath = strings.Replace(volPath, "\\040", "", -1) 64 if len(volPath) <= 1 { 65 return nil, fmt.Errorf("failed to get volume path from global path=%s", globalMapPath) 66 } 67 block := v1.PersistentVolumeBlock 68 vsphereVolume := &v1.PersistentVolume{ 69 ObjectMeta: metav1.ObjectMeta{ 70 Name: volumeName, 71 }, 72 Spec: v1.PersistentVolumeSpec{ 73 PersistentVolumeSource: v1.PersistentVolumeSource{ 74 VsphereVolume: &v1.VsphereVirtualDiskVolumeSource{ 75 VolumePath: volPath, 76 }, 77 }, 78 VolumeMode: &block, 79 }, 80 } 81 return volume.NewSpecFromPersistentVolume(vsphereVolume, true), nil 82 } 83 84 func (plugin *vsphereVolumePlugin) NewBlockVolumeMapper(spec *volume.Spec, pod *v1.Pod, _ volume.VolumeOptions) (volume.BlockVolumeMapper, error) { 85 // If this called via GenerateUnmapDeviceFunc(), pod is nil. 86 // Pass empty string as dummy uid since uid isn't used in the case. 87 var uid types.UID 88 if pod != nil { 89 uid = pod.UID 90 } 91 return plugin.newBlockVolumeMapperInternal(spec, uid, &VsphereDiskUtil{}, plugin.host.GetMounter(plugin.GetPluginName())) 92 } 93 94 func (plugin *vsphereVolumePlugin) newBlockVolumeMapperInternal(spec *volume.Spec, podUID types.UID, manager vdManager, mounter mount.Interface) (volume.BlockVolumeMapper, error) { 95 volumeSource, _, err := getVolumeSource(spec) 96 if err != nil { 97 klog.Errorf("Failed to get Volume source from volume Spec: %+v with error: %+v", *spec, err) 98 return nil, err 99 } 100 volPath := volumeSource.VolumePath 101 mapper := &vsphereBlockVolumeMapper{ 102 vsphereVolume: &vsphereVolume{ 103 volName: spec.Name(), 104 podUID: podUID, 105 volPath: volPath, 106 manager: manager, 107 mounter: mounter, 108 plugin: plugin, 109 MetricsProvider: volume.NewMetricsStatFS(getPath(podUID, spec.Name(), plugin.host)), 110 }, 111 } 112 113 blockPath, err := mapper.GetGlobalMapPath(spec) 114 if err != nil { 115 return nil, fmt.Errorf("failed to get device path: %v", err) 116 } 117 mapper.MetricsProvider = volume.NewMetricsBlock(filepath.Join(blockPath, string(podUID))) 118 119 return mapper, nil 120 } 121 122 func (plugin *vsphereVolumePlugin) NewBlockVolumeUnmapper(volName string, podUID types.UID) (volume.BlockVolumeUnmapper, error) { 123 return plugin.newUnmapperInternal(volName, podUID, &VsphereDiskUtil{}) 124 } 125 126 func (plugin *vsphereVolumePlugin) newUnmapperInternal(volName string, podUID types.UID, manager vdManager) (volume.BlockVolumeUnmapper, error) { 127 return &vsphereBlockVolumeUnmapper{ 128 vsphereVolume: &vsphereVolume{ 129 volName: volName, 130 podUID: podUID, 131 volPath: volName, 132 manager: manager, 133 plugin: plugin, 134 }, 135 }, nil 136 } 137 138 var _ volume.BlockVolumeMapper = &vsphereBlockVolumeMapper{} 139 140 type vsphereBlockVolumeMapper struct { 141 *vsphereVolume 142 } 143 144 var _ volume.BlockVolumeUnmapper = &vsphereBlockVolumeUnmapper{} 145 146 type vsphereBlockVolumeUnmapper struct { 147 *vsphereVolume 148 volume.MetricsNil 149 } 150 151 // GetGlobalMapPath returns global map path and error 152 // path: plugins/kubernetes.io/{PluginName}/volumeDevices/volumePath 153 func (v *vsphereVolume) GetGlobalMapPath(spec *volume.Spec) (string, error) { 154 volumeSource, _, err := getVolumeSource(spec) 155 if err != nil { 156 return "", err 157 } 158 return filepath.Join(v.plugin.host.GetVolumeDevicePluginDir(vsphereVolumePluginName), string(volumeSource.VolumePath)), nil 159 } 160 161 func (v *vsphereVolume) GetPodDeviceMapPath() (string, string) { 162 return v.plugin.host.GetPodVolumeDeviceDir(v.podUID, utilstrings.EscapeQualifiedName(vsphereVolumePluginName)), v.volName 163 } 164 165 // SupportsMetrics returns true for vsphereBlockVolumeMapper as it initializes the 166 // MetricsProvider. 167 func (vbvm *vsphereBlockVolumeMapper) SupportsMetrics() bool { 168 return true 169 }