Skip to content

Commit a8cafd0

Browse files
authored
Merge pull request #6477 from zhzhuang-zju/frq
Use rbSpec.clusters and rbSpec.ReplicaRequirements to calculate rb' resource usage
2 parents 3e97b8e + 3ed8f15 commit a8cafd0

File tree

2 files changed

+100
-45
lines changed

2 files changed

+100
-45
lines changed

pkg/controllers/federatedresourcequota/federated_resource_quota_enforcement_controller.go

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -266,34 +266,52 @@ func (c *QuotaEnforcementController) collectQuotaStatus(quota *policyv1alpha1.Fe
266266
func calculateUsedWithResourceBinding(resourceBindings []workv1alpha2.ResourceBinding, overall corev1.ResourceList) corev1.ResourceList {
267267
overallUsed := corev1.ResourceList{}
268268
for _, binding := range resourceBindings {
269-
if binding.Spec.ReplicaRequirements == nil || binding.Spec.Clusters == nil {
270-
continue
271-
}
272-
used := binding.Spec.ReplicaRequirements.ResourceRequest
273-
replicas := binding.Spec.Replicas
274-
275-
for name, quantity := range used {
276-
// Update quantity to reflect number of replicas in resource
277-
q := quantity.DeepCopy()
278-
q.Mul(int64(replicas))
279-
280-
// Update quantity to reflect the number of clusters resource is duplicated to
281-
if binding.Spec.Placement != nil && binding.Spec.Placement.ReplicaSchedulingType() == policyv1alpha1.ReplicaSchedulingTypeDuplicated {
282-
q.Mul(int64(len(binding.Spec.Clusters)))
283-
}
284-
269+
usage := calculateResourceUsage(&binding)
270+
for name, quantity := range usage {
285271
existing, found := overallUsed[name]
286272
if found {
287-
existing.Add(q)
273+
existing.Add(quantity)
288274
overallUsed[name] = existing
289275
} else {
290-
overallUsed[name] = q
276+
overallUsed[name] = quantity
291277
}
292278
}
293279
}
294280
return filterResourceListByOverall(overallUsed, overall)
295281
}
296282

283+
// calculateResourceUsage calculates the total resource usage based on the ResourceBinding.
284+
func calculateResourceUsage(rb *workv1alpha2.ResourceBinding) corev1.ResourceList {
285+
if rb == nil || rb.Spec.ReplicaRequirements == nil || len(rb.Spec.ReplicaRequirements.ResourceRequest) == 0 || len(rb.Spec.Clusters) == 0 {
286+
return corev1.ResourceList{}
287+
}
288+
289+
totalReplicas := int32(0)
290+
for _, cluster := range rb.Spec.Clusters {
291+
totalReplicas += cluster.Replicas
292+
}
293+
294+
if totalReplicas == 0 {
295+
return corev1.ResourceList{}
296+
}
297+
298+
usage := corev1.ResourceList{}
299+
replicaCount := int64(totalReplicas)
300+
301+
for resourceName, quantityPerReplica := range rb.Spec.ReplicaRequirements.ResourceRequest {
302+
if quantityPerReplica.IsZero() {
303+
continue
304+
}
305+
306+
totalQuantity := quantityPerReplica.DeepCopy()
307+
totalQuantity.Mul(replicaCount)
308+
309+
usage[resourceName] = totalQuantity
310+
}
311+
312+
return usage
313+
}
314+
297315
// Filters source ResourceList using the keys provided by reference
298316
func filterResourceListByOverall(source, reference corev1.ResourceList) corev1.ResourceList {
299317
filteredUsed := corev1.ResourceList{}

pkg/controllers/federatedresourcequota/federated_resource_quota_enforcement_controller_test.go

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
corev1 "k8s.io/api/core/v1"
2424
"k8s.io/apimachinery/pkg/api/resource"
2525

26-
policyv1alpha1 "github.com/karmada-io/karmada/pkg/apis/policy/v1alpha1"
2726
workv1alpha2 "github.com/karmada-io/karmada/pkg/apis/work/v1alpha2"
2827
)
2928

@@ -35,9 +34,18 @@ func TestCalculateUsedWithResourceBinding(t *testing.T) {
3534
expected corev1.ResourceList
3635
}{
3736
{
38-
name: "single binding, 3 replicas",
37+
name: "single binding",
3938
bindings: []workv1alpha2.ResourceBinding{
40-
makeBinding("500m", "128Mi", int32(3), policyv1alpha1.ReplicaSchedulingTypeDivided),
39+
makeBinding("500m", "128Mi", []workv1alpha2.TargetCluster{
40+
{
41+
Name: "Cluster1",
42+
Replicas: int32(1),
43+
},
44+
{
45+
Name: "Cluster2",
46+
Replicas: int32(2),
47+
},
48+
}),
4149
},
4250
overall: makeResourceRequest("2000m", "1Gi"),
4351
expected: corev1.ResourceList{
@@ -46,11 +54,38 @@ func TestCalculateUsedWithResourceBinding(t *testing.T) {
4654
},
4755
},
4856
{
49-
name: "multiple bindings, mixed scheduling strategies",
57+
name: "multiple bindings",
5058
bindings: []workv1alpha2.ResourceBinding{
51-
makeBinding("1", "2Gi", 2, policyv1alpha1.ReplicaSchedulingTypeDivided),
52-
makeBinding("500m", "500Mi", 2, policyv1alpha1.ReplicaSchedulingTypeDuplicated),
53-
makeBinding("2", "1Gi", 2, policyv1alpha1.ReplicaSchedulingTypeDivided),
59+
makeBinding("1", "2Gi", []workv1alpha2.TargetCluster{
60+
{
61+
Name: "Cluster1",
62+
Replicas: int32(1),
63+
},
64+
{
65+
Name: "Cluster2",
66+
Replicas: int32(1),
67+
},
68+
}),
69+
makeBinding("500m", "500Mi", []workv1alpha2.TargetCluster{
70+
{
71+
Name: "Cluster1",
72+
Replicas: int32(2),
73+
},
74+
{
75+
Name: "Cluster2",
76+
Replicas: int32(2),
77+
},
78+
}),
79+
makeBinding("2", "1Gi", []workv1alpha2.TargetCluster{
80+
{
81+
Name: "Cluster1",
82+
Replicas: int32(1),
83+
},
84+
{
85+
Name: "Cluster2",
86+
Replicas: int32(1),
87+
},
88+
}),
5489
},
5590
overall: makeResourceRequest("10", "10Gi"),
5691
expected: corev1.ResourceList{
@@ -61,7 +96,16 @@ func TestCalculateUsedWithResourceBinding(t *testing.T) {
6196
{
6297
name: "single binding, overall only includes cpu",
6398
bindings: []workv1alpha2.ResourceBinding{
64-
makeBinding("500m", "1Gi", int32(3), policyv1alpha1.ReplicaSchedulingTypeDivided),
99+
makeBinding("500m", "1Gi", []workv1alpha2.TargetCluster{
100+
{
101+
Name: "Cluster1",
102+
Replicas: int32(1),
103+
},
104+
{
105+
Name: "Cluster2",
106+
Replicas: int32(2),
107+
},
108+
}),
65109
},
66110
overall: makeResourceRequest("10", ""),
67111
expected: corev1.ResourceList{
@@ -80,15 +124,18 @@ func TestCalculateUsedWithResourceBinding(t *testing.T) {
80124
ReplicaRequirements: &workv1alpha2.ReplicaRequirements{
81125
ResourceRequest: nil,
82126
},
83-
Replicas: 2,
84-
Placement: &policyv1alpha1.Placement{
85-
ReplicaScheduling: &policyv1alpha1.ReplicaSchedulingStrategy{
86-
ReplicaSchedulingType: policyv1alpha1.ReplicaSchedulingTypeDuplicated,
87-
},
88-
},
89127
},
90128
},
91-
makeBinding("200m", "128Mi", 2, policyv1alpha1.ReplicaSchedulingTypeDivided),
129+
makeBinding("200m", "128Mi", []workv1alpha2.TargetCluster{
130+
{
131+
Name: "Cluster1",
132+
Replicas: int32(1),
133+
},
134+
{
135+
Name: "Cluster2",
136+
Replicas: int32(1),
137+
},
138+
}),
92139
},
93140
overall: makeResourceRequest("10", "10Gi"),
94141
expected: corev1.ResourceList{
@@ -118,23 +165,13 @@ func TestCalculateUsedWithResourceBinding(t *testing.T) {
118165
}
119166
}
120167

121-
func makeBinding(cpu string, memory string, replicas int32, strategy policyv1alpha1.ReplicaSchedulingType) workv1alpha2.ResourceBinding {
122-
schedulingStrategy := &policyv1alpha1.ReplicaSchedulingStrategy{
123-
ReplicaSchedulingType: strategy,
124-
}
168+
func makeBinding(cpu string, memory string, clusters []workv1alpha2.TargetCluster) workv1alpha2.ResourceBinding {
125169
return workv1alpha2.ResourceBinding{
126170
Spec: workv1alpha2.ResourceBindingSpec{
127-
Clusters: []workv1alpha2.TargetCluster{
128-
{Name: "cluster1"},
129-
{Name: "cluster2"},
130-
},
171+
Clusters: clusters,
131172
ReplicaRequirements: &workv1alpha2.ReplicaRequirements{
132173
ResourceRequest: makeResourceRequest(cpu, memory),
133174
},
134-
Replicas: replicas,
135-
Placement: &policyv1alpha1.Placement{
136-
ReplicaScheduling: schedulingStrategy,
137-
},
138175
},
139176
}
140177
}

0 commit comments

Comments
 (0)