From 4edb93b58105b500bf464f625446cfd6f415b59d Mon Sep 17 00:00:00 2001 From: ston1th Date: Wed, 10 Jun 2020 00:35:20 +0200 Subject: [PATCH] added initial node scheduling --- node.go | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 123 insertions(+), 2 deletions(-) diff --git a/node.go b/node.go index f58bc1e..e6b05a5 100644 --- a/node.go +++ b/node.go @@ -23,16 +23,137 @@ const ( ) type Node struct { - Name string `json:"node"` - Status NodeStatus `json:"status"` + Name string `json:"node"` + Status NodeStatus `json:"status"` + CPU float64 `json:"cpu"` + MaxCPU float64 `json:"maxcpu"` + Mem int64 `json:"mem"` + MaxMem int64 `json:"maxmem"` + Disk int64 `json:"disk"` + MaxDisk int64 `json:"maxdisk"` + ServerList ServerList `json:"-"` +} + +func (n *Node) MemFreePercent() float64 { + return float64(n.Mem) / float64(n.MaxMem) * 100 } type NodeList []*Node +func (nl NodeList) sortByFreeMem() { + sort.Sort(memSorter(nl)) +} + +func (nl *NodeList) remove(i int) { + (*nl)[i] = (*nl)[len(*nl)-1] + *nl = (*nl)[:len(*nl)-1] +} + +func (nl *NodeList) Filter(filters ...NodeFilter) { + for _, f := range filters { + f(nl) + } +} + +func (nl *NodeList) GetServerList(ctx context.Context, c *NodeClient) (err error) { + for _, n := range *nl { + n.ServerList, err = c.ListServers(ctx, n) + if err != nil { + return + } + } +} + +type memSorter NodeList + +func (m memSorter) Len() int { return len(m) } +func (m memSorter) Less(i, j int) bool { return m[i].MemFreePercent() < m[j].MemFreePercent() } +func (m memSorter) Swap(i, j int) { m[i], m[j] = m[j], m[i] } + +type NodeFilter func(*NodeList) + +func FilterOnlineNode() NodeFilter { + return func(nl *NodeList) { + for i, n := range *nl { + if n.Status != NodeStatusOnline { + nl.remove(i) + } + } + } +} + +func FilterNodeName(name string) NodeFilter { + return func(nl *NodeList) { + for i, n := range *nl { + if n.Name == name { + nl.remove(i) + return + } + } + } +} + +func FilterMaxCores(cores int64) NodeFilter { + return func(nl *NodeList) { + for i, n := range *nl { + if cores > n.MaxCPU { + nl.remove(i) + } + } + } +} + +const ( + mib = 1024 * 1024 + gib = mib * 1024 +) + +func FilterFreeMem(mem int64) NodeFilter { + return func(nl *NodeList) { + for i, n := range *nl { + if (mem * gib) >= n.MaxMem-n.Mem { + nl.remove(i) + } + } + } +} + +// Useful? only local disk? +func FilterFreeDisk(disk int64) NodeFilter { + return func(nl *NodeList) { + for i, n := range *nl { + if (disk * gib) >= n.MaxDisk-n.Disk { + nl.remove(i) + } + } + } +} + +func FilterVMAntiAffinity(url string) NodeFilter { + return func(nl *NodeList) { + _, _, id, err := ParseURL(url) + if err != nil { + return + } + for i, n := range *nl { + for _, s := range n.ServerList { + if s.ID == id { + nl.remove(i) + return + } + } + } + } +} + type NodeClient struct { client *Client } +func (c *NodeClient) Schedule(ctx context.Context) (n *Node, err error) { + return +} + func (c *NodeClient) List(ctx context.Context) (nl NodeList, err error) { req, err := c.client.NewRequest(ctx, "GET", "/nodes", nil) if err != nil {