vsphere_volume_block.go 5.5 KB

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