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>
| ... | ... |
@@ -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 |
|
| ... | ... |
@@ -1375,8 +1375,7 @@ func (c *Cluster) GetNetwork(input string) (apitypes.NetworkResource, error) {
|
| 1375 | 1375 |
return convert.BasicNetworkFromGRPC(*network), nil |
| 1376 | 1376 |
} |
| 1377 | 1377 |
|
| 1378 |
-// GetNetworks returns all current cluster managed networks. |
|
| 1379 |
-func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) {
|
|
| 1378 |
+func (c *Cluster) getNetworks(filters *swarmapi.ListNetworksRequest_Filters) ([]apitypes.NetworkResource, error) {
|
|
| 1380 | 1379 |
c.mu.RLock() |
| 1381 | 1380 |
defer c.mu.RUnlock() |
| 1382 | 1381 |
|
| ... | ... |
@@ -1388,7 +1387,7 @@ func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) {
|
| 1388 | 1388 |
ctx, cancel := c.getRequestContext() |
| 1389 | 1389 |
defer cancel() |
| 1390 | 1390 |
|
| 1391 |
- r, err := state.controlClient.ListNetworks(ctx, &swarmapi.ListNetworksRequest{})
|
|
| 1391 |
+ r, err := state.controlClient.ListNetworks(ctx, &swarmapi.ListNetworksRequest{Filters: filters})
|
|
| 1392 | 1392 |
if err != nil {
|
| 1393 | 1393 |
return nil, err |
| 1394 | 1394 |
} |
| ... | ... |
@@ -1402,6 +1401,21 @@ func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) {
|
| 1402 | 1402 |
return networks, nil |
| 1403 | 1403 |
} |
| 1404 | 1404 |
|
| 1405 |
+// GetNetworks returns all current cluster managed networks. |
|
| 1406 |
+func (c *Cluster) GetNetworks() ([]apitypes.NetworkResource, error) {
|
|
| 1407 |
+ return c.getNetworks(nil) |
|
| 1408 |
+} |
|
| 1409 |
+ |
|
| 1410 |
+// GetNetworksByName returns cluster managed networks by name. |
|
| 1411 |
+// It is ok to have multiple networks here. #18864 |
|
| 1412 |
+func (c *Cluster) GetNetworksByName(name string) ([]apitypes.NetworkResource, error) {
|
|
| 1413 |
+ // Note that swarmapi.GetNetworkRequest.Name is not functional. |
|
| 1414 |
+ // So we cannot just use that with c.GetNetwork. |
|
| 1415 |
+ return c.getNetworks(&swarmapi.ListNetworksRequest_Filters{
|
|
| 1416 |
+ Names: []string{name},
|
|
| 1417 |
+ }) |
|
| 1418 |
+} |
|
| 1419 |
+ |
|
| 1405 | 1420 |
func attacherKey(target, containerID string) string {
|
| 1406 | 1421 |
return containerID + ":" + target |
| 1407 | 1422 |
} |
| ... | ... |
@@ -1508,3 +1508,50 @@ func (s *DockerTrustedSwarmSuite) TestTrustedServiceUpdate(c *check.C) {
|
| 1508 | 1508 |
c.Assert(err, check.NotNil, check.Commentf(out)) |
| 1509 | 1509 |
c.Assert(string(out), checker.Contains, "Error: remote trust data does not exist", check.Commentf(out)) |
| 1510 | 1510 |
} |
| 1511 |
+ |
|
| 1512 |
+// Test case for issue #27866, which did not allow NW name that is the prefix of a swarm NW ID. |
|
| 1513 |
+// e.g. if the ingress ID starts with "n1", it was impossible to create a NW named "n1". |
|
| 1514 |
+func (s *DockerSwarmSuite) TestSwarmNetworkCreateIssue27866(c *check.C) {
|
|
| 1515 |
+ d := s.AddDaemon(c, true, true) |
|
| 1516 |
+ out, err := d.Cmd("network", "inspect", "-f", "{{.Id}}", "ingress")
|
|
| 1517 |
+ c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
|
| 1518 |
+ ingressID := strings.TrimSpace(out) |
|
| 1519 |
+ c.Assert(ingressID, checker.Not(checker.Equals), "") |
|
| 1520 |
+ |
|
| 1521 |
+ // create a network of which name is the prefix of the ID of an overlay network |
|
| 1522 |
+ // (ingressID in this case) |
|
| 1523 |
+ newNetName := ingressID[0:2] |
|
| 1524 |
+ out, err = d.Cmd("network", "create", "--driver", "overlay", newNetName)
|
|
| 1525 |
+ // In #27866, it was failing because of "network with name %s already exists" |
|
| 1526 |
+ c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
|
| 1527 |
+ out, err = d.Cmd("network", "rm", newNetName)
|
|
| 1528 |
+ c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
|
| 1529 |
+} |
|
| 1530 |
+ |
|
| 1531 |
+// Test case for https://github.com/docker/docker/pull/27938#issuecomment-265768303 |
|
| 1532 |
+// This test creates two networks with the same name sequentially, with various drivers. |
|
| 1533 |
+// Since the operations in this test are done sequentially, the 2nd call should fail with |
|
| 1534 |
+// "network with name FOO already exists". |
|
| 1535 |
+// Note that it is to ok have multiple networks with the same name if the operations are done |
|
| 1536 |
+// in parallel. (#18864) |
|
| 1537 |
+func (s *DockerSwarmSuite) TestSwarmNetworkCreateDup(c *check.C) {
|
|
| 1538 |
+ d := s.AddDaemon(c, true, true) |
|
| 1539 |
+ drivers := []string{"bridge", "overlay"}
|
|
| 1540 |
+ for i, driver1 := range drivers {
|
|
| 1541 |
+ nwName := fmt.Sprintf("network-test-%d", i)
|
|
| 1542 |
+ for _, driver2 := range drivers {
|
|
| 1543 |
+ c.Logf("Creating a network named %q with %q, then %q",
|
|
| 1544 |
+ nwName, driver1, driver2) |
|
| 1545 |
+ out, err := d.Cmd("network", "create", "--driver", driver1, nwName)
|
|
| 1546 |
+ c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
|
| 1547 |
+ out, err = d.Cmd("network", "create", "--driver", driver2, nwName)
|
|
| 1548 |
+ c.Assert(out, checker.Contains, |
|
| 1549 |
+ fmt.Sprintf("network with name %s already exists", nwName))
|
|
| 1550 |
+ c.Assert(err, checker.NotNil) |
|
| 1551 |
+ c.Logf("As expected, the attempt to network %q with %q failed: %s",
|
|
| 1552 |
+ nwName, driver2, out) |
|
| 1553 |
+ out, err = d.Cmd("network", "rm", nwName)
|
|
| 1554 |
+ c.Assert(err, checker.IsNil, check.Commentf("out: %v", out))
|
|
| 1555 |
+ } |
|
| 1556 |
+ } |
|
| 1557 |
+} |