From cb59bd0c5194f3f74cd405a87b562465219cad8a Mon Sep 17 00:00:00 2001 From: Yong Tang Date: Tue, 27 Dec 2016 13:43:21 -0800 Subject: [PATCH] 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 --- integration-cli/docker_cli_swarm_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/integration-cli/docker_cli_swarm_test.go b/integration-cli/docker_cli_swarm_test.go index 3d04561c5f..17e73073d6 100644 --- a/integration-cli/docker_cli_swarm_test.go +++ b/integration-cli/docker_cli_swarm_test.go @@ -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}") +}