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