Преглед изворни кода

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 пре 9 година
родитељ
комит
e03daebb48
2 измењених фајлова са 81 додато и 19 уклоњено
  1. 9 19
      daemon/container_unix.go
  2. 72 0
      integration-cli/docker_cli_network_unix_test.go

+ 9 - 19
daemon/container_unix.go

@@ -680,6 +680,10 @@ func (container *Container) buildEndpointInfo(n libnetwork.Network, ep libnetwor
 		return networkSettings, nil
 		return networkSettings, nil
 	}
 	}
 
 
+	if iface.MacAddress() != nil {
+		networkSettings.Networks[n.Name()].MacAddress = iface.MacAddress().String()
+	}
+
 	if iface.Address() != nil {
 	if iface.Address() != nil {
 		ones, _ := iface.Address().Mask.Size()
 		ones, _ := iface.Address().Mask.Size()
 		networkSettings.Networks[n.Name()].IPAddress = iface.Address().IP.String()
 		networkSettings.Networks[n.Name()].IPAddress = iface.Address().IP.String()
@@ -692,23 +696,14 @@ func (container *Container) buildEndpointInfo(n libnetwork.Network, ep libnetwor
 		networkSettings.Networks[n.Name()].GlobalIPv6PrefixLen = onesv6
 		networkSettings.Networks[n.Name()].GlobalIPv6PrefixLen = onesv6
 	}
 	}
 
 
-	driverInfo, err := ep.DriverInfo()
-	if err != nil {
-		return nil, err
-	}
-
-	if driverInfo == nil {
-		// It is not an error for epInfo to be nil
-		return networkSettings, nil
-	}
-	if mac, ok := driverInfo[netlabel.MacAddress]; ok {
-		networkSettings.Networks[n.Name()].MacAddress = mac.(net.HardwareAddr).String()
-	}
-
 	return networkSettings, nil
 	return networkSettings, nil
 }
 }
 
 
 func (container *Container) updateJoinInfo(n libnetwork.Network, ep libnetwork.Endpoint) error {
 func (container *Container) updateJoinInfo(n libnetwork.Network, ep libnetwork.Endpoint) error {
+	if _, err := container.buildPortMapInfo(ep, container.NetworkSettings); err != nil {
+		return err
+	}
+
 	epInfo := ep.Info()
 	epInfo := ep.Info()
 	if epInfo == nil {
 	if epInfo == nil {
 		// It is not an error to get an empty endpoint info
 		// It is not an error to get an empty endpoint info
@@ -754,12 +749,7 @@ func (container *Container) updateNetworkSettings(n libnetwork.Network) error {
 }
 }
 
 
 func (container *Container) updateEndpointNetworkSettings(n libnetwork.Network, ep libnetwork.Endpoint) error {
 func (container *Container) updateEndpointNetworkSettings(n libnetwork.Network, ep libnetwork.Endpoint) error {
-	networkSettings, err := container.buildPortMapInfo(ep, container.NetworkSettings)
-	if err != nil {
-		return err
-	}
-
-	networkSettings, err = container.buildEndpointInfo(n, ep, networkSettings)
+	networkSettings, err := container.buildEndpointInfo(n, ep, container.NetworkSettings)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}

+ 72 - 0
integration-cli/docker_cli_network_unix_test.go

@@ -20,6 +20,7 @@ import (
 	remoteipam "github.com/docker/libnetwork/ipams/remote/api"
 	remoteipam "github.com/docker/libnetwork/ipams/remote/api"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/docker/libnetwork/netlabel"
 	"github.com/go-check/check"
 	"github.com/go-check/check"
+	"github.com/vishvananda/netlink"
 )
 )
 
 
 const dummyNetworkDriver = "dummy-network-driver"
 const dummyNetworkDriver = "dummy-network-driver"
@@ -79,6 +80,36 @@ func (s *DockerNetworkSuite) SetUpSuite(c *check.C) {
 		fmt.Fprintf(w, "null")
 		fmt.Fprintf(w, "null")
 	})
 	})
 
 
+	mux.HandleFunc(fmt.Sprintf("/%s.CreateEndpoint", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
+		fmt.Fprintf(w, `{"Interface":{"MacAddress":"a0:b1:c2:d3:e4:f5"}}`)
+	})
+
+	mux.HandleFunc(fmt.Sprintf("/%s.Join", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
+
+		veth := &netlink.Veth{
+			LinkAttrs: netlink.LinkAttrs{Name: "randomIfName", TxQLen: 0}, PeerName: "cnt0"}
+		if err := netlink.LinkAdd(veth); err != nil {
+			fmt.Fprintf(w, `{"Error":"failed to add veth pair: `+err.Error()+`"}`)
+		} else {
+			fmt.Fprintf(w, `{"InterfaceName":{ "SrcName":"cnt0", "DstPrefix":"veth"}}`)
+		}
+	})
+
+	mux.HandleFunc(fmt.Sprintf("/%s.Leave", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
+		fmt.Fprintf(w, "null")
+	})
+
+	mux.HandleFunc(fmt.Sprintf("/%s.DeleteEndpoint", driverapi.NetworkPluginEndpointType), func(w http.ResponseWriter, r *http.Request) {
+		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
+		if link, err := netlink.LinkByName("cnt0"); err == nil {
+			netlink.LinkDel(link)
+		}
+		fmt.Fprintf(w, "null")
+	})
+
 	// Ipam Driver implementation
 	// Ipam Driver implementation
 	var (
 	var (
 		poolRequest       remoteipam.RequestPoolRequest
 		poolRequest       remoteipam.RequestPoolRequest
@@ -566,3 +597,44 @@ func (s *DockerNetworkSuite) TestDockerNetworkLinkOndefaultNetworkOnly(c *check.
 	dockerCmd(c, "network", "connect", "bridge", cnt2)
 	dockerCmd(c, "network", "connect", "bridge", cnt2)
 	dockerCmd(c, "run", "-d", "--link", fmt.Sprintf("%s:%s", cnt2, cnt2), "busybox", "top")
 	dockerCmd(c, "run", "-d", "--link", fmt.Sprintf("%s:%s", cnt2, cnt2), "busybox", "top")
 }
 }
+
+func (s *DockerNetworkSuite) TestDockerNetworkOverlayPortMapping(c *check.C) {
+	// Verify exposed ports are present in ps output when running a container on
+	// a network managed by a driver which does not provide the default gateway
+	// for the container
+	nwn := "ov"
+	ctn := "bb"
+	port1 := 80
+	port2 := 443
+	expose1 := fmt.Sprintf("--expose=%d", port1)
+	expose2 := fmt.Sprintf("--expose=%d", port2)
+
+	dockerCmd(c, "network", "create", "-d", dummyNetworkDriver, nwn)
+	assertNwIsAvailable(c, nwn)
+
+	dockerCmd(c, "run", "-d", "--net", nwn, "--name", ctn, expose1, expose2, "busybox", "top")
+
+	// Check docker ps o/p for last created container reports the unpublished ports
+	unpPort1 := fmt.Sprintf("%d/tcp", port1)
+	unpPort2 := fmt.Sprintf("%d/tcp", port2)
+	out, _ := dockerCmd(c, "ps", "-n=1")
+	// Missing unpublished ports in docker ps output
+	c.Assert(out, checker.Contains, unpPort1)
+	// Missing unpublished ports in docker ps output
+	c.Assert(out, checker.Contains, unpPort2)
+}
+
+func (s *DockerNetworkSuite) TestDockerNetworkMacInspect(c *check.C) {
+	// Verify endpoint MAC address is correctly populated in container's network settings
+	nwn := "ov"
+	ctn := "bb"
+
+	dockerCmd(c, "network", "create", "-d", dummyNetworkDriver, nwn)
+	assertNwIsAvailable(c, nwn)
+
+	dockerCmd(c, "run", "-d", "--net", nwn, "--name", ctn, "busybox", "top")
+
+	mac, err := inspectField(ctn, "NetworkSettings.Networks."+nwn+".MacAddress")
+	c.Assert(err, checker.IsNil)
+	c.Assert(mac, checker.Equals, "a0:b1:c2:d3:e4:f5")
+}