attacher.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. /*
  2. Copyright 2017 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 flexvolume
  14. import (
  15. "time"
  16. "k8s.io/api/core/v1"
  17. "k8s.io/apimachinery/pkg/types"
  18. "k8s.io/klog"
  19. "k8s.io/kubernetes/pkg/volume"
  20. )
  21. type flexVolumeAttacher struct {
  22. plugin *flexVolumeAttachablePlugin
  23. }
  24. var _ volume.Attacher = &flexVolumeAttacher{}
  25. var _ volume.DeviceMounter = &flexVolumeAttacher{}
  26. // Attach is part of the volume.Attacher interface
  27. func (a *flexVolumeAttacher) Attach(spec *volume.Spec, hostName types.NodeName) (string, error) {
  28. call := a.plugin.NewDriverCall(attachCmd)
  29. call.AppendSpec(spec, a.plugin.host, nil)
  30. call.Append(string(hostName))
  31. status, err := call.Run()
  32. if isCmdNotSupportedErr(err) {
  33. return (*attacherDefaults)(a).Attach(spec, hostName)
  34. } else if err != nil {
  35. return "", err
  36. }
  37. return status.DevicePath, err
  38. }
  39. // WaitForAttach is part of the volume.Attacher interface
  40. func (a *flexVolumeAttacher) WaitForAttach(spec *volume.Spec, devicePath string, _ *v1.Pod, timeout time.Duration) (string, error) {
  41. call := a.plugin.NewDriverCallWithTimeout(waitForAttachCmd, timeout)
  42. call.Append(devicePath)
  43. call.AppendSpec(spec, a.plugin.host, nil)
  44. status, err := call.Run()
  45. if isCmdNotSupportedErr(err) {
  46. return (*attacherDefaults)(a).WaitForAttach(spec, devicePath, timeout)
  47. } else if err != nil {
  48. return "", err
  49. }
  50. return status.DevicePath, nil
  51. }
  52. // GetDeviceMountPath is part of the volume.Attacher interface
  53. func (a *flexVolumeAttacher) GetDeviceMountPath(spec *volume.Spec) (string, error) {
  54. return a.plugin.getDeviceMountPath(spec)
  55. }
  56. // MountDevice is part of the volume.Attacher interface
  57. func (a *flexVolumeAttacher) MountDevice(spec *volume.Spec, devicePath string, deviceMountPath string) error {
  58. // Mount only once.
  59. alreadyMounted, err := prepareForMount(a.plugin.host.GetMounter(a.plugin.GetPluginName()), deviceMountPath)
  60. if err != nil {
  61. return err
  62. }
  63. if alreadyMounted {
  64. return nil
  65. }
  66. call := a.plugin.NewDriverCall(mountDeviceCmd)
  67. call.Append(deviceMountPath)
  68. call.Append(devicePath)
  69. call.AppendSpec(spec, a.plugin.host, nil)
  70. _, err = call.Run()
  71. if isCmdNotSupportedErr(err) {
  72. // Devicepath is empty if the plugin does not support attach calls. Ignore mountDevice calls if the
  73. // plugin does not implement attach interface.
  74. if devicePath != "" {
  75. return (*attacherDefaults)(a).MountDevice(spec, devicePath, deviceMountPath, a.plugin.host.GetMounter(a.plugin.GetPluginName()))
  76. }
  77. return nil
  78. }
  79. return err
  80. }
  81. func (a *flexVolumeAttacher) VolumesAreAttached(specs []*volume.Spec, nodeName types.NodeName) (map[*volume.Spec]bool, error) {
  82. volumesAttachedCheck := make(map[*volume.Spec]bool)
  83. for _, spec := range specs {
  84. volumesAttachedCheck[spec] = true
  85. call := a.plugin.NewDriverCall(isAttached)
  86. call.AppendSpec(spec, a.plugin.host, nil)
  87. call.Append(string(nodeName))
  88. status, err := call.Run()
  89. if isCmdNotSupportedErr(err) {
  90. return nil, nil
  91. } else if err == nil {
  92. if !status.Attached {
  93. volumesAttachedCheck[spec] = false
  94. klog.V(2).Infof("VolumesAreAttached: check volume (%q) is no longer attached", spec.Name())
  95. }
  96. } else {
  97. return nil, err
  98. }
  99. }
  100. return volumesAttachedCheck, nil
  101. }