diff --git a/api/server/router/network/network_routes.go b/api/server/router/network/network_routes.go index 2d9c78668908c..10c0fa3224a0d 100644 --- a/api/server/router/network/network_routes.go +++ b/api/server/router/network/network_routes.go @@ -3,6 +3,7 @@ package network import ( "encoding/json" "net/http" + "strings" "golang.org/x/net/context" @@ -79,8 +80,16 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr return err } - if _, err := n.clusterProvider.GetNetwork(create.Name); err == nil { - return libnetwork.NetworkNameError(create.Name) + if nw, err := n.clusterProvider.GetNetwork(create.Name); err == nil { + // GetNetwork can return nw if: + // 1. nw.Name == create.Name + // 2. nw.ID == create.Name + // 3. nw.ID starts with create.Name + // + // we do not need to raise an error for the case 3. + if !strings.HasPrefix(nw.ID, create.Name) { + return libnetwork.NetworkNameError(create.Name) + } } nw, err := n.backend.CreateNetwork(create) diff --git a/integration-cli/docker_cli_swarm_test.go b/integration-cli/docker_cli_swarm_test.go index 5cf19160d6612..7319bc1698501 100644 --- a/integration-cli/docker_cli_swarm_test.go +++ b/integration-cli/docker_cli_swarm_test.go @@ -588,3 +588,21 @@ func (s *DockerSwarmSuite) TestSwarmServiceEnvFile(c *check.C) { c.Assert(err, checker.IsNil) c.Assert(out, checker.Contains, "[VAR1=C VAR2]") } + +// Test case for #27866 +func (s *DockerSwarmSuite) TestSwarmNetworkCreateIssue27866(c *check.C) { + d := s.AddDaemon(c, true, true) + out, err := d.Cmd("network", "inspect", "-f", "{{.Id}}", "ingress") + c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) + ingressID := strings.TrimSpace(out) + c.Assert(ingressID, checker.Not(checker.Equals), "") + + // create a network of which name is the prefix of the ID of an overlay network + // (ingressID in this case) + newNetName := ingressID[0:2] + out, err = d.Cmd("network", "create", "--driver", "overlay", newNetName) + // In #27866, it was failing because of "network with name %s already exists" + c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) + out, err = d.Cmd("network", "rm", newNetName) + c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) +}