Fix issues of multiple published ports mapping to the same target port

This fix tries to address the issue raised in docker/docker-29730
where a service with multiple published ports mapping to the same target
port (e.g., `--publish 5000:80 --publish 5001:80`) can't be allocated.

The reason for the issue is that, `getPortConfigKey` is used for both
allocated ports and configured (may or may not be allocated) ports.
However, `getPortConfigKey` will not take into consideration the
`PublishedPort` field, which actually could be different for different
allocated ports.

This fix saves a map of `portKey:portNum:portState`,  instead of currently
used `portKey:portState` so that multiple published ports could be processed.

Signed-off-by: Yong Tang <yong.tang.github@outlook.com>
This commit is contained in:
Yong Tang 2016-12-27 13:43:21 -08:00
parent 8563492eef
commit cb59bd0c51
1 changed files with 19 additions and 0 deletions

View File

@ -1572,3 +1572,22 @@ func (s *DockerSwarmSuite) TestSwarmServicePsMultipleServiceIDs(c *check.C) {
c.Assert(out, checker.Contains, name2+".2")
c.Assert(out, checker.Contains, name2+".3")
}
func (s *DockerSwarmSuite) TestSwarmPublishDuplicatePorts(c *check.C) {
d := s.AddDaemon(c, true, true)
out, err := d.Cmd("service", "create", "--publish", "5000:80", "--publish", "5001:80", "--publish", "80", "--publish", "80", "busybox", "top")
c.Assert(err, check.IsNil, check.Commentf(out))
id := strings.TrimSpace(out)
// make sure task has been deployed.
waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1)
// Total len = 4, with 2 dynamic ports and 2 non-dynamic ports
// Dynamic ports are likely to be 30000 and 30001 but doesn't matter
out, err = d.Cmd("service", "inspect", "--format", "{{.Endpoint.Ports}} len={{len .Endpoint.Ports}}", id)
c.Assert(err, check.IsNil, check.Commentf(out))
c.Assert(out, checker.Contains, "len=4")
c.Assert(out, checker.Contains, "{ tcp 80 5000 ingress}")
c.Assert(out, checker.Contains, "{ tcp 80 5001 ingress}")
}