From 98e6dda697f2faeb62aebb8373c2cfe8409bb479 Mon Sep 17 00:00:00 2001 From: xtex Date: Mon, 11 Sep 2023 19:53:55 +0800 Subject: [PATCH] Add label! filter and tests to containers and pods Thanks to Ed Santiago for tests. Signed-off-by: xtex --- docs/source/markdown/podman-ps.1.md | 1 + pkg/domain/filters/containers.go | 4 ++++ pkg/domain/filters/pods.go | 5 ++++ test/apiv2/20-containers.at | 13 +++++++++- .../python/rest_api/test_v2_0_0_container.py | 24 +++++++++++++++++-- 5 files changed, 44 insertions(+), 3 deletions(-) diff --git a/docs/source/markdown/podman-ps.1.md b/docs/source/markdown/podman-ps.1.md index 1bf2ecb996..7ef399a7ff 100644 --- a/docs/source/markdown/podman-ps.1.md +++ b/docs/source/markdown/podman-ps.1.md @@ -50,6 +50,7 @@ Valid filters are listed below: | id | [ID] Container's ID (CID prefix match by default; accepts regex) | | name | [Name] Container's name (accepts regex) | | label | [Key] or [Key=Value] Label assigned to a container | +| label! | [Key] or [Key=Value] Label NOT assigned to a container | | exited | [Int] Container's exit code | | status | [Status] Container's status: 'created', 'exited', 'paused', 'running', 'unknown' | | ancestor | [ImageName] Image or descendant used to create container (accepts regex) | diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go index a81e21d950..5eb64f8457 100644 --- a/pkg/domain/filters/containers.go +++ b/pkg/domain/filters/containers.go @@ -25,6 +25,10 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo return func(c *libpod.Container) bool { return filters.MatchLabelFilters(filterValues, c.Labels()) }, nil + case "label!": + return func(c *libpod.Container) bool { + return !filters.MatchLabelFilters(filterValues, c.Labels()) + }, nil case "name": // we only have to match one name return func(c *libpod.Container) bool { diff --git a/pkg/domain/filters/pods.go b/pkg/domain/filters/pods.go index e1ff3d44af..2dc0de6cb5 100644 --- a/pkg/domain/filters/pods.go +++ b/pkg/domain/filters/pods.go @@ -119,6 +119,11 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti labels := p.Labels() return filters.MatchLabelFilters(filterValues, labels) }, nil + case "label!": + return func(p *libpod.Pod) bool { + labels := p.Labels() + return !filters.MatchLabelFilters(filterValues, labels) + }, nil case "until": return func(p *libpod.Pod) bool { until, err := filters.ComputeUntilTimestamp(filterValues) diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index a51ec2206d..6906273fe9 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -409,6 +409,9 @@ t GET containers/json 200 \ podman stop bar #compat api list containers sanity checks +podman run -d --rm --name labelcontainer_with $ENV_WORKDIR_IMG top +podman run -d --rm --name labelcontainer_without $IMAGE top + t GET containers/json?filters='garb1age}' 500 \ .cause="invalid character 'g' looking for beginning of value" t GET containers/json?filters='{"label":["testl' 500 \ @@ -436,7 +439,15 @@ t POST containers/prune?filters='{"label":["tes' 500 \ t POST libpod/containers/prune?filters='{"label":["tes' 500 \ .cause="unexpected end of JSON input" -t GET libpod/containers/json?filters='{"label":["testlabel"]}' 200 length=0 +t GET libpod/containers/json?filters='{"label":["created_by"]}' 200 \ + length=1 \ + .[0].Names[0]="labelcontainer_with" +t GET libpod/containers/json?filters='{"label!":["created_by"]}' 200 \ + length=1 \ + .[0].Names[0]="labelcontainer_without" +t GET libpod/containers/json?filters='{"label!":["testlabel"]}' 200 length=2 + +podman stop -t0 labelcontainer_with labelcontainer_without # libpod api: do not use list filters for prune t POST libpod/containers/prune?filters='{"name":["anyname"]}' 500 \ diff --git a/test/apiv2/python/rest_api/test_v2_0_0_container.py b/test/apiv2/python/rest_api/test_v2_0_0_container.py index 15f6c36169..0c8ce881aa 100644 --- a/test/apiv2/python/rest_api/test_v2_0_0_container.py +++ b/test/apiv2/python/rest_api/test_v2_0_0_container.py @@ -22,10 +22,30 @@ def test_list(self): obj = r.json() self.assertEqual(len(obj), 1) - def test_list_filters(self): + def test_list_filters_status(self): r = requests.get( self.podman_url - + "/v1.40/containers/json?filters%3D%7B%22status%22%3A%5B%22running%22%5D%7D" + + "/v1.40/containers/json?filters=%7B%22status%22%3A%5B%22running%22%5D%7D" + ) + self.assertEqual(r.status_code, 200, r.text) + payload = r.json() + containerAmnt = len(payload) + self.assertGreater(containerAmnt, 0) + + def test_list_filters_label(self): + r = requests.get( + self.podman_url + + "/v1.40/containers/json?filters=%7B%22label%22%3A%5B%22nonexistlabel%22%5D%7D" + ) + self.assertEqual(r.status_code, 200, r.text) + payload = r.json() + containerAmnt = len(payload) + self.assertEqual(containerAmnt, 0) + + def test_list_filters_label_not(self): + r = requests.get( + self.podman_url + + "/v1.40/containers/json?filters=%7B%22label%21%22%3A%5B%22nonexistlabel%22%5D%7D" ) self.assertEqual(r.status_code, 200, r.text) payload = r.json()