in vsphere/nodemanager.go [83:248]
func (nm *NodeManager) DiscoverNode(node *v1.Node) error {
type VmSearch struct {
vc string
datacenter *vclib.Datacenter
}
var mutex = &sync.Mutex{}
var globalErrMutex = &sync.Mutex{}
var queueChannel chan *VmSearch
var wg sync.WaitGroup
var globalErr *error
queueChannel = make(chan *VmSearch, QUEUE_SIZE)
nodeUUID, err := GetNodeUUID(node)
if err != nil {
klog.Errorf("Node Discovery failed to get node uuid for node %s with error: %v", node.Name, err)
return err
}
klog.V(4).Infof("Discovering node %s with uuid %s", node.ObjectMeta.Name, nodeUUID)
vmFound := false
globalErr = nil
setGlobalErr := func(err error) {
globalErrMutex.Lock()
globalErr = &err
globalErrMutex.Unlock()
}
setVMFound := func(found bool) {
mutex.Lock()
vmFound = found
mutex.Unlock()
}
getVMFound := func() bool {
mutex.Lock()
found := vmFound
mutex.Unlock()
return found
}
go func() {
var datacenterObjs []*vclib.Datacenter
for vc, vsi := range nm.vsphereInstanceMap {
found := getVMFound()
if found == true {
break
}
// Create context
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
err := nm.vcConnect(ctx, vsi)
if err != nil {
klog.V(4).Info("Discovering node error vc:", err)
setGlobalErr(err)
continue
}
if vsi.cfg.Datacenters == "" {
datacenterObjs, err = vclib.GetAllDatacenter(ctx, vsi.conn)
if err != nil {
klog.V(4).Info("Discovering node error dc:", err)
setGlobalErr(err)
continue
}
} else {
datacenters := strings.Split(vsi.cfg.Datacenters, ",")
for _, dc := range datacenters {
dc = strings.TrimSpace(dc)
if dc == "" {
continue
}
datacenterObj, err := vclib.GetDatacenter(ctx, vsi.conn, dc)
if err != nil {
klog.V(4).Info("Discovering node error dc:", err)
setGlobalErr(err)
continue
}
datacenterObjs = append(datacenterObjs, datacenterObj)
}
}
for _, datacenterObj := range datacenterObjs {
found := getVMFound()
if found == true {
break
}
klog.V(4).Infof("Finding node %s in vc=%s and datacenter=%s", node.Name, vc, datacenterObj.Name())
queueChannel <- &VmSearch{
vc: vc,
datacenter: datacenterObj,
}
}
}
close(queueChannel)
}()
for i := 0; i < POOL_SIZE; i++ {
wg.Add(1)
go func() {
for res := range queueChannel {
ctx, cancel := context.WithCancel(context.Background())
vm, err := res.datacenter.GetVMByUUID(ctx, nodeUUID)
if err != nil {
klog.V(4).Infof("Error while looking for vm=%+v in vc=%s and datacenter=%s: %v",
vm, res.vc, res.datacenter.Name(), err)
if err != vclib.ErrNoVMFound {
setGlobalErr(err)
} else {
klog.V(4).Infof("Did not find node %s in vc=%s and datacenter=%s",
node.Name, res.vc, res.datacenter.Name())
}
cancel()
continue
}
if vm != nil {
klog.V(4).Infof("Found node %s as vm=%+v in vc=%s and datacenter=%s",
node.Name, vm, res.vc, res.datacenter.Name())
var vmObj mo.VirtualMachine
err := vm.Properties(ctx, vm.Reference(), []string{"config"}, &vmObj)
if err != nil || vmObj.Config == nil {
klog.Errorf("failed to retrieve guest vmconfig for node: %s Err: %v", node.Name, err)
} else {
klog.V(4).Infof("vm hardware version for node:%s is %s", node.Name, vmObj.Config.Version)
// vmconfig.Version returns vm hardware version as vmx-11, vmx-13, vmx-14, vmx-15 etc.
vmhardwaredeprecated, err := isGuestHardwareVersionDeprecated(vmObj.Config.Version)
if err != nil {
klog.Errorf("failed to check if vm hardware version is deprecated. VM Hardware Version: %s Err: %v", vmObj.Config.Version, err)
}
if vmhardwaredeprecated {
klog.Warningf("VM Hardware version: %s from node: %s is deprecated. Please consider upgrading virtual machine hardware version to vmx-15 or higher", vmObj.Config.Version, node.Name)
}
}
// Get the node zone information
nodeFd := node.ObjectMeta.Labels[v1.LabelTopologyZone]
nodeRegion := node.ObjectMeta.Labels[v1.LabelTopologyRegion]
nodeZone := &cloudprovider.Zone{FailureDomain: nodeFd, Region: nodeRegion}
nodeInfo := &NodeInfo{dataCenter: res.datacenter, vm: vm, vcServer: res.vc, vmUUID: nodeUUID, zone: nodeZone}
nm.addNodeInfo(node.ObjectMeta.Name, nodeInfo)
for range queueChannel {
}
setVMFound(true)
cancel()
break
}
}
wg.Done()
}()
}
wg.Wait()
if vmFound {
return nil
}
if globalErr != nil {
return *globalErr
}
klog.V(4).Infof("Discovery Node: %q vm not found", node.Name)
return vclib.ErrNoVMFound
}