From 9313406bb75ff2bd827c5c660fe8826307d9ac47 Mon Sep 17 00:00:00 2001 From: Sebastiaan van Stijn Date: Mon, 28 May 2018 12:29:39 +0200 Subject: [PATCH] Revert "Match Swarm in how to combine filters" When filtering objects on labels, and two different filter values are passed for a single label, Swarm combines those filters as an AND. Effectively, this means that: --filter label=something=yes --filter label=something=no Means; > Give me all objects that have label "something" set to "yes AND no" This is never true, because labels are stored as a "map" (so an object can only have a _single_ label named "something". As a result this filter will _never_ return a result. This behavior is also inconsistent with other situations, where filters are combined using an OR, for example; --filter label=something=yes --filter label=somethingelse=foo Means; > Give me all objects that have label "something" set to "yes", > or label "somethingelse" set to "foo" This commit was added to make Kubernetes mimic the (odd) behavior, so that the behavior would be consistent for both orchestrators. Given that the existing (swarm/docker) behavior; - Is an oversight (bug?) - Is not (clearly) documented - Most likely a very narrow corner-case It may be a better option to fix the situation in the Swarm side (if desirable, keep the old behavior based on API version), and revert this commit to not let this behavior find its way into new features. This reverts commit 297866ebbe843dd20b867fa15b3e3de34c169bf3. Signed-off-by: Sebastiaan van Stijn --- cli/command/stack/kubernetes/services.go | 11 +++++++---- cli/command/stack/kubernetes/services_test.go | 3 +-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cli/command/stack/kubernetes/services.go b/cli/command/stack/kubernetes/services.go index 5a1db529dda1..9cf89f4f0fa8 100644 --- a/cli/command/stack/kubernetes/services.go +++ b/cli/command/stack/kubernetes/services.go @@ -24,11 +24,14 @@ var supportedServicesFilters = map[string]bool{ func generateSelector(labels map[string][]string) []string { var result []string for k, v := range labels { - for _, val := range v { - result = append(result, fmt.Sprintf("%s=%s", k, val)) - } - if len(v) == 0 { + switch len(v) { + case 0: result = append(result, k) + case 1: + result = append(result, fmt.Sprintf("%s=%s", k, v[0])) + default: + sort.Strings(v) + result = append(result, fmt.Sprintf("%s in (%s)", k, strings.Join(v, ","))) } } return result diff --git a/cli/command/stack/kubernetes/services_test.go b/cli/command/stack/kubernetes/services_test.go index 41a3348e0b09..9537f203f98e 100644 --- a/cli/command/stack/kubernetes/services_test.go +++ b/cli/command/stack/kubernetes/services_test.go @@ -75,8 +75,7 @@ func TestServiceFiltersLabelSelectorGen(t *testing.T) { ), expectedSelectorParts: []string{ "com.docker.stack.namespace=test", - "label1=test", - "label1=test2", + "label1 in (test,test2)", }, }, {