Signed-off-by: Alessandro Boch <aboch@docker.com>
| ... | ... |
@@ -660,7 +660,8 @@ func getEndpointPortMapInfo(ep libnetwork.Endpoint) (nat.PortMap, error) {
|
| 660 | 660 |
return pm, nil |
| 661 | 661 |
} |
| 662 | 662 |
|
| 663 |
-func getSandboxPortMapInfo(sb libnetwork.Sandbox) nat.PortMap {
|
|
| 663 |
+// GetSandboxPortMapInfo retrieves the current port-mapping programmed for the given sandbox |
|
| 664 |
+func GetSandboxPortMapInfo(sb libnetwork.Sandbox) nat.PortMap {
|
|
| 664 | 665 |
pm := nat.PortMap{}
|
| 665 | 666 |
if sb == nil {
|
| 666 | 667 |
return pm |
| ... | ... |
@@ -817,7 +818,7 @@ func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epC |
| 817 | 817 |
} |
| 818 | 818 |
|
| 819 | 819 |
// Port-mapping rules belong to the container & applicable only to non-internal networks |
| 820 |
- portmaps := getSandboxPortMapInfo(sb) |
|
| 820 |
+ portmaps := GetSandboxPortMapInfo(sb) |
|
| 821 | 821 |
if n.Info().Internal() || len(portmaps) > 0 {
|
| 822 | 822 |
return createOptions, nil |
| 823 | 823 |
} |
| ... | ... |
@@ -27,6 +27,7 @@ var ( |
| 27 | 27 |
// ErrRootFSReadOnly is returned when a container |
| 28 | 28 |
// rootfs is marked readonly. |
| 29 | 29 |
ErrRootFSReadOnly = errors.New("container rootfs is marked read-only")
|
| 30 |
+ getPortMapInfo = container.GetSandboxPortMapInfo |
|
| 30 | 31 |
) |
| 31 | 32 |
|
| 32 | 33 |
func (daemon *Daemon) buildSandboxOptions(container *container.Container, n libnetwork.Network) ([]libnetwork.SandboxOption, error) {
|
| ... | ... |
@@ -587,6 +588,8 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName |
| 587 | 587 |
return fmt.Errorf("Updating join info failed: %v", err)
|
| 588 | 588 |
} |
| 589 | 589 |
|
| 590 |
+ container.NetworkSettings.Ports = getPortMapInfo(sb) |
|
| 591 |
+ |
|
| 590 | 592 |
daemon.LogNetworkEventWithAttributes(n, "connect", map[string]string{"container": container.ID})
|
| 591 | 593 |
return nil |
| 592 | 594 |
} |
| ... | ... |
@@ -639,6 +642,8 @@ func disconnectFromNetwork(container *container.Container, n libnetwork.Network, |
| 639 | 639 |
return fmt.Errorf("container %s failed to leave network %s: %v", container.ID, n.Name(), err)
|
| 640 | 640 |
} |
| 641 | 641 |
|
| 642 |
+ container.NetworkSettings.Ports = getPortMapInfo(sbox) |
|
| 643 |
+ |
|
| 642 | 644 |
if err := ep.Delete(false); err != nil {
|
| 643 | 645 |
return fmt.Errorf("endpoint delete failed for container %s on network %s: %v", container.ID, n.Name(), err)
|
| 644 | 646 |
} |
| ... | ... |
@@ -1110,6 +1110,52 @@ func (s *DockerNetworkSuite) TestDockerNetworkConnectWithPortMapping(c *check.C) |
| 1110 | 1110 |
dockerCmd(c, "network", "connect", "test1", "c1") |
| 1111 | 1111 |
} |
| 1112 | 1112 |
|
| 1113 |
+func verifyPortMap(c *check.C, container, port, originalMapping string, mustBeEqual bool) {
|
|
| 1114 |
+ chk := checker.Equals |
|
| 1115 |
+ if !mustBeEqual {
|
|
| 1116 |
+ chk = checker.Not(checker.Equals) |
|
| 1117 |
+ } |
|
| 1118 |
+ currentMapping, _ := dockerCmd(c, "port", container, port) |
|
| 1119 |
+ c.Assert(currentMapping, chk, originalMapping) |
|
| 1120 |
+} |
|
| 1121 |
+ |
|
| 1122 |
+func (s *DockerNetworkSuite) TestDockerNetworkConnectDisconnectWithPortMapping(c *check.C) {
|
|
| 1123 |
+ // Connect and disconnect a container with explicit and non-explicit |
|
| 1124 |
+ // host port mapping to/from networks which do cause and do not cause |
|
| 1125 |
+ // the container default gateway to change, and verify docker port cmd |
|
| 1126 |
+ // returns congruent information |
|
| 1127 |
+ testRequires(c, NotArm) |
|
| 1128 |
+ cnt := "c1" |
|
| 1129 |
+ dockerCmd(c, "network", "create", "aaa") |
|
| 1130 |
+ dockerCmd(c, "network", "create", "ccc") |
|
| 1131 |
+ |
|
| 1132 |
+ dockerCmd(c, "run", "-d", "--name", cnt, "-p", "9000:90", "-p", "70", "busybox", "top") |
|
| 1133 |
+ c.Assert(waitRun(cnt), check.IsNil) |
|
| 1134 |
+ curPortMap, _ := dockerCmd(c, "port", cnt, "70") |
|
| 1135 |
+ curExplPortMap, _ := dockerCmd(c, "port", cnt, "90") |
|
| 1136 |
+ |
|
| 1137 |
+ // Connect to a network which causes the container's default gw switch |
|
| 1138 |
+ dockerCmd(c, "network", "connect", "aaa", cnt) |
|
| 1139 |
+ verifyPortMap(c, cnt, "70", curPortMap, false) |
|
| 1140 |
+ verifyPortMap(c, cnt, "90", curExplPortMap, true) |
|
| 1141 |
+ |
|
| 1142 |
+ // Read current mapping |
|
| 1143 |
+ curPortMap, _ = dockerCmd(c, "port", cnt, "70") |
|
| 1144 |
+ |
|
| 1145 |
+ // Disconnect from a network which causes the container's default gw switch |
|
| 1146 |
+ dockerCmd(c, "network", "disconnect", "aaa", cnt) |
|
| 1147 |
+ verifyPortMap(c, cnt, "70", curPortMap, false) |
|
| 1148 |
+ verifyPortMap(c, cnt, "90", curExplPortMap, true) |
|
| 1149 |
+ |
|
| 1150 |
+ // Read current mapping |
|
| 1151 |
+ curPortMap, _ = dockerCmd(c, "port", cnt, "70") |
|
| 1152 |
+ |
|
| 1153 |
+ // Connect to a network which does not cause the container's default gw switch |
|
| 1154 |
+ dockerCmd(c, "network", "connect", "ccc", cnt) |
|
| 1155 |
+ verifyPortMap(c, cnt, "70", curPortMap, true) |
|
| 1156 |
+ verifyPortMap(c, cnt, "90", curExplPortMap, true) |
|
| 1157 |
+} |
|
| 1158 |
+ |
|
| 1113 | 1159 |
func (s *DockerNetworkSuite) TestDockerNetworkConnectWithMac(c *check.C) {
|
| 1114 | 1160 |
macAddress := "02:42:ac:11:00:02" |
| 1115 | 1161 |
dockerCmd(c, "network", "create", "mynetwork") |