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
api: allow NW name that is the prefix of a swarm NW ID #27938
Conversation
ping @mrjana |
@@ -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 { |
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 check doesn't seem very useful. First, it's racy. Also, it does a prefix match, which is not what we want here.
n.clusterProvider.CreateNetwork
will fail if the name conflicts. Could we just remove this check?
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.
Makes sense, however, we need to check the conflict before calling backend.CreateNetwork()
, so as to detect a conflict like this:
$ docker service create -d overlay foo
$ docker service create -d bridge foo
Error response from daemon: network with name foo already exists
A solution I can come up with is to call clusterProvider.CreateNetwork()
before calling backend.CreateNetwork()
for swarm-scoped networks, but I'm not sure how we can detect the scope here.
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 my opinion we should not even try to fix this. We should just fix the test to use longer names.
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 can understand your opinion. But even for production, people may try to create a network named "n1", "n2"..
It would be great if we can find a solution.
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.
Agree. But I am afraid this cannot be guaranteed unless we serialize the network creation at API level. Which seems too much of a penalty.
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 agree with @AkihiroSuda. It's ridiculous not to allow creating a network if its name is a prefix of another network's ID.
And using longer names in the test won't solve the problem, it will just make the failures less likely - so when they do happen, they will be very hard to reproduce and cause a lot of confusion.
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 entire check needs to be coordinated by the swarm manager. The prefix/name/id game can be handled but doing so correctly is subtle. I've written out the approach in moby/swarmkit#1279 (comment) and a few other times.
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.
isn't it the same as partial ID matches for containers; ID > full name match > partial ID match
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.
isn't it the same as partial ID matches for containers; ID > full name match > partial ID match
I am not sure. Typically, there should be a resolution component and the getter should only take ID. In this case, I think we hit the docker API, so ambiguity of id/name may be a problem.
1e5398f
to
f771e06
Compare
Updated PR. This fix should be enough for the original issue #27866 . However, this doesn't fix an issue about removing networks. e.g. $ docker network ls
NETWORK ID NAME DRIVER SCOPE
0db1e31d181f bridge bridge local
4f8a8c0144ad docker_gwbridge bridge local
4aa7a6b845ef host host local
kveaqnegpm66 ingress overlay swarm
82ba9477298d kvea bridge swarm
7190e8d532c5 none null local
$ docker network rm kvea
Error response from daemon: rpc error: code = 7 desc = ingress (kveaqnegpm66y75q9wj6urfwq) is a pre-defined network and cannot be removed ( For removal, we would need to implement the "set" approach which @stevvooe repeatedly mentioned (e.g. moby/swarmkit#1279 (comment), moby/swarmkit#1194 (comment)) in another PR. |
@@ -80,7 +80,7 @@ func (n *networkRouter) postNetworkCreate(ctx context.Context, w http.ResponseWr | |||
return err | |||
} | |||
|
|||
if _, err := n.clusterProvider.GetNetwork(create.Name); err == nil { | |||
if _, err := n.clusterProvider.GetNetworkByName(create.Name); err == nil { | |||
return libnetwork.NetworkNameError(create.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.
Not directly related to this PR, but wondering; should this check only be performed if create.CheckDuplicate
is true? (see daemon/network.go#L256-L258)
Since allowing duplicate names is by design (#18864 (comment)), I wonder if it should error out.
(t.b.h. I would rather stop allowing duplicate names, because I think the name is used in many cases as the only reference)
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.
hmm, probably in another PR?
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.
Yes, that makes sense, then we can confirm if it should be fixed / changed on that PR
@AkihiroSuda @thaJeztah I can't think of a good use-case for this to be a useful fix. Yes. this is an inconvenience for some cases, but I don't see a strong need to get this PR. IMO living with this restriction is better than trying to fix it and cause more head-aches. |
@mavenugo: What downside do you see? The old code was querying for a duplicate network in a way that would do prefix matching on IDs, which is clearly wrong. This was causing random integration test failures (sometimes "n1" would be a prefix of a network with ID "n1..."). I know there are still some remaining issues, but would like to understand what headaches it may cause to correct this check. |
@aaronlehmann the existing UX accepts |
One of the use cases is what I mentioned above. If you try to create a network named I don't see this as adding a feature, but instead correcting incorrect validation. It's completely legitimate to have a name overlap with an ID prefix. We allow it for other kinds of objects. Networks are handled inconsistently and this is a bug. There should be no issue with |
@aaronlehmann okay. if this is something unique to network then i agree we should fix it. Do you prefer fixing the IT issue alone in this PR and address the rest later in other PRs ? Also, the simpler fix for the IT issue would be to change the TestPruneNetwork to use a longer randomized network name. And we do rely on the uniqueness of IDs (since the randomization really works and doesn't cause flaky tests for other tests :) ) |
Yes, I think we should start by allowing names to overlap with ID prefixes, and in separate PRs we should fix the other issues.
I agree that this would technically work and that we rely on ID uniqueness. My preference is to allow names to overlap with ID prefixes for consistency with other objects, as done in the latest revision of this PR. |
if err != nil { | ||
return apitypes.NetworkResource{}, err | ||
} | ||
return convert.BasicNetworkFromGRPC(*network), nil | ||
} | ||
|
||
// GetNetwork returns a cluster network by an ID. | ||
func (c *Cluster) GetNetwork(input string) (apitypes.NetworkResource, 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.
rename input
to id
to make it clearer
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.
done
} | ||
|
||
// GetNetworkByName returns a cluster network by name. | ||
func (c *Cluster) GetNetworkByName(input string) (apitypes.NetworkResource, 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.
rename input
to 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.
done
f771e06
to
81d6c93
Compare
updated PR, about @tiborvass 's comments |
81d6c93
to
4cc6ff2
Compare
rebased |
4cc6ff2
to
4ca15ef
Compare
@thaJeztah thank you a lot for testing! update: updated PR and added two tests: |
38d0542
to
9a36f17
Compare
|
9a36f17
to
9c5ed6a
Compare
Now CI green |
c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) | ||
} | ||
|
||
// Reversed case for TestSwarmNeetworkCreateDup |
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.
typo: TestSwarmNeetworkCreateDup
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.
done (and rebased)
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.
LGTM
we should probably address #27938 (comment) though (in a separate PR)
oh, and needs a rebase 😢 |
9c5ed6a
to
3beb858
Compare
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.
Two small comments (that could be seen as nits) but otherwise looks good
c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) | ||
} | ||
|
||
// Test case for https://github.com/docker/docker/pull/27938#issuecomment-265768303 |
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.
Would be cool if there could also be a description on what it does 👼 (linking the issue is 👍, but it would be even better with a small explanation so the reader doesn't have to necessary open his browser to know why it's there 👼)
Same above for TestSwarmNetworkCreateIssue27866
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.
❤️
} | ||
|
||
// Reversed case for TestSwarmNetworkCreateDup | ||
func (s *DockerSwarmSuite) TestSwarmNetworkCreateDup2(c *check.C) { |
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.
Pretty sure these 2 tests could be on the same one 👼
ping @AkihiroSuda this needs a rebase, also, could you address @vdemeester's comments, then we should be ready to merge for 1.13.0-rc4 |
3beb858
to
401804d
Compare
…f 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 moby#27866 Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
401804d
to
edfbc3b
Compare
@thaJeztah @vdemeester updated PR, sorry for being late 😅 |
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.
LGTM 🐸
c.Assert(err, checker.IsNil, check.Commentf("out: %v", out)) | ||
} | ||
|
||
// Test case for https://github.com/docker/docker/pull/27938#issuecomment-265768303 |
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.
❤️
all green 💚 |
- What I did
Allows 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.
Fix #27866 (Flaky test: DockerSwarmSuite.TestPruneNetwork)
- How I did it
Please look at api/server/router/network/network_routes.go
- How to verify it
- Description for the changelog
api: allow NW name that is the prefix of a swarm NW ID
- A picture of a cute animal (not mandatory but encouraged)
Signed-off-by: Akihiro Suda suda.akihiro@lab.ntt.co.jp