Browse code

Execute buildPortMapInfo after Endpoint.Join()

- As the retrieved info may not be available at
Endpoint creation time for certain network drivers
- Also retrieve the MAC address from Endpoint.Info().Iface()

Signed-off-by: Alessandro Boch <aboch@docker.com>

Alessandro Boch authored on 2015/10/30 01:25:29
Showing 2 changed files
... ...
@@ -680,6 +680,10 @@ func (container *Container) buildEndpointInfo(n libnetwork.Network, ep libnetwor
680 680
 		return networkSettings, nil
681 681
 	}
682 682
 
683
+	if iface.MacAddress() != nil {
684
+		networkSettings.Networks[n.Name()].MacAddress = iface.MacAddress().String()
685
+	}
686
+
683 687
 	if iface.Address() != nil {
684 688
 		ones, _ := iface.Address().Mask.Size()
685 689
 		networkSettings.Networks[n.Name()].IPAddress = iface.Address().IP.String()
... ...
@@ -692,23 +696,14 @@ func (container *Container) buildEndpointInfo(n libnetwork.Network, ep libnetwor
692 692
 		networkSettings.Networks[n.Name()].GlobalIPv6PrefixLen = onesv6
693 693
 	}
694 694
 
695
-	driverInfo, err := ep.DriverInfo()
696
-	if err != nil {
697
-		return nil, err
698
-	}
699
-
700
-	if driverInfo == nil {
701
-		// It is not an error for epInfo to be nil
702
-		return networkSettings, nil
703
-	}
704
-	if mac, ok := driverInfo[netlabel.MacAddress]; ok {
705
-		networkSettings.Networks[n.Name()].MacAddress = mac.(net.HardwareAddr).String()
706
-	}
707
-
708 695
 	return networkSettings, nil
709 696
 }
710 697
 
711 698
 func (container *Container) updateJoinInfo(n libnetwork.Network, ep libnetwork.Endpoint) error {
699
+	if _, err := container.buildPortMapInfo(ep, container.NetworkSettings); err != nil {
700
+		return err
701
+	}
702
+
712 703
 	epInfo := ep.Info()
713 704
 	if epInfo == nil {
714 705
 		// It is not an error to get an empty endpoint info
... ...
@@ -754,12 +749,7 @@ func (container *Container) updateNetworkSettings(n libnetwork.Network) error {
754 754
 }
755 755
 
756 756
 func (container *Container) updateEndpointNetworkSettings(n libnetwork.Network, ep libnetwork.Endpoint) error {
757
-	networkSettings, err := container.buildPortMapInfo(ep, container.NetworkSettings)
758
-	if err != nil {
759
-		return err
760
-	}
761
-
762
-	networkSettings, err = container.buildEndpointInfo(n, ep, networkSettings)
757
+	networkSettings, err := container.buildEndpointInfo(n, ep, container.NetworkSettings)
763 758
 	if err != nil {
764 759
 		return err
765 760
 	}
... ...
@@ -20,6 +20,7 @@ import (
20 20
 	remoteipam "github.com/docker/libnetwork/ipams/remote/api"
21 21
 	"github.com/docker/libnetwork/netlabel"
22 22
 	"github.com/go-check/check"
23
+	"github.com/vishvananda/netlink"
23 24
 )
24 25
 
25 26
 const dummyNetworkDriver = "dummy-network-driver"
... ...
@@ -79,6 +80,36 @@ func (s *DockerNetworkSuite) SetUpSuite(c *check.C) {
79 79
 		fmt.Fprintf(w, "null")
80 80
 	})
81 81
 
82
+	mux.HandleFunc(fmt.Sprintf("/%s.CreateEndpoint", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
83
+		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
84
+		fmt.Fprintf(w, `{"Interface":{"MacAddress":"a0:b1:c2:d3:e4:f5"}}`)
85
+	})
86
+
87
+	mux.HandleFunc(fmt.Sprintf("/%s.Join", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
88
+		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
89
+
90
+		veth := &netlink.Veth{
91
+			LinkAttrs: netlink.LinkAttrs{Name: "randomIfName", TxQLen: 0}, PeerName: "cnt0"}
92
+		if err := netlink.LinkAdd(veth); err != nil {
93
+			fmt.Fprintf(w, `{"Error":"failed to add veth pair: `+err.Error()+`"}`)
94
+		} else {
95
+			fmt.Fprintf(w, `{"InterfaceName":{ "SrcName":"cnt0", "DstPrefix":"veth"}}`)
96
+		}
97
+	})
98
+
99
+	mux.HandleFunc(fmt.Sprintf("/%s.Leave", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
100
+		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
101
+		fmt.Fprintf(w, "null")
102
+	})
103
+
104
+	mux.HandleFunc(fmt.Sprintf("/%s.DeleteEndpoint", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
105
+		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
106
+		if link, err := netlink.LinkByName("cnt0"); err == nil {
107
+			netlink.LinkDel(link)
108
+		}
109
+		fmt.Fprintf(w, "null")
110
+	})
111
+
82 112
 	// Ipam Driver implementation
83 113
 	var (
84 114
 		poolRequest       remoteipam.RequestPoolRequest
... ...
@@ -566,3 +597,44 @@ func (s *DockerNetworkSuite) TestDockerNetworkLinkOndefaultNetworkOnly(c *check.
566 566
 	dockerCmd(c, "network", "connect", "bridge", cnt2)
567 567
 	dockerCmd(c, "run", "-d", "--link", fmt.Sprintf("%s:%s", cnt2, cnt2), "busybox", "top")
568 568
 }
569
+
570
+func (s *DockerNetworkSuite) TestDockerNetworkOverlayPortMapping(c *check.C) {
571
+	// Verify exposed ports are present in ps output when running a container on
572
+	// a network managed by a driver which does not provide the default gateway
573
+	// for the container
574
+	nwn := "ov"
575
+	ctn := "bb"
576
+	port1 := 80
577
+	port2 := 443
578
+	expose1 := fmt.Sprintf("--expose=%d", port1)
579
+	expose2 := fmt.Sprintf("--expose=%d", port2)
580
+
581
+	dockerCmd(c, "network", "create", "-d", dummyNetworkDriver, nwn)
582
+	assertNwIsAvailable(c, nwn)
583
+
584
+	dockerCmd(c, "run", "-d", "--net", nwn, "--name", ctn, expose1, expose2, "busybox", "top")
585
+
586
+	// Check docker ps o/p for last created container reports the unpublished ports
587
+	unpPort1 := fmt.Sprintf("%d/tcp", port1)
588
+	unpPort2 := fmt.Sprintf("%d/tcp", port2)
589
+	out, _ := dockerCmd(c, "ps", "-n=1")
590
+	// Missing unpublished ports in docker ps output
591
+	c.Assert(out, checker.Contains, unpPort1)
592
+	// Missing unpublished ports in docker ps output
593
+	c.Assert(out, checker.Contains, unpPort2)
594
+}
595
+
596
+func (s *DockerNetworkSuite) TestDockerNetworkMacInspect(c *check.C) {
597
+	// Verify endpoint MAC address is correctly populated in container's network settings
598
+	nwn := "ov"
599
+	ctn := "bb"
600
+
601
+	dockerCmd(c, "network", "create", "-d", dummyNetworkDriver, nwn)
602
+	assertNwIsAvailable(c, nwn)
603
+
604
+	dockerCmd(c, "run", "-d", "--net", nwn, "--name", ctn, "busybox", "top")
605
+
606
+	mac, err := inspectField(ctn, "NetworkSettings.Networks."+nwn+".MacAddress")
607
+	c.Assert(err, checker.IsNil)
608
+	c.Assert(mac, checker.Equals, "a0:b1:c2:d3:e4:f5")
609
+}