-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(schd): returning list of preferred nodes for scheduling #2
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,16 +17,22 @@ limitations under the License. | |
package scheduler | ||
|
||
import ( | ||
"math" | ||
"sort" | ||
|
||
"github.com/container-storage-interface/spec/lib/go/csi" | ||
k8sapi "github.com/openebs/lib-csi/pkg/client/k8s" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/klog" | ||
) | ||
|
||
// key value struct for creating the filtered list | ||
type kv struct { | ||
Key string | ||
Value int64 | ||
} | ||
|
||
// getNodeList gets the nodelist which satisfies the topology info | ||
func getNodeList(topo *csi.TopologyRequirement) ([]string, error) { | ||
func getNodeList(topo []*csi.Topology) ([]string, error) { | ||
|
||
var nodelist []string | ||
|
||
|
@@ -36,7 +42,7 @@ func getNodeList(topo *csi.TopologyRequirement) ([]string, error) { | |
} | ||
|
||
for _, node := range list.Items { | ||
for _, prf := range topo.Preferred { | ||
for _, prf := range topo { | ||
nodeFiltered := false | ||
for key, value := range prf.Segments { | ||
if node.Labels[key] != value { | ||
|
@@ -54,45 +60,70 @@ func getNodeList(topo *csi.TopologyRequirement) ([]string, error) { | |
return nodelist, nil | ||
} | ||
|
||
// runScheduler goes through the node mapping | ||
// in the topology and picks the node which is less weighted | ||
func runScheduler(nodelist []string, nmap map[string]int64) string { | ||
var selected string | ||
// runScheduler goes through the node mapping in the topology | ||
// and creates the list of preferred nodes as per their weight | ||
func runScheduler(nodelist []string, nmap map[string]int64) []string { | ||
var preferred []string | ||
var fmap []kv | ||
|
||
var weight int64 = math.MaxInt64 | ||
|
||
// schedule it on the node which has less weight | ||
// go though the filtered node and prepare the preferred list | ||
for _, node := range nodelist { | ||
if nmap[node] < weight { | ||
selected = node | ||
weight = nmap[node] | ||
if val, ok := nmap[node]; ok { | ||
// create the filtered node map | ||
fmap = append(fmap, kv{node, val}) | ||
} else { | ||
// put the non occupied nodes in beginning of the list | ||
preferred = append(preferred, node) | ||
} | ||
} | ||
return selected | ||
|
||
// sort the filtered node map | ||
sort.Slice(fmap, func(i, j int) bool { | ||
return fmap[i].Value < fmap[j].Value | ||
}) | ||
|
||
// put the occupied nodes in the sorted order at the end | ||
for _, kv := range fmap { | ||
preferred = append(preferred, kv.Key) | ||
} | ||
|
||
return preferred | ||
} | ||
|
||
// Scheduler schedules the PV as per topology constraints for | ||
// the given node weight. | ||
func Scheduler(req *csi.CreateVolumeRequest, nmap map[string]int64) string { | ||
topo := req.AccessibilityRequirements | ||
if topo == nil || | ||
len(topo.Preferred) == 0 { | ||
func Scheduler(req *csi.CreateVolumeRequest, nmap map[string]int64) []string { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. q_: is it required to maintain backward compatibility for this API so that any of the CSI drivers using this method can still work, after this is merged and if they are using the latest code from this repo (without changing their code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it will work even after the merge because of the gomod. |
||
var nodelist []string | ||
areq := req.AccessibilityRequirements | ||
|
||
if areq == nil { | ||
klog.Errorf("scheduler: Accessibility Requirements not provided") | ||
return nodelist | ||
} | ||
|
||
topo := areq.Preferred | ||
if len(topo) == 0 { | ||
// if preferred list is empty, use the requisite | ||
topo = areq.Requisite | ||
} | ||
|
||
if len(topo) == 0 { | ||
klog.Errorf("scheduler: topology information not provided") | ||
return "" | ||
return nodelist | ||
} | ||
|
||
nodelist, err := getNodeList(topo) | ||
if err != nil { | ||
klog.Errorf("scheduler: can not get the nodelist err : %v", err.Error()) | ||
return "" | ||
return nodelist | ||
} else if len(nodelist) == 0 { | ||
klog.Errorf("scheduler: nodelist is empty") | ||
return "" | ||
return nodelist | ||
} | ||
|
||
// if there is a single node, schedule it on that | ||
if len(nodelist) == 1 { | ||
return nodelist[0] | ||
return nodelist | ||
} | ||
|
||
return runScheduler(nodelist, nmap) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
n_: the comments needs to change to reflect the change in the logic.