Skip to content

Commit

Permalink
Merge pull request #4145 from halfrost/fix-modeling-issue
Browse files Browse the repository at this point in the history
Fix: karmada-controller-manager: panic: runtime error: index out of range
  • Loading branch information
karmada-bot authored Oct 24, 2023
2 parents 670d3c3 + 92ab33e commit 086cbcc
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 316 deletions.
4 changes: 2 additions & 2 deletions pkg/controllers/status/cluster_status_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -618,8 +618,8 @@ func getAllocatableModelings(cluster *clusterv1alpha1.Cluster, nodes []*corev1.N
modelingSummary.AddToResourceSummary(modeling.NewClusterResourceNode(nodeAvailable))
}

m := make([]clusterv1alpha1.AllocatableModeling, len(modelingSummary))
for index, resourceModel := range modelingSummary {
m := make([]clusterv1alpha1.AllocatableModeling, len(modelingSummary.RMs))
for index, resourceModel := range modelingSummary.RMs {
m[index].Grade = cluster.Spec.ResourceModels[index].Grade
m[index].Count = resourceModel.Quantity
}
Expand Down
88 changes: 13 additions & 75 deletions pkg/modeling/modeling.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@ import (

var (
mu sync.Mutex
modelSortings [][]resource.Quantity
defaultModelSorting []clusterapis.ResourceName
)

// ResourceSummary records the list of resourceModels
type ResourceSummary []resourceModels
type ResourceSummary struct {
RMs []resourceModels
modelSortings [][]resource.Quantity
}

// resourceModels records the number of each allocatable resource models.
type resourceModels struct {
Expand Down Expand Up @@ -62,10 +64,10 @@ type ClusterResourceNode struct {
type ResourceList map[clusterapis.ResourceName]resource.Quantity

// InitSummary is the init function of modeling data structure
func InitSummary(resourceModels []clusterapis.ResourceModel) (ResourceSummary, error) {
func InitSummary(resourceModel []clusterapis.ResourceModel) (ResourceSummary, error) {
var rsName []clusterapis.ResourceName
var rsList []ResourceList
for _, rm := range resourceModels {
for _, rm := range resourceModel {
tmp := map[clusterapis.ResourceName]resource.Quantity{}
for _, rmItem := range rm.Ranges {
if len(rsName) != len(rm.Ranges) {
Expand All @@ -77,21 +79,21 @@ func InitSummary(resourceModels []clusterapis.ResourceModel) (ResourceSummary, e
}

if len(rsName) != 0 && len(rsList) != 0 && (len(rsName) != len(rsList[0])) {
return nil, errors.New("the number of resourceName is not equal the number of resourceList")
return ResourceSummary{}, errors.New("the number of resourceName is not equal the number of resourceList")
}
var rs ResourceSummary

if len(rsName) != 0 {
defaultModelSorting = rsName
}
rs = make(ResourceSummary, len(rsList))
rms := make([]resourceModels, len(rsList))
// generate a sorted array by first priority of ResourceName
modelSortings = make([][]resource.Quantity, len(rsName))
modelSortings := make([][]resource.Quantity, len(rsName))
for index := 0; index < len(rsList); index++ {
for i, name := range rsName {
modelSortings[i] = append(modelSortings[i], rsList[index][name])
}
}
return rs, nil
return ResourceSummary{RMs: rms, modelSortings: modelSortings}, nil
}

// NewClusterResourceNode create new cluster resource node
Expand All @@ -105,7 +107,7 @@ func NewClusterResourceNode(resourceList corev1.ResourceList) ClusterResourceNod
func (rs *ResourceSummary) getIndex(crn ClusterResourceNode) int {
index := math.MaxInt
for i, m := range defaultModelSorting {
tmpIndex := searchLastLessElement(modelSortings[i], crn.resourceList[m])
tmpIndex := searchLastLessElement(rs.modelSortings[i], crn.resourceList[m])
if tmpIndex < index {
index = tmpIndex
}
Expand Down Expand Up @@ -166,7 +168,7 @@ func (rs *ResourceSummary) AddToResourceSummary(crn ClusterResourceNode) {
klog.Error("ClusterResource can not add to resource summary: index is invalid.")
return
}
modeling := &(*rs)[index]
modeling := &(*rs).RMs[index]
if rs.GetNodeNumFromModel(modeling) <= 5 {
root := modeling.linkedlist
if root == nil {
Expand Down Expand Up @@ -269,67 +271,3 @@ func (rs *ResourceSummary) GetNodeNumFromModel(model *resourceModels) int {
}
return 0
}

// DeleteFromResourceSummary deletes resource node into modeling summary
func (rs *ResourceSummary) DeleteFromResourceSummary(crn ClusterResourceNode) error {
index := rs.getIndex(crn)
if index == -1 {
return errors.New("ClusterResource can not delete the resource summary: index is invalid")
}
modeling := &(*rs)[index]
if rs.GetNodeNumFromModel(modeling) >= 6 {
root := modeling.redblackTree
tmpNode := root.GetNode(crn)
if tmpNode != nil {
node := tmpNode.Key.(ClusterResourceNode)
safeChangeNum(&node.quantity, -crn.quantity)
tmpNode.Key = node
if node.quantity == 0 {
root.Remove(tmpNode)
}
} else {
return errors.New("delete fail: node no found in redblack tree")
}
modeling.redblackTree = root
} else {
root, tree := modeling.linkedlist, modeling.redblackTree
if root == nil && tree != nil {
root = rbtConvertToLl(tree)
}
if root == nil && tree == nil {
return errors.New("delete fail: node no found in linked list")
}
found := false
// traverse linkedlist to remove quantity of recourse modeling
for element := root.Front(); element != nil; element = element.Next() {
if clusterResourceNodeComparator(element.Value, crn) == 0 {
tmpCrn := element.Value.(ClusterResourceNode)
safeChangeNum(&tmpCrn.quantity, -crn.quantity)
element.Value = tmpCrn
if tmpCrn.quantity == 0 {
root.Remove(element)
}
found = true
}
if found {
break
}
}
if !found {
return errors.New("delete fail: node no found in linkedlist")
}
modeling.linkedlist = root
}
safeChangeNum(&modeling.Quantity, -crn.quantity)
return nil
}

// UpdateInResourceSummary update resource node into modeling summary
func (rs *ResourceSummary) UpdateInResourceSummary(oldNode, newNode ClusterResourceNode) error {
rs.AddToResourceSummary(newNode)
err := rs.DeleteFromResourceSummary(oldNode)
if err != nil {
return errors.New("delete fail: node no found in linked list")
}
return nil
}
Loading

0 comments on commit 086cbcc

Please sign in to comment.