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

Minor API modifications

* Modified NB API with self referential var-aarg for future proofing the APIs
* Modified Driver API's option parameter to be a Map of interface{}

Signed-off-by: Madhu Venugopal <madhu@docker.com>
This commit is contained in:
Madhu Venugopal 2015-04-30 17:57:06 -07:00
parent 8de4608de7
commit cc4f27f6af
14 changed files with 277 additions and 147 deletions

View file

@ -21,31 +21,46 @@ There are many networking solutions available to suit a broad range of use-cases
```go
// Create a new controller instance
controller := libnetwork.New()
// Create a new controller instance
controller := libnetwork.New()
// This option is only needed for in-tree drivers. Plugins(in future) will get
// their options through plugin infrastructure.
option := options.Generic{}
err := controller.NewNetworkDriver("bridge", option)
if err != nil {
return
}
// Select and configure the network driver
networkType := "bridge"
netOptions := options.Generic{}
// Create a network for containers to join.
network, err := controller.NewNetwork("bridge", "network1", netOptions)
if err != nil {
return
}
driverOptions := options.Generic{}
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = driverOptions
err := controller.ConfigureNetworkDriver(networkType, genericOption)
if err != nil {
return
}
// For each new container: allocate IP and interfaces. The returned network
// settings will be used for container infos (inspect and such), as well as
// iptables rules for port publishing.
ep, err := network.CreateEndpoint("Endpoint1", nil)
if err != nil {
return
}
// Create a network for containers to join.
// NewNetwork accepts Variadic optional arguments that libnetwork and Drivers can make of
network, err := controller.NewNetwork(networkType, "network1")
if err != nil {
return
}
// For each new container: allocate IP and interfaces. The returned network
// settings will be used for container infos (inspect and such), as well as
// iptables rules for port publishing. This info is contained or accessible
// from the returned endpoint.
ep, err := network.CreateEndpoint("Endpoint1")
if err != nil {
return
}
// A container can join the endpoint by providing the container ID to the join
// api which returns the sandbox key which can be used to access the sandbox
// created for the container during join.
// Join acceps Variadic arguments which will be made use of by libnetwork and Drivers
_, err = ep.Join("container1",
libnetwork.JoinOptionHostname("test"),
libnetwork.JoinOptionDomainname("docker.io"))
if err != nil {
return
}
```
## Future

View file

@ -11,15 +11,18 @@ func main() {
// Select and configure the network driver
networkType := "bridge"
option := options.Generic{}
err := controller.ConfigureNetworkDriver(networkType, option)
driverOptions := options.Generic{}
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = driverOptions
err := controller.ConfigureNetworkDriver(networkType, genericOption)
if err != nil {
return
}
netOptions := options.Generic{}
// Create a network for containers to join.
network, err := controller.NewNetwork(networkType, "network1", netOptions)
// NewNetwork accepts Variadic optional arguments that libnetwork and Drivers can make of
network, err := controller.NewNetwork(networkType, "network1")
if err != nil {
return
}
@ -28,7 +31,7 @@ func main() {
// settings will be used for container infos (inspect and such), as well as
// iptables rules for port publishing. This info is contained or accessible
// from the returned endpoint.
ep, err := network.CreateEndpoint("Endpoint1", nil)
ep, err := network.CreateEndpoint("Endpoint1")
if err != nil {
return
}
@ -36,7 +39,10 @@ func main() {
// A container can join the endpoint by providing the container ID to the join
// api which returns the sandbox key which can be used to access the sandbox
// created for the container during join.
_, err = ep.Join("container1")
// Join acceps Variadic arguments which will be made use of by libnetwork and Drivers
_, err = ep.Join("container1",
libnetwork.JoinOptionHostname("test"),
libnetwork.JoinOptionDomainname("docker.io"))
if err != nil {
return
}

View file

@ -17,7 +17,7 @@ func main() {
controller := libnetwork.New()
netType := "bridge"
err := controller.ConfigureNetworkDriver(netType, options)
netw, err := controller.NewNetwork(netType, "dummy", "")
netw, err := controller.NewNetwork(netType, "dummy")
if err != nil {
log.Fatal(err)
}

View file

@ -2,40 +2,46 @@
Package libnetwork provides the basic functionality and extension points to
create network namespaces and allocate interfaces for containers to use.
// Create a new controller instance
controller := libnetwork.New()
// Create a new controller instance
controller := libnetwork.New()
// Select and configure the network driver
networkType := "bridge"
option := options.Generic{}
err := controller.ConfigureNetworkDriver(networkType, option)
if err != nil {
return
}
// Select and configure the network driver
networkType := "bridge"
netOptions := options.Generic{}
// Create a network for containers to join.
network, err := controller.NewNetwork(networkType, "network1", netOptions)
if err != nil {
return
}
driverOptions := options.Generic{}
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = driverOptions
err := controller.ConfigureNetworkDriver(networkType, genericOption)
if err != nil {
return
}
// For each new container: allocate IP and interfaces. The returned network
// settings will be used for container infos (inspect and such), as well as
// iptables rules for port publishing. This info is contained or accessible
// from the returned endpoint.
ep, err := network.CreateEndpoint("Endpoint1", nil)
if err != nil {
return
}
// Create a network for containers to join.
// NewNetwork accepts Variadic optional arguments that libnetwork and Drivers can make of
network, err := controller.NewNetwork(networkType, "network1")
if err != nil {
return
}
// A container can join the endpoint by providing the container ID to the join
// api which returns the sandbox key which can be used to access the sandbox
// created for the container during join.
_, err = ep.Join("container1")
if err != nil {
return
}
// For each new container: allocate IP and interfaces. The returned network
// settings will be used for container infos (inspect and such), as well as
// iptables rules for port publishing. This info is contained or accessible
// from the returned endpoint.
ep, err := network.CreateEndpoint("Endpoint1")
if err != nil {
return
}
// A container can join the endpoint by providing the container ID to the join
// api which returns the sandbox key which can be used to access the sandbox
// created for the container during join.
// Join acceps Variadic arguments which will be made use of by libnetwork and Drivers
_, err = ep.Join("container1",
libnetwork.JoinOptionHostname("test"),
libnetwork.JoinOptionDomainname("docker.io"))
if err != nil {
return
}
*/
package libnetwork
@ -51,11 +57,11 @@ import (
// networks.
type NetworkController interface {
// ConfigureNetworkDriver applies the passed options to the driver instance for the specified network type
ConfigureNetworkDriver(networkType string, options interface{}) error
ConfigureNetworkDriver(networkType string, options map[string]interface{}) error
// Create a new network. The options parameter carries network specific options.
// Labels support will be added in the near future.
NewNetwork(networkType, name string, options interface{}) (Network, error)
NewNetwork(networkType, name string, options ...NetworkOption) (Network, error)
// Networks returns the list of Network(s) managed by this controller.
Networks() []Network
@ -95,7 +101,7 @@ func New() NetworkController {
return &controller{networkTable{}, enumerateDrivers(), sandboxTable{}, sync.Mutex{}}
}
func (c *controller) ConfigureNetworkDriver(networkType string, options interface{}) error {
func (c *controller) ConfigureNetworkDriver(networkType string, options map[string]interface{}) error {
d, ok := c.drivers[networkType]
if !ok {
return NetworkTypeError(networkType)
@ -105,7 +111,7 @@ func (c *controller) ConfigureNetworkDriver(networkType string, options interfac
// NewNetwork creates a new network of the specified network type. The options
// are network specific and modeled in a generic way.
func (c *controller) NewNetwork(networkType, name string, options interface{}) (Network, error) {
func (c *controller) NewNetwork(networkType, name string, options ...NetworkOption) (Network, error) {
// Check if a driver for the specified network type is available
d, ok := c.drivers[networkType]
if !ok {
@ -131,8 +137,9 @@ func (c *controller) NewNetwork(networkType, name string, options interface{}) (
endpoints: endpointTable{},
}
network.processOptions(options...)
// Create the network
if err := d.CreateNetwork(network.id, options); err != nil {
if err := d.CreateNetwork(network.id, network.generic); err != nil {
return nil, err
}

View file

@ -19,12 +19,12 @@ var (
// Driver is an interface that every plugin driver needs to implement.
type Driver interface {
// Push driver specific config to the driver
Config(config interface{}) error
Config(options map[string]interface{}) error
// CreateNetwork invokes the driver method to create a network passing
// the network id and network specific config. The config mechanism will
// eventually be replaced with labels which are yet to be introduced.
CreateNetwork(nid types.UUID, config interface{}) error
CreateNetwork(nid types.UUID, options map[string]interface{}) error
// DeleteNetwork invokes the driver method to delete network passing
// the network id.
@ -34,7 +34,7 @@ type Driver interface {
// passing the network id, endpoint id and driver
// specific config. The config mechanism will eventually be replaced
// with labels which are yet to be introduced.
CreateEndpoint(nid, eid types.UUID, config interface{}) (*sandbox.Info, error)
CreateEndpoint(nid, eid types.UUID, options map[string]interface{}) (*sandbox.Info, error)
// DeleteEndpoint invokes the driver method to delete an endpoint
// passing the network id and endpoint id.

View file

@ -133,7 +133,7 @@ func (n *bridgeNetwork) getEndpoint(eid types.UUID) (*bridgeEndpoint, error) {
return nil, nil
}
func (d *driver) Config(option interface{}) error {
func (d *driver) Config(option map[string]interface{}) error {
var config *Configuration
d.Lock()
@ -143,28 +143,32 @@ func (d *driver) Config(option interface{}) error {
return ErrConfigExists
}
switch opt := option.(type) {
case options.Generic:
opaqueConfig, err := options.GenerateFromModel(opt, &Configuration{})
if err != nil {
genericData := option[options.GenericData]
if genericData != nil {
switch opt := genericData.(type) {
case options.Generic:
opaqueConfig, err := options.GenerateFromModel(opt, &Configuration{})
if err != nil {
return err
}
config = opaqueConfig.(*Configuration)
case *Configuration:
config = opt
default:
return ErrInvalidDriverConfig
}
if err := config.Validate(); err != nil {
return err
}
config = opaqueConfig.(*Configuration)
case *Configuration:
config = opt
d.config = config
}
if err := config.Validate(); err != nil {
return err
}
d.config = config
return nil
}
// Create a new network using bridge plugin
func (d *driver) CreateNetwork(id types.UUID, option interface{}) error {
func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) error {
var err error
// Driver must be configured
@ -297,7 +301,7 @@ func (d *driver) DeleteNetwork(nid types.UUID) error {
return err
}
func (d *driver) CreateEndpoint(nid, eid types.UUID, epOptions interface{}) (*sandbox.Info, error) {
func (d *driver) CreateEndpoint(nid, eid types.UUID, epOptions map[string]interface{}) (*sandbox.Info, error) {
var (
ipv6Addr *net.IPNet
err error
@ -554,11 +558,15 @@ func (d *driver) Type() string {
return networkType
}
func parseEndpointOptions(epOptions interface{}) (*EndpointConfiguration, error) {
func parseEndpointOptions(epOptions map[string]interface{}) (*EndpointConfiguration, error) {
if epOptions == nil {
return nil, nil
}
switch opt := epOptions.(type) {
genericData := epOptions[options.GenericData]
if genericData == nil {
return nil, nil
}
switch opt := genericData.(type) {
case options.Generic:
opaqueConfig, err := options.GenerateFromModel(opt, &EndpointConfiguration{})
if err != nil {

View file

@ -6,6 +6,7 @@ import (
"testing"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/pkg/options"
"github.com/vishvananda/netlink"
)
@ -14,11 +15,14 @@ func TestCreate(t *testing.T) {
_, d := New()
config := &Configuration{BridgeName: DefaultBridgeName}
if err := d.Config(config); err != nil {
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = config
if err := d.Config(genericOption); err != nil {
t.Fatalf("Failed to setup driver config: %v", err)
}
if err := d.CreateNetwork("dummy", ""); err != nil {
if err := d.CreateNetwork("dummy", nil); err != nil {
t.Fatalf("Failed to create bridge: %v", err)
}
}
@ -28,11 +32,14 @@ func TestCreateFail(t *testing.T) {
_, d := New()
config := &Configuration{BridgeName: "dummy0"}
if err := d.Config(config); err != nil {
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = config
if err := d.Config(genericOption); err != nil {
t.Fatalf("Failed to setup driver config: %v", err)
}
if err := d.CreateNetwork("dummy", ""); err == nil {
if err := d.CreateNetwork("dummy", nil); err == nil {
t.Fatal("Bridge creation was expected to fail")
}
}
@ -49,11 +56,14 @@ func TestCreateFullOptions(t *testing.T) {
EnableIPForwarding: true,
}
_, config.FixedCIDRv6, _ = net.ParseCIDR("2001:db8::/48")
if err := d.Config(config); err != nil {
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = config
if err := d.Config(genericOption); err != nil {
t.Fatalf("Failed to setup driver config: %v", err)
}
err := d.CreateNetwork("dummy", "")
err := d.CreateNetwork("dummy", nil)
if err != nil {
t.Fatalf("Failed to create bridge: %v", err)
}
@ -64,19 +74,23 @@ func TestCreateLinkWithOptions(t *testing.T) {
_, d := New()
config := &Configuration{BridgeName: DefaultBridgeName}
if err := d.Config(config); err != nil {
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = config
if err := d.Config(genericOption); err != nil {
t.Fatalf("Failed to setup driver config: %v", err)
}
err := d.CreateNetwork("net1", "")
err := d.CreateNetwork("net1", nil)
if err != nil {
t.Fatalf("Failed to create bridge: %v", err)
}
mac := net.HardwareAddr([]byte{0x1e, 0x67, 0x66, 0x44, 0x55, 0x66})
epConf := &EndpointConfiguration{MacAddress: mac}
genericOption[options.GenericData] = epConf
sinfo, err := d.CreateEndpoint("net1", "ep", epConf)
sinfo, err := d.CreateEndpoint("net1", "ep", genericOption)
if err != nil {
t.Fatalf("Failed to create a link: %s", err.Error())
}
@ -198,7 +212,10 @@ func TestSetDefaultGw(t *testing.T) {
DefaultGatewayIPv6: gw6,
}
if err := d.Config(config); err != nil {
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = config
if err := d.Config(genericOption); err != nil {
t.Fatalf("Failed to setup driver config: %v", err)
}

View file

@ -10,6 +10,9 @@ var (
// ErrConfigExists error is returned when driver already has a config applied.
ErrConfigExists = errors.New("configuration already exists, bridge configuration can be applied only once")
// ErrInvalidDriverConfig error is returned when Bridge Driver is passed an invalid config
ErrInvalidDriverConfig = errors.New("Invalid configuration passed to Bridge Driver")
// ErrInvalidConfig error is returned when a network is created on a driver without valid config.
ErrInvalidConfig = errors.New("trying to create a network on a driver without valid config")

View file

@ -5,6 +5,7 @@ import (
"github.com/docker/libnetwork/driverapi"
"github.com/docker/libnetwork/netutils"
"github.com/docker/libnetwork/pkg/options"
"github.com/vishvananda/netlink"
)
@ -19,11 +20,13 @@ func TestLinkCreate(t *testing.T) {
Mtu: mtu,
EnableIPv6: true,
}
if err := d.Config(config); err != nil {
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = config
if err := d.Config(genericOption); err != nil {
t.Fatalf("Failed to setup driver config: %v", err)
}
err := d.CreateNetwork("dummy", "")
err := d.CreateNetwork("dummy", nil)
if err != nil {
t.Fatalf("Failed to create bridge: %v", err)
}
@ -102,11 +105,13 @@ func TestLinkCreateTwo(t *testing.T) {
config := &Configuration{
BridgeName: DefaultBridgeName,
EnableIPv6: true}
if err := d.Config(config); err != nil {
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = config
if err := d.Config(genericOption); err != nil {
t.Fatalf("Failed to setup driver config: %v", err)
}
err := d.CreateNetwork("dummy", "")
err := d.CreateNetwork("dummy", nil)
if err != nil {
t.Fatalf("Failed to create bridge: %v", err)
}
@ -132,11 +137,14 @@ func TestLinkCreateNoEnableIPv6(t *testing.T) {
config := &Configuration{
BridgeName: DefaultBridgeName}
if err := d.Config(config); err != nil {
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = config
if err := d.Config(genericOption); err != nil {
t.Fatalf("Failed to setup driver config: %v", err)
}
err := d.CreateNetwork("dummy", "")
err := d.CreateNetwork("dummy", nil)
if err != nil {
t.Fatalf("Failed to create bridge: %v", err)
}
@ -163,11 +171,14 @@ func TestLinkDelete(t *testing.T) {
config := &Configuration{
BridgeName: DefaultBridgeName,
EnableIPv6: true}
if err := d.Config(config); err != nil {
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = config
if err := d.Config(genericOption); err != nil {
t.Fatalf("Failed to setup driver config: %v", err)
}
err := d.CreateNetwork("dummy", "")
err := d.CreateNetwork("dummy", nil)
if err != nil {
t.Fatalf("Failed to create bridge: %v", err)
}

View file

@ -15,11 +15,11 @@ func New() (string, driverapi.Driver) {
return networkType, &driver{}
}
func (d *driver) Config(option interface{}) error {
func (d *driver) Config(option map[string]interface{}) error {
return nil
}
func (d *driver) CreateNetwork(id types.UUID, option interface{}) error {
func (d *driver) CreateNetwork(id types.UUID, option map[string]interface{}) error {
return nil
}
@ -27,7 +27,7 @@ func (d *driver) DeleteNetwork(nid types.UUID) error {
return nil
}
func (d *driver) CreateEndpoint(nid, eid types.UUID, epOptions interface{}) (*sandbox.Info, error) {
func (d *driver) CreateEndpoint(nid, eid types.UUID, epOptions map[string]interface{}) (*sandbox.Info, error) {
return nil, nil
}

View file

@ -5,6 +5,7 @@ import (
"path/filepath"
"github.com/docker/docker/pkg/etchosts"
"github.com/docker/libnetwork/pkg/options"
"github.com/docker/libnetwork/sandbox"
"github.com/docker/libnetwork/types"
)
@ -65,6 +66,7 @@ type endpoint struct {
sandboxInfo *sandbox.Info
sandBox sandbox.Sandbox
container *containerInfo
generic options.Generic
}
const prefix = "/var/lib/docker/network/files"
@ -88,6 +90,27 @@ func (ep *endpoint) SandboxInfo() *sandbox.Info {
return ep.sandboxInfo.GetCopy()
}
// EndpointOption is a option setter function type used to pass various options to
// CreateEndpoint method. The various setter functions of type EndpointOption are
// provided by libnetwork, they look like EndpointOptionXXXX(...)
type EndpointOption func(ep *endpoint)
// EndpointOptionGeneric function returns an option setter for a Generic option defined
// in a Dictionary of Key-Value pair
func EndpointOptionGeneric(generic map[string]interface{}) EndpointOption {
return func(ep *endpoint) {
ep.generic = generic
}
}
func (ep *endpoint) processOptions(options ...EndpointOption) {
for _, opt := range options {
if opt != nil {
opt(ep)
}
}
}
func createBasePath(dir string) error {
err := os.MkdirAll(dir, 0644)
if err != nil && !os.IsExist(err) {
@ -132,9 +155,7 @@ func (ep *endpoint) Join(containerID string, options ...JoinOption) (*ContainerD
}
}()
if options != nil {
ep.processOptions(options...)
}
ep.processJoinOptions(options...)
ep.container.Data.HostsPath = prefix + "/" + containerID + "/hosts"
err = createHostsFile(ep.container.Data.HostsPath)
@ -255,8 +276,10 @@ func JoinOptionDomainname(name string) JoinOption {
}
}
func (ep *endpoint) processOptions(options ...JoinOption) {
func (ep *endpoint) processJoinOptions(options ...JoinOption) {
for _, opt := range options {
opt(ep)
if opt != nil {
opt(ep)
}
}
}

View file

@ -17,13 +17,15 @@ const (
func createTestNetwork(networkType, networkName string, option options.Generic) (libnetwork.Network, error) {
controller := libnetwork.New()
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = option
err := controller.ConfigureNetworkDriver(networkType, option)
err := controller.ConfigureNetworkDriver(networkType, genericOption)
if err != nil {
return nil, err
}
network, err := controller.NewNetwork(networkType, networkName, "")
network, err := controller.NewNetwork(networkType, networkName)
if err != nil {
return nil, err
}
@ -31,13 +33,19 @@ func createTestNetwork(networkType, networkName string, option options.Generic)
return network, nil
}
func getEmptyGenericOption() map[string]interface{} {
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = options.Generic{}
return genericOption
}
func TestNull(t *testing.T) {
network, err := createTestNetwork("null", "testnetwork", options.Generic{})
if err != nil {
t.Fatal(err)
}
ep, err := network.CreateEndpoint("testep", nil)
ep, err := network.CreateEndpoint("testep")
if err != nil {
t.Fatal(err)
}
@ -101,7 +109,7 @@ func TestBridge(t *testing.T) {
t.Fatal(err)
}
ep, err := network.CreateEndpoint("testep", nil)
ep, err := network.CreateEndpoint("testep")
if err != nil {
t.Fatal(err)
}
@ -131,8 +139,8 @@ func TestUnknownDriver(t *testing.T) {
func TestNilDriver(t *testing.T) {
controller := libnetwork.New()
option := options.Generic{}
_, err := controller.NewNetwork("framerelay", "dummy", option)
_, err := controller.NewNetwork("framerelay", "dummy",
libnetwork.NetworkOptionGeneric(getEmptyGenericOption()))
if err == nil {
t.Fatal("Expected to fail. But instead succeeded")
}
@ -145,8 +153,8 @@ func TestNilDriver(t *testing.T) {
func TestNoInitDriver(t *testing.T) {
controller := libnetwork.New()
option := options.Generic{}
_, err := controller.NewNetwork("ppp", "dummy", option)
_, err := controller.NewNetwork("ppp", "dummy",
libnetwork.NetworkOptionGeneric(getEmptyGenericOption()))
if err == nil {
t.Fatal("Expected to fail. But instead succeeded")
}
@ -160,18 +168,20 @@ func TestDuplicateNetwork(t *testing.T) {
defer netutils.SetupTestNetNS(t)()
controller := libnetwork.New()
option := options.Generic{}
err := controller.ConfigureNetworkDriver(netType, option)
genericOption := make(map[string]interface{})
genericOption[options.GenericData] = options.Generic{}
err := controller.ConfigureNetworkDriver(netType, genericOption)
if err != nil {
t.Fatal(err)
t.Fatal(err.Error())
}
_, err = controller.NewNetwork(netType, "testnetwork", "")
_, err = controller.NewNetwork(netType, "testnetwork", nil)
if err != nil {
t.Fatal(err)
t.Fatal("Expected to fail. But instead succeeded")
}
_, err = controller.NewNetwork(netType, "testnetwork", "")
_, err = controller.NewNetwork(netType, "testnetwork")
if err == nil {
t.Fatal("Expected to fail. But instead succeeded")
}
@ -231,7 +241,7 @@ func TestDeleteNetworkWithActiveEndpoints(t *testing.T) {
t.Fatal(err)
}
ep, err := network.CreateEndpoint("testep", nil)
ep, err := network.CreateEndpoint("testep")
if err != nil {
t.Fatal(err)
}
@ -299,7 +309,7 @@ func TestUnknownEndpoint(t *testing.T) {
t.Fatal(err)
}
ep, err := network.CreateEndpoint("testep", nil)
ep, err := network.CreateEndpoint("testep")
if err != nil {
t.Fatal(err)
}
@ -329,22 +339,21 @@ func TestNetworkEndpointsWalkers(t *testing.T) {
controller := libnetwork.New()
netType := "bridge"
option := options.Generic{}
err := controller.ConfigureNetworkDriver(netType, option)
err := controller.ConfigureNetworkDriver(netType, getEmptyGenericOption())
if err != nil {
t.Fatal(err)
}
// Create network 1 and add 2 endpoint: ep11, ep12
net1, err := controller.NewNetwork(netType, "network1", "")
net1, err := controller.NewNetwork(netType, "network1")
if err != nil {
t.Fatal(err)
}
ep11, err := net1.CreateEndpoint("ep11", nil)
ep11, err := net1.CreateEndpoint("ep11")
if err != nil {
t.Fatal(err)
}
ep12, err := net1.CreateEndpoint("ep12", nil)
ep12, err := net1.CreateEndpoint("ep12")
if err != nil {
t.Fatal(err)
}
@ -409,14 +418,13 @@ func TestControllerQuery(t *testing.T) {
controller := libnetwork.New()
netType := "bridge"
option := options.Generic{}
err := controller.ConfigureNetworkDriver(netType, option)
err := controller.ConfigureNetworkDriver(netType, getEmptyGenericOption())
if err != nil {
t.Fatal(err)
}
// Create network 1
net1, err := controller.NewNetwork(netType, "network1", "")
net1, err := controller.NewNetwork(netType, "network1")
if err != nil {
t.Fatal(err)
}
@ -455,22 +463,21 @@ func TestNetworkQuery(t *testing.T) {
controller := libnetwork.New()
netType := "bridge"
option := options.Generic{}
err := controller.ConfigureNetworkDriver(netType, option)
err := controller.ConfigureNetworkDriver(netType, getEmptyGenericOption())
if err != nil {
t.Fatal(err)
}
// Create network 1 and add 2 endpoint: ep11, ep12
net1, err := controller.NewNetwork(netType, "network1", "")
net1, err := controller.NewNetwork(netType, "network1")
if err != nil {
t.Fatal(err)
}
ep11, err := net1.CreateEndpoint("ep11", nil)
ep11, err := net1.CreateEndpoint("ep11")
if err != nil {
t.Fatal(err)
}
ep12, err := net1.CreateEndpoint("ep12", nil)
ep12, err := net1.CreateEndpoint("ep12")
if err != nil {
t.Fatal(err)
}
@ -512,7 +519,7 @@ func TestEndpointJoin(t *testing.T) {
t.Fatal(err)
}
ep, err := n.CreateEndpoint("ep1", nil)
ep, err := n.CreateEndpoint("ep1")
if err != nil {
t.Fatal(err)
}
@ -538,7 +545,7 @@ func TestEndpointJoinInvalidContainerId(t *testing.T) {
t.Fatal(err)
}
ep, err := n.CreateEndpoint("ep1", nil)
ep, err := n.CreateEndpoint("ep1")
if err != nil {
t.Fatal(err)
}
@ -561,7 +568,7 @@ func TestEndpointMultipleJoins(t *testing.T) {
t.Fatal(err)
}
ep, err := n.CreateEndpoint("ep1", nil)
ep, err := n.CreateEndpoint("ep1")
if err != nil {
t.Fatal(err)
}
@ -597,7 +604,7 @@ func TestEndpointInvalidLeave(t *testing.T) {
t.Fatal(err)
}
ep, err := n.CreateEndpoint("ep1", nil)
ep, err := n.CreateEndpoint("ep1")
if err != nil {
t.Fatal(err)
}

View file

@ -5,6 +5,7 @@ import (
"github.com/docker/docker/pkg/stringid"
"github.com/docker/libnetwork/driverapi"
"github.com/docker/libnetwork/pkg/options"
"github.com/docker/libnetwork/types"
)
@ -23,7 +24,7 @@ type Network interface {
// Create a new endpoint to this network symbolically identified by the
// specified unique name. The options parameter carry driver specific options.
// Labels support will be added in the near future.
CreateEndpoint(name string, options interface{}) (Endpoint, error)
CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error)
// Delete the network.
Delete() error
@ -52,6 +53,7 @@ type network struct {
id types.UUID
driver driverapi.Driver
endpoints endpointTable
generic options.Generic
sync.Mutex
}
@ -71,6 +73,27 @@ func (n *network) Type() string {
return n.driver.Type()
}
// NetworkOption is a option setter function type used to pass varios options to
// NewNetwork method. The various setter functions of type NetworkOption are
// provided by libnetwork, they look like NetworkOptionXXXX(...)
type NetworkOption func(n *network)
// NetworkOptionGeneric function returns an option setter for a Generic option defined
// in a Dictionary of Key-Value pair
func NetworkOptionGeneric(generic map[string]interface{}) NetworkOption {
return func(n *network) {
n.generic = generic
}
}
func (n *network) processOptions(options ...NetworkOption) {
for _, opt := range options {
if opt != nil {
opt(n)
}
}
}
func (n *network) Delete() error {
var err error
@ -103,13 +126,14 @@ func (n *network) Delete() error {
return err
}
func (n *network) CreateEndpoint(name string, options interface{}) (Endpoint, error) {
func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoint, error) {
ep := &endpoint{name: name}
ep.id = types.UUID(stringid.GenerateRandomID())
ep.network = n
ep.processOptions(options...)
d := n.driver
sinfo, err := d.CreateEndpoint(n.id, ep.id, options)
sinfo, err := d.CreateEndpoint(n.id, ep.id, ep.generic)
if err != nil {
return nil, err
}

View file

@ -7,6 +7,15 @@ import (
"reflect"
)
const (
// GenericData constant that helps to identify an option as a Generic constant
GenericData = "io.docker.network.generic"
// PortMap constant represents Port Mapping
PortMap = "io.docker.network.endpoint.portmap"
// MacAddress constant represents Mac Address config of a Container
MacAddress = "io.docker.network.endpoint.macaddress"
)
// NoSuchFieldError is the error returned when the generic parameters hold a
// value for a field absent from the destination structure.
type NoSuchFieldError struct {