-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Fix order of processing of some xx-add/xx-rm service update flags #2668
Fix order of processing of some xx-add/xx-rm service update flags #2668
Conversation
Combining `-add` and `-rm` flags on `docker service update` should be usable to explicitly replace existing options. The current order of processing did not allow this, causing the `-rm` flag to remove properties that were specified in `-add`. This behavior was inconsistent with (for example) `--host-add` and `--host-rm`. This patch updates the behavior to first remove properties, then add new properties. Note that there's still some improvements to make, to make the removal more granulas (e.g. to make `--label-rm label=some-value` only remove the label if value matches `some-value`); these changes are left for a follow-up. Before this change: ----------------------------- Create a service with two env-vars ```bash docker service create --env FOO=bar --env BAR=baz --name=test nginx:alpine docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Env }}' test | jq . [ "FOO=bar", "BAR=baz" ] ``` Update the service, with the intent to replace the value of `FOO` for a new value ```bash docker service update --env-rm FOO --env-add FOO=updated-foo test docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Env }}' test | jq . [ "BAR=baz" ] ``` Create a service with two labels ```bash docker service create --label FOO=bar --label BAR=baz --name=test nginx:alpine docker service inspect --format '{{json .Spec.Labels }}' test | jq . { "BAR": "baz", "FOO": "bar" } ``` Update the service, with the intent to replace the value of `FOO` for a new value ```bash docker service update --label-rm FOO --label-add FOO=updated-foo test docker service inspect --format '{{json .Spec.Labels }}' test | jq . { "BAR": "baz" } ``` Create a service with two container labels ```bash docker service create --container-label FOO=bar --container-label BAR=baz --name=test nginx:alpine docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Labels }}' test | jq . { "BAR": "baz", "FOO": "bar" } ``` Update the service, with the intent to replace the value of `FOO` for a new value ```bash docker service update --container-label-rm FOO --container-label-add FOO=updated-foo test docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Labels }}' test | jq . { "BAR": "baz", } ``` With this patch applied: -------------------------------- Create a service with two env-vars ```bash docker service create --env FOO=bar --env BAR=baz --name=test nginx:alpine docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Env }}' test | jq . [ "FOO=bar", "BAR=baz" ] ``` Update the service, and replace the value of `FOO` for a new value ```bash docker service update --env-rm FOO --env-add FOO=updated-foo test docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Env }}' test | jq . [ "BAR=baz", "FOO=updated-foo" ] ``` Create a service with two labels ```bash docker service create --label FOO=bar --label BAR=baz --name=test nginx:alpine docker service inspect --format '{{json .Spec.Labels }}' test | jq . { "BAR": "baz", "FOO": "bar" } ``` Update the service, and replace the value of `FOO` for a new value ```bash docker service update --label-rm FOO --label-add FOO=updated-foo test docker service inspect --format '{{json .Spec.Labels }}' test | jq . { "BAR": "baz", "FOO": "updated-foo" } ``` Create a service with two container labels ```bash docker service create --container-label FOO=bar --container-label BAR=baz --name=test nginx:alpine docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Labels }}' test | jq . { "BAR": "baz", "FOO": "bar" } ``` Update the service, and replace the value of `FOO` for a new value ```bash docker service update --container-label-rm FOO --container-label-add FOO=updated-foo test docker service inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Labels }}' test | jq . { "BAR": "baz", "FOO": "updated-foo" } ``` Signed-off-by: Sebastiaan van Stijn <[email protected]>
Codecov Report
@@ Coverage Diff @@
## master #2668 +/- ##
==========================================
+ Coverage 58.13% 58.16% +0.03%
==========================================
Files 295 295
Lines 21207 21207
==========================================
+ Hits 12328 12336 +8
+ Misses 7970 7963 -7
+ Partials 909 908 -1 |
@@ -640,6 +640,12 @@ func updatePlacementPreferences(flags *pflag.FlagSet, placement *swarm.Placement | |||
} | |||
|
|||
func updateContainerLabels(flags *pflag.FlagSet, field *map[string]string) { | |||
if *field != nil && flags.Changed(flagContainerLabelRemove) { |
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.
question: should we test field to?
if field != nil && *field != 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.
Good one, I easily get confused by these 🤔
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.
yeah pointer on pointer is mind blowing 😁
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'll look for the extra check in a follow-up
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.
Looks good 👍
(noticed this while reviewing #2663. I thought we fixed these, but apparently not for all flags)
Combining
-add
and-rm
flags ondocker service update
should be usable to explicitly replace existing options. The current order of processing did not allow this, causing the-rm
flag to remove properties that were specified in-add
. This behavior was inconsistent with (for example)--host-add
and--host-rm
.This patch updates the behavior to first remove properties, then add new properties.
Note that there's still some improvements to make, to make the removal more granulas (e.g. to make
--label-rm label=some-value
only remove the label if value matchessome-value
); these changes are left for a follow-up.Before this change:
Create a service with two env-vars
Update the service, with the intent to replace the value of
FOO
for a new valueCreate a service with two labels
Update the service, with the intent to replace the value of
FOO
for a new valueCreate a service with two container labels
Update the service, with the intent to replace the value of
FOO
for a new valueWith this patch applied:
Create a service with two env-vars
Update the service, and replace the value of
FOO
for a new valueCreate a service with two labels
Update the service, and replace the value of
FOO
for a new valueCreate a service with two container labels
Update the service, and replace the value of
FOO
for a new value- What I did
- How I did it
- How to verify it
- Description for the changelog
- A picture of a cute animal (not mandatory but encouraged)