Skip to content

Commit fba12ef

Browse files
enoodledavidLif
andauthored
fix: backport 1642 to v0.15 (#1676)
Signed-off-by: Erez Freiberger <enoodle@gmail.com> Co-authored-by: davidLif <davidshani12@gmail.com>
1 parent baf5b06 commit fba12ef

6 files changed

Lines changed: 87 additions & 13 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
88

99
### Fixed
1010
- Improved solver performance in some large reclaim scenarios [#1627](https://github.com/kai-scheduler/KAI-Scheduler/pull/1627) [itsomri](https://github.com/itsomri)
11+
- Grove grouper now sets `minSubGroup` (equal to the number of child SubGroups) instead of `minMember=0` on parent SubGroups generated from `topologyConstraintGroupConfigs` [#1639](https://github.com/kai-scheduler/KAI-Scheduler/issues/1639) [davidLif](https://github.com/davidLif)
1112

1213
## [v0.15.1] - 2026-06-01
1314

pkg/podgrouper/podgroup/handler.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,17 @@ func (h *Handler) createPodGroupForMetadata(podGroupMetadata Metadata) *scheduli
9898
},
9999
},
100100
Spec: schedulingv2alpha2.PodGroupSpec{
101-
MinMember: ptr.To(podGroupMetadata.MinAvailable),
102101
Queue: podGroupMetadata.Queue,
103102
PriorityClassName: podGroupMetadata.PriorityClassName,
104103
SubGroups: []schedulingv2alpha2.SubGroup{},
105104
Preemptibility: podGroupMetadata.Preemptibility,
106105
},
107106
}
107+
if podGroupMetadata.MinSubGroup != nil {
108+
pg.Spec.MinSubGroup = podGroupMetadata.MinSubGroup
109+
} else {
110+
pg.Spec.MinMember = ptr.To(podGroupMetadata.MinAvailable)
111+
}
108112

109113
for _, subGroup := range podGroupMetadata.SubGroups {
110114
var topologyConstraint *schedulingv2alpha2.TopologyConstraint
@@ -115,13 +119,17 @@ func (h *Handler) createPodGroupForMetadata(podGroupMetadata Metadata) *scheduli
115119
Topology: subGroup.TopologyConstraints.Topology,
116120
}
117121
}
118-
pg.Spec.SubGroups = append(pg.Spec.SubGroups,
119-
schedulingv2alpha2.SubGroup{
120-
Name: subGroup.Name,
121-
MinMember: ptr.To(subGroup.MinAvailable),
122-
Parent: subGroup.Parent,
123-
TopologyConstraint: topologyConstraint,
124-
})
122+
newSubGroup := schedulingv2alpha2.SubGroup{
123+
Name: subGroup.Name,
124+
Parent: subGroup.Parent,
125+
TopologyConstraint: topologyConstraint,
126+
}
127+
if subGroup.MinSubGroup != nil {
128+
newSubGroup.MinSubGroup = subGroup.MinSubGroup
129+
} else {
130+
newSubGroup.MinMember = ptr.To(subGroup.MinAvailable)
131+
}
132+
pg.Spec.SubGroups = append(pg.Spec.SubGroups, newSubGroup)
125133
}
126134

127135
pg.Spec.TopologyConstraint = schedulingv2alpha2.TopologyConstraint{

pkg/podgrouper/podgroup/handler_test.go

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ func Test_createPodGroupForMetadata(t *testing.T) {
316316
{
317317
Name: "parent-group",
318318
MinAvailable: 0,
319+
MinSubGroup: ptr.To(int32(2)),
319320
Parent: nil,
320321
},
321322
{
@@ -354,7 +355,7 @@ func Test_createPodGroupForMetadata(t *testing.T) {
354355
SubGroups: []schedulingv2alpha2.SubGroup{
355356
{
356357
Name: "parent-group",
357-
MinMember: ptr.To(int32(0)),
358+
MinSubGroup: ptr.To(int32(2)),
358359
Parent: nil,
359360
TopologyConstraint: nil,
360361
},
@@ -560,6 +561,7 @@ func Test_createPodGroupForMetadata(t *testing.T) {
560561
{
561562
Name: "parent-group",
562563
MinAvailable: 0,
564+
MinSubGroup: ptr.To(int32(2)),
563565
Parent: nil,
564566
TopologyConstraints: &TopologyConstraintMetadata{
565567
PreferredTopologyLevel: "rack",
@@ -621,9 +623,9 @@ func Test_createPodGroupForMetadata(t *testing.T) {
621623
MinMember: ptr.To(int32(20)),
622624
SubGroups: []schedulingv2alpha2.SubGroup{
623625
{
624-
Name: "parent-group",
625-
MinMember: ptr.To(int32(0)),
626-
Parent: nil,
626+
Name: "parent-group",
627+
MinSubGroup: ptr.To(int32(2)),
628+
Parent: nil,
627629
TopologyConstraint: &schedulingv2alpha2.TopologyConstraint{
628630
PreferredTopologyLevel: "rack",
629631
RequiredTopologyLevel: "zone",
@@ -665,6 +667,57 @@ func Test_createPodGroupForMetadata(t *testing.T) {
665667
},
666668
},
667669
},
670+
{
671+
name: "MinSubGroup at root populates Spec.MinSubGroup and leaves MinMember nil",
672+
input: Metadata{
673+
Name: "root-minsubgroup",
674+
Namespace: "ns",
675+
MinSubGroup: ptr.To(int32(2)),
676+
Owner: metav1.OwnerReference{APIVersion: "v1", Kind: "Pod", Name: "o", UID: "u"},
677+
},
678+
expected: &schedulingv2alpha2.PodGroup{
679+
ObjectMeta: metav1.ObjectMeta{
680+
Name: "root-minsubgroup",
681+
Namespace: "ns",
682+
OwnerReferences: []metav1.OwnerReference{
683+
{APIVersion: "v1", Kind: "Pod", Name: "o", UID: "u"},
684+
},
685+
},
686+
Spec: schedulingv2alpha2.PodGroupSpec{
687+
MinSubGroup: ptr.To(int32(2)),
688+
SubGroups: []schedulingv2alpha2.SubGroup{},
689+
},
690+
},
691+
},
692+
{
693+
name: "MinSubGroup on a SubGroup populates SubGroup.MinSubGroup and leaves MinMember nil",
694+
input: Metadata{
695+
Name: "parent-pg",
696+
Namespace: "ns",
697+
MinSubGroup: ptr.To(int32(1)),
698+
Owner: metav1.OwnerReference{APIVersion: "v1", Kind: "Pod", Name: "o", UID: "u"},
699+
SubGroups: []*SubGroupMetadata{
700+
{Name: "parent", MinSubGroup: ptr.To(int32(3))},
701+
{Name: "leaf-0", MinAvailable: 4, Parent: ptr.To("parent")},
702+
},
703+
},
704+
expected: &schedulingv2alpha2.PodGroup{
705+
ObjectMeta: metav1.ObjectMeta{
706+
Name: "parent-pg",
707+
Namespace: "ns",
708+
OwnerReferences: []metav1.OwnerReference{
709+
{APIVersion: "v1", Kind: "Pod", Name: "o", UID: "u"},
710+
},
711+
},
712+
Spec: schedulingv2alpha2.PodGroupSpec{
713+
MinSubGroup: ptr.To(int32(1)),
714+
SubGroups: []schedulingv2alpha2.SubGroup{
715+
{Name: "parent", MinSubGroup: ptr.To(int32(3))},
716+
{Name: "leaf-0", MinMember: ptr.To(int32(4)), Parent: ptr.To("parent")},
717+
},
718+
},
719+
},
720+
},
668721
}
669722

670723
for _, tt := range tests {

pkg/podgrouper/podgroup/metadata.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type TopologyConstraintMetadata struct {
1717
type SubGroupMetadata struct {
1818
Name string
1919
MinAvailable int32
20+
MinSubGroup *int32
2021
Parent *string
2122
PodsReferences []string
2223
TopologyConstraints *TopologyConstraintMetadata
@@ -31,6 +32,7 @@ type Metadata struct {
3132
Namespace string
3233
Name string
3334
MinAvailable int32
35+
MinSubGroup *int32
3436
Owner metav1.OwnerReference
3537
SubGroups []*SubGroupMetadata
3638

pkg/podgrouper/podgrouper/plugins/grove/grove_grouper.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -417,7 +417,7 @@ func parseGroupTopologyConfig(config map[string]interface{}, subGroupToParentMap
417417

418418
return &podgroup.SubGroupMetadata{
419419
Name: name,
420-
MinAvailable: 0,
420+
MinSubGroup: ptr.To(int32(len(podGroupNames))),
421421
Parent: nil,
422422
PodsReferences: nil,
423423
TopologyConstraints: topologyConstraint,

pkg/podgrouper/podgrouper/plugins/grove/grove_grouper_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,8 @@ func TestGetPodGroupMetadata_WithTopologyHierarchy(t *testing.T) {
405405
// Parent SubGroup
406406
assert.Equal(t, "group1", metadata.SubGroups[0].Name)
407407
assert.Equal(t, int32(0), metadata.SubGroups[0].MinAvailable)
408+
assert.NotNil(t, metadata.SubGroups[0].MinSubGroup)
409+
assert.Equal(t, int32(2), *metadata.SubGroups[0].MinSubGroup)
408410
assert.Nil(t, metadata.SubGroups[0].Parent)
409411
assert.NotNil(t, metadata.SubGroups[0].TopologyConstraints)
410412
assert.Equal(t, "node", metadata.SubGroups[0].TopologyConstraints.PreferredTopologyLevel)
@@ -593,8 +595,12 @@ func TestGetPodGroupMetadata_MultipleParentGroups(t *testing.T) {
593595
// Parents first
594596
assert.Equal(t, "group1", metadata.SubGroups[0].Name)
595597
assert.Equal(t, int32(0), metadata.SubGroups[0].MinAvailable)
598+
assert.NotNil(t, metadata.SubGroups[0].MinSubGroup)
599+
assert.Equal(t, int32(2), *metadata.SubGroups[0].MinSubGroup)
596600
assert.Equal(t, "group2", metadata.SubGroups[1].Name)
597601
assert.Equal(t, int32(0), metadata.SubGroups[1].MinAvailable)
602+
assert.NotNil(t, metadata.SubGroups[1].MinSubGroup)
603+
assert.Equal(t, int32(1), *metadata.SubGroups[1].MinSubGroup)
598604

599605
// Children
600606
assert.Equal(t, "pg1", metadata.SubGroups[2].Name)
@@ -1906,6 +1912,8 @@ func TestGetPodGroupMetadata_ThreeLevelTopologyWithLeafVerification(t *testing.T
19061912
assert.Equal(t, "test-topology", metadata.SubGroups[0].TopologyConstraints.Topology)
19071913
assert.Nil(t, metadata.SubGroups[0].Parent)
19081914
assert.Equal(t, int32(0), metadata.SubGroups[0].MinAvailable)
1915+
assert.NotNil(t, metadata.SubGroups[0].MinSubGroup)
1916+
assert.Equal(t, int32(2), *metadata.SubGroups[0].MinSubGroup)
19091917

19101918
// Level 2: Verify Parent group2
19111919
assert.Equal(t, "group2", metadata.SubGroups[1].Name)
@@ -1915,6 +1923,8 @@ func TestGetPodGroupMetadata_ThreeLevelTopologyWithLeafVerification(t *testing.T
19151923
assert.Equal(t, "test-topology", metadata.SubGroups[1].TopologyConstraints.Topology)
19161924
assert.Nil(t, metadata.SubGroups[1].Parent)
19171925
assert.Equal(t, int32(0), metadata.SubGroups[1].MinAvailable)
1926+
assert.NotNil(t, metadata.SubGroups[1].MinSubGroup)
1927+
assert.Equal(t, int32(1), *metadata.SubGroups[1].MinSubGroup)
19181928

19191929
// Level 3 (LEAF): Verify Child pg1 under group1
19201930
assert.Equal(t, "pg1", metadata.SubGroups[2].Name)

0 commit comments

Comments
 (0)