浏览代码

Add methods to walk Endpoints and Networks

- From Network and Controller interfaces, respectively

Signed-off-by: Alessandro Boch <aboch@docker.com>
Alessandro Boch 10 年之前
父节点
当前提交
1c7c0f371b
共有 2 个文件被更改,包括 135 次插入21 次删除
  1. 80 8
      libnetwork/libnetwork_test.go
  2. 55 13
      libnetwork/network.go

+ 80 - 8
libnetwork/libnetwork_test.go

@@ -74,14 +74,6 @@ func TestBridge(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	epList := network.Endpoints()
-	if len(epList) != 1 {
-		t.Fatal(err)
-	}
-	if ep != epList[0] {
-		t.Fatal(err)
-	}
-
 	if err := ep.Delete(); err != nil {
 		t.Fatal(err)
 	}
@@ -299,3 +291,83 @@ func TestUnknownEndpoint(t *testing.T) {
 		t.Fatal(err)
 	}
 }
+
+func TestNetworkEndpointsWalkers(t *testing.T) {
+	defer netutils.SetupTestNetNS(t)()
+	controller := libnetwork.New()
+	netType := "bridge"
+
+	option := options.Generic{}
+	err := controller.ConfigureNetworkDriver(netType, option)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Create network 1 and add 2 endpoint: ep11, ep12
+	net1, err := controller.NewNetwork(netType, "network1", "")
+	if err != nil {
+		t.Fatal(err)
+	}
+	ep11, err := net1.CreateEndpoint("ep11", "sbox1", nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+	ep12, err := net1.CreateEndpoint("ep12", "sbox2", nil)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Test list methods on net1
+	epList1 := net1.Endpoints()
+	if len(epList1) != 2 {
+		t.Fatalf("Endpoints() returned wrong number of elements: %d instead of 2", len(epList1))
+	}
+	// endpoint order is not guaranteed
+	for _, e := range epList1 {
+		if e != ep11 && e != ep12 {
+			t.Fatal("Endpoints() did not return all the expected elements")
+		}
+	}
+
+	// Test Endpoint Walk method
+	var epName string
+	var epWanted libnetwork.Endpoint
+	wlk := func(ep libnetwork.Endpoint) bool {
+		if ep.Name() == epName {
+			epWanted = ep
+			return true
+		}
+		return false
+	}
+
+	// Look for ep1 on network1
+	epName = "ep11"
+	net1.WalkEndpoints(wlk)
+	if epWanted == nil {
+		t.Fatal(err)
+	}
+	if ep11 != epWanted {
+		t.Fatal(err)
+	}
+
+	// Test Network Walk method
+	var netName string
+	var netWanted libnetwork.Network
+	nwWlk := func(nw libnetwork.Network) bool {
+		if nw.Name() == netName {
+			netWanted = nw
+			return true
+		}
+		return false
+	}
+
+	// Look for network named "network1"
+	netName = "network1"
+	controller.WalkNetworks(nwWlk)
+	if netWanted == nil {
+		t.Fatal(err)
+	}
+	if net1 != netWanted {
+		t.Fatal(err)
+	}
+}

+ 55 - 13
libnetwork/network.go

@@ -52,9 +52,16 @@ import (
 type NetworkController interface {
 	// ConfigureNetworkDriver applies the passed options to the driver instance for the specified network type
 	ConfigureNetworkDriver(networkType string, options 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)
+
+	// Networks returns the list of Network(s) managed by this controller.
+	Networks() []Network
+
+	// WalkNetworks uses the provided function to walk the Network(s) managed by this controller.
+	WalkNetworks(walker NetworkWalker)
 }
 
 // A Network represents a logical connectivity zone that containers may
@@ -74,13 +81,20 @@ type Network interface {
 	// Labels support will be added in the near future.
 	CreateEndpoint(name string, sboxKey string, options interface{}) (Endpoint, error)
 
-	// Endpoints returns the list of Endpoint in this network.
+	// Endpoints returns the list of Endpoint(s) in this network.
 	Endpoints() []Endpoint
 
+	// WalkEndpoints uses the provided function to walk the Endpoints
+	WalkEndpoints(walker EndpointWalker)
+
 	// Delete the network.
 	Delete() error
 }
 
+// NetworkWalker is a client provided function which will be used to walk the Networks.
+// When the function returns true, the walk will stop.
+type NetworkWalker func(nw Network) bool
+
 // Endpoint represents a logical connection between a network and a sandbox.
 type Endpoint interface {
 	// A system generated id for this endpoint.
@@ -99,12 +113,9 @@ type Endpoint interface {
 	Delete() error
 }
 
-type endpoint struct {
-	name        string
-	id          types.UUID
-	network     *network
-	sandboxInfo *sandbox.Info
-}
+// EndpointWalker is a client provided function which will be used to walk the Endpoints.
+// When the function returns true, the walk will stop.
+type EndpointWalker func(ep Endpoint) bool
 
 type network struct {
 	ctrlr       *controller
@@ -116,6 +127,13 @@ type network struct {
 	sync.Mutex
 }
 
+type endpoint struct {
+	name        string
+	id          types.UUID
+	network     *network
+	sandboxInfo *sandbox.Info
+}
+
 type networkTable map[types.UUID]*network
 type endpointTable map[types.UUID]*endpoint
 
@@ -179,6 +197,26 @@ func (c *controller) NewNetwork(networkType, name string, options interface{}) (
 	return network, nil
 }
 
+func (c *controller) Networks() []Network {
+	c.Lock()
+	defer c.Unlock()
+
+	list := make([]Network, 0, len(c.networks))
+	for _, n := range c.networks {
+		list = append(list, n)
+	}
+
+	return list
+}
+
+func (c *controller) WalkNetworks(walker NetworkWalker) {
+	for _, n := range c.Networks() {
+		if walker(n) {
+			return
+		}
+	}
+}
+
 func (n *network) Name() string {
 	return n.name
 }
@@ -248,18 +286,22 @@ func (n *network) CreateEndpoint(name string, sboxKey string, options interface{
 func (n *network) Endpoints() []Endpoint {
 	n.Lock()
 	defer n.Unlock()
-
-	list := make([]Endpoint, len(n.endpoints))
-
-	idx := 0
+	list := make([]Endpoint, 0, len(n.endpoints))
 	for _, e := range n.endpoints {
-		list[idx] = e
-		idx++
+		list = append(list, e)
 	}
 
 	return list
 }
 
+func (n *network) WalkEndpoints(walker EndpointWalker) {
+	for _, e := range n.Endpoints() {
+		if walker(e) {
+			return
+		}
+	}
+}
+
 func (ep *endpoint) ID() string {
 	return string(ep.id)
 }