Skip to content

Commit b67c938

Browse files
authored
Merge pull request #954 from threefoldtech/development_update_farmerbot
update farmerbot
2 parents b8ba9e3 + 6a4d007 commit b67c938

File tree

6 files changed

+85
-141
lines changed

6 files changed

+85
-141
lines changed

internal/provider/resource_scheduler.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/pkg/errors"
1313
"github.com/threefoldtech/terraform-provider-grid/internal/provider/scheduler"
1414
"github.com/threefoldtech/tfgrid-sdk-go/grid-client/deployer"
15+
"github.com/threefoldtech/tfgrid-sdk-go/rmb-sdk-go/peer"
1516
"github.com/threefoldtech/zos/pkg/gridtypes"
1617
)
1718

@@ -132,7 +133,7 @@ func parseRequests(d *schema.ResourceData, assignment map[string]uint32) []sched
132133

133134
reqs = append(reqs, scheduler.Request{
134135
Name: mp["name"].(string),
135-
FarmId: uint32(mp["farm_id"].(int)),
136+
FarmID: uint32(mp["farm_id"].(int)),
136137
PublicConfig: mp["public_config"].(bool),
137138
PublicIpsCount: uint32(mp["public_ips_count"].(int)),
138139
Certified: mp["certified"].(bool),
@@ -158,7 +159,12 @@ func schedule(ctx context.Context, d *schema.ResourceData, meta interface{}) dia
158159
assignment := parseAssignment(d)
159160
reqs := parseRequests(d, assignment)
160161

161-
scheduler := scheduler.NewScheduler(tfPluginClient.GridProxyClient, uint64(tfPluginClient.TwinID), tfPluginClient.RMB)
162+
rpcClient, ok := tfPluginClient.RMB.(*peer.RpcClient)
163+
if !ok {
164+
return diag.FromErr(fmt.Errorf("failed to cast rmb client into rpc client"))
165+
}
166+
167+
scheduler := scheduler.NewScheduler(tfPluginClient.GridProxyClient, uint64(tfPluginClient.TwinID), rpcClient)
162168
if err := scheduler.ProcessRequests(ctx, reqs, assignment); err != nil {
163169
return diag.FromErr(err)
164170
}

internal/provider/scheduler/farmer_bot.go

Lines changed: 42 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -4,73 +4,30 @@ import (
44
"context"
55
"fmt"
66
"log"
7-
"strconv"
8-
"strings"
9-
"time"
107

11-
"github.com/google/uuid"
128
"github.com/pkg/errors"
139
)
1410

1511
const (
12+
rmbTimeout = 40
1613
FarmerBotVersionAction = "farmerbot.farmmanager.version"
1714
FarmerBotFindNodeAction = "farmerbot.nodemanager.findnode"
18-
FarmerBotRMBFunction = "execute_job"
1915
)
2016

21-
type FarmerBotAction struct {
22-
Guid string `json:"guid"`
23-
TwinID uint32 `json:"twinid"`
24-
Action string `json:"action"`
25-
Args FarmerBotArgs `json:"args"`
26-
Result FarmerBotArgs `json:"result"`
27-
State string `json:"state"`
28-
Start uint64 `json:"start"`
29-
End uint64 `json:"end"`
30-
GracePeriod uint32 `json:"grace_period"`
31-
Error string `json:"error"`
32-
Timeout uint32 `json:"timeout"`
33-
SourceTwinID uint32 `json:"src_twinid"`
34-
SourceAction string `json:"src_action"`
35-
Dependencies []string `json:"dependencies"`
36-
}
37-
38-
type FarmerBotArgs struct {
39-
Args []Args `json:"args"`
40-
Params []Params `json:"params"`
41-
}
42-
43-
type Args struct {
44-
RequiredHRU *uint64 `json:"required_hru,omitempty"`
45-
RequiredSRU *uint64 `json:"required_sru,omitempty"`
46-
RequiredCRU *uint64 `json:"required_cru,omitempty"`
47-
RequiredMRU *uint64 `json:"required_mru,omitempty"`
48-
NodeExclude []uint32 `json:"node_exclude,omitempty"`
49-
Dedicated *bool `json:"dedicated,omitempty"`
50-
PublicConfig *bool `json:"public_config,omitempty"`
51-
PublicIPs *uint32 `json:"public_ips"`
52-
Certified *bool `json:"certified,omitempty"`
53-
}
54-
55-
type Params struct {
56-
Key string `json:"key"`
57-
Value interface{} `json:"value"`
58-
}
59-
6017
func (s *Scheduler) hasFarmerBot(ctx context.Context, farmID uint32) bool {
61-
args := []Args{}
62-
params := []Params{}
63-
data := buildFarmerBotAction(farmID, uint32(s.twinID), args, params, FarmerBotVersionAction)
18+
ctx, cancel := context.WithTimeout(ctx, rmbTimeout)
19+
defer cancel()
6420

6521
info, err := s.getFarmInfo(ctx, farmID)
6622
if err != nil {
6723
return false
6824
}
6925

7026
dst := info.farmerTwinID
71-
var output FarmerBotAction
7227

73-
err = s.rmbClient.Call(ctx, dst, FarmerBotRMBFunction, data, &output)
28+
service := fmt.Sprintf("farmerbot-%d", farmID)
29+
var version string
30+
err = s.rmbClient.CallWithSession(ctx, info.farmerTwinID, &service, FarmerBotVersionAction, nil, &version)
7431
if err != nil {
7532
log.Printf("error while pinging farmerbot on farm %d with farmer twin %d. %s", farmID, dst, err.Error())
7633
}
@@ -79,94 +36,75 @@ func (s *Scheduler) hasFarmerBot(ctx context.Context, farmID uint32) bool {
7936
}
8037

8138
func (n *Scheduler) farmerBotSchedule(ctx context.Context, r *Request) (uint32, error) {
82-
info, err := n.getFarmInfo(ctx, r.FarmId)
83-
if err != nil {
84-
return 0, errors.Wrapf(err, "failed to get farm %d info", r.FarmId)
85-
}
86-
params := buildFarmerBotParams(r)
87-
args := buildFarmerBotArgs(r)
88-
data := buildFarmerBotAction(info.farmerTwinID, uint32(n.twinID), args, params, FarmerBotFindNodeAction)
89-
output := FarmerBotAction{}
39+
ctx, cancel := context.WithTimeout(ctx, rmbTimeout)
40+
defer cancel()
9041

91-
err = n.rmbClient.Call(ctx, info.farmerTwinID, FarmerBotRMBFunction, data, &output)
42+
info, err := n.getFarmInfo(ctx, r.FarmID)
9243
if err != nil {
93-
return 0, err
94-
}
95-
if len(output.Result.Params) < 1 {
96-
return 0, fmt.Errorf("cannot find an eligible node on farm %d", r.FarmId)
44+
return 0, errors.Wrapf(err, "failed to get farm %d info", r.FarmID)
9745
}
98-
nodeId, err := strconv.ParseUint(output.Result.Params[0].Value.(string), 10, 32)
99-
if err != nil {
46+
47+
data := buildNodeOptions(r)
48+
var nodeID uint32
49+
50+
service := fmt.Sprintf("farmerbot-%d", r.FarmID)
51+
if err := n.rmbClient.CallWithSession(ctx, info.farmerTwinID, &service, FarmerBotFindNodeAction, data, &nodeID); err != nil {
10052
return 0, err
10153
}
102-
log.Printf("got a node with id %d", nodeId)
103-
return uint32(nodeId), nil
54+
55+
log.Printf("got a node with id %d", nodeID)
56+
return nodeID, nil
10457
}
10558

106-
func buildFarmerBotArgs(r *Request) []Args {
107-
return []Args{}
59+
type NodeFilterOption struct {
60+
NodesExcluded []uint32 `json:"nodes_excluded,omitempty"`
61+
Certified bool `json:"certified,omitempty"`
62+
Dedicated bool `json:"dedicated,omitempty"`
63+
PublicConfig bool `json:"public_config,omitempty"`
64+
PublicIPs uint64 `json:"public_ips,omitempty"`
65+
HRU uint64 `json:"hru,omitempty"` // in GB
66+
SRU uint64 `json:"sru,omitempty"` // in GB
67+
CRU uint64 `json:"cru,omitempty"`
68+
MRU uint64 `json:"mru,omitempty"` // in GB
10869
}
109-
func buildFarmerBotParams(r *Request) []Params {
110-
params := []Params{}
70+
71+
func buildNodeOptions(r *Request) NodeFilterOption {
72+
options := NodeFilterOption{}
11173
if r.Capacity.HRU != 0 {
112-
params = append(params, Params{Key: "required_hru", Value: r.Capacity.HRU})
74+
options.HRU = r.Capacity.HRU / (1024 * 1024 * 1024)
11375
}
11476

11577
if r.Capacity.SRU != 0 {
116-
params = append(params, Params{Key: "required_sru", Value: r.Capacity.SRU})
78+
options.SRU = r.Capacity.SRU / (1024 * 1024 * 1024)
11779
}
11880

11981
if r.Capacity.MRU != 0 {
120-
params = append(params, Params{Key: "required_mru", Value: r.Capacity.MRU})
82+
options.MRU = r.Capacity.MRU / (1024 * 1024 * 1024)
12183
}
12284

12385
if r.Capacity.CRU != 0 {
124-
params = append(params, Params{Key: "required_cru", Value: r.Capacity.CRU})
86+
options.CRU = r.Capacity.CRU
12587
}
12688

12789
if len(r.NodeExclude) != 0 {
128-
value := strings.Trim(strings.Join(strings.Fields(fmt.Sprint(r.NodeExclude)), ","), "")
129-
params = append(params, Params{Key: "node_exclude", Value: value})
90+
options.NodesExcluded = append(options.NodesExcluded, r.NodeExclude...)
13091
}
13192

13293
if r.Dedicated {
133-
params = append(params, Params{Key: "dedicated", Value: r.Dedicated})
94+
options.Dedicated = r.Dedicated
13495
}
13596

13697
if r.PublicConfig {
137-
params = append(params, Params{Key: "public_config", Value: r.PublicConfig})
98+
options.PublicConfig = r.PublicConfig
13899
}
139100

140101
if r.PublicIpsCount > 0 {
141-
params = append(params, Params{Key: "public_ips", Value: r.PublicIpsCount})
102+
options.PublicIPs = uint64(r.PublicIpsCount)
142103
}
143104

144105
if r.Certified {
145-
params = append(params, Params{Key: "certified", Value: r.Certified})
106+
options.Certified = r.Certified
146107
}
147-
return params
148-
}
149108

150-
func buildFarmerBotAction(farmerTwinID uint32, sourceTwinID uint32, args []Args, params []Params, action string) FarmerBotAction {
151-
return FarmerBotAction{
152-
Guid: uuid.NewString(),
153-
TwinID: farmerTwinID,
154-
Action: action,
155-
Args: FarmerBotArgs{
156-
Args: args,
157-
Params: params,
158-
},
159-
Result: FarmerBotArgs{
160-
Args: []Args{},
161-
Params: []Params{},
162-
},
163-
State: "init",
164-
Start: uint64(time.Now().Unix()),
165-
End: 0,
166-
GracePeriod: 0,
167-
Error: "",
168-
Timeout: 6000,
169-
SourceTwinID: sourceTwinID,
170-
Dependencies: []string{},
171-
}
109+
return options
172110
}

internal/provider/scheduler/request.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ var (
1414
type Request struct {
1515
Capacity Capacity
1616
Name string
17-
FarmId uint32
17+
FarmID uint32
1818
PublicConfig bool
1919
PublicIpsCount uint32
2020
Certified bool
@@ -28,8 +28,9 @@ func (r *Request) constructFilter(twinID uint64) (f proxyTypes.NodeFilter) {
2828
// grid proxy should support filtering a node by certification type.
2929
f.Status = []string{statusUP}
3030
f.AvailableFor = &twinID
31-
if r.FarmId != 0 {
32-
f.FarmIDs = []uint64{uint64(r.FarmId)}
31+
f.Healthy = &trueVal
32+
if r.FarmID != 0 {
33+
f.FarmIDs = []uint64{uint64(r.FarmID)}
3334
}
3435
if r.Capacity.HRU != 0 {
3536
f.FreeHRU = &r.Capacity.HRU

internal/provider/scheduler/request_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func TestFulfilsSuccess(t *testing.T) {
2929
SRU: 3,
3030
HRU: 3,
3131
},
32-
FarmId: 1,
32+
FarmID: 1,
3333
PublicIpsCount: 1,
3434
PublicConfig: false,
3535
}, farm), true, "fullfil-success")
@@ -53,7 +53,7 @@ func TestFulfilsFail(t *testing.T) {
5353
SRU: 3,
5454
HRU: 3,
5555
},
56-
FarmId: 1,
56+
FarmID: 1,
5757
PublicIpsCount: 0,
5858
PublicConfig: false,
5959
}
@@ -66,7 +66,7 @@ func TestFulfilsFail(t *testing.T) {
6666
"mru": func(r *Request) { r.Capacity.MRU = 4 },
6767
"sru": func(r *Request) { r.Capacity.SRU = 9 },
6868
"hru": func(r *Request) { r.Capacity.HRU = 4 },
69-
"farm_id": func(r *Request) { r.FarmId = 2 },
69+
"farm_id": func(r *Request) { r.FarmID = 2 },
7070
"public_ips_count": func(r *Request) { r.PublicIpsCount = 3 },
7171
"public_config": func(r *Request) { r.PublicConfig = true },
7272
}
@@ -86,7 +86,7 @@ func TestConstructFilter(t *testing.T) {
8686
HRU: 3,
8787
},
8888
Name: "a",
89-
FarmId: 1,
89+
FarmID: 1,
9090
PublicIpsCount: 1,
9191
PublicConfig: false,
9292
Certified: true,
@@ -99,7 +99,7 @@ func TestConstructFilter(t *testing.T) {
9999
assert.Equal(t, *con.FreeHRU, uint64(3), "construct-filter-hru")
100100
assert.Empty(t, con.Country, "construct-filter-country")
101101
assert.Empty(t, con.City, "construct-filter-city")
102-
assert.Equal(t, con.FarmIDs, []uint64{uint64(r.FarmId)}, "construct-filter-farm-ids")
102+
assert.Equal(t, con.FarmIDs, []uint64{uint64(r.FarmID)}, "construct-filter-farm-ids")
103103
assert.Equal(t, *con.FreeIPs, uint64(1), "construct-filter-free-ips")
104104
assert.Empty(t, con.IPv4, "construct-filter-ipv4")
105105
assert.Empty(t, con.IPv6, "construct-filter-ipv6")

internal/provider/scheduler/scheduler.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,22 @@ import (
99
"github.com/pkg/errors"
1010
proxy "github.com/threefoldtech/tfgrid-sdk-go/grid-proxy/pkg/client"
1111
proxyTypes "github.com/threefoldtech/tfgrid-sdk-go/grid-proxy/pkg/types"
12-
"github.com/threefoldtech/tfgrid-sdk-go/rmb-sdk-go"
1312
)
1413

1514
// NoNodesFoundErr for empty nodes returned from scheduler
1615
var NoNodesFoundErr = errors.New("couldn't find a node satisfying the given requirements")
1716

17+
type rmbClient interface {
18+
CallWithSession(ctx context.Context, twin uint32, session *string, fn string, data interface{}, result interface{}) error
19+
}
20+
1821
// Scheduler struct for scheduling
1922
type Scheduler struct {
2023
nodes map[uint32]nodeInfo
2124
farms map[uint32]farmInfo
2225
twinID uint64
2326
gridProxyClient proxy.Client
24-
rmbClient rmb.Client
27+
rmbClient rmbClient
2528
}
2629

2730
// nodeInfo related to scheduling
@@ -45,7 +48,7 @@ func (node *nodeInfo) fulfils(r *Request, farm farmInfo) bool {
4548
if r.Capacity.MRU > node.FreeCapacity.MRU ||
4649
r.Capacity.HRU > node.FreeCapacity.HRU ||
4750
r.Capacity.SRU > node.FreeCapacity.SRU ||
48-
(r.FarmId != 0 && node.Node.FarmID != int(r.FarmId)) ||
51+
(r.FarmID != 0 && node.Node.FarmID != int(r.FarmID)) ||
4952
(r.PublicConfig && node.Node.PublicConfig.Domain == "") ||
5053
(r.PublicIpsCount > uint32(farm.freeIPs)) ||
5154
(r.Dedicated && !node.Node.Dedicated) ||
@@ -57,7 +60,7 @@ func (node *nodeInfo) fulfils(r *Request, farm farmInfo) bool {
5760
}
5861

5962
// NewScheduler generates a new scheduler
60-
func NewScheduler(gridProxyClient proxy.Client, twinID uint64, rmbClient rmb.Client) Scheduler {
63+
func NewScheduler(gridProxyClient proxy.Client, twinID uint64, rmbClient rmbClient) Scheduler {
6164
return Scheduler{
6265
nodes: map[uint32]nodeInfo{},
6366
gridProxyClient: gridProxyClient,
@@ -137,12 +140,11 @@ func (n *Scheduler) addNodes(nodes []proxyTypes.Node) {
137140

138141
// Schedule makes sure there's at least one node that satisfies the given request
139142
func (n *Scheduler) Schedule(ctx context.Context, r *Request) (uint32, error) {
140-
// TODO: update farmerbot
141-
// if r.FarmId != 0 {
142-
// if n.hasFarmerBot(ctx, r.FarmId) {
143-
// return n.farmerBotSchedule(ctx, r)
144-
// }
145-
// }
143+
if r.FarmID != 0 {
144+
if n.hasFarmerBot(ctx, r.FarmID) {
145+
return n.farmerBotSchedule(ctx, r)
146+
}
147+
}
146148
return n.gridProxySchedule(ctx, r)
147149
}
148150

0 commit comments

Comments
 (0)