Skip to content

Commit 02dd505

Browse files
committed
Merge pull request #36 from contiv/mapuri/resourceAllocator
Resource allocator interface changes
2 parents 4826801 + be9278c commit 02dd505

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+3259
-1104
lines changed

Makefile

+6
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,16 @@ clean-demo:
2727
unit-test: build
2828
CONTIV_HOST_GOBIN=$(HOST_GOBIN) CONTIV_HOST_GOROOT=$(HOST_GOROOT) ./scripts/unittests -vagrant
2929

30+
# setting CONTIV_SOE=1 while calling 'make system-test' will stop the test
31+
# on first failure and leave setup in that state. This can be useful for debugging
32+
# as part of development.
3033
system-test: build
3134
go test -v -run "sanity" github.com/contiv/netplugin/systemtests/singlehost
3235
go test --timeout 20m -v -run "sanity" github.com/contiv/netplugin/systemtests/twohosts
3336

37+
# setting CONTIV_SOE=1 while calling 'make regress-test' will stop the test
38+
# on first failure and leave setup in that state. This can be useful for debugging
39+
# as part of development.
3440
regress-test: build
3541
go test -v -run "regress" github.com/contiv/netplugin/systemtests/singlehost
3642
go test --timeout 60m -v -run "regress" github.com/contiv/netplugin/systemtests/twohosts

core/core.go

+25-6
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,6 @@ type Address struct {
2727
addr string
2828
}
2929

30-
type State interface {
31-
Write() error
32-
Read(id string) error
33-
Clear() error
34-
}
35-
3630
type Config struct {
3731
// Config object parsed from a json styled config
3832
V interface{}
@@ -103,5 +97,30 @@ type StateDriver interface {
10397
marshal func(interface{}) ([]byte, error)) error
10498
ReadState(key string, value State,
10599
unmarshal func([]byte, interface{}) error) error
100+
ReadAllState(baseKey string, stateType State,
101+
unmarshal func([]byte, interface{}) error) ([]State, error)
106102
ClearState(key string) error
107103
}
104+
105+
type Resource interface {
106+
// Resource defines a allocatable unit. A resource is uniquely identified
107+
// by 'Id'. A resource description identifies the nature of the resource.
108+
State
109+
Init(rsrcCfg interface{}) error
110+
Deinit()
111+
Description() string
112+
Allocate() (interface{}, error)
113+
Deallocate(interface{}) error
114+
}
115+
116+
type ResourceManager interface {
117+
// A resource manager provides mechanism to manage (define/undefine,
118+
// allocate/deallocate) resources. Example, it may provide management in
119+
// logically centralized manner in a distributed system
120+
Init() error
121+
Deinit()
122+
DefineResource(id, desc string, rsrcCfg interface{}) error
123+
UndefineResource(id, desc string) error
124+
AllocateResourceVal(id, desc string) (interface{}, error)
125+
DeallocateResourceVal(id, desc string, value interface{}) error
126+
}

core/state.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package core
2+
3+
type State interface {
4+
Read(id string) error
5+
ReadAll() ([]State, error)
6+
Write() error
7+
Clear() error
8+
}
9+
10+
// CommonState defines the fields common to all core.State implementations.
11+
// This struct shall be embedded as anonymous field in all structs that
12+
// implement core.State
13+
type CommonState struct {
14+
StateDriver StateDriver `json:"-"`
15+
Id string `json:"id"`
16+
}

drivers/etcdstatedriver.go

+44-1
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ package drivers
1717

1818
import (
1919
"fmt"
20-
"github.com/contiv/go-etcd/etcd"
20+
"reflect"
2121

22+
"github.com/contiv/go-etcd/etcd"
2223
"github.com/contiv/netplugin/core"
2324
)
2425

@@ -103,6 +104,48 @@ func (d *EtcdStateDriver) ReadState(key string, value core.State,
103104
return nil
104105
}
105106

107+
// XXX: move this to some common file
108+
func ReadAllStateCommon(d core.StateDriver, baseKey string, sType core.State,
109+
unmarshal func([]byte, interface{}) error) ([]core.State, error) {
110+
stateType := reflect.TypeOf(sType)
111+
sliceType := reflect.SliceOf(stateType)
112+
values := reflect.MakeSlice(sliceType, 0, 1)
113+
114+
byteValues, err := d.ReadAll(baseKey)
115+
if err != nil {
116+
return nil, err
117+
}
118+
for _, byteValue := range byteValues {
119+
value := reflect.New(stateType)
120+
err = unmarshal(byteValue, value.Interface())
121+
if err != nil {
122+
return nil, err
123+
}
124+
values = reflect.Append(values, value.Elem())
125+
}
126+
127+
stateValues := []core.State{}
128+
for i := 0; i < values.Len(); i++ {
129+
// sanity checks
130+
if !values.Index(i).Elem().FieldByName("CommonState").IsValid() {
131+
panic(fmt.Sprintf("The state structure %v is missing core.CommonState",
132+
stateType))
133+
return nil, &core.Error{Desc: fmt.Sprintf("The state structure %v is missing core.CommonState",
134+
stateType)}
135+
}
136+
//the following works as every core.State is expected to embed core.CommonState struct
137+
values.Index(i).Elem().FieldByName("CommonState").FieldByName("StateDriver").Set(reflect.ValueOf(d))
138+
stateValue := values.Index(i).Interface().(core.State)
139+
stateValues = append(stateValues, stateValue)
140+
}
141+
return stateValues, nil
142+
}
143+
144+
func (d *EtcdStateDriver) ReadAllState(baseKey string, sType core.State,
145+
unmarshal func([]byte, interface{}) error) ([]core.State, error) {
146+
return ReadAllStateCommon(d, baseKey, sType, unmarshal)
147+
}
148+
106149
func (d *EtcdStateDriver) WriteState(key string, value core.State,
107150
marshal func(interface{}) ([]byte, error)) error {
108151
encodedState, err := marshal(value)

drivers/etcdstatedriver_test.go

+4-20
Original file line numberDiff line numberDiff line change
@@ -23,26 +23,6 @@ import (
2323
"github.com/contiv/netplugin/core"
2424
)
2525

26-
// setup a etcd cluster, run tests and then cleanup the cluster
27-
// XXX: enabled once I upgrade to golang 1.4
28-
//func TestMain(m *testing.M) {
29-
//
30-
// // start etcd
31-
// proc, err := os.StartProcess("etcd", []string{}, nil)
32-
// if err != nil {
33-
// log.Printf("failed to start etcd. Error: %s", err)
34-
// os.Exit(-1)
35-
// }
36-
//
37-
// //run the tests
38-
// exitC := m.Run()
39-
//
40-
// // stop etcd
41-
// proc.Kill()
42-
//
43-
// os.Exit(exitC)
44-
//}
45-
4626
func setupDriver(t *testing.T) *EtcdStateDriver {
4727
etcdConfig := &EtcdStateDriverConfig{}
4828
etcdConfig.Etcd.Machines = []string{"http://127.0.0.1:4001"}
@@ -125,6 +105,10 @@ func (s *testState) Read(id string) error {
125105
return &core.Error{Desc: "Should not be called!!"}
126106
}
127107

108+
func (s *testState) ReadAll() ([]core.State, error) {
109+
return nil, &core.Error{Desc: "Should not be called!!"}
110+
}
111+
128112
func (s *testState) Clear() error {
129113
return &core.Error{Desc: "Should not be called!!"}
130114
}

drivers/fakestatedriver.go

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package drivers
2+
3+
import (
4+
"log"
5+
"strings"
6+
7+
"github.com/contiv/netplugin/core"
8+
)
9+
10+
// The FakeStateDriver implements core.StateDriver interface for use with
11+
// unit-tests
12+
13+
type ValueData struct {
14+
value []byte
15+
}
16+
17+
type FakeStateDriver struct {
18+
TestState map[string]ValueData
19+
}
20+
21+
func (d *FakeStateDriver) Init(config *core.Config) error {
22+
d.TestState = make(map[string]ValueData)
23+
24+
return nil
25+
}
26+
27+
func (d *FakeStateDriver) Deinit() {
28+
d.TestState = nil
29+
}
30+
31+
func (d *FakeStateDriver) Write(key string, value []byte) error {
32+
val := ValueData{value: value}
33+
d.TestState[key] = val
34+
35+
return nil
36+
}
37+
38+
func (d *FakeStateDriver) Read(key string) ([]byte, error) {
39+
if val, ok := d.TestState[key]; ok {
40+
return val.value, nil
41+
}
42+
43+
return []byte{}, &core.Error{Desc: "Key not found!"}
44+
}
45+
46+
func (d *FakeStateDriver) ReadAll(baseKey string) ([][]byte, error) {
47+
values := [][]byte{}
48+
49+
for key, val := range d.TestState {
50+
if strings.Contains(key, baseKey) {
51+
values = append(values, val.value)
52+
}
53+
}
54+
return values, nil
55+
}
56+
57+
func (d *FakeStateDriver) ClearState(key string) error {
58+
if _, ok := d.TestState[key]; ok {
59+
delete(d.TestState, key)
60+
}
61+
return nil
62+
}
63+
64+
func (d *FakeStateDriver) ReadState(key string, value core.State,
65+
unmarshal func([]byte, interface{}) error) error {
66+
encodedState, err := d.Read(key)
67+
if err != nil {
68+
return err
69+
}
70+
71+
err = unmarshal(encodedState, value)
72+
if err != nil {
73+
return err
74+
}
75+
76+
return nil
77+
}
78+
79+
func (d *FakeStateDriver) ReadAllState(baseKey string, sType core.State,
80+
unmarshal func([]byte, interface{}) error) ([]core.State, error) {
81+
return ReadAllStateCommon(d, baseKey, sType, unmarshal)
82+
}
83+
84+
func (d *FakeStateDriver) WriteState(key string, value core.State,
85+
marshal func(interface{}) ([]byte, error)) error {
86+
encodedState, err := marshal(value)
87+
if err != nil {
88+
return err
89+
}
90+
91+
err = d.Write(key, encodedState)
92+
if err != nil {
93+
return err
94+
}
95+
96+
return nil
97+
}
98+
99+
func (d *FakeStateDriver) DumpState() {
100+
for key, _ := range d.TestState {
101+
log.Printf("key: %q\n", key)
102+
}
103+
}

drivers/ovsdriver.go

+22-16
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ func vxlanIfName(netId, vtepIp string) string {
328328
}
329329

330330
func (d *OvsDriver) createVtep(epCfg *OvsCfgEndpointState) error {
331-
cfgNw := OvsCfgNetworkState{StateDriver: d.stateDriver}
331+
cfgNw := OvsCfgNetworkState{}
332+
cfgNw.StateDriver = d.stateDriver
332333
err := cfgNw.Read(epCfg.NetId)
333334
if err != nil {
334335
return err
@@ -352,7 +353,8 @@ func (d *OvsDriver) createVtep(epCfg *OvsCfgEndpointState) error {
352353

353354
func (d *OvsDriver) deleteVtep(epOper *OvsOperEndpointState) error {
354355

355-
cfgNw := OvsCfgNetworkState{StateDriver: d.stateDriver}
356+
cfgNw := OvsCfgNetworkState{}
357+
cfgNw.StateDriver = d.stateDriver
356358
err := cfgNw.Read(epOper.NetId)
357359
if err != nil {
358360
return err
@@ -423,7 +425,8 @@ func (d *OvsDriver) Deinit() {
423425
}
424426

425427
func (d *OvsDriver) CreateNetwork(id string) error {
426-
cfgNw := OvsCfgNetworkState{StateDriver: d.stateDriver}
428+
cfgNw := OvsCfgNetworkState{}
429+
cfgNw.StateDriver = d.stateDriver
427430
err := cfgNw.Read(id)
428431
if err != nil {
429432
log.Printf("Failed to read net %s \n", cfgNw.Id)
@@ -450,7 +453,8 @@ func (d *OvsDriver) CreateEndpoint(id string) error {
450453
intfName := portName
451454
intfType := "internal"
452455

453-
epCfg := OvsCfgEndpointState{StateDriver: d.stateDriver}
456+
epCfg := OvsCfgEndpointState{}
457+
epCfg.StateDriver = d.stateDriver
454458
err = epCfg.Read(id)
455459
if err != nil {
456460
return err
@@ -476,7 +480,8 @@ func (d *OvsDriver) CreateEndpoint(id string) error {
476480
intfType = ""
477481
}
478482

479-
cfgNw := OvsCfgNetworkState{StateDriver: d.stateDriver}
483+
cfgNw := OvsCfgNetworkState{}
484+
cfgNw.StateDriver = d.stateDriver
480485
err = cfgNw.Read(epCfg.NetId)
481486
if err != nil {
482487
return err
@@ -495,16 +500,16 @@ func (d *OvsDriver) CreateEndpoint(id string) error {
495500
}()
496501

497502
operEp := OvsOperEndpointState{
498-
StateDriver: d.stateDriver,
499-
Id: id,
500-
PortName: portName,
501-
NetId: epCfg.NetId,
502-
AttachUUID: epCfg.AttachUUID,
503-
ContName: epCfg.ContName,
504-
IpAddress: epCfg.IpAddress,
505-
IntfName: intfName,
506-
HomingHost: epCfg.HomingHost,
507-
VtepIp: epCfg.VtepIp}
503+
PortName: portName,
504+
NetId: epCfg.NetId,
505+
AttachUUID: epCfg.AttachUUID,
506+
ContName: epCfg.ContName,
507+
IpAddress: epCfg.IpAddress,
508+
IntfName: intfName,
509+
HomingHost: epCfg.HomingHost,
510+
VtepIp: epCfg.VtepIp}
511+
operEp.StateDriver = d.stateDriver
512+
operEp.Id = id
508513
err = operEp.Write()
509514
if err != nil {
510515
return err
@@ -520,7 +525,8 @@ func (d *OvsDriver) CreateEndpoint(id string) error {
520525

521526
func (d *OvsDriver) DeleteEndpoint(id string) (err error) {
522527

523-
epOper := OvsOperEndpointState{StateDriver: d.stateDriver}
528+
epOper := OvsOperEndpointState{}
529+
epOper.StateDriver = d.stateDriver
524530
err = epOper.Read(id)
525531
if err != nil {
526532
return err

drivers/ovsdriver_test.go

+5
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ func (d *testOvsStateDriver) ReadState(key string, value core.State,
172172
return &core.Error{Desc: fmt.Sprintf("unknown key! %s", key)}
173173
}
174174

175+
func (d *testOvsStateDriver) ReadAllState(key string, value core.State,
176+
unmarshal func([]byte, interface{}) error) ([]core.State, error) {
177+
return nil, &core.Error{Desc: "shouldn't be called!"}
178+
}
179+
175180
func (d *testOvsStateDriver) WriteState(key string, value core.State,
176181
marshal func(interface{}) ([]byte, error)) error {
177182
return nil

0 commit comments

Comments
 (0)