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 <suda.akihiro@lab.ntt.co.jp>
(cherry picked from commit edfbc3b8767ab2e89e73ba3142d2ddad295001e9)
Signed-off-by: Victor Vieux <vieux@docker.com>
| ... | ... |
@@ -80,7 +80,7 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr |
| 80 | 80 |
return err |
| 81 | 81 |
} |
| 82 | 82 |
|
| 83 |
- if _, err := n.clusterProvider.GetNetwork(create.Name); err == nil {
|
|
| 83 |
+ if nws, err := n.clusterProvider.GetNetworksByName(create.Name); err == nil && len(nws) > 0 {
|
|
| 84 | 84 |
return libnetwork.NetworkNameError(create.Name) |
| 85 | 85 |
} |
| 86 | 86 |
|
| ... | ... |
@@ -1556,8 +1556,7 @@ func (c *Cluster) GetNetwork(input string) (apitypes.NetworkResource, error) {
|
| 1556 | 1556 |
return convert.BasicNetworkFromGRPC(*network), nil |
| 1557 | 1557 |
} |
| 1558 | 1558 |
|
| 1559 |
-// GetNetworks returns all current cluster managed networks. |
|
| 1560 |
-func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) {
|
|
| 1559 |
+func (c *Cluster) getNetworks(filters *swarmapi.ListNetworksRequest_Filters) ([]apitypes.NetworkResource, error) {
|
|
| 1561 | 1560 |
c.RLock() |
| 1562 | 1561 |
defer c.RUnlock() |
| 1563 | 1562 |
|
| ... | ... |
@@ -1568,7 +1567,7 @@ func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) {
|
| 1568 | 1568 |
ctx, cancel := c.getRequestContext() |
| 1569 | 1569 |
defer cancel() |
| 1570 | 1570 |
|
| 1571 |
- r, err := c.client.ListNetworks(ctx, &swarmapi.ListNetworksRequest{})
|
|
| 1571 |
+ r, err := c.client.ListNetworks(ctx, &swarmapi.ListNetworksRequest{Filters: filters})
|
|
| 1572 | 1572 |
if err != nil {
|
| 1573 | 1573 |
return nil, err |
| 1574 | 1574 |
} |
| ... | ... |
@@ -1582,6 +1581,21 @@ func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) {
|
| 1582 | 1582 |
return networks, nil |
| 1583 | 1583 |
} |
| 1584 | 1584 |
|
| 1585 |
+// GetNetworks returns all current cluster managed networks. |
|
| 1586 |
+func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) {
|
|
| 1587 |
+ return c.getNetworks(nil) |
|
| 1588 |
+} |
|
| 1589 |
+ |
|
| 1590 |
+// GetNetworksByName returns cluster managed networks by name. |
|
| 1591 |
+// It is ok to have multiple networks here. #18864 |
|
| 1592 |
+func (c *Cluster) GetNetworksByName(name string) ([]apitypes.NetworkResource, error) {
|
|
| 1593 |
+ // Note that swarmapi.GetNetworkRequest.Name is not functional. |
|
| 1594 |
+ // So we cannot just use that with c.GetNetwork. |
|
| 1595 |
+ return c.getNetworks(&swarmapi.ListNetworksRequest_Filters{
|
|
| 1596 |
+ Names: []string{name},
|
|
| 1597 |
+ }) |
|
| 1598 |
+} |
|
| 1599 |
+ |
|
| 1585 | 1600 |
func attacherKey(target, containerID string) string {
|
| 1586 | 1601 |
return containerID + ":" + target |
| 1587 | 1602 |
} |
| ... | ... |
@@ -1184,3 +1184,50 @@ func (s *DockerTrustedSwarmSuite) TestTrustedServiceUpdate(c *check.C) {
|
| 1184 | 1184 |
c.Assert(err, check.NotNil, check.Commentf(out)) |
| 1185 | 1185 |
c.Assert(string(out), checker.Contains, "Error: remote trust data does not exist", check.Commentf(out)) |
| 1186 | 1186 |
} |
| 1187 |
+ |
|
| 1188 |
+// Test case for issue #27866, which did not allow NW name that is the prefix of a swarm NW ID. |
|
| 1189 |
+// e.g. if the ingress ID starts with "n1", it was impossible to create a NW named "n1". |
|
| 1190 |
+func (s *DockerSwarmSuite) TestSwarmNetworkCreateIssue27866(c *check.C) {
|
|
| 1191 |
+ d := s.AddDaemon(c, true, true) |
|
| 1192 |
+ out, err := d.Cmd("network", "inspect", "-f", "{{.Id}}", "ingress")
|
|
| 1193 |
+ c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
|
| 1194 |
+ ingressID := strings.TrimSpace(out) |
|
| 1195 |
+ c.Assert(ingressID, checker.Not(checker.Equals), "") |
|
| 1196 |
+ |
|
| 1197 |
+ // create a network of which name is the prefix of the ID of an overlay network |
|
| 1198 |
+ // (ingressID in this case) |
|
| 1199 |
+ newNetName := ingressID[0:2] |
|
| 1200 |
+ out, err = d.Cmd("network", "create", "--driver", "overlay", newNetName)
|
|
| 1201 |
+ // In #27866, it was failing because of "network with name %s already exists" |
|
| 1202 |
+ c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
|
| 1203 |
+ out, err = d.Cmd("network", "rm", newNetName)
|
|
| 1204 |
+ c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
|
| 1205 |
+} |
|
| 1206 |
+ |
|
| 1207 |
+// Test case for https://github.com/docker/docker/pull/27938#issuecomment-265768303 |
|
| 1208 |
+// This test creates two networks with the same name sequentially, with various drivers. |
|
| 1209 |
+// Since the operations in this test are done sequentially, the 2nd call should fail with |
|
| 1210 |
+// "network with name FOO already exists". |
|
| 1211 |
+// Note that it is to ok have multiple networks with the same name if the operations are done |
|
| 1212 |
+// in parallel. (#18864) |
|
| 1213 |
+func (s *DockerSwarmSuite) TestSwarmNetworkCreateDup(c *check.C) {
|
|
| 1214 |
+ d := s.AddDaemon(c, true, true) |
|
| 1215 |
+ drivers := []string{"bridge", "overlay"}
|
|
| 1216 |
+ for i, driver1 := range drivers {
|
|
| 1217 |
+ nwName := fmt.Sprintf("network-test-%d", i)
|
|
| 1218 |
+ for _, driver2 := range drivers {
|
|
| 1219 |
+ c.Logf("Creating a network named %q with %q, then %q",
|
|
| 1220 |
+ nwName, driver1, driver2) |
|
| 1221 |
+ out, err := d.Cmd("network", "create", "--driver", driver1, nwName)
|
|
| 1222 |
+ c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
|
| 1223 |
+ out, err = d.Cmd("network", "create", "--driver", driver2, nwName)
|
|
| 1224 |
+ c.Assert(out, checker.Contains, |
|
| 1225 |
+ fmt.Sprintf("network with name %s already exists", nwName))
|
|
| 1226 |
+ c.Assert(err, checker.NotNil) |
|
| 1227 |
+ c.Logf("As expected, the attempt to network %q with %q failed: %s",
|
|
| 1228 |
+ nwName, driver2, out) |
|
| 1229 |
+ out, err = d.Cmd("network", "rm", nwName)
|
|
| 1230 |
+ c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
|
| 1231 |
+ } |
|
| 1232 |
+ } |
|
| 1233 |
+} |