mirror of
https://github.com/containers/podman.git
synced 2025-06-25 11:57:13 +08:00
Merge pull request #8376 from Luap99/podman-filters
Align the podman ps --filter behavior with docker
This commit is contained in:
@ -98,14 +98,6 @@ func checkFlags(c *cobra.Command) error {
|
|||||||
if listOpts.Last >= 0 && listOpts.Latest {
|
if listOpts.Last >= 0 && listOpts.Latest {
|
||||||
return errors.Errorf("last and latest are mutually exclusive")
|
return errors.Errorf("last and latest are mutually exclusive")
|
||||||
}
|
}
|
||||||
// Filter on status forces all
|
|
||||||
for _, filter := range filters {
|
|
||||||
splitFilter := strings.SplitN(filter, "=", 2)
|
|
||||||
if strings.ToLower(splitFilter[0]) == "status" {
|
|
||||||
listOpts.All = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Quiet conflicts with size and namespace and is overridden by a Go
|
// Quiet conflicts with size and namespace and is overridden by a Go
|
||||||
// template.
|
// template.
|
||||||
if listOpts.Quiet {
|
if listOpts.Quiet {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package lpfilters
|
package lpfilters
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"regexp"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
@ -11,101 +10,133 @@ import (
|
|||||||
"github.com/containers/podman/v2/pkg/timetype"
|
"github.com/containers/podman/v2/pkg/timetype"
|
||||||
"github.com/containers/podman/v2/pkg/util"
|
"github.com/containers/podman/v2/pkg/util"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GenerateContainerFilterFuncs return ContainerFilter functions based of filter.
|
// GenerateContainerFilterFuncs return ContainerFilter functions based of filter.
|
||||||
func GenerateContainerFilterFuncs(filter, filterValue 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 strings.Contains(c.ID(), filterValue)
|
return util.StringMatchRegexSlice(c.ID(), filterValues)
|
||||||
}, nil
|
}, nil
|
||||||
case "label":
|
case "label":
|
||||||
var filterArray = strings.SplitN(filterValue, "=", 2)
|
// we have to match that all given labels exits on that container
|
||||||
var filterKey = filterArray[0]
|
return func(c *libpod.Container) bool {
|
||||||
if len(filterArray) > 1 {
|
labels := c.Labels()
|
||||||
filterValue = filterArray[1]
|
for _, filterValue := range filterValues {
|
||||||
} else {
|
matched := false
|
||||||
filterValue = ""
|
filterArray := strings.SplitN(filterValue, "=", 2)
|
||||||
|
filterKey := filterArray[0]
|
||||||
|
if len(filterArray) > 1 {
|
||||||
|
filterValue = filterArray[1]
|
||||||
|
} else {
|
||||||
|
filterValue = ""
|
||||||
|
}
|
||||||
|
for labelKey, labelValue := range labels {
|
||||||
|
if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
|
||||||
|
matched = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !matched {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}, nil
|
||||||
|
case "name":
|
||||||
|
// we only have to match one name
|
||||||
|
return func(c *libpod.Container) bool {
|
||||||
|
return util.StringMatchRegexSlice(c.Name(), filterValues)
|
||||||
|
}, nil
|
||||||
|
case "exited":
|
||||||
|
var exitCodes []int32
|
||||||
|
for _, exitCode := range filterValues {
|
||||||
|
ec, err := strconv.ParseInt(exitCode, 10, 32)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "exited code out of range %q", ec)
|
||||||
|
}
|
||||||
|
exitCodes = append(exitCodes, int32(ec))
|
||||||
}
|
}
|
||||||
return func(c *libpod.Container) bool {
|
return func(c *libpod.Container) bool {
|
||||||
for labelKey, labelValue := range c.Labels() {
|
ec, exited, err := c.ExitCode()
|
||||||
if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
|
if err == nil && exited {
|
||||||
return true
|
for _, exitCode := range exitCodes {
|
||||||
|
if ec == exitCode {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}, nil
|
}, nil
|
||||||
case "name":
|
|
||||||
return func(c *libpod.Container) bool {
|
|
||||||
match, err := regexp.MatchString(filterValue, c.Name())
|
|
||||||
if err != nil {
|
|
||||||
logrus.Errorf("Failed to compile regex for 'name' filter: %v", err)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return match
|
|
||||||
}, nil
|
|
||||||
case "exited":
|
|
||||||
exitCode, err := strconv.ParseInt(filterValue, 10, 32)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrapf(err, "exited code out of range %q", filterValue)
|
|
||||||
}
|
|
||||||
return func(c *libpod.Container) bool {
|
|
||||||
ec, exited, err := c.ExitCode()
|
|
||||||
if ec == int32(exitCode) && err == nil && exited {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}, nil
|
|
||||||
case "status":
|
case "status":
|
||||||
if !util.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
|
for _, filterValue := range filterValues {
|
||||||
return nil, errors.Errorf("%s is not a valid status", filterValue)
|
if !util.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
|
||||||
|
return nil, errors.Errorf("%s is not a valid status", filterValue)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return func(c *libpod.Container) bool {
|
return func(c *libpod.Container) bool {
|
||||||
status, err := c.State()
|
status, err := c.State()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if filterValue == "stopped" {
|
|
||||||
filterValue = "exited"
|
|
||||||
}
|
|
||||||
state := status.String()
|
state := status.String()
|
||||||
if status == define.ContainerStateConfigured {
|
if status == define.ContainerStateConfigured {
|
||||||
state = "created"
|
state = "created"
|
||||||
} else if status == define.ContainerStateStopped {
|
} else if status == define.ContainerStateStopped {
|
||||||
state = "exited"
|
state = "exited"
|
||||||
}
|
}
|
||||||
return state == filterValue
|
for _, filterValue := range filterValues {
|
||||||
|
if filterValue == "stopped" {
|
||||||
|
filterValue = "exited"
|
||||||
|
}
|
||||||
|
if state == filterValue {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}, nil
|
}, nil
|
||||||
case "ancestor":
|
case "ancestor":
|
||||||
// This needs to refine to match docker
|
// This needs to refine to match docker
|
||||||
// - ancestor=(<image-name>[:tag]|<image-id>| ⟨image@digest⟩) - containers created from an image or a descendant.
|
// - ancestor=(<image-name>[:tag]|<image-id>| ⟨image@digest⟩) - containers created from an image or a descendant.
|
||||||
return func(c *libpod.Container) bool {
|
return func(c *libpod.Container) bool {
|
||||||
containerConfig := c.Config()
|
for _, filterValue := range filterValues {
|
||||||
if strings.Contains(containerConfig.RootfsImageID, filterValue) || strings.Contains(containerConfig.RootfsImageName, filterValue) {
|
containerConfig := c.Config()
|
||||||
return true
|
if strings.Contains(containerConfig.RootfsImageID, filterValue) || strings.Contains(containerConfig.RootfsImageName, filterValue) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}, nil
|
}, nil
|
||||||
case "before":
|
case "before":
|
||||||
ctr, err := r.LookupContainer(filterValue)
|
var createTime time.Time
|
||||||
if err != nil {
|
for _, filterValue := range filterValues {
|
||||||
return nil, errors.Errorf("unable to find container by name or id of %s", filterValue)
|
ctr, err := r.LookupContainer(filterValue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
containerConfig := ctr.Config()
|
||||||
|
if createTime.IsZero() || createTime.After(containerConfig.CreatedTime) {
|
||||||
|
createTime = containerConfig.CreatedTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
containerConfig := ctr.Config()
|
|
||||||
createTime := containerConfig.CreatedTime
|
|
||||||
return func(c *libpod.Container) bool {
|
return func(c *libpod.Container) bool {
|
||||||
cc := c.Config()
|
cc := c.Config()
|
||||||
return createTime.After(cc.CreatedTime)
|
return createTime.After(cc.CreatedTime)
|
||||||
}, nil
|
}, nil
|
||||||
case "since":
|
case "since":
|
||||||
ctr, err := r.LookupContainer(filterValue)
|
var createTime time.Time
|
||||||
if err != nil {
|
for _, filterValue := range filterValues {
|
||||||
return nil, errors.Errorf("unable to find container by name or id of %s", filterValue)
|
ctr, err := r.LookupContainer(filterValue)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
containerConfig := ctr.Config()
|
||||||
|
if createTime.IsZero() || createTime.After(containerConfig.CreatedTime) {
|
||||||
|
createTime = containerConfig.CreatedTime
|
||||||
|
}
|
||||||
}
|
}
|
||||||
containerConfig := ctr.Config()
|
|
||||||
createTime := containerConfig.CreatedTime
|
|
||||||
return func(c *libpod.Container) bool {
|
return func(c *libpod.Container) bool {
|
||||||
cc := c.Config()
|
cc := c.Config()
|
||||||
return createTime.Before(cc.CreatedTime)
|
return createTime.Before(cc.CreatedTime)
|
||||||
@ -115,17 +146,27 @@ func GenerateContainerFilterFuncs(filter, filterValue string, r *libpod.Runtime)
|
|||||||
return func(c *libpod.Container) bool {
|
return func(c *libpod.Container) bool {
|
||||||
containerConfig := c.Config()
|
containerConfig := c.Config()
|
||||||
var dest string
|
var dest string
|
||||||
arr := strings.Split(filterValue, ":")
|
for _, filterValue := range filterValues {
|
||||||
source := arr[0]
|
arr := strings.SplitN(filterValue, ":", 2)
|
||||||
if len(arr) == 2 {
|
source := arr[0]
|
||||||
dest = arr[1]
|
if len(arr) == 2 {
|
||||||
}
|
dest = arr[1]
|
||||||
for _, mount := range containerConfig.Spec.Mounts {
|
|
||||||
if dest != "" && (mount.Source == source && mount.Destination == dest) {
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
if dest == "" && mount.Source == source {
|
for _, mount := range containerConfig.Spec.Mounts {
|
||||||
return true
|
if dest != "" && (mount.Source == source && mount.Destination == dest) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if dest == "" && mount.Source == source {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, vname := range containerConfig.NamedVolumes {
|
||||||
|
if dest != "" && (vname.Name == source && vname.Dest == dest) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if dest == "" && vname.Name == source {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -136,10 +177,18 @@ func GenerateContainerFilterFuncs(filter, filterValue string, r *libpod.Runtime)
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return hcStatus == filterValue
|
for _, filterValue := range filterValues {
|
||||||
|
if hcStatus == filterValue {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
}, nil
|
}, nil
|
||||||
case "until":
|
case "until":
|
||||||
ts, err := timetype.GetTimestamp(filterValue, time.Now())
|
if len(filterValues) != 1 {
|
||||||
|
return nil, errors.Errorf("specify exactly one timestamp for %s", filter)
|
||||||
|
}
|
||||||
|
ts, err := timetype.GetTimestamp(filterValues[0], time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ func PruneContainers(w http.ResponseWriter, r *http.Request) {
|
|||||||
var (
|
var (
|
||||||
delContainers []string
|
delContainers []string
|
||||||
space int64
|
space int64
|
||||||
filterFuncs []libpod.ContainerFilter
|
|
||||||
)
|
)
|
||||||
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
runtime := r.Context().Value("runtime").(*libpod.Runtime)
|
||||||
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
decoder := r.Context().Value("decoder").(*schema.Decoder)
|
||||||
@ -28,15 +27,14 @@ func PruneContainers(w http.ResponseWriter, r *http.Request) {
|
|||||||
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
|
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
filterFuncs := make([]libpod.ContainerFilter, 0, len(query.Filters))
|
||||||
for k, v := range query.Filters {
|
for k, v := range query.Filters {
|
||||||
for _, val := range v {
|
generatedFunc, err := lpfilters.GenerateContainerFilterFuncs(k, v, runtime)
|
||||||
generatedFunc, err := lpfilters.GenerateContainerFilterFuncs(k, val, runtime)
|
if err != nil {
|
||||||
if err != nil {
|
utils.InternalServerError(w, err)
|
||||||
utils.InternalServerError(w, err)
|
return
|
||||||
return
|
|
||||||
}
|
|
||||||
filterFuncs = append(filterFuncs, generatedFunc)
|
|
||||||
}
|
}
|
||||||
|
filterFuncs = append(filterFuncs, generatedFunc)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Libpod response differs
|
// Libpod response differs
|
||||||
|
@ -205,15 +205,13 @@ func (ic *ContainerEngine) ContainerStop(ctx context.Context, namesOrIds []strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (ic *ContainerEngine) ContainerPrune(ctx context.Context, options entities.ContainerPruneOptions) (*entities.ContainerPruneReport, error) {
|
func (ic *ContainerEngine) ContainerPrune(ctx context.Context, options entities.ContainerPruneOptions) (*entities.ContainerPruneReport, error) {
|
||||||
var filterFuncs []libpod.ContainerFilter
|
filterFuncs := make([]libpod.ContainerFilter, 0, len(options.Filters))
|
||||||
for k, v := range options.Filters {
|
for k, v := range options.Filters {
|
||||||
for _, val := range v {
|
generatedFunc, err := lpfilters.GenerateContainerFilterFuncs(k, v, ic.Libpod)
|
||||||
generatedFunc, err := lpfilters.GenerateContainerFilterFuncs(k, val, ic.Libpod)
|
if err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
filterFuncs = append(filterFuncs, generatedFunc)
|
|
||||||
}
|
}
|
||||||
|
filterFuncs = append(filterFuncs, generatedFunc)
|
||||||
}
|
}
|
||||||
return ic.pruneContainersHelper(filterFuncs)
|
return ic.pruneContainersHelper(filterFuncs)
|
||||||
}
|
}
|
||||||
|
16
pkg/ps/ps.go
16
pkg/ps/ps.go
@ -21,19 +21,17 @@ import (
|
|||||||
|
|
||||||
func GetContainerLists(runtime *libpod.Runtime, options entities.ContainerListOptions) ([]entities.ListContainer, error) {
|
func GetContainerLists(runtime *libpod.Runtime, options entities.ContainerListOptions) ([]entities.ListContainer, error) {
|
||||||
var (
|
var (
|
||||||
filterFuncs []libpod.ContainerFilter
|
pss = []entities.ListContainer{}
|
||||||
pss = []entities.ListContainer{}
|
|
||||||
)
|
)
|
||||||
|
filterFuncs := make([]libpod.ContainerFilter, 0, len(options.Filters))
|
||||||
all := options.All || options.Last > 0
|
all := options.All || options.Last > 0
|
||||||
if len(options.Filters) > 0 {
|
if len(options.Filters) > 0 {
|
||||||
for k, v := range options.Filters {
|
for k, v := range options.Filters {
|
||||||
for _, val := range v {
|
generatedFunc, err := lpfilters.GenerateContainerFilterFuncs(k, v, runtime)
|
||||||
generatedFunc, err := lpfilters.GenerateContainerFilterFuncs(k, val, runtime)
|
if err != nil {
|
||||||
if err != nil {
|
return nil, err
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
filterFuncs = append(filterFuncs, generatedFunc)
|
|
||||||
}
|
}
|
||||||
|
filterFuncs = append(filterFuncs, generatedFunc)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +41,7 @@ func GetContainerLists(runtime *libpod.Runtime, options entities.ContainerListOp
|
|||||||
all = true
|
all = true
|
||||||
}
|
}
|
||||||
if !all {
|
if !all {
|
||||||
runningOnly, err := lpfilters.GenerateContainerFilterFuncs("status", define.ContainerStateRunning.String(), runtime)
|
runningOnly, err := lpfilters.GenerateContainerFilterFuncs("status", []string{define.ContainerStateRunning.String()}, runtime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -84,6 +85,17 @@ func StringInSlice(s string, sl []string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringMatchRegexSlice determines if a given string matches one of the given regexes, returns bool
|
||||||
|
func StringMatchRegexSlice(s string, re []string) bool {
|
||||||
|
for _, r := range re {
|
||||||
|
m, err := regexp.MatchString(r, s)
|
||||||
|
if err == nil && m {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// ImageConfig is a wrapper around the OCIv1 Image Configuration struct exported
|
// ImageConfig is a wrapper around the OCIv1 Image Configuration struct exported
|
||||||
// by containers/image, but containing additional fields that are not supported
|
// by containers/image, but containing additional fields that are not supported
|
||||||
// by OCIv1 (but are by Docker v2) - notably OnBuild.
|
// by OCIv1 (but are by Docker v2) - notably OnBuild.
|
||||||
|
@ -545,4 +545,126 @@ var _ = Describe("Podman ps", func() {
|
|||||||
Expect(result.ExitCode()).To(Equal(0))
|
Expect(result.ExitCode()).To(Equal(0))
|
||||||
Expect(result.OutputToString()).To(ContainSubstring("ago"))
|
Expect(result.OutputToString()).To(ContainSubstring("ago"))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("podman ps filter test", func() {
|
||||||
|
session := podmanTest.Podman([]string{"run", "-d", "--name", "test1", "--label", "foo=1",
|
||||||
|
"--label", "bar=2", "--volume", "volume1:/test", ALPINE, "top"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
cid1 := session.OutputToString()
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"run", "--name", "test2", "--label", "foo=1",
|
||||||
|
ALPINE, "ls", "/fail"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(1))
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"create", "--name", "test3", ALPINE, cid1})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"run", "--name", "test4", "--volume", "volume1:/test1",
|
||||||
|
"--volume", "/:/test2", ALPINE, "ls"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "name=test"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(5))
|
||||||
|
Expect(session.LineInOutputContains("test1")).To(BeTrue())
|
||||||
|
Expect(session.LineInOutputContains("test2")).To(BeTrue())
|
||||||
|
Expect(session.LineInOutputContains("test3")).To(BeTrue())
|
||||||
|
Expect(session.LineInOutputContains("test4")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "name=test1", "--filter", "name=test2"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(3))
|
||||||
|
Expect(session.LineInOutputContains("test1")).To(BeTrue())
|
||||||
|
Expect(session.LineInOutputContains("test2")).To(BeTrue())
|
||||||
|
|
||||||
|
// check container id matches with regex
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "id=" + cid1[:40], "--filter", "id=" + cid1 + "$"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(2))
|
||||||
|
Expect(session.LineInOutputContains("test1")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--filter", "status=created"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(2))
|
||||||
|
Expect(session.LineInOutputContains("test3")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--filter", "status=created", "--filter", "status=exited"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(4))
|
||||||
|
Expect(session.LineInOutputContains("test2")).To(BeTrue())
|
||||||
|
Expect(session.LineInOutputContains("test3")).To(BeTrue())
|
||||||
|
Expect(session.LineInOutputContains("test4")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "label=foo=1"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(3))
|
||||||
|
Expect(session.LineInOutputContains("test1")).To(BeTrue())
|
||||||
|
Expect(session.LineInOutputContains("test2")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--filter", "label=foo=1", "--filter", "status=exited"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(2))
|
||||||
|
Expect(session.LineInOutputContains("test2")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "label=foo=1", "--filter", "label=non=1"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(1))
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "label=foo=1", "--filter", "label=bar=2"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(2))
|
||||||
|
Expect(session.LineInOutputContains("test1")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "exited=1"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(2))
|
||||||
|
Expect(session.LineInOutputContains("test2")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "exited=1", "--filter", "exited=0"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(3))
|
||||||
|
Expect(session.LineInOutputContains("test2")).To(BeTrue())
|
||||||
|
Expect(session.LineInOutputContains("test4")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "volume=volume1"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(3))
|
||||||
|
Expect(session.LineInOutputContains("test1")).To(BeTrue())
|
||||||
|
Expect(session.LineInOutputContains("test4")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "volume=/:/test2"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(2))
|
||||||
|
Expect(session.LineInOutputContains("test4")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "before=test2"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(2))
|
||||||
|
Expect(session.LineInOutputContains("test1")).To(BeTrue())
|
||||||
|
|
||||||
|
session = podmanTest.Podman([]string{"ps", "--all", "--filter", "since=test2"})
|
||||||
|
session.WaitWithDefaultTimeout()
|
||||||
|
Expect(session.ExitCode()).To(Equal(0))
|
||||||
|
Expect(len(session.OutputToStringArray())).To(Equal(3))
|
||||||
|
Expect(session.LineInOutputContains("test3")).To(BeTrue())
|
||||||
|
Expect(session.LineInOutputContains("test4")).To(BeTrue())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user