From 1e5398f3c2671da56ca8fae71f8c9fa817b25715 Mon Sep 17 00:00:00 2001 From: Akihiro Suda Date: Tue, 1 Nov 2016 05:49:39 +0000 Subject: [PATCH] api: allow creating a network of which name is the prefix of the ID of a swarm network Previously, it doesn't allow creating such a network: e.g. $ docker network inspect -f '{{.Id}}' ingress 84xh9knigj6zyt00u31e26nj3 $ docker network create 84 Error response from daemon: network with name 84 already exists Fix #27866 Signed-off-by: Akihiro Suda --- api/server/router/network/network_routes.go | 13 +++++++++++-- integration-cli/docker_cli_swarm_test.go | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) 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)) +}