- 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>
... | ... |
@@ -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 |
+} |