Fix --network-add adding duplicate networks#780
Conversation
|
Didn't have a look yet at creating a unit-test for this (if we want one) |
Codecov Report
@@ Coverage Diff @@
## master #780 +/- ##
==========================================
+ Coverage 50.9% 52.22% +1.31%
==========================================
Files 237 237
Lines 15338 15342 +4
==========================================
+ Hits 7808 8012 +204
+ Misses 7028 6819 -209
- Partials 502 511 +9 |
|
hmm, not sure how this works. Isn't the problem in |
|
Yeah, basically
Each network set by However, that translation was not done for So on network create; {
"EndpointSpec": {
"Mode": "vip"
},
"Labels": {},
"Mode": {
"Replicated": {}
},
"Name": "bla",
"TaskTemplate": {
"ContainerSpec": {
"DNSConfig": {},
"Image": "nginx:alpine@sha256:40e95eef5082a5b26c5fd9441bd7ee6bcda1bb5f9fbf7a4a1ef9b2b0f88d5c43"
},
"ForceUpdate": 0,
"Networks": [
{
"Target": "foo"
}
],
"Placement": {
"Platforms": [
{
"Architecture": "amd64",
"OS": "linux"
}
]
},
"Resources": {
"Limits": {},
"Reservations": {}
}
}
}Then, on update, the spec is fetched from the daemon (which returns network ID's), but the added network is added to the spec by name, so this is sent on update: {
"EndpointSpec": {
"Mode": "vip"
},
"Labels": {},
"Mode": {
"Replicated": {
"Replicas": 1
}
},
"Name": "bla",
"TaskTemplate": {
"ContainerSpec": {
"DNSConfig": {},
"Image": "nginx:alpine@sha256:40e95eef5082a5b26c5fd9441bd7ee6bcda1bb5f9fbf7a4a1ef9b2b0f88d5c43"
},
"ForceUpdate": 0,
"Networks": [
{
"Target": "foo"
},
{
"Target": "x8bnlf8np4o8gk8nnh0ilg6oo"
}
],
"Placement": {
"Platforms": [
{
"Architecture": "amd64",
"OS": "linux"
}
]
},
"Resources": {
"Limits": {},
"Reservations": {}
},
"Runtime": "container"
}
}Where |
|
Ok, but the code that is changed here is for converting opts to the swarn spec, not specifically for update, right? Isn't the update logic in cli/command/service/update.go updateNetworks() ? So I'm wondering if this fix is maybe in the wrong place. |
|
Well, For cli/cli/command/service/update.go Lines 1101 to 1107 in 97b148b Existing networks (in the spec) already have an ID (no name); cli/cli/command/service/update.go Lines 1111 to 1118 in 97b148b For cli/cli/command/service/update.go Lines 1122 to 1126 in 97b148b So this change will address both Alternatively, we move the |
|
It would be great to remove Thanks, I understand the change now. I missed that this was being called from |
dnephin
left a comment
There was a problem hiding this comment.
LGTM
A unit test for updateNetworks() would be great, but unfortunately (due to all the "lookup by id nonsense") that is a lot more difficult than it should be.
It's should still be possible with a fakeClient that implements NetworkInspect()
I agree; looking at this again, I think moving the Given that this didn't make it for 18.01-rc1; let me change this to
I confirmed this bug already being in 17.09, so it's not new, so not super-urgent (and containers get only a single network assigned, so no duplicates there) |
9b19a8c to
56d3fd9
Compare
|
@dnephin updated with the changes discussed, PTAL |
| DriverOpts: net.DriverOpts, | ||
| }) | ||
| } | ||
| sort.Sort(byNetworkTarget(netAttach)) |
There was a problem hiding this comment.
Moved the sorting out of here as well, otherwise service create would sort by network name, and service update sorted by network ID
cli/command/service/opts.go
Outdated
| if err != nil { | ||
| return "", err | ||
| } | ||
| return nw.ID, nil |
There was a problem hiding this comment.
nit: the if is unnecessary since NetworkIsnpect returns a struct not a pointer. It can be replaced by
return nw.ID, errThere was a problem hiding this comment.
Oh, nice one! I'll add that change
When adding a network using `docker service update --network-add`,
the new network was added by _name_.
Existing entries in a service spec are listed by network ID, which
resulted in the CLI not detecting duplicate entries for the same
network.
This patch changes the behavior to always use the network-ID,
so that duplicate entries are correctly caught.
Before this change;
$ docker network create -d overlay foo
$ docker service create --name=test --network=foo nginx:alpine
$ docker service update --network-add foo test
$ docker service inspect --format '{{ json .Spec.TaskTemplate.Networks}}' test
[
{
"Target": "9ot0ieagg5xv1gxd85m7y33eq"
},
{
"Target": "9ot0ieagg5xv1gxd85m7y33eq"
}
]
After this change:
$ docker network create -d overlay foo
$ docker service create --name=test --network=foo nginx:alpine
$ docker service update --network-add foo test
service is already attached to network foo
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
56d3fd9 to
e6ebaf5
Compare
|
ping @vdemeester PTAL |
Fix --network-add adding duplicate networks Upstream-commit: fbb9de2 Component: cli


When adding a network using
docker service update --network-add,the new network was added by name.
Existing entries in a service spec are listed by network ID, which
resulted in the CLI not detecting duplicate entries for the same
network.
This patch changes the behavior to always use the network-ID,
so that duplicate entries are correctly caught.
Before this change;
After this change:
$ docker network create -d overlay foo $ docker service create --name=test --network=foo nginx:alpine $ docker service update --network-add foo test service is already attached to network 9ot0ieagg5xv1gxd85m7y33eq- Description for the changelog