photon_util.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. /*
  2. Copyright 2016 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 photon_pd
  14. import (
  15. "errors"
  16. "fmt"
  17. "io/ioutil"
  18. "strings"
  19. "time"
  20. "k8s.io/api/core/v1"
  21. cloudprovider "k8s.io/cloud-provider"
  22. volumehelpers "k8s.io/cloud-provider/volume/helpers"
  23. "k8s.io/klog"
  24. "k8s.io/kubernetes/pkg/cloudprovider/providers/photon"
  25. "k8s.io/kubernetes/pkg/util/mount"
  26. "k8s.io/kubernetes/pkg/volume"
  27. volumeutil "k8s.io/kubernetes/pkg/volume/util"
  28. )
  29. const (
  30. maxRetries = 10
  31. checkSleepDuration = time.Second
  32. diskByIDPath = "/dev/disk/by-id/"
  33. diskPhotonPrefix = "wwn-0x"
  34. )
  35. var ErrProbeVolume = errors.New("Error scanning attached volumes")
  36. // volNameToDeviceName is a mapping between spec.Name from detacher
  37. // and the device name inside scsi path. Once pvscsi controller is
  38. // supported, this won't be needed.
  39. var volNameToDeviceName = make(map[string]string)
  40. type PhotonDiskUtil struct{}
  41. func removeFromScsiSubsystem(volName string) {
  42. // TODO: if using pvscsi controller, this won't be needed
  43. deviceName := volNameToDeviceName[volName]
  44. fileName := "/sys/block/" + deviceName + "/device/delete"
  45. data := []byte("1")
  46. ioutil.WriteFile(fileName, data, 0666)
  47. }
  48. func scsiHostScan() {
  49. // TODO: if using pvscsi controller, this won't be needed
  50. scsi_path := "/sys/class/scsi_host/"
  51. if dirs, err := ioutil.ReadDir(scsi_path); err == nil {
  52. for _, f := range dirs {
  53. name := scsi_path + f.Name() + "/scan"
  54. data := []byte("- - -")
  55. ioutil.WriteFile(name, data, 0666)
  56. klog.Errorf("scsiHostScan scan for %s", name)
  57. }
  58. }
  59. }
  60. func verifyDevicePath(path string) (string, error) {
  61. if pathExists, err := mount.PathExists(path); err != nil {
  62. return "", fmt.Errorf("Error checking if path exists: %v", err)
  63. } else if pathExists {
  64. return path, nil
  65. }
  66. klog.V(4).Infof("verifyDevicePath: path not exists yet")
  67. return "", nil
  68. }
  69. // CreateVolume creates a PhotonController persistent disk.
  70. func (util *PhotonDiskUtil) CreateVolume(p *photonPersistentDiskProvisioner) (pdID string, capacityGB int, fstype string, err error) {
  71. cloud, err := getCloudProvider(p.plugin.host.GetCloudProvider())
  72. if err != nil {
  73. klog.Errorf("Photon Controller Util: CreateVolume failed to get cloud provider. Error [%v]", err)
  74. return "", 0, "", err
  75. }
  76. capacity := p.options.PVC.Spec.Resources.Requests[v1.ResourceName(v1.ResourceStorage)]
  77. // PhotonController works with GiB, convert to GiB with rounding up
  78. volSizeGB, err := volumehelpers.RoundUpToGiBInt(capacity)
  79. if err != nil {
  80. return "", 0, "", err
  81. }
  82. name := volumeutil.GenerateVolumeName(p.options.ClusterName, p.options.PVName, 255)
  83. volumeOptions := &photon.VolumeOptions{
  84. CapacityGB: volSizeGB,
  85. Tags: *p.options.CloudTags,
  86. Name: name,
  87. }
  88. for parameter, value := range p.options.Parameters {
  89. switch strings.ToLower(parameter) {
  90. case "flavor":
  91. volumeOptions.Flavor = value
  92. case volume.VolumeParameterFSType:
  93. fstype = value
  94. klog.V(4).Infof("Photon Controller Util: Setting fstype to %s", fstype)
  95. default:
  96. klog.Errorf("Photon Controller Util: invalid option %s for volume plugin %s.", parameter, p.plugin.GetPluginName())
  97. return "", 0, "", fmt.Errorf("Photon Controller Util: invalid option %s for volume plugin %s.", parameter, p.plugin.GetPluginName())
  98. }
  99. }
  100. pdID, err = cloud.CreateDisk(volumeOptions)
  101. if err != nil {
  102. klog.Errorf("Photon Controller Util: failed to CreateDisk. Error [%v]", err)
  103. return "", 0, "", err
  104. }
  105. klog.V(4).Infof("Successfully created Photon Controller persistent disk %s", name)
  106. return pdID, volSizeGB, "", nil
  107. }
  108. // DeleteVolume deletes a vSphere volume.
  109. func (util *PhotonDiskUtil) DeleteVolume(pd *photonPersistentDiskDeleter) error {
  110. cloud, err := getCloudProvider(pd.plugin.host.GetCloudProvider())
  111. if err != nil {
  112. klog.Errorf("Photon Controller Util: DeleteVolume failed to get cloud provider. Error [%v]", err)
  113. return err
  114. }
  115. if err = cloud.DeleteDisk(pd.pdID); err != nil {
  116. klog.Errorf("Photon Controller Util: failed to DeleteDisk for pdID %s. Error [%v]", pd.pdID, err)
  117. return err
  118. }
  119. klog.V(4).Infof("Successfully deleted PhotonController persistent disk %s", pd.pdID)
  120. return nil
  121. }
  122. func getCloudProvider(cloud cloudprovider.Interface) (*photon.PCCloud, error) {
  123. if cloud == nil {
  124. klog.Errorf("Photon Controller Util: Cloud provider not initialized properly")
  125. return nil, fmt.Errorf("Photon Controller Util: Cloud provider not initialized properly")
  126. }
  127. pcc := cloud.(*photon.PCCloud)
  128. if pcc == nil {
  129. klog.Errorf("Invalid cloud provider: expected Photon Controller")
  130. return nil, fmt.Errorf("Invalid cloud provider: expected Photon Controller")
  131. }
  132. return pcc, nil
  133. }