mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 17:30:00 +00:00
Merge pull request #120101 from lowang-bh/Hotfix
fix: concurrent map writes in e2e test
This commit is contained in:
commit
27c9d32d46
@ -51,7 +51,7 @@ func bootstrapOnce(f *framework.Framework) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
framework.Failf("Failed to get nodes: %v", err)
|
framework.Failf("Failed to get nodes: %v", err)
|
||||||
}
|
}
|
||||||
TestContext = Context{NodeMapper: &NodeMapper{}, VSphereInstances: vsphereInstances}
|
TestContext = Context{NodeMapper: NewNodeMapper(), VSphereInstances: vsphereInstances}
|
||||||
// 3. Get Node to VSphere mapping
|
// 3. Get Node to VSphere mapping
|
||||||
err = TestContext.NodeMapper.GenerateNodeMap(vsphereInstances, *nodeList)
|
err = TestContext.NodeMapper.GenerateNodeMap(vsphereInstances, *nodeList)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -36,6 +36,9 @@ import (
|
|||||||
|
|
||||||
// NodeMapper contains information to generate nameToNodeInfo and vcToZoneDatastore maps
|
// NodeMapper contains information to generate nameToNodeInfo and vcToZoneDatastore maps
|
||||||
type NodeMapper struct {
|
type NodeMapper struct {
|
||||||
|
nodeInfoRWLock *sync.RWMutex
|
||||||
|
nameToNodeInfo map[string]*NodeInfo
|
||||||
|
vcToZoneDatastoresMap map[string](map[string][]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NodeInfo contains information about vcenter nodes
|
// NodeInfo contains information about vcenter nodes
|
||||||
@ -54,10 +57,14 @@ const (
|
|||||||
hostSystemType = "HostSystem"
|
hostSystemType = "HostSystem"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
// NewNodeMapper returns a new NodeMapper
|
||||||
nameToNodeInfo = make(map[string]*NodeInfo)
|
func NewNodeMapper() *NodeMapper {
|
||||||
vcToZoneDatastoresMap = make(map[string](map[string][]string))
|
return &NodeMapper{
|
||||||
)
|
nodeInfoRWLock: &sync.RWMutex{},
|
||||||
|
nameToNodeInfo: make(map[string]*NodeInfo),
|
||||||
|
vcToZoneDatastoresMap: make(map[string](map[string][]string)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// GenerateNodeMap populates node name to node info map
|
// GenerateNodeMap populates node name to node info map
|
||||||
func (nm *NodeMapper) GenerateNodeMap(vSphereInstances map[string]*VSphere, nodeList v1.NodeList) error {
|
func (nm *NodeMapper) GenerateNodeMap(vSphereInstances map[string]*VSphere, nodeList v1.NodeList) error {
|
||||||
@ -108,6 +115,7 @@ func (nm *NodeMapper) GenerateNodeMap(vSphereInstances map[string]*VSphere, node
|
|||||||
|
|
||||||
for _, node := range nodeList.Items {
|
for _, node := range nodeList.Items {
|
||||||
n := node
|
n := node
|
||||||
|
wg.Add(1)
|
||||||
go func() {
|
go func() {
|
||||||
nodeUUID := getUUIDFromProviderID(n.Spec.ProviderID)
|
nodeUUID := getUUIDFromProviderID(n.Spec.ProviderID)
|
||||||
framework.Logf("Searching for node with UUID: %s", nodeUUID)
|
framework.Logf("Searching for node with UUID: %s", nodeUUID)
|
||||||
@ -132,11 +140,10 @@ func (nm *NodeMapper) GenerateNodeMap(vSphereInstances map[string]*VSphere, node
|
|||||||
}
|
}
|
||||||
wg.Done()
|
wg.Done()
|
||||||
}()
|
}()
|
||||||
wg.Add(1)
|
|
||||||
}
|
}
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
if len(nameToNodeInfo) != len(nodeList.Items) {
|
if len(nm.nameToNodeInfo) != len(nodeList.Items) {
|
||||||
return errors.New("all nodes not mapped to respective vSphere")
|
return errors.New("all nodes not mapped to respective vSphere")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -220,7 +227,7 @@ func (nm *NodeMapper) GenerateZoneToDatastoreMap() error {
|
|||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
// 3. Populate vcToZoneHostsMap and vcToHostDatastoresMap
|
// 3. Populate vcToZoneHostsMap and vcToHostDatastoresMap
|
||||||
for _, nodeInfo := range nameToNodeInfo {
|
for _, nodeInfo := range nm.nameToNodeInfo {
|
||||||
vc := nodeInfo.VSphere.Config.Hostname
|
vc := nodeInfo.VSphere.Config.Hostname
|
||||||
host := nodeInfo.HostSystemRef.Value
|
host := nodeInfo.HostSystemRef.Value
|
||||||
for _, zone := range nodeInfo.Zones {
|
for _, zone := range nodeInfo.Zones {
|
||||||
@ -247,13 +254,13 @@ func (nm *NodeMapper) GenerateZoneToDatastoreMap() error {
|
|||||||
for vc, zoneToHostsMap := range vcToZoneHostsMap {
|
for vc, zoneToHostsMap := range vcToZoneHostsMap {
|
||||||
for zone, hosts := range zoneToHostsMap {
|
for zone, hosts := range zoneToHostsMap {
|
||||||
commonDatastores := retrieveCommonDatastoresAmongHosts(hosts, vcToHostDatastoresMap[vc])
|
commonDatastores := retrieveCommonDatastoresAmongHosts(hosts, vcToHostDatastoresMap[vc])
|
||||||
if vcToZoneDatastoresMap[vc] == nil {
|
if nm.vcToZoneDatastoresMap[vc] == nil {
|
||||||
vcToZoneDatastoresMap[vc] = make(map[string][]string)
|
nm.vcToZoneDatastoresMap[vc] = make(map[string][]string)
|
||||||
}
|
}
|
||||||
vcToZoneDatastoresMap[vc][zone] = commonDatastores
|
nm.vcToZoneDatastoresMap[vc][zone] = commonDatastores
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
framework.Logf("Zone to datastores map : %+v", vcToZoneDatastoresMap)
|
framework.Logf("Zone to datastores map : %+v", nm.vcToZoneDatastoresMap)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,15 +284,21 @@ func retrieveCommonDatastoresAmongHosts(hosts []string, hostToDatastoresMap map[
|
|||||||
|
|
||||||
// GetDatastoresInZone returns all the datastores in the specified zone
|
// GetDatastoresInZone returns all the datastores in the specified zone
|
||||||
func (nm *NodeMapper) GetDatastoresInZone(vc string, zone string) []string {
|
func (nm *NodeMapper) GetDatastoresInZone(vc string, zone string) []string {
|
||||||
return vcToZoneDatastoresMap[vc][zone]
|
nm.nodeInfoRWLock.RLock()
|
||||||
|
defer nm.nodeInfoRWLock.RUnlock()
|
||||||
|
return nm.vcToZoneDatastoresMap[vc][zone]
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNodeInfo returns NodeInfo for given nodeName
|
// GetNodeInfo returns NodeInfo for given nodeName
|
||||||
func (nm *NodeMapper) GetNodeInfo(nodeName string) *NodeInfo {
|
func (nm *NodeMapper) GetNodeInfo(nodeName string) *NodeInfo {
|
||||||
return nameToNodeInfo[nodeName]
|
nm.nodeInfoRWLock.RLock()
|
||||||
|
defer nm.nodeInfoRWLock.RUnlock()
|
||||||
|
return nm.nameToNodeInfo[nodeName]
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetNodeInfo sets NodeInfo for given nodeName. This function is not thread safe. Users need to handle concurrency.
|
// SetNodeInfo sets NodeInfo for given nodeName. This function is not thread safe. Users need to handle concurrency.
|
||||||
func (nm *NodeMapper) SetNodeInfo(nodeName string, nodeInfo *NodeInfo) {
|
func (nm *NodeMapper) SetNodeInfo(nodeName string, nodeInfo *NodeInfo) {
|
||||||
nameToNodeInfo[nodeName] = nodeInfo
|
nm.nodeInfoRWLock.Lock()
|
||||||
|
defer nm.nodeInfoRWLock.Unlock()
|
||||||
|
nm.nameToNodeInfo[nodeName] = nodeInfo
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user