Skip to content

Commit 99371ae

Browse files
committed
node scheduler
1 parent 1371175 commit 99371ae

File tree

19 files changed

+677
-91
lines changed

19 files changed

+677
-91
lines changed

cloud/interfaces.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type ClusterSettter interface {
4646
// MachineGetter is an interface which can get machine information.
4747
type MachineGetter interface {
4848
Client
49-
GetScheduler() *scheduler.Scheduler
49+
GetScheduler(client *proxmox.Service) *scheduler.Scheduler
5050
Name() string
5151
Namespace() string
5252
// Zone() string
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
package framework
2+
3+
type CycleState struct {
4+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package framework
2+
3+
import (
4+
"context"
5+
6+
"github.com/sp-yduck/proxmox-go/api"
7+
)
8+
9+
type Plugin interface {
10+
// return plugin name
11+
Name() string
12+
}
13+
14+
type NodeFilterPlugin interface {
15+
Plugin
16+
Filter(ctx context.Context, state *CycleState, config api.VirtualMachineCreateOptions, nodeInfo *NodeInfo) *Status
17+
}
18+
19+
type NodeScorePlugin interface {
20+
Plugin
21+
Score(ctx context.Context, state *CycleState, config api.VirtualMachineCreateOptions, nodeInfo *NodeInfo) (int64, *Status)
22+
}

cloud/scheduler/framework/types.go

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
package framework
2+
3+
import (
4+
"context"
5+
6+
"github.com/sp-yduck/proxmox-go/api"
7+
"github.com/sp-yduck/proxmox-go/proxmox"
8+
)
9+
10+
type Status struct {
11+
code int
12+
reasons []string
13+
err error
14+
failedPlugin string
15+
}
16+
17+
func NewStatus() *Status {
18+
return &Status{code: 0}
19+
}
20+
21+
func (s *Status) Code() int {
22+
return s.code
23+
}
24+
25+
func (s *Status) SetCode(code int) {
26+
s.code = code
27+
}
28+
29+
func (s *Status) Reasons() []string {
30+
if s.err != nil {
31+
return append([]string{s.err.Error()}, s.reasons...)
32+
}
33+
return s.reasons
34+
}
35+
36+
func (s *Status) FailedPlugin() string {
37+
return s.failedPlugin
38+
}
39+
40+
func (s *Status) SetFailedPlugin(name string) {
41+
s.failedPlugin = name
42+
}
43+
44+
func (s *Status) IsSuccess() bool {
45+
return s.code == 0
46+
}
47+
48+
func (s *Status) Error() error {
49+
return s.err
50+
}
51+
52+
// NodeInfo is node level aggregated information
53+
type NodeInfo struct {
54+
node *api.Node
55+
56+
// qemus assigned to the node
57+
qemus []*api.VirtualMachine
58+
}
59+
60+
func GetNodeInfoList(ctx context.Context, client *proxmox.Service) ([]*NodeInfo, error) {
61+
nodes, err := client.Nodes(ctx)
62+
if err != nil {
63+
return nil, err
64+
}
65+
nodeInfos := []*NodeInfo{}
66+
for _, node := range nodes {
67+
qemus, err := client.RESTClient().GetVirtualMachines(ctx, node.Node)
68+
if err != nil {
69+
return nil, err
70+
}
71+
nodeInfos = append(nodeInfos, &NodeInfo{node: node, qemus: qemus})
72+
}
73+
return nodeInfos, nil
74+
}
75+
76+
func (n NodeInfo) Node() *api.Node {
77+
return n.node
78+
}
79+
80+
// NodeScoreList declares a list of nodes and their scores.
81+
type NodeScoreList []NodeScore
82+
83+
// NodeScore is a struct with node name and score.
84+
type NodeScore struct {
85+
Name string
86+
Score int64
87+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package names
2+
3+
// node plugins
4+
const (
5+
// filter plugins
6+
7+
NodeName = "NodeName"
8+
9+
// score plugins
10+
11+
Random = "Random"
12+
)
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package nodename
2+
3+
import (
4+
"context"
5+
6+
"github.com/sp-yduck/proxmox-go/api"
7+
8+
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scheduler/framework"
9+
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scheduler/plugins/node/names"
10+
)
11+
12+
type NodeName struct{}
13+
14+
var _ framework.NodeFilterPlugin = &NodeName{}
15+
16+
const (
17+
Name = names.NodeName
18+
ErrReason = "node didn't match the requested node name"
19+
)
20+
21+
func (pl *NodeName) Name() string {
22+
return Name
23+
}
24+
25+
func (pl *NodeName) Filter(ctx context.Context, _ *framework.CycleState, config api.VirtualMachineCreateOptions, nodeInfo *framework.NodeInfo) *framework.Status {
26+
if !Fits(config, nodeInfo) {
27+
status := framework.NewStatus()
28+
status.SetCode(1)
29+
return status
30+
}
31+
return &framework.Status{}
32+
}
33+
34+
// return true if config.Node is empty or match with node name
35+
func Fits(config api.VirtualMachineCreateOptions, nodeInfo *framework.NodeInfo) bool {
36+
return config.Node == "" || config.Node == nodeInfo.Node().Node
37+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package random
2+
3+
import (
4+
"context"
5+
"math/rand"
6+
"time"
7+
8+
"github.com/sp-yduck/proxmox-go/api"
9+
10+
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scheduler/framework"
11+
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scheduler/plugins/node/names"
12+
)
13+
14+
type Random struct{}
15+
16+
var _ framework.NodeScorePlugin = &Random{}
17+
18+
const (
19+
Name = names.Random
20+
)
21+
22+
func (pl *Random) Name() string {
23+
return Name
24+
}
25+
26+
// return random score: 0 <= n < 100
27+
func (pl *Random) Score(ctx context.Context, state *framework.CycleState, config api.VirtualMachineCreateOptions, nodeInfo *framework.NodeInfo) (int64, *framework.Status) {
28+
src := rand.NewSource(time.Now().Unix())
29+
r := rand.New(src)
30+
score := r.Int63n(100)
31+
return score, nil
32+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package plugins
2+
3+
import (
4+
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scheduler/framework"
5+
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scheduler/plugins/node/nodename"
6+
"github.com/sp-yduck/cluster-api-provider-proxmox/cloud/scheduler/plugins/node/random"
7+
)
8+
9+
func NewNodeFilterPlugins() []framework.NodeFilterPlugin {
10+
return []framework.NodeFilterPlugin{&nodename.NodeName{}}
11+
}
12+
13+
func NewNodeScorePlugins() []framework.NodeScorePlugin {
14+
return []framework.NodeScorePlugin{&random.Random{}}
15+
}

0 commit comments

Comments
 (0)