-
Notifications
You must be signed in to change notification settings - Fork 18.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update FindNetwork
to address network name duplications#30897
Conversation
@@ -15,6 +15,6 @@ type Backend interface { | |||
CreateNetwork(nc types.NetworkCreateRequest) (*types.NetworkCreateResponse, error) | |||
ConnectContainerToNetwork(containerName, networkName string, endpointConfig *network.EndpointSettings) error | |||
DisconnectContainerFromNetwork(containerName string, networkName string, force bool) error | |||
DeleteNetwork(name string) error | |||
DeleteNetwork(networkID string) error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change to networkID
to enforcing the usage of ID instead of Name/ID/Prefix
@@ -208,7 +139,12 @@ func (n *networkRouter) postNetworkConnect(ctx context.Context, w http.ResponseW | |||
return err | |||
} | |||
|
|||
return n.backend.ConnectContainerToNetwork(connect.Container, vars["id"], connect.EndpointConfig) | |||
// Always make sure there is no ambiguity with respect to the network ID/name |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is a lot easier to enforcing non-ambiguity here.
@@ -225,22 +161,31 @@ func (n *networkRouter) postNetworkDisconnect(ctx context.Context, w http.Respon | |||
return err | |||
} | |||
|
|||
return n.backend.DisconnectContainerFromNetwork(disconnect.Container, vars["id"], disconnect.Force) | |||
// Always make sure there is no ambiguity with respect to the network ID/name | |||
nw, err := n.backend.FindNetwork(vars["id"]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Non-ambiguity at the api level.
if err != nil { | ||
return err | ||
} | ||
return n.backend.ConnectContainerToNetwork(connect.Container, nw.ID(), connect.EndpointConfig) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass nw.ID()
for connect.
if err != nil { | ||
return err | ||
} | ||
return n.backend.DisconnectContainerFromNetwork(disconnect.Container, nw.ID(), disconnect.Force) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pass nw.ID() for disconnect.
return err | ||
} | ||
} else { | ||
if err := n.backend.DeleteNetwork(nw.ID); err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Delete might happen in both local and scoped networks.
@@ -412,3 +357,82 @@ func (n *networkRouter) postNetworksPrune(ctx context.Context, w http.ResponseWr | |||
} | |||
return httputils.WriteJSON(w, http.StatusOK, pruneReport) | |||
} | |||
|
|||
func (n *networkRouter) findNetwork(term string) (types.NetworkResource, error) { | |||
// NOTE: This findNetwork is differnt from FindNetwork from the daemon. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This findNetwork
is different from daemon.FindNetwork
as it will be cross scopes (both local and swarm).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you make this comment a docstring (above the function) ? Right now it looks like it's documenting the variables inside the function.
Also what do you think about findUniqueNetwork()
as a name?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @dnephin. The comment has been updated to doc string. The name has also been changed.
// networks returns a list of network names attached to the container. The | ||
// returned name can be used to lookup the corresponding network create | ||
// options. | ||
func (c *containerConfig) networks() []string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The networks()
is returning the name only, which should not be encouraged (should always use ID if possible).
@@ -1053,3 +1050,10 @@ func (daemon *Daemon) DeactivateContainerServiceBinding(containerName string) er | |||
} | |||
return sb.DisableService() | |||
} | |||
|
|||
func getNetworkID(name string, endpointSettings *networktypes.EndpointSettings) string { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alway try to use NetworkID
whenever NetworkID
is available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This name is a bit odd (from just the name, I would expect it to always return an ID), not a big thing because it's not exported, but perhaps we should find a better name for it
daemon/network.go
Outdated
@@ -249,7 +267,9 @@ func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string | |||
} | |||
if nw != nil { | |||
if create.CheckDuplicate { | |||
return nil, libnetwork.NetworkNameError(create.Name) | |||
if !agent || nw.Info().Dynamic() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case of swarm networks, we have to allow creation even if a local network with the same name already exist.
9c44301
to
7c4538f
Compare
The Jenkins failure seems real. Will spend time to investigate it. |
FindNetwork
to address network name duplicationsFindNetwork
to address network name duplications
5666f16
to
a2bfaab
Compare
FindNetwork
to address network name duplicationsFindNetwork
to address network name duplications
All tests passed now. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There seem to be a bunch of changes to DeleteNetwork.
Could you give more of an explanation of what this changes, and why it fixes the problem?
id2 := createNetwork(c, configNotCheck, true) | ||
|
||
deleteNetwork(c, id1, true) | ||
deleteNetwork(c, id2, true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should these be defer
, and called immediately after the create for each?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. The PR has been updated.
a2bfaab
to
7295c58
Compare
Thanks @dnephin for the review. The goal of this PR is to try to address the issue caused by name duplication in network names. Previously, the network name is unique so some of the implementation uses will look up the network name (instead of network ID) when needed. However, later on the flag Adding swarm network in, the same network name could appears in either However, in the existing implementation, many places uses That causes issues:
This PR tries to address the issue mentioned by always avoid |
case len(listByFullName) == 1: | ||
return listByFullName[0], nil | ||
case len(listByFullName) > 1: | ||
return nil, fmt.Errorf("network %s is ambiguous (%d matches found based on name)", term, len(listByFullName)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not be using fmt.Errorf
for these errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@cpuguy83 Sorry, that was probably due to the multiple rebase/conflict that was overlooked. Let me take a look and have a fix for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No worries. I've got it fixed in my errdefs or.
@@ -12,11 +12,11 @@ import ( | |||
// Backend is all the methods that need to be implemented | |||
// to provide network specific functionality. | |||
type Backend interface { | |||
FindNetwork(idName string) (libnetwork.Network, error) | |||
FindUniqueNetwork(idName string) (libnetwork.Network, error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should've kept the old name here (FindNetwork
); the issue being resolved here is a bugfix, so I don't see a real reason to rename the function (in general, I'd expect a function like this to return a unique network, so not sure a change in naming is really needed)
@yongtang @vdemeester wdyt?
This fix tries to add a `scope` in the query of `/networks/<id>` (`NetworkInspect`) so that in case of duplicate network names, it is possible to locate the network ID based on the network scope (`local`, 'swarm', or `global`). Multiple networks might exist in different scopes, which is a legitimate case. For example, a network name `foo` might exists locally and in swarm network. However, before this PR it was not possible to query a network name `foo` in a specific scope like swarm. This fix fixes the issue by allowing a `scope` query in `/networks/<id>`. Additional test cases have been added to unit tests and integration tests. This fix is related to docker/cli#167, moby/moby#30897, moby/moby#33561, moby/moby#30242 This fix fixes docker/cli#167 Signed-off-by: Yong Tang <yong.tang.github@outlook.com> Upstream-commit: 158b2a1 Component: engine
- What I did
This fix is part of the effort to address #30242 (comment) where issue arise when creating services because of the fact that multiple networks may share the same name (within or across local/swarm scopes).
- How I did it
The focus of this fix is to allow creation of service when a network in local scope has the same name as the service network.
- How to verify it
An integration test has been added.
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)
This fix is related to #30242.
Signed-off-by: Yong Tang yong.tang.github@outlook.com