DockerCLI/cli/command
Sebastiaan van Stijn 2fc608cea6
Fix order of processing of some xx-add/xx-rm service update flags
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 <github@gone.nl>
2020-08-04 19:09:59 +02:00
..
builder Fix builder prune -a/--all flag description 2020-02-18 14:30:28 +01:00
checkpoint Replace deprecated Cobra command.SetOutput() with command.SetOut() 2020-05-07 14:25:59 +02:00
commands Remove "docker engine" subcommands 2019-12-12 17:51:25 +01:00
config Replace deprecated Cobra command.SetOutput() with command.SetOut() 2020-05-07 14:25:59 +02:00
container refactor opts tests 2020-07-01 14:45:47 +02:00
context bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-23 00:28:55 +01:00
formatter cli/formatter: reformat TestImageContext test cases 2020-07-16 11:34:52 +02:00
idresolver bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-23 00:28:55 +01:00
image support emulated version detection 2020-07-30 11:38:29 -07:00
inspect bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-23 00:28:55 +01:00
manifest Added support for setting OS version in docker manifest annotate. 2020-06-12 12:04:03 -07:00
network Replace deprecated Cobra command.SetOutput() with command.SetOut() 2020-05-07 14:25:59 +02:00
node Replace deprecated Cobra command.SetOutput() with command.SetOut() 2020-05-07 14:25:59 +02:00
plugin Replace deprecated Cobra command.SetOutput() with command.SetOut() 2020-05-07 14:25:59 +02:00
registry Don't filter out registries to logout from with config file contents 2020-06-15 14:29:37 +02:00
secret Replace deprecated Cobra command.SetOutput() with command.SetOut() 2020-05-07 14:25:59 +02:00
service Fix order of processing of some xx-add/xx-rm service update flags 2020-08-04 19:09:59 +02:00
stack TestServiceUpdateResolveImageChanged: use subtests 2020-07-06 14:58:40 +02:00
swarm Replace deprecated Cobra command.SetOutput() with command.SetOut() 2020-05-07 14:25:59 +02:00
system support emulated version detection 2020-07-30 11:38:29 -07:00
task bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-23 00:28:55 +01:00
testdata Dynamically register kubernetes context store endpoint type. 2019-05-20 13:28:11 +01:00
trust Replace deprecated Cobra command.SetOutput() with command.SetOut() 2020-05-07 14:25:59 +02:00
volume Replace deprecated Cobra command.SetOutput() with command.SetOut() 2020-05-07 14:25:59 +02:00
cli.go Fix bug with panic when DOCKER_CLI_EXPERIMENTAL environment variable is incorrect 2020-05-24 23:21:20 +03:00
cli_options.go update docker, replace github.com/docker/pkg/term, github.com/docker/pkg/mount 2020-04-22 17:16:13 +02:00
cli_options_test.go bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-23 00:28:55 +01:00
cli_test.go bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-23 00:28:55 +01:00
context.go Don't loose additional metadata fields 2020-06-10 15:07:23 +02:00
context_test.go Don't loose additional metadata fields 2020-06-10 15:07:23 +02:00
defaultcontextstore.go Push check for kubernetes requirement down into the endpoint 2019-05-20 13:28:11 +01:00
defaultcontextstore_test.go bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-23 00:28:55 +01:00
events_utils.go updated vendoring 2017-09-01 19:41:06 -04:00
orchestrator.go Fast Context Switch: commands 2019-01-10 22:25:43 +01:00
orchestrator_test.go bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-23 00:28:55 +01:00
registry.go update docker, replace github.com/docker/pkg/term, github.com/docker/pkg/mount 2020-04-22 17:16:13 +02:00
registry_test.go bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-23 00:28:55 +01:00
streams.go Extract streams helpers from command package to their own package to remove a cyclic dependency from command to internal/containerizedengine 2019-01-28 14:36:00 +01:00
trust.go Refactor content_trust cli/flags handling 2018-03-08 15:00:43 -05:00
utils.go docker cp: prevent NPE when failing to stat destination 2019-12-09 15:32:02 +01:00
utils_test.go bump gotest.tools v3.0.1 for compatibility with Go 1.14 2020-02-23 00:28:55 +01:00