1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #143 from squaremo/driver_init_not_new

Make driver packages register themselves via DriverCallback
This commit is contained in:
Jana Radhakrishnan 2015-05-11 22:14:51 -07:00
commit d1ce8f01a4
16 changed files with 112 additions and 124 deletions

View file

@ -11,7 +11,10 @@ import (
func main() { func main() {
// Create a new controller instance // Create a new controller instance
controller := libnetwork.New() controller, err := libnetwork.New()
if err != nil {
return
}
// Select and configure the network driver // Select and configure the network driver
networkType := "bridge" networkType := "bridge"
@ -19,7 +22,7 @@ func main() {
driverOptions := options.Generic{} driverOptions := options.Generic{}
genericOption := make(map[string]interface{}) genericOption := make(map[string]interface{})
genericOption[netlabel.GenericData] = driverOptions genericOption[netlabel.GenericData] = driverOptions
err := controller.ConfigureNetworkDriver(networkType, genericOption) err = controller.ConfigureNetworkDriver(networkType, genericOption)
if err != nil { if err != nil {
return return
} }

View file

@ -14,9 +14,12 @@ func main() {
net.IP = ip net.IP = ip
options := options.Generic{"AddressIPv4": net} options := options.Generic{"AddressIPv4": net}
controller := libnetwork.New() controller, err := libnetwork.New()
if err != nil {
log.Fatal(err)
}
netType := "bridge" netType := "bridge"
err := controller.ConfigureNetworkDriver(netType, options) err = controller.ConfigureNetworkDriver(netType, options)
netw, err := controller.NewNetwork(netType, "dummy") netw, err := controller.NewNetwork(netType, "dummy")
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)

View file

@ -3,7 +3,7 @@ Package libnetwork provides the basic functionality and extension points to
create network namespaces and allocate interfaces for containers to use. create network namespaces and allocate interfaces for containers to use.
// Create a new controller instance // Create a new controller instance
controller := libnetwork.New() controller, _err := libnetwork.New()
// Select and configure the network driver // Select and configure the network driver
networkType := "bridge" networkType := "bridge"
@ -98,11 +98,15 @@ type controller struct {
} }
// New creates a new instance of network controller. // New creates a new instance of network controller.
func New() NetworkController { func New() (NetworkController, error) {
c := &controller{networks: networkTable{}, sandboxes: sandboxTable{}} c := &controller{
c.drivers = enumerateDrivers(c) networks: networkTable{},
return c sandboxes: sandboxTable{},
drivers: driverTable{}}
if err := initDrivers(c); err != nil {
return nil, err
}
return c, nil
} }
func (c *controller) ConfigureNetworkDriver(networkType string, options map[string]interface{}) error { func (c *controller) ConfigureNetworkDriver(networkType string, options map[string]interface{}) error {

View file

@ -119,7 +119,7 @@ The APIs are still work in progress and there can be changes to these based on t
## Implementations ## Implementations
Libnetwork includes the following drivers: Libnetwork includes the following driver packages:
- null - null
- bridge - bridge
@ -142,7 +142,7 @@ For more details on its design, please see the [Overlay Driver Design](overlay.m
### Remote ### Remote
The `remote` driver, provides a means of supporting drivers over a remote transport. The `remote` package does not provide a driver, but provides a means of supporting drivers over a remote transport.
This allows a driver to be written in a language of your choice. This allows a driver to be written in a language of your choice.
For further details, please see the [Remote Driver Design](remote.md) For further details, please see the [Remote Driver Design](remote.md)

View file

@ -1,17 +1,13 @@
Remote Driver Remote Drivers
============= ==============
Remote driver is a special built-in driver. This driver in itself doesn't provide any networking functionality. But it depends on actual remote drivers aka `Dynamic Drivers` to provide the required networking between the containers. The dynamic drivers (such as : Weave, OVS, OVN, ACI, Calico and external networking plugins) registers itself with the Build-In `Remote` Driver. The remote driver package provides the integration point for dynamically-registered drivers.
## LibNetwork Integration ## LibNetwork Integration
When LibNetwork creates an instance of the Built-in `Remote` Driver via the `New()` function, it passes a `DriverCallback` as a parameter which implements the `RegisterDriver()`. The Built-in Remote Driver can use this interface to register any of the `Dynamic` Drivers/Plugins with LibNetwork's `NetworkController` When LibNetwork initialises the `Remote` package with the `Init()` function, it passes a `DriverCallback` as a parameter, which implements the `RegisterDriver()`. The Remote Driver package can use this interface to register any of the `Dynamic` Drivers/Plugins with LibNetwork's `NetworkController`.
Please Refer to [Remote Driver Test](https://github.com/docker/libnetwork/blob/master/drivers/remote/driver_test.go) which provides an example of registering a Dynamic driver with LibNetwork. This design ensures that the implementation details (TBD) of Dynamic Driver Registration mechanism is completely owned by the inbuilt-Remote driver, and it doesn't expose any of the driver layer to the North of LibNetwork (none of the LibNetwork client APIs are impacted).
This design ensures that the implementation details of Dynamic Driver Registration mechanism is completely owned by the inbuilt-Remote driver and it also doesnt expose any of the driver layer to the North of LibNetwork (none of the LibNetwork client APIs are impacted).
When the inbuilt `Remote` driver detects a `Dynamic` Driver it can call the `registerRemoteDriver` method. This method will take care of creating a new `Remote` Driver instance with the passed 'NetworkType' and register it with Libnetwork's 'NetworkController
## Implementation ## Implementation

View file

@ -10,18 +10,16 @@ import (
type driverTable map[string]driverapi.Driver type driverTable map[string]driverapi.Driver
func enumerateDrivers(dc driverapi.DriverCallback) driverTable { func initDrivers(dc driverapi.DriverCallback) error {
drivers := make(driverTable) for _, fn := range [](func(driverapi.DriverCallback) error){
bridge.Init,
for _, fn := range [](func(driverapi.DriverCallback) (string, driverapi.Driver)){ host.Init,
bridge.New, null.Init,
host.New, remote.Init,
null.New,
remote.New,
} { } {
name, driver := fn(dc) if err := fn(dc); err != nil {
drivers[name] = driver return err
}
} }
return nil
return drivers
} }

View file

@ -92,9 +92,14 @@ func init() {
portMapper = portmapper.New() portMapper = portmapper.New()
} }
// New provides a new instance of bridge driver // New constructs a new bridge driver
func New(dc driverapi.DriverCallback) (string, driverapi.Driver) { func newDriver() driverapi.Driver {
return networkType, &driver{} return &driver{}
}
// Init registers a new instance of bridge driver
func Init(dc driverapi.DriverCallback) error {
return dc.RegisterDriver(networkType, newDriver())
} }
// Validate performs a static validation on the network configuration parameters. // Validate performs a static validation on the network configuration parameters.

View file

@ -15,7 +15,7 @@ import (
func TestCreateFullOptions(t *testing.T) { func TestCreateFullOptions(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
_, d := New(nil) d := newDriver()
config := &Configuration{ config := &Configuration{
EnableIPForwarding: true, EnableIPForwarding: true,
@ -46,7 +46,7 @@ func TestCreateFullOptions(t *testing.T) {
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
_, d := New(nil) d := newDriver()
config := &NetworkConfiguration{BridgeName: DefaultBridgeName} config := &NetworkConfiguration{BridgeName: DefaultBridgeName}
genericOption := make(map[string]interface{}) genericOption := make(map[string]interface{})
@ -59,7 +59,7 @@ func TestCreate(t *testing.T) {
func TestCreateFail(t *testing.T) { func TestCreateFail(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
_, d := New(nil) d := newDriver()
config := &NetworkConfiguration{BridgeName: "dummy0"} config := &NetworkConfiguration{BridgeName: "dummy0"}
genericOption := make(map[string]interface{}) genericOption := make(map[string]interface{})
@ -72,8 +72,8 @@ func TestCreateFail(t *testing.T) {
func TestQueryEndpointInfo(t *testing.T) { func TestQueryEndpointInfo(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
d := newDriver()
_, d := New(nil) dd, _ := d.(*driver)
config := &NetworkConfiguration{ config := &NetworkConfiguration{
BridgeName: DefaultBridgeName, BridgeName: DefaultBridgeName,
@ -97,7 +97,6 @@ func TestQueryEndpointInfo(t *testing.T) {
t.Fatalf("Failed to create an endpoint : %s", err.Error()) t.Fatalf("Failed to create an endpoint : %s", err.Error())
} }
dd := d.(*driver)
ep, _ := dd.network.endpoints["ep1"] ep, _ := dd.network.endpoints["ep1"]
data, err := d.EndpointInfo(dd.network.id, ep.id) data, err := d.EndpointInfo(dd.network.id, ep.id)
if err != nil { if err != nil {
@ -129,8 +128,7 @@ func TestQueryEndpointInfo(t *testing.T) {
func TestCreateLinkWithOptions(t *testing.T) { func TestCreateLinkWithOptions(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
d := newDriver()
_, d := New(nil)
config := &NetworkConfiguration{BridgeName: DefaultBridgeName} config := &NetworkConfiguration{BridgeName: DefaultBridgeName}
netOptions := make(map[string]interface{}) netOptions := make(map[string]interface{})
@ -180,7 +178,7 @@ func getPortMapping() []netutils.PortBinding {
func TestLinkContainers(t *testing.T) { func TestLinkContainers(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
_, d := New(nil) d := newDriver()
config := &NetworkConfiguration{ config := &NetworkConfiguration{
BridgeName: DefaultBridgeName, BridgeName: DefaultBridgeName,
@ -385,7 +383,7 @@ func TestValidateConfig(t *testing.T) {
func TestSetDefaultGw(t *testing.T) { func TestSetDefaultGw(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
_, d := New(nil) d := newDriver()
_, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80") _, subnetv6, _ := net.ParseCIDR("2001:db8:ea9:9abc:b0c4::/80")
gw4 := bridgeNetworks[0].IP.To4() gw4 := bridgeNetworks[0].IP.To4()

View file

@ -11,7 +11,7 @@ import (
func TestLinkCreate(t *testing.T) { func TestLinkCreate(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
_, d := New(nil) d := newDriver()
dr := d.(*driver) dr := d.(*driver)
mtu := 1490 mtu := 1490
@ -97,7 +97,7 @@ func TestLinkCreate(t *testing.T) {
func TestLinkCreateTwo(t *testing.T) { func TestLinkCreateTwo(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
_, d := New(nil) d := newDriver()
config := &NetworkConfiguration{ config := &NetworkConfiguration{
BridgeName: DefaultBridgeName, BridgeName: DefaultBridgeName,
@ -127,7 +127,7 @@ func TestLinkCreateTwo(t *testing.T) {
func TestLinkCreateNoEnableIPv6(t *testing.T) { func TestLinkCreateNoEnableIPv6(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
_, d := New(nil) d := newDriver()
config := &NetworkConfiguration{ config := &NetworkConfiguration{
BridgeName: DefaultBridgeName} BridgeName: DefaultBridgeName}
@ -156,7 +156,7 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) {
func TestLinkDelete(t *testing.T) { func TestLinkDelete(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
_, d := New(nil) d := newDriver()
config := &NetworkConfiguration{ config := &NetworkConfiguration{
BridgeName: DefaultBridgeName, BridgeName: DefaultBridgeName,

View file

@ -18,7 +18,7 @@ func TestMain(m *testing.M) {
func TestPortMappingConfig(t *testing.T) { func TestPortMappingConfig(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
_, d := New(nil) d := newDriver()
binding1 := netutils.PortBinding{Proto: netutils.UDP, Port: uint16(400), HostPort: uint16(54000)} binding1 := netutils.PortBinding{Proto: netutils.UDP, Port: uint16(400), HostPort: uint16(54000)}
binding2 := netutils.PortBinding{Proto: netutils.TCP, Port: uint16(500), HostPort: uint16(65000)} binding2 := netutils.PortBinding{Proto: netutils.TCP, Port: uint16(500), HostPort: uint16(65000)}

View file

@ -10,9 +10,9 @@ const networkType = "host"
type driver struct{} type driver struct{}
// New provides a new instance of host driver // Init registers a new instance of host driver
func New(dc driverapi.DriverCallback) (string, driverapi.Driver) { func Init(dc driverapi.DriverCallback) error {
return networkType, &driver{} return dc.RegisterDriver(networkType, &driver{})
} }
func (d *driver) Config(option map[string]interface{}) error { func (d *driver) Config(option map[string]interface{}) error {

View file

@ -10,9 +10,9 @@ const networkType = "null"
type driver struct{} type driver struct{}
// New provides a new instance of null driver // Init registers a new instance of null driver
func New(dc driverapi.DriverCallback) (string, driverapi.Driver) { func Init(dc driverapi.DriverCallback) error {
return networkType, &driver{} return dc.RegisterDriver(networkType, &driver{})
} }
func (d *driver) Config(option map[string]interface{}) error { func (d *driver) Config(option map[string]interface{}) error {

View file

@ -13,28 +13,11 @@ var errNoCallback = errors.New("No Callback handler registered with Driver")
const remoteNetworkType = "remote" const remoteNetworkType = "remote"
type driver struct { type driver struct {
networkType string
callback driverapi.DriverCallback
} }
// New instance of remote driver returned to LibNetwork // Init does the necessary work to register remote drivers
func New(dc driverapi.DriverCallback) (string, driverapi.Driver) { func Init(dc driverapi.DriverCallback) error {
d := &driver{networkType: remoteNetworkType} return nil
d.callback = dc
return d.networkType, d
}
// Internal Convenience method to register a remote driver.
// The implementation of this method will change based on the dynamic driver registration design
func (d *driver) registerRemoteDriver(networkType string) (driverapi.Driver, error) {
newDriver := &driver{networkType: networkType}
if d.callback == nil {
return nil, errNoCallback
}
if err := d.callback.RegisterDriver(networkType, newDriver); err != nil {
return nil, err
}
return newDriver, nil
} }
func (d *driver) Config(option map[string]interface{}) error { func (d *driver) Config(option map[string]interface{}) error {
@ -72,5 +55,5 @@ func (d *driver) Leave(nid, eid types.UUID, options map[string]interface{}) erro
} }
func (d *driver) Type() string { func (d *driver) Type() string {
return d.networkType return remoteNetworkType
} }

View file

@ -1,29 +0,0 @@
package remote
import (
"testing"
"github.com/docker/libnetwork/driverapi"
)
type testCallbackStruct struct {
networkType string
}
func (t *testCallbackStruct) RegisterDriver(networkType string, driver driverapi.Driver) error {
t.networkType = networkType
return nil
}
func TestCallback(t *testing.T) {
tc := &testCallbackStruct{}
_, d := New(tc)
expected := "test-dummy"
_, err := d.(*driver).registerRemoteDriver(expected)
if err != nil {
t.Fatalf("Remote Driver callback registration failed with Error : %v", err)
}
if tc.networkType != expected {
t.Fatal("Remote Driver Callback Registration failed")
}
}

View file

@ -8,8 +8,11 @@ import (
func TestDriverRegistration(t *testing.T) { func TestDriverRegistration(t *testing.T) {
bridgeNetType := "bridge" bridgeNetType := "bridge"
c := New() c, err := New()
err := c.(*controller).RegisterDriver(bridgeNetType, nil) if err != nil {
t.Fatal(err)
}
err = c.(*controller).RegisterDriver(bridgeNetType, nil)
if err == nil { if err == nil {
t.Fatalf("Expecting the RegisterDriver to fail for %s", bridgeNetType) t.Fatalf("Expecting the RegisterDriver to fail for %s", bridgeNetType)
} }

View file

@ -34,11 +34,14 @@ func TestMain(m *testing.M) {
} }
func createTestNetwork(networkType, networkName string, option options.Generic, netOption options.Generic) (libnetwork.Network, error) { func createTestNetwork(networkType, networkName string, option options.Generic, netOption options.Generic) (libnetwork.Network, error) {
controller := libnetwork.New() controller, err := libnetwork.New()
if err != nil {
return nil, err
}
genericOption := make(map[string]interface{}) genericOption := make(map[string]interface{})
genericOption[netlabel.GenericData] = option genericOption[netlabel.GenericData] = option
err := controller.ConfigureNetworkDriver(networkType, genericOption) err = controller.ConfigureNetworkDriver(networkType, genericOption)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -219,9 +222,12 @@ func TestUnknownDriver(t *testing.T) {
} }
func TestNilDriver(t *testing.T) { func TestNilDriver(t *testing.T) {
controller := libnetwork.New() controller, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
_, err := controller.NewNetwork("framerelay", "dummy", _, err = controller.NewNetwork("framerelay", "dummy",
libnetwork.NetworkOptionGeneric(getEmptyGenericOption())) libnetwork.NetworkOptionGeneric(getEmptyGenericOption()))
if err == nil { if err == nil {
t.Fatal("Expected to fail. But instead succeeded") t.Fatal("Expected to fail. But instead succeeded")
@ -233,9 +239,12 @@ func TestNilDriver(t *testing.T) {
} }
func TestNoInitDriver(t *testing.T) { func TestNoInitDriver(t *testing.T) {
controller := libnetwork.New() controller, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
_, err := controller.NewNetwork("ppp", "dummy", _, err = controller.NewNetwork("ppp", "dummy",
libnetwork.NetworkOptionGeneric(getEmptyGenericOption())) libnetwork.NetworkOptionGeneric(getEmptyGenericOption()))
if err == nil { if err == nil {
t.Fatal("Expected to fail. But instead succeeded") t.Fatal("Expected to fail. But instead succeeded")
@ -248,12 +257,15 @@ func TestNoInitDriver(t *testing.T) {
func TestDuplicateNetwork(t *testing.T) { func TestDuplicateNetwork(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
controller := libnetwork.New() controller, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
genericOption := make(map[string]interface{}) genericOption := make(map[string]interface{})
genericOption[netlabel.GenericData] = options.Generic{} genericOption[netlabel.GenericData] = options.Generic{}
err := controller.ConfigureNetworkDriver(bridgeNetType, genericOption) err = controller.ConfigureNetworkDriver(bridgeNetType, genericOption)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -435,9 +447,12 @@ func TestUnknownEndpoint(t *testing.T) {
func TestNetworkEndpointsWalkers(t *testing.T) { func TestNetworkEndpointsWalkers(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
controller := libnetwork.New() controller, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
err := controller.ConfigureNetworkDriver(bridgeNetType, getEmptyGenericOption()) err = controller.ConfigureNetworkDriver(bridgeNetType, getEmptyGenericOption())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -513,9 +528,12 @@ func TestNetworkEndpointsWalkers(t *testing.T) {
func TestControllerQuery(t *testing.T) { func TestControllerQuery(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
controller := libnetwork.New() controller, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
err := controller.ConfigureNetworkDriver(bridgeNetType, getEmptyGenericOption()) err = controller.ConfigureNetworkDriver(bridgeNetType, getEmptyGenericOption())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -573,9 +591,12 @@ func TestControllerQuery(t *testing.T) {
func TestNetworkQuery(t *testing.T) { func TestNetworkQuery(t *testing.T) {
defer netutils.SetupTestNetNS(t)() defer netutils.SetupTestNetNS(t)()
controller := libnetwork.New() controller, err := libnetwork.New()
if err != nil {
t.Fatal(err)
}
err := controller.ConfigureNetworkDriver(bridgeNetType, getEmptyGenericOption()) err = controller.ConfigureNetworkDriver(bridgeNetType, getEmptyGenericOption())
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
@ -1031,7 +1052,10 @@ func createGlobalInstance(t *testing.T) {
t.Fatal(err) t.Fatal(err)
} }
ctrlr = libnetwork.New() ctrlr, err = libnetwork.New()
if err != nil {
t.Fatal(err)
}
err = ctrlr.ConfigureNetworkDriver(bridgeNetType, getEmptyGenericOption()) err = ctrlr.ConfigureNetworkDriver(bridgeNetType, getEmptyGenericOption())
if err != nil { if err != nil {