@@ -17,16 +17,22 @@ limitations under the License.
17
17
package scheduler
18
18
19
19
import (
20
- "math "
20
+ "sort "
21
21
22
22
"github.com/container-storage-interface/spec/lib/go/csi"
23
23
k8sapi "github.com/openebs/lib-csi/pkg/client/k8s"
24
24
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25
25
"k8s.io/klog"
26
26
)
27
27
28
+ // key value struct for creating the filtered list
29
+ type kv struct {
30
+ Key string
31
+ Value int64
32
+ }
33
+
28
34
// getNodeList gets the nodelist which satisfies the topology info
29
- func getNodeList (topo * csi.TopologyRequirement ) ([]string , error ) {
35
+ func getNodeList (topo [] * csi.Topology ) ([]string , error ) {
30
36
31
37
var nodelist []string
32
38
@@ -36,7 +42,7 @@ func getNodeList(topo *csi.TopologyRequirement) ([]string, error) {
36
42
}
37
43
38
44
for _ , node := range list .Items {
39
- for _ , prf := range topo . Preferred {
45
+ for _ , prf := range topo {
40
46
nodeFiltered := false
41
47
for key , value := range prf .Segments {
42
48
if node .Labels [key ] != value {
@@ -54,45 +60,70 @@ func getNodeList(topo *csi.TopologyRequirement) ([]string, error) {
54
60
return nodelist , nil
55
61
}
56
62
57
- // runScheduler goes through the node mapping
58
- // in the topology and picks the node which is less weighted
59
- func runScheduler (nodelist []string , nmap map [string ]int64 ) string {
60
- var selected string
63
+ // runScheduler goes through the node mapping in the topology
64
+ // and creates the list of preferred nodes as per their weight
65
+ func runScheduler (nodelist []string , nmap map [string ]int64 ) []string {
66
+ var preferred []string
67
+ var fmap []kv
61
68
62
- var weight int64 = math .MaxInt64
63
-
64
- // schedule it on the node which has less weight
69
+ // go though the filtered node and prepare the preferred list
65
70
for _ , node := range nodelist {
66
- if nmap [node ] < weight {
67
- selected = node
68
- weight = nmap [node ]
71
+ if val , ok := nmap [node ]; ok {
72
+ // create the filtered node map
73
+ fmap = append (fmap , kv {node , val })
74
+ } else {
75
+ // put the non occupied nodes in beginning of the list
76
+ preferred = append (preferred , node )
69
77
}
70
78
}
71
- return selected
79
+
80
+ // sort the filtered node map
81
+ sort .Slice (fmap , func (i , j int ) bool {
82
+ return fmap [i ].Value < fmap [j ].Value
83
+ })
84
+
85
+ // put the occupied nodes in the sorted order at the end
86
+ for _ , kv := range fmap {
87
+ preferred = append (preferred , kv .Key )
88
+ }
89
+
90
+ return preferred
72
91
}
73
92
74
93
// Scheduler schedules the PV as per topology constraints for
75
94
// the given node weight.
76
- func Scheduler (req * csi.CreateVolumeRequest , nmap map [string ]int64 ) string {
77
- topo := req .AccessibilityRequirements
78
- if topo == nil ||
79
- len (topo .Preferred ) == 0 {
95
+ func Scheduler (req * csi.CreateVolumeRequest , nmap map [string ]int64 ) []string {
96
+ var nodelist []string
97
+ areq := req .AccessibilityRequirements
98
+
99
+ if areq == nil {
100
+ klog .Errorf ("scheduler: Accessibility Requirements not provided" )
101
+ return nodelist
102
+ }
103
+
104
+ topo := areq .Preferred
105
+ if len (topo ) == 0 {
106
+ // if preferred list is empty, use the requisite
107
+ topo = areq .Requisite
108
+ }
109
+
110
+ if len (topo ) == 0 {
80
111
klog .Errorf ("scheduler: topology information not provided" )
81
- return ""
112
+ return nodelist
82
113
}
83
114
84
115
nodelist , err := getNodeList (topo )
85
116
if err != nil {
86
117
klog .Errorf ("scheduler: can not get the nodelist err : %v" , err .Error ())
87
- return ""
118
+ return nodelist
88
119
} else if len (nodelist ) == 0 {
89
120
klog .Errorf ("scheduler: nodelist is empty" )
90
- return ""
121
+ return nodelist
91
122
}
92
123
93
124
// if there is a single node, schedule it on that
94
125
if len (nodelist ) == 1 {
95
- return nodelist [ 0 ]
126
+ return nodelist
96
127
}
97
128
98
129
return runScheduler (nodelist , nmap )
0 commit comments