mirror of
https://github.com/containers/podman.git
synced 2025-06-26 21:07:02 +08:00
Merge pull request #18798 from edsantiago/fix_filters
filters: better handling of id=
This commit is contained in:
@ -290,7 +290,7 @@ func sortPodPsOutput(sortBy string, lprs []*entities.ListPodsReport) error {
|
|||||||
case "status":
|
case "status":
|
||||||
sort.Sort(podPsSortedStatus{lprs})
|
sort.Sort(podPsSortedStatus{lprs})
|
||||||
default:
|
default:
|
||||||
return errors.New("invalid option for --sort, options are: id, names, or number")
|
return errors.New("invalid option for --sort, options are: created, id, name, number, or status")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -29,8 +29,8 @@ Filters with the same key work inclusive with the only exception being
|
|||||||
Valid filters are listed below:
|
Valid filters are listed below:
|
||||||
|
|
||||||
| **Filter** | **Description** |
|
| **Filter** | **Description** |
|
||||||
| --------------- | -------------------------------------------------------------------------------- |
|
|------------|----------------------------------------------------------------------------------|
|
||||||
| id | [ID] Container's ID (accepts regex) |
|
| id | [ID] Container's ID (CID prefix match by default; accepts regex) |
|
||||||
| name | [Name] Container's name (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 assigned to a container |
|
||||||
| exited | [Int] Container's exit code |
|
| exited | [Int] Container's exit code |
|
||||||
|
@ -49,12 +49,12 @@ The *filters* argument format is of `key=value`. If there is more than one *filt
|
|||||||
Supported filters:
|
Supported filters:
|
||||||
|
|
||||||
| Filter | Description |
|
| Filter | Description |
|
||||||
| ---------- | -------------------------------------------------------------------------------------------------- |
|
|--------------|--------------------------------------------------------------------------------------------------|
|
||||||
| *ctr-ids* | Filter by container ID within the pod. |
|
| *ctr-ids* | Filter by container ID within the pod. (CID prefix match by default; accepts regex) |
|
||||||
| *ctr-names* | Filter by container name within the pod. |
|
| *ctr-names* | Filter by container name within the pod. |
|
||||||
| *ctr-number*| Filter by number of containers in the pod. |
|
| *ctr-number* | Filter by number of containers in the pod. |
|
||||||
| *ctr-status*| Filter by container status within the pod. |
|
| *ctr-status* | Filter by container status within the pod. |
|
||||||
| *id* | Filter by pod ID. |
|
| *id* | Filter by pod ID. (Prefix match by default; accepts regex) |
|
||||||
| *label* | Filter by container with (or without, in the case of label!=[...] is used) the specified labels. |
|
| *label* | Filter by container with (or without, in the case of label!=[...] is used) the specified labels. |
|
||||||
| *name* | Filter by pod name. |
|
| *name* | Filter by pod name. |
|
||||||
| *network* | Filter by network name or full ID of network. |
|
| *network* | Filter by network name or full ID of network. |
|
||||||
|
@ -46,8 +46,8 @@ Filters with the same key work inclusive with the only exception being
|
|||||||
Valid filters are listed below:
|
Valid filters are listed below:
|
||||||
|
|
||||||
| **Filter** | **Description** |
|
| **Filter** | **Description** |
|
||||||
| --------------- | -------------------------------------------------------------------------------- |
|
|------------|----------------------------------------------------------------------------------|
|
||||||
| id | [ID] Container's ID (accepts regex) |
|
| id | [ID] Container's ID (CID prefix match by default; accepts regex) |
|
||||||
| name | [Name] Container's name (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 assigned to a container |
|
||||||
| exited | [Int] Container's exit code |
|
| exited | [Int] Container's exit code |
|
||||||
|
@ -32,8 +32,8 @@ Filters with the same key work inclusive with the only exception being
|
|||||||
Valid filters are listed below:
|
Valid filters are listed below:
|
||||||
|
|
||||||
| **Filter** | **Description** |
|
| **Filter** | **Description** |
|
||||||
| --------------- | -------------------------------------------------------------------------------- |
|
|------------|----------------------------------------------------------------------------------|
|
||||||
| id | [ID] Container's ID (accepts regex) |
|
| id | [ID] Container's ID (CID prefix match by default; accepts regex) |
|
||||||
| name | [Name] Container's name (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 assigned to a container |
|
||||||
| exited | [Int] Container's exit code |
|
| exited | [Int] Container's exit code |
|
||||||
|
@ -34,8 +34,8 @@ Filters with the same key work inclusive with the only exception being
|
|||||||
Valid filters are listed below:
|
Valid filters are listed below:
|
||||||
|
|
||||||
| **Filter** | **Description** |
|
| **Filter** | **Description** |
|
||||||
| --------------- | -------------------------------------------------------------------------------- |
|
|------------|----------------------------------------------------------------------------------|
|
||||||
| id | [ID] Container's ID (accepts regex) |
|
| id | [ID] Container's ID (CID prefix match by default; accepts regex) |
|
||||||
| name | [Name] Container's name (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 assigned to a container |
|
||||||
| exited | [Int] Container's exit code |
|
| exited | [Int] Container's exit code |
|
||||||
|
@ -37,8 +37,8 @@ Filters with the same key work inclusive with the only exception being
|
|||||||
Valid filters are listed below:
|
Valid filters are listed below:
|
||||||
|
|
||||||
| **Filter** | **Description** |
|
| **Filter** | **Description** |
|
||||||
| --------------- | -------------------------------------------------------------------------------- |
|
|------------|----------------------------------------------------------------------------------|
|
||||||
| id | [ID] Container's ID (accepts regex) |
|
| id | [ID] Container's ID (CID prefix match by default; accepts regex) |
|
||||||
| name | [Name] Container's name (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 assigned to a container |
|
||||||
| exited | [Int] Container's exit code |
|
| exited | [Int] Container's exit code |
|
||||||
|
@ -33,8 +33,8 @@ Filters with the same key work inclusive with the only exception being
|
|||||||
Valid filters are listed below:
|
Valid filters are listed below:
|
||||||
|
|
||||||
| **Filter** | **Description** |
|
| **Filter** | **Description** |
|
||||||
| --------------- | -------------------------------------------------------------------------------- |
|
|------------|----------------------------------------------------------------------------------|
|
||||||
| id | [ID] Container's ID (accepts regex) |
|
| id | [ID] Container's ID (CID prefix match by default; accepts regex) |
|
||||||
| name | [Name] Container's name (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 assigned to a container |
|
||||||
| exited | [Int] Container's exit code |
|
| exited | [Int] Container's exit code |
|
||||||
|
@ -29,8 +29,8 @@ Filters with the same key work inclusive with the only exception being
|
|||||||
Valid filters are listed below:
|
Valid filters are listed below:
|
||||||
|
|
||||||
| **Filter** | **Description** |
|
| **Filter** | **Description** |
|
||||||
| --------------- | -------------------------------------------------------------------------------- |
|
|------------|----------------------------------------------------------------------------------|
|
||||||
| id | [ID] Container's ID (accepts regex) |
|
| id | [ID] Container's ID (CID prefix match by default; accepts regex) |
|
||||||
| name | [Name] Container's name (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 assigned to a container |
|
||||||
| exited | [Int] Container's exit code |
|
| exited | [Int] Container's exit code |
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/containers/common/libnetwork/types"
|
"github.com/containers/common/libnetwork/types"
|
||||||
|
"github.com/containers/storage/pkg/regexp"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -17,6 +18,9 @@ var (
|
|||||||
// This must NOT be changed from outside of Libpod. It should be a
|
// This must NOT be changed from outside of Libpod. It should be a
|
||||||
// constant, but Go won't let us do that.
|
// constant, but Go won't let us do that.
|
||||||
NameRegex = types.NameRegex
|
NameRegex = types.NameRegex
|
||||||
|
// NotHexRegex is a regular expression to check if a string is
|
||||||
|
// a hexadecimal string.
|
||||||
|
NotHexRegex = regexp.Delayed(`[^0-9a-fA-F]`)
|
||||||
// RegexError is thrown in presence of an invalid container/pod name.
|
// RegexError is thrown in presence of an invalid container/pod name.
|
||||||
RegexError = types.RegexError
|
RegexError = types.RegexError
|
||||||
)
|
)
|
||||||
|
@ -3,6 +3,7 @@ package filters
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -18,9 +19,19 @@ import (
|
|||||||
func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpod.Runtime) (func(container *libpod.Container) bool, error) {
|
func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpod.Runtime) (func(container *libpod.Container) bool, error) {
|
||||||
switch filter {
|
switch filter {
|
||||||
case "id":
|
case "id":
|
||||||
// we only have to match one ID
|
|
||||||
return func(c *libpod.Container) bool {
|
return func(c *libpod.Container) bool {
|
||||||
return util.StringMatchRegexSlice(c.ID(), filterValues)
|
for _, want := range filterValues {
|
||||||
|
isRegex := define.NotHexRegex.MatchString(want)
|
||||||
|
if isRegex {
|
||||||
|
match, err := regexp.MatchString(want, c.ID())
|
||||||
|
if err == nil && match {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else if strings.HasPrefix(c.ID(), strings.ToLower(want)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}, nil
|
}, nil
|
||||||
case "label":
|
case "label":
|
||||||
// we have to match that all given labels exits on that container
|
// we have to match that all given labels exits on that container
|
||||||
|
@ -3,6 +3,7 @@ package filters
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -25,8 +26,25 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
for _, want := range filterValues {
|
||||||
|
isRegex := define.NotHexRegex.MatchString(want)
|
||||||
|
if isRegex {
|
||||||
|
re, err := regexp.Compile(want)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
for _, id := range ctrIds {
|
for _, id := range ctrIds {
|
||||||
return util.StringMatchRegexSlice(id, filterValues)
|
if re.MatchString(id) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, id := range ctrIds {
|
||||||
|
if strings.HasPrefix(id, strings.ToLower(want)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}, nil
|
}, nil
|
||||||
@ -89,7 +107,18 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
|
|||||||
}, nil
|
}, nil
|
||||||
case "id":
|
case "id":
|
||||||
return func(p *libpod.Pod) bool {
|
return func(p *libpod.Pod) bool {
|
||||||
return util.StringMatchRegexSlice(p.ID(), filterValues)
|
for _, want := range filterValues {
|
||||||
|
isRegex := define.NotHexRegex.MatchString(want)
|
||||||
|
if isRegex {
|
||||||
|
match, err := regexp.MatchString(want, p.ID())
|
||||||
|
if err == nil && match {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} else if strings.HasPrefix(p.ID(), strings.ToLower(want)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}, nil
|
}, nil
|
||||||
case "name":
|
case "name":
|
||||||
return func(p *libpod.Pod) bool {
|
return func(p *libpod.Pod) bool {
|
||||||
|
@ -37,22 +37,37 @@ load helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
@test "podman ps --filter" {
|
@test "podman ps --filter" {
|
||||||
run_podman run -d --name runner $IMAGE top
|
local -A cid
|
||||||
cid_runner=$output
|
|
||||||
|
|
||||||
|
# Create three containers, each of whose CID begins with a different char
|
||||||
|
run_podman run -d --name running $IMAGE top
|
||||||
|
cid[running]=$output
|
||||||
|
|
||||||
|
cid[stopped]=$output
|
||||||
|
while [[ ${cid[stopped]:0:1} == ${cid[running]:0:1} ]]; do
|
||||||
|
run_podman rm -f stopped
|
||||||
run_podman run -d --name stopped $IMAGE true
|
run_podman run -d --name stopped $IMAGE true
|
||||||
cid_stopped=$output
|
cid[stopped]=$output
|
||||||
run_podman wait stopped
|
run_podman wait stopped
|
||||||
|
done
|
||||||
|
|
||||||
|
cid[failed]=${cid[stopped]}
|
||||||
|
while [[ ${cid[failed]:0:1} == ${cid[running]:0:1} ]] || [[ ${cid[failed]:0:1} == ${cid[stopped]:0:1} ]]; do
|
||||||
|
run_podman rm -f failed
|
||||||
run_podman run -d --name failed $IMAGE false
|
run_podman run -d --name failed $IMAGE false
|
||||||
cid_failed=$output
|
cid[failed]=$output
|
||||||
run_podman wait failed
|
run_podman wait failed
|
||||||
|
done
|
||||||
|
|
||||||
|
# This one is never tested in the id filter, so its cid can be anything
|
||||||
run_podman create --name created $IMAGE echo hi
|
run_podman create --name created $IMAGE echo hi
|
||||||
cid_created=$output
|
cid[created]=$output
|
||||||
|
|
||||||
run_podman ps --filter name=runner --format '{{.ID}}'
|
# For debugging
|
||||||
is "$output" "${cid_runner:0:12}" "filter: name=runner"
|
run_podman ps -a
|
||||||
|
|
||||||
|
run_podman ps --filter name=running --format '{{.ID}}'
|
||||||
|
is "$output" "${cid[running]:0:12}" "filter: name=running"
|
||||||
|
|
||||||
# Stopped container should not appear (because we're not using -a)
|
# Stopped container should not appear (because we're not using -a)
|
||||||
run_podman ps --filter name=stopped --format '{{.ID}}'
|
run_podman ps --filter name=stopped --format '{{.ID}}'
|
||||||
@ -60,7 +75,7 @@ load helpers
|
|||||||
|
|
||||||
# Again, but with -a
|
# Again, but with -a
|
||||||
run_podman ps -a --filter name=stopped --format '{{.ID}}'
|
run_podman ps -a --filter name=stopped --format '{{.ID}}'
|
||||||
is "$output" "${cid_stopped:0:12}" "filter: name=stopped (with -a)"
|
is "$output" "${cid[stopped]:0:12}" "filter: name=stopped (with -a)"
|
||||||
|
|
||||||
run_podman ps --filter status=stopped --format '{{.Names}}' --sort names
|
run_podman ps --filter status=stopped --format '{{.Names}}' --sort names
|
||||||
is "${lines[0]}" "failed" "status=stopped: 1 of 2"
|
is "${lines[0]}" "failed" "status=stopped: 1 of 2"
|
||||||
@ -72,14 +87,52 @@ load helpers
|
|||||||
run_podman ps --filter status=exited --filter exited=1 --format '{{.Names}}'
|
run_podman ps --filter status=exited --filter exited=1 --format '{{.Names}}'
|
||||||
is "$output" "failed" "exited=1"
|
is "$output" "failed" "exited=1"
|
||||||
|
|
||||||
|
run_podman ps --filter status=created --format '{{.Names}}'
|
||||||
|
is "$output" "created" "state=created"
|
||||||
|
|
||||||
# Multiple statuses allowed; and test sort=created
|
# Multiple statuses allowed; and test sort=created
|
||||||
run_podman ps -a --filter status=exited --filter status=running \
|
run_podman ps -a --filter status=exited --filter status=running \
|
||||||
--format '{{.Names}}' --sort created
|
--format '{{.Names}}' --sort created
|
||||||
is "${lines[0]}" "runner" "status=stopped: 1 of 3"
|
is "${lines[0]}" "running" "status=stopped: 1 of 3"
|
||||||
is "${lines[1]}" "stopped" "status=stopped: 2 of 3"
|
is "${lines[1]}" "stopped" "status=stopped: 2 of 3"
|
||||||
is "${lines[2]}" "failed" "status=stopped: 3 of 3"
|
is "${lines[2]}" "failed" "status=stopped: 3 of 3"
|
||||||
|
|
||||||
run_podman stop -t 1 runner
|
# ID filtering: if filter is only hex chars, it's a prefix; if it has
|
||||||
|
# anything else, it's a regex
|
||||||
|
run_podman rm created
|
||||||
|
for state in running stopped failed; do
|
||||||
|
local test_cid=${cid[$state]}
|
||||||
|
for prefix in ${test_cid:0:1} ${test_cid:0:2} ${test_cid:0:13}; do
|
||||||
|
# Test lower-case (default), upper-case, and with '^' anchor
|
||||||
|
for uclc in ${prefix,,} ${prefix^^} "^$prefix"; do
|
||||||
|
run_podman ps -a --filter id=$uclc --format '{{.Names}}'
|
||||||
|
assert "$output" = "$state" "ps --filter id=$uclc"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# Regex check
|
||||||
|
local f="^[^${test_cid:0:1}]"
|
||||||
|
run_podman ps -a --filter id="$f" --format '{{.Names}}'
|
||||||
|
assert "${#lines[*]}" == "2" "filter id=$f: number of lines"
|
||||||
|
assert "$output" !~ $state "filter id=$f: '$state' not in results"
|
||||||
|
done
|
||||||
|
|
||||||
|
# All CIDs will have hex characters
|
||||||
|
run_podman ps -a --filter id="[0-9a-f]" --format '{{.Names}}' --sort names
|
||||||
|
assert "${lines[0]}" == "failed" "filter id=[0-9a-f], line 1"
|
||||||
|
assert "${lines[1]}" == "running" "filter id=[0-9a-f], line 2"
|
||||||
|
assert "${lines[2]}" == "stopped" "filter id=[0-9a-f], line 3"
|
||||||
|
|
||||||
|
run_podman ps -a --filter id="[^0-9a-f]" --noheading
|
||||||
|
assert "$output" = "" "id=[^0-9a-f], should match no containers"
|
||||||
|
|
||||||
|
# Finally, multiple filters
|
||||||
|
run_podman ps -a --filter id=${cid[running]} --filter id=${cid[failed]} \
|
||||||
|
--format '{{.Names}}' --sort names
|
||||||
|
assert "${lines[0]}" == "failed" "filter id=running+failed, line 1"
|
||||||
|
assert "${lines[1]}" == "running" "filter id=running+failed, line 2"
|
||||||
|
|
||||||
|
run_podman stop -t 1 running
|
||||||
run_podman rm -a
|
run_podman rm -a
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,4 +567,101 @@ io.max | $lomajmin rbps=1048576 wbps=1048576 riops=max wiops=max
|
|||||||
run_podman 1 pod exists $podname
|
run_podman 1 pod exists $podname
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Helper used by pod ps --filter test. Creates one pod or container
|
||||||
|
# with a UNIQUE two-character CID prefix.
|
||||||
|
function thingy_with_unique_id() {
|
||||||
|
local what="$1"; shift # pod or container
|
||||||
|
local how="$1"; shift # e.g. "--name p1c1 --pod p1"
|
||||||
|
|
||||||
|
while :;do
|
||||||
|
local try_again=
|
||||||
|
|
||||||
|
run_podman $what create $how
|
||||||
|
# This is our return value; it propagates up to caller's namespace
|
||||||
|
id="$output"
|
||||||
|
|
||||||
|
# Make sure the first two characters aren't already used in an ID
|
||||||
|
for existing_id in "$@"; do
|
||||||
|
if [[ -z "$try_again" ]]; then
|
||||||
|
if [[ "${existing_id:0:2}" == "${id:0:2}" ]]; then
|
||||||
|
run_podman $what rm $id
|
||||||
|
try_again=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z "$try_again" ]]; then
|
||||||
|
# Nope! groovy! caller gets $id
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
@test "podman pod ps --filter" {
|
||||||
|
local -A podid
|
||||||
|
local -A ctrid
|
||||||
|
|
||||||
|
# Setup: create three pods, each with three containers, all of them with
|
||||||
|
# unique (distinct) first two characters of their pod/container ID.
|
||||||
|
for p in 1 2 3;do
|
||||||
|
# no infra, please! That creates an extra container with a CID
|
||||||
|
# that may collide with our other ones, and it's too hard to fix.
|
||||||
|
thingy_with_unique_id "pod" "--infra=false --name p${p}" \
|
||||||
|
${podid[*]} ${ctrid[*]}
|
||||||
|
podid[$p]=$id
|
||||||
|
|
||||||
|
for c in 1 2 3; do
|
||||||
|
thingy_with_unique_id "container" \
|
||||||
|
"--pod p${p} --name p${p}c${c} $IMAGE true" \
|
||||||
|
${podid[*]} ${ctrid[*]}
|
||||||
|
ctrid[$p$c]=$id
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# for debugging; without this, on test failure it's too hard to
|
||||||
|
# associate IDs with names
|
||||||
|
run_podman pod ps
|
||||||
|
run_podman ps -a
|
||||||
|
|
||||||
|
# Test: ps and filter for each pod and container, by ID
|
||||||
|
for p in 1 2 3; do
|
||||||
|
local pid=${podid[$p]}
|
||||||
|
|
||||||
|
# Search by short pod ID, longer pod ID, pod ID regex, and pod name
|
||||||
|
# ps by short ID, longer ID, regex, and name
|
||||||
|
for filter in "id=${pid:0:2}" "id=${pid:0:10}" "id=^${pid:0:2}" "name=p$p"; do
|
||||||
|
run_podman pod ps --filter=$filter --format '{{.Name}}:{{.Id}}'
|
||||||
|
assert "$output" == "p$p:${pid:0:12}" "pod $p, filter=$filter"
|
||||||
|
done
|
||||||
|
|
||||||
|
# ps by negation (regex) of our pid, should find all other pods
|
||||||
|
f1="^[^${pid:0:1}]"
|
||||||
|
f2="^.[^${pid:1:1}]"
|
||||||
|
run_podman pod ps --filter=id="$f1" --filter=id="$f2" --format '{{.Name}}'
|
||||||
|
assert "${#lines[*]}" == "2" "filter=$f1 + $f2 finds 2 pods"
|
||||||
|
assert "$output" !~ "p$p" "filter=$f1 + $f2 does not find p$p"
|
||||||
|
|
||||||
|
# Search by *container* ID
|
||||||
|
for c in 1 2 3;do
|
||||||
|
local cid=${ctrid[$p$c]}
|
||||||
|
for filter in "ctr-ids=${cid:0:2}" "ctr-ids=^${cid:0:2}.*"; do
|
||||||
|
run_podman pod ps --filter=$filter --format '{{.Name}}:{{.Id}}'
|
||||||
|
assert "$output" == "p${p}:${pid:0:12}" \
|
||||||
|
"pod $p, container $c, filter=$filter"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
# Multiple filters, multiple pods
|
||||||
|
run_podman pod ps --filter=ctr-ids=${ctrid[12]} \
|
||||||
|
--filter=ctr-ids=${ctrid[23]} \
|
||||||
|
--filter=ctr-ids=${ctrid[31]} \
|
||||||
|
--format='{{.Name}}' --sort=name
|
||||||
|
assert "$(echo $output)" == "p1 p2 p3" "multiple ctr-ids filters"
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
run_podman pod rm -f -a
|
||||||
|
run_podman rm -f -a
|
||||||
|
}
|
||||||
|
|
||||||
# vim: filetype=sh
|
# vim: filetype=sh
|
||||||
|
Reference in New Issue
Block a user