
If node does not exist, node's volumes will be detached automatically and become available. So mark them detached and return false without error. Fix #50266
133 lines
4.6 KiB
Go
133 lines
4.6 KiB
Go
/*
|
|
Copyright 2016 The Kubernetes Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package vclib
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
|
|
"github.com/vmware/govmomi/find"
|
|
"github.com/vmware/govmomi/object"
|
|
"github.com/vmware/govmomi/vim25/types"
|
|
)
|
|
|
|
// IsNotFound return true if err is NotFoundError or DefaultNotFoundError
|
|
func IsNotFound(err error) bool {
|
|
_, ok := err.(*find.NotFoundError)
|
|
if ok {
|
|
return true
|
|
}
|
|
|
|
_, ok = err.(*find.DefaultNotFoundError)
|
|
if ok {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func getFinder(dc *Datacenter) *find.Finder {
|
|
finder := find.NewFinder(dc.Client(), true)
|
|
finder.SetDatacenter(dc.Datacenter)
|
|
return finder
|
|
}
|
|
|
|
// formatVirtualDiskUUID removes any spaces and hyphens in UUID
|
|
// Example UUID input is 42375390-71f9-43a3-a770-56803bcd7baa and output after format is 4237539071f943a3a77056803bcd7baa
|
|
func formatVirtualDiskUUID(uuid string) string {
|
|
uuidwithNoSpace := strings.Replace(uuid, " ", "", -1)
|
|
uuidWithNoHypens := strings.Replace(uuidwithNoSpace, "-", "", -1)
|
|
return strings.ToLower(uuidWithNoHypens)
|
|
}
|
|
|
|
// getSCSIControllersOfType filters specific type of Controller device from given list of Virtual Machine Devices
|
|
func getSCSIControllersOfType(vmDevices object.VirtualDeviceList, scsiType string) []*types.VirtualController {
|
|
// get virtual scsi controllers of passed argument type
|
|
var scsiControllers []*types.VirtualController
|
|
for _, device := range vmDevices {
|
|
devType := vmDevices.Type(device)
|
|
if devType == scsiType {
|
|
if c, ok := device.(types.BaseVirtualController); ok {
|
|
scsiControllers = append(scsiControllers, c.GetVirtualController())
|
|
}
|
|
}
|
|
}
|
|
return scsiControllers
|
|
}
|
|
|
|
// getAvailableSCSIController gets available SCSI Controller from list of given controllers, which has less than 15 disk devices.
|
|
func getAvailableSCSIController(scsiControllers []*types.VirtualController) *types.VirtualController {
|
|
// get SCSI controller which has space for adding more devices
|
|
for _, controller := range scsiControllers {
|
|
if len(controller.Device) < SCSIControllerDeviceLimit {
|
|
return controller
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// getNextUnitNumber gets the next available SCSI controller unit number from given list of Controller Device List
|
|
func getNextUnitNumber(devices object.VirtualDeviceList, c types.BaseVirtualController) (int32, error) {
|
|
var takenUnitNumbers [SCSIDeviceSlots]bool
|
|
takenUnitNumbers[SCSIReservedSlot] = true
|
|
key := c.GetVirtualController().Key
|
|
|
|
for _, device := range devices {
|
|
d := device.GetVirtualDevice()
|
|
if d.ControllerKey == key {
|
|
if d.UnitNumber != nil {
|
|
takenUnitNumbers[*d.UnitNumber] = true
|
|
}
|
|
}
|
|
}
|
|
for unitNumber, takenUnitNumber := range takenUnitNumbers {
|
|
if !takenUnitNumber {
|
|
return int32(unitNumber), nil
|
|
}
|
|
}
|
|
return -1, fmt.Errorf("SCSI Controller with key=%d does not have any available slots", key)
|
|
}
|
|
|
|
// getSCSIControllers filters and return list of Controller Devices from given list of Virtual Machine Devices.
|
|
func getSCSIControllers(vmDevices object.VirtualDeviceList) []*types.VirtualController {
|
|
// get all virtual scsi controllers
|
|
var scsiControllers []*types.VirtualController
|
|
for _, device := range vmDevices {
|
|
devType := vmDevices.Type(device)
|
|
switch devType {
|
|
case SCSIControllerType, strings.ToLower(LSILogicControllerType), strings.ToLower(BusLogicControllerType), PVSCSIControllerType, strings.ToLower(LSILogicSASControllerType):
|
|
if c, ok := device.(types.BaseVirtualController); ok {
|
|
scsiControllers = append(scsiControllers, c.GetVirtualController())
|
|
}
|
|
}
|
|
}
|
|
return scsiControllers
|
|
}
|
|
|
|
// RemoveClusterFromVDiskPath removes the cluster or folder path from the vDiskPath
|
|
// for vDiskPath [DatastoreCluster/sharedVmfs-0] kubevols/e2e-vmdk-1234.vmdk, return value is [sharedVmfs-0] kubevols/e2e-vmdk-1234.vmdk
|
|
// for vDiskPath [sharedVmfs-0] kubevols/e2e-vmdk-1234.vmdk, return value remains same [sharedVmfs-0] kubevols/e2e-vmdk-1234.vmdk
|
|
func RemoveClusterFromVDiskPath(vDiskPath string) string {
|
|
datastore := regexp.MustCompile("\\[(.*?)\\]").FindStringSubmatch(vDiskPath)[1]
|
|
if filepath.Base(datastore) != datastore {
|
|
vDiskPath = strings.Replace(vDiskPath, datastore, filepath.Base(datastore), 1)
|
|
}
|
|
return vDiskPath
|
|
}
|