Signed-off-by: Alessandro Boch <aboch@docker.com>
(cherry picked from commit f198dfd856ca6125ef50b11d9d698550d66c9d4e)
... | ... |
@@ -667,7 +667,8 @@ func getEndpointPortMapInfo(ep libnetwork.Endpoint) (nat.PortMap, error) { |
667 | 667 |
return pm, nil |
668 | 668 |
} |
669 | 669 |
|
670 |
-func getSandboxPortMapInfo(sb libnetwork.Sandbox) nat.PortMap { |
|
670 |
+// GetSandboxPortMapInfo retrieves the current port-mapping programmed for the given sandbox |
|
671 |
+func GetSandboxPortMapInfo(sb libnetwork.Sandbox) nat.PortMap { |
|
671 | 672 |
pm := nat.PortMap{} |
672 | 673 |
if sb == nil { |
673 | 674 |
return pm |
... | ... |
@@ -824,7 +825,7 @@ func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epC |
824 | 824 |
} |
825 | 825 |
|
826 | 826 |
// Port-mapping rules belong to the container & applicable only to non-internal networks |
827 |
- portmaps := getSandboxPortMapInfo(sb) |
|
827 |
+ portmaps := GetSandboxPortMapInfo(sb) |
|
828 | 828 |
if n.Info().Internal() || len(portmaps) > 0 { |
829 | 829 |
return createOptions, nil |
830 | 830 |
} |
... | ... |
@@ -26,6 +26,7 @@ var ( |
26 | 26 |
// ErrRootFSReadOnly is returned when a container |
27 | 27 |
// rootfs is marked readonly. |
28 | 28 |
ErrRootFSReadOnly = errors.New("container rootfs is marked read-only") |
29 |
+ getPortMapInfo = container.GetSandboxPortMapInfo |
|
29 | 30 |
) |
30 | 31 |
|
31 | 32 |
func (daemon *Daemon) buildSandboxOptions(container *container.Container, n libnetwork.Network) ([]libnetwork.SandboxOption, error) { |
... | ... |
@@ -581,6 +582,8 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName |
581 | 581 |
return fmt.Errorf("Updating join info failed: %v", err) |
582 | 582 |
} |
583 | 583 |
|
584 |
+ container.NetworkSettings.Ports = getPortMapInfo(sb) |
|
585 |
+ |
|
584 | 586 |
daemon.LogNetworkEventWithAttributes(n, "connect", map[string]string{"container": container.ID}) |
585 | 587 |
return nil |
586 | 588 |
} |
... | ... |
@@ -633,6 +636,8 @@ func disconnectFromNetwork(container *container.Container, n libnetwork.Network, |
633 | 633 |
return fmt.Errorf("container %s failed to leave network %s: %v", container.ID, n.Name(), err) |
634 | 634 |
} |
635 | 635 |
|
636 |
+ container.NetworkSettings.Ports = getPortMapInfo(sbox) |
|
637 |
+ |
|
636 | 638 |
if err := ep.Delete(false); err != nil { |
637 | 639 |
return fmt.Errorf("endpoint delete failed for container %s on network %s: %v", container.ID, n.Name(), err) |
638 | 640 |
} |
... | ... |
@@ -1080,6 +1080,52 @@ func (s *DockerNetworkSuite) TestDockerNetworkConnectWithPortMapping(c *check.C) |
1080 | 1080 |
dockerCmd(c, "network", "connect", "test1", "c1") |
1081 | 1081 |
} |
1082 | 1082 |
|
1083 |
+func verifyPortMap(c *check.C, container, port, originalMapping string, mustBeEqual bool) { |
|
1084 |
+ chk := checker.Equals |
|
1085 |
+ if !mustBeEqual { |
|
1086 |
+ chk = checker.Not(checker.Equals) |
|
1087 |
+ } |
|
1088 |
+ currentMapping, _ := dockerCmd(c, "port", container, port) |
|
1089 |
+ c.Assert(currentMapping, chk, originalMapping) |
|
1090 |
+} |
|
1091 |
+ |
|
1092 |
+func (s *DockerNetworkSuite) TestDockerNetworkConnectDisconnectWithPortMapping(c *check.C) { |
|
1093 |
+ // Connect and disconnect a container with explicit and non-explicit |
|
1094 |
+ // host port mapping to/from networks which do cause and do not cause |
|
1095 |
+ // the container default gateway to change, and verify docker port cmd |
|
1096 |
+ // returns congruent information |
|
1097 |
+ testRequires(c, NotArm) |
|
1098 |
+ cnt := "c1" |
|
1099 |
+ dockerCmd(c, "network", "create", "aaa") |
|
1100 |
+ dockerCmd(c, "network", "create", "ccc") |
|
1101 |
+ |
|
1102 |
+ dockerCmd(c, "run", "-d", "--name", cnt, "-p", "9000:90", "-p", "70", "busybox", "top") |
|
1103 |
+ c.Assert(waitRun(cnt), check.IsNil) |
|
1104 |
+ curPortMap, _ := dockerCmd(c, "port", cnt, "70") |
|
1105 |
+ curExplPortMap, _ := dockerCmd(c, "port", cnt, "90") |
|
1106 |
+ |
|
1107 |
+ // Connect to a network which causes the container's default gw switch |
|
1108 |
+ dockerCmd(c, "network", "connect", "aaa", cnt) |
|
1109 |
+ verifyPortMap(c, cnt, "70", curPortMap, false) |
|
1110 |
+ verifyPortMap(c, cnt, "90", curExplPortMap, true) |
|
1111 |
+ |
|
1112 |
+ // Read current mapping |
|
1113 |
+ curPortMap, _ = dockerCmd(c, "port", cnt, "70") |
|
1114 |
+ |
|
1115 |
+ // Disconnect from a network which causes the container's default gw switch |
|
1116 |
+ dockerCmd(c, "network", "disconnect", "aaa", cnt) |
|
1117 |
+ verifyPortMap(c, cnt, "70", curPortMap, false) |
|
1118 |
+ verifyPortMap(c, cnt, "90", curExplPortMap, true) |
|
1119 |
+ |
|
1120 |
+ // Read current mapping |
|
1121 |
+ curPortMap, _ = dockerCmd(c, "port", cnt, "70") |
|
1122 |
+ |
|
1123 |
+ // Connect to a network which does not cause the container's default gw switch |
|
1124 |
+ dockerCmd(c, "network", "connect", "ccc", cnt) |
|
1125 |
+ verifyPortMap(c, cnt, "70", curPortMap, true) |
|
1126 |
+ verifyPortMap(c, cnt, "90", curExplPortMap, true) |
|
1127 |
+} |
|
1128 |
+ |
|
1083 | 1129 |
func (s *DockerNetworkSuite) TestDockerNetworkConnectWithMac(c *check.C) { |
1084 | 1130 |
macAddress := "02:42:ac:11:00:02" |
1085 | 1131 |
dockerCmd(c, "network", "create", "mynetwork") |