|
@@ -2,7 +2,6 @@ package libnetwork
|
|
|
|
|
|
import (
|
|
import (
|
|
"fmt"
|
|
"fmt"
|
|
- "reflect"
|
|
|
|
|
|
|
|
"github.com/docker/libnetwork/pkg/options"
|
|
"github.com/docker/libnetwork/pkg/options"
|
|
)
|
|
)
|
|
@@ -10,8 +9,13 @@ import (
|
|
// DriverParams are a generic structure to hold driver specific settings.
|
|
// DriverParams are a generic structure to hold driver specific settings.
|
|
type DriverParams options.Generic
|
|
type DriverParams options.Generic
|
|
|
|
|
|
|
|
+// DriverInterface is an interface that every plugin driver needs to implement.
|
|
|
|
+type DriverInterface interface {
|
|
|
|
+ CreateNetwork(string, interface{}) (Network, error)
|
|
|
|
+}
|
|
|
|
+
|
|
var drivers = map[string]struct {
|
|
var drivers = map[string]struct {
|
|
- creatorFn interface{}
|
|
|
|
|
|
+ creatorFn DriverInterface
|
|
creatorArg interface{}
|
|
creatorArg interface{}
|
|
}{}
|
|
}{}
|
|
|
|
|
|
@@ -19,35 +23,30 @@ var drivers = map[string]struct {
|
|
// new network. It is called by the various network implementations, and used
|
|
// new network. It is called by the various network implementations, and used
|
|
// upon invokation of the libnetwork.NetNetwork function.
|
|
// upon invokation of the libnetwork.NetNetwork function.
|
|
//
|
|
//
|
|
-// creatorFn must be of type func (creatorArgType) (Network, error), where
|
|
|
|
-// createArgType is the type of the creatorArg argument.
|
|
|
|
|
|
+// creatorFn must implement DriverInterface
|
|
//
|
|
//
|
|
// For example:
|
|
// For example:
|
|
//
|
|
//
|
|
-// func CreateTestNetwork(name string, config *TestNetworkConfig()) (Network, error) {
|
|
|
|
|
|
+// type driver struct{}
|
|
|
|
+//
|
|
|
|
+// func (d *driver) CreateNetwork(name string, config *TestNetworkConfig) (Network, error) {
|
|
// }
|
|
// }
|
|
//
|
|
//
|
|
// func init() {
|
|
// func init() {
|
|
-// RegisterNetworkType("test", CreateTestNetwork, &TestNetworkConfig{})
|
|
|
|
|
|
+// RegisterNetworkType("test", &driver{}, &TestNetworkConfig{})
|
|
// }
|
|
// }
|
|
//
|
|
//
|
|
-func RegisterNetworkType(name string, creatorFn interface{}, creatorArg interface{}) error {
|
|
|
|
- // Validate the creator function signature.
|
|
|
|
- ctorArg := []reflect.Type{reflect.TypeOf((*string)(nil)), reflect.TypeOf(creatorArg)}
|
|
|
|
- ctorRet := []reflect.Type{reflect.TypeOf((*Network)(nil)).Elem(), reflect.TypeOf((*error)(nil)).Elem()}
|
|
|
|
- if err := validateFunctionSignature(creatorFn, ctorArg, ctorRet); err != nil {
|
|
|
|
- sig := fmt.Sprintf("func (%s) (Network, error)", ctorArg[0].Name())
|
|
|
|
- return fmt.Errorf("invalid signature for %q creator function (expected %s)", name, sig)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+func RegisterNetworkType(name string, creatorFn DriverInterface, creatorArg interface{}) error {
|
|
// Store the new driver information to invoke at creation time.
|
|
// Store the new driver information to invoke at creation time.
|
|
if _, ok := drivers[name]; ok {
|
|
if _, ok := drivers[name]; ok {
|
|
return fmt.Errorf("a driver for network type %q is already registed", name)
|
|
return fmt.Errorf("a driver for network type %q is already registed", name)
|
|
}
|
|
}
|
|
|
|
+
|
|
drivers[name] = struct {
|
|
drivers[name] = struct {
|
|
- creatorFn interface{}
|
|
|
|
|
|
+ creatorFn DriverInterface
|
|
creatorArg interface{}
|
|
creatorArg interface{}
|
|
}{creatorFn, creatorArg}
|
|
}{creatorFn, creatorArg}
|
|
|
|
+
|
|
return nil
|
|
return nil
|
|
}
|
|
}
|
|
|
|
|
|
@@ -62,47 +61,5 @@ func createNetwork(networkType, name string, generic DriverParams) (Network, err
|
|
return nil, fmt.Errorf("failed to generate driver config: %v", err)
|
|
return nil, fmt.Errorf("failed to generate driver config: %v", err)
|
|
}
|
|
}
|
|
|
|
|
|
- arg := []reflect.Value{reflect.ValueOf(name), reflect.ValueOf(config)}
|
|
|
|
- res := reflect.ValueOf(d.creatorFn).Call(arg)
|
|
|
|
- return makeCreateResult(res)
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func makeCreateResult(res []reflect.Value) (net Network, err error) {
|
|
|
|
- if !res[0].IsNil() {
|
|
|
|
- net = res[0].Interface().(Network)
|
|
|
|
- }
|
|
|
|
- if !res[1].IsNil() {
|
|
|
|
- err = res[1].Interface().(error)
|
|
|
|
- }
|
|
|
|
- return
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-func validateFunctionSignature(fn interface{}, params []reflect.Type, returns []reflect.Type) error {
|
|
|
|
- // Valid that argument is a function.
|
|
|
|
- fnType := reflect.TypeOf(fn)
|
|
|
|
- if fnType.Kind() != reflect.Func {
|
|
|
|
- return fmt.Errorf("argument is %s, not function", fnType.Name())
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Vaidate arguments numbers and types.
|
|
|
|
- if fnType.NumIn() != len(params) {
|
|
|
|
- return fmt.Errorf("expected function with %d arguments, got %d", len(params), fnType.NumIn())
|
|
|
|
- }
|
|
|
|
- for i, argType := range params {
|
|
|
|
- if argType != fnType.In(i) {
|
|
|
|
- return fmt.Errorf("argument %d type should be %s, got %s", i, argType.Name(), fnType.In(i).Name())
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Validate return values numbers and types.
|
|
|
|
- if fnType.NumOut() != len(returns) {
|
|
|
|
- return fmt.Errorf("expected function with %d return values, got %d", len(params), fnType.NumIn())
|
|
|
|
- }
|
|
|
|
- for i, retType := range returns {
|
|
|
|
- if retType != fnType.Out(i) {
|
|
|
|
- return fmt.Errorf("return value %d type should be %s, got %s", i, retType.Name(), fnType.Out(i).Name())
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return nil
|
|
|
|
|
|
+ return d.creatorFn.CreateNetwork(name, config)
|
|
}
|
|
}
|