summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
Diffstat (limited to 'libpod')
-rw-r--r--libpod/filters/containers.go163
-rw-r--r--libpod/filters/pods.go97
2 files changed, 163 insertions, 97 deletions
diff --git a/libpod/filters/containers.go b/libpod/filters/containers.go
index da1b5b263..2520c4f30 100644
--- a/libpod/filters/containers.go
+++ b/libpod/filters/containers.go
@@ -1,7 +1,6 @@
package lpfilters
import (
- "regexp"
"strconv"
"strings"
"time"
@@ -11,101 +10,133 @@ import (
"github.com/containers/podman/v2/pkg/timetype"
"github.com/containers/podman/v2/pkg/util"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
)
// 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 {
case "id":
+ // we only have to match one ID
return func(c *libpod.Container) bool {
- return strings.Contains(c.ID(), filterValue)
+ return util.StringMatchRegexSlice(c.ID(), filterValues)
}, nil
case "label":
- var filterArray = strings.SplitN(filterValue, "=", 2)
- var filterKey = filterArray[0]
- if len(filterArray) > 1 {
- filterValue = filterArray[1]
- } else {
- filterValue = ""
- }
+ // we have to match that all given labels exits on that container
return func(c *libpod.Container) bool {
- for labelKey, labelValue := range c.Labels() {
- if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
- return true
+ labels := c.Labels()
+ for _, filterValue := range filterValues {
+ matched := false
+ 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 false
+ return true
}, nil
case "name":
+ // we only have to match one 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
+ return util.StringMatchRegexSlice(c.Name(), filterValues)
}, 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)
+ 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 {
ec, exited, err := c.ExitCode()
- if ec == int32(exitCode) && err == nil && exited {
- return true
+ if err == nil && exited {
+ for _, exitCode := range exitCodes {
+ if ec == exitCode {
+ return true
+ }
+ }
}
return false
}, nil
case "status":
- if !util.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
- return nil, errors.Errorf("%s is not a valid status", filterValue)
+ for _, filterValue := range filterValues {
+ 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 {
status, err := c.State()
if err != nil {
return false
}
- if filterValue == "stopped" {
- filterValue = "exited"
- }
state := status.String()
if status == define.ContainerStateConfigured {
state = "created"
} else if status == define.ContainerStateStopped {
state = "exited"
}
- return state == filterValue
+ for _, filterValue := range filterValues {
+ if filterValue == "stopped" {
+ filterValue = "exited"
+ }
+ if state == filterValue {
+ return true
+ }
+ }
+ return false
}, nil
case "ancestor":
// This needs to refine to match docker
// - ancestor=(<image-name>[:tag]|<image-id>| ⟨image@digest⟩) - containers created from an image or a descendant.
return func(c *libpod.Container) bool {
- containerConfig := c.Config()
- if strings.Contains(containerConfig.RootfsImageID, filterValue) || strings.Contains(containerConfig.RootfsImageName, filterValue) {
- return true
+ for _, filterValue := range filterValues {
+ containerConfig := c.Config()
+ if strings.Contains(containerConfig.RootfsImageID, filterValue) || strings.Contains(containerConfig.RootfsImageName, filterValue) {
+ return true
+ }
}
return false
}, nil
case "before":
- ctr, err := r.LookupContainer(filterValue)
- if err != nil {
- return nil, errors.Errorf("unable to find container by name or id of %s", filterValue)
+ var createTime time.Time
+ for _, filterValue := range filterValues {
+ 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 {
cc := c.Config()
return createTime.After(cc.CreatedTime)
}, nil
case "since":
- ctr, err := r.LookupContainer(filterValue)
- if err != nil {
- return nil, errors.Errorf("unable to find container by name or id of %s", filterValue)
+ var createTime time.Time
+ for _, filterValue := range filterValues {
+ 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 {
cc := c.Config()
return createTime.Before(cc.CreatedTime)
@@ -115,17 +146,27 @@ func GenerateContainerFilterFuncs(filter, filterValue string, r *libpod.Runtime)
return func(c *libpod.Container) bool {
containerConfig := c.Config()
var dest string
- arr := strings.Split(filterValue, ":")
- source := arr[0]
- if len(arr) == 2 {
- dest = arr[1]
- }
- for _, mount := range containerConfig.Spec.Mounts {
- if dest != "" && (mount.Source == source && mount.Destination == dest) {
- return true
+ for _, filterValue := range filterValues {
+ arr := strings.SplitN(filterValue, ":", 2)
+ source := arr[0]
+ if len(arr) == 2 {
+ dest = arr[1]
}
- if dest == "" && mount.Source == source {
- return true
+ for _, mount := range containerConfig.Spec.Mounts {
+ 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
@@ -136,10 +177,18 @@ func GenerateContainerFilterFuncs(filter, filterValue string, r *libpod.Runtime)
if err != nil {
return false
}
- return hcStatus == filterValue
+ for _, filterValue := range filterValues {
+ if hcStatus == filterValue {
+ return true
+ }
+ }
+ return false
}, nil
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 {
return nil, err
}
diff --git a/libpod/filters/pods.go b/libpod/filters/pods.go
index 3cd97728f..17b3f3ca9 100644
--- a/libpod/filters/pods.go
+++ b/libpod/filters/pods.go
@@ -1,7 +1,6 @@
package lpfilters
import (
- "regexp"
"strconv"
"strings"
@@ -9,13 +8,12 @@ import (
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/util"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
)
// GeneratePodFilterFunc takes a filter and filtervalue (key, value)
// and generates a libpod function that can be used to filter
// pods
-func GeneratePodFilterFunc(filter, filterValue string) (
+func GeneratePodFilterFunc(filter string, filterValues []string) (
func(pod *libpod.Pod) bool, error) {
switch filter {
case "ctr-ids":
@@ -24,7 +22,10 @@ func GeneratePodFilterFunc(filter, filterValue string) (
if err != nil {
return false
}
- return util.StringInSlice(filterValue, ctrIds)
+ for _, id := range ctrIds {
+ return util.StringMatchRegexSlice(id, filterValues)
+ }
+ return false
}, nil
case "ctr-names":
return func(p *libpod.Pod) bool {
@@ -33,9 +34,7 @@ func GeneratePodFilterFunc(filter, filterValue string) (
return false
}
for _, ctr := range ctrs {
- if filterValue == ctr.Name() {
- return true
- }
+ return util.StringMatchRegexSlice(ctr.Name(), filterValues)
}
return false
}, nil
@@ -45,18 +44,22 @@ func GeneratePodFilterFunc(filter, filterValue string) (
if err != nil {
return false
}
-
- fVint, err2 := strconv.Atoi(filterValue)
- if err2 != nil {
- return false
+ for _, filterValue := range filterValues {
+ fVint, err2 := strconv.Atoi(filterValue)
+ if err2 != nil {
+ return false
+ }
+ if len(ctrIds) == fVint {
+ return true
+ }
}
- return len(ctrIds) == fVint
+ return false
}, nil
case "ctr-status":
- if !util.StringInSlice(filterValue,
- []string{"created", "restarting", "running", "paused",
- "exited", "unknown"}) {
- return nil, errors.Errorf("%s is not a valid status", filterValue)
+ for _, filterValue := range filterValues {
+ if !util.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
+ return nil, errors.Errorf("%s is not a valid status", filterValue)
+ }
}
return func(p *libpod.Pod) bool {
ctrStatuses, err := p.Status()
@@ -67,55 +70,69 @@ func GeneratePodFilterFunc(filter, filterValue string) (
state := ctrStatus.String()
if ctrStatus == define.ContainerStateConfigured {
state = "created"
+ } else if ctrStatus == define.ContainerStateStopped {
+ state = "exited"
}
- if state == filterValue {
- return true
+ for _, filterValue := range filterValues {
+ if filterValue == "stopped" {
+ filterValue = "exited"
+ }
+ if state == filterValue {
+ return true
+ }
}
}
return false
}, nil
case "id":
return func(p *libpod.Pod) bool {
- return strings.Contains(p.ID(), filterValue)
+ return util.StringMatchRegexSlice(p.ID(), filterValues)
}, nil
case "name":
return func(p *libpod.Pod) bool {
- match, err := regexp.MatchString(filterValue, p.Name())
- if err != nil {
- logrus.Errorf("Failed to compile regex for 'name' filter: %v", err)
- return false
- }
- return match
+ return util.StringMatchRegexSlice(p.Name(), filterValues)
}, nil
case "status":
- if !util.StringInSlice(filterValue, []string{"stopped", "running", "paused", "exited", "dead", "created", "degraded"}) {
- return nil, errors.Errorf("%s is not a valid pod status", filterValue)
+ for _, filterValue := range filterValues {
+ if !util.StringInSlice(filterValue, []string{"stopped", "running", "paused", "exited", "dead", "created", "degraded"}) {
+ return nil, errors.Errorf("%s is not a valid pod status", filterValue)
+ }
}
return func(p *libpod.Pod) bool {
status, err := p.GetPodStatus()
if err != nil {
return false
}
- if strings.ToLower(status) == filterValue {
- return true
+ for _, filterValue := range filterValues {
+ if strings.ToLower(status) == filterValue {
+ return true
+ }
}
return false
}, nil
case "label":
- var filterArray = strings.SplitN(filterValue, "=", 2)
- var filterKey = filterArray[0]
- if len(filterArray) > 1 {
- filterValue = filterArray[1]
- } else {
- filterValue = ""
- }
return func(p *libpod.Pod) bool {
- for labelKey, labelValue := range p.Labels() {
- if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
- return true
+ labels := p.Labels()
+ for _, filterValue := range filterValues {
+ matched := false
+ 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 false
+ return true
}, nil
}
return nil, errors.Errorf("%s is an invalid filter", filter)