github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/libpod/filters/pods.go (about)

     1  package lpfilters
     2  
     3  import (
     4  	"strconv"
     5  	"strings"
     6  
     7  	"github.com/containers/podman/v2/libpod"
     8  	"github.com/containers/podman/v2/libpod/define"
     9  	"github.com/containers/podman/v2/pkg/util"
    10  	"github.com/pkg/errors"
    11  )
    12  
    13  // GeneratePodFilterFunc takes a filter and filtervalue (key, value)
    14  // and generates a libpod function that can be used to filter
    15  // pods
    16  func GeneratePodFilterFunc(filter string, filterValues []string) (
    17  	func(pod *libpod.Pod) bool, error) {
    18  	switch filter {
    19  	case "ctr-ids":
    20  		return func(p *libpod.Pod) bool {
    21  			ctrIds, err := p.AllContainersByID()
    22  			if err != nil {
    23  				return false
    24  			}
    25  			for _, id := range ctrIds {
    26  				return util.StringMatchRegexSlice(id, filterValues)
    27  			}
    28  			return false
    29  		}, nil
    30  	case "ctr-names":
    31  		return func(p *libpod.Pod) bool {
    32  			ctrs, err := p.AllContainers()
    33  			if err != nil {
    34  				return false
    35  			}
    36  			for _, ctr := range ctrs {
    37  				return util.StringMatchRegexSlice(ctr.Name(), filterValues)
    38  			}
    39  			return false
    40  		}, nil
    41  	case "ctr-number":
    42  		return func(p *libpod.Pod) bool {
    43  			ctrIds, err := p.AllContainersByID()
    44  			if err != nil {
    45  				return false
    46  			}
    47  			for _, filterValue := range filterValues {
    48  				fVint, err2 := strconv.Atoi(filterValue)
    49  				if err2 != nil {
    50  					return false
    51  				}
    52  				if len(ctrIds) == fVint {
    53  					return true
    54  				}
    55  			}
    56  			return false
    57  		}, nil
    58  	case "ctr-status":
    59  		for _, filterValue := range filterValues {
    60  			if !util.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
    61  				return nil, errors.Errorf("%s is not a valid status", filterValue)
    62  			}
    63  		}
    64  		return func(p *libpod.Pod) bool {
    65  			ctrStatuses, err := p.Status()
    66  			if err != nil {
    67  				return false
    68  			}
    69  			for _, ctrStatus := range ctrStatuses {
    70  				state := ctrStatus.String()
    71  				if ctrStatus == define.ContainerStateConfigured {
    72  					state = "created"
    73  				} else if ctrStatus == define.ContainerStateStopped {
    74  					state = "exited"
    75  				}
    76  				for _, filterValue := range filterValues {
    77  					if filterValue == "stopped" {
    78  						filterValue = "exited"
    79  					}
    80  					if state == filterValue {
    81  						return true
    82  					}
    83  				}
    84  			}
    85  			return false
    86  		}, nil
    87  	case "id":
    88  		return func(p *libpod.Pod) bool {
    89  			return util.StringMatchRegexSlice(p.ID(), filterValues)
    90  		}, nil
    91  	case "name":
    92  		return func(p *libpod.Pod) bool {
    93  			return util.StringMatchRegexSlice(p.Name(), filterValues)
    94  		}, nil
    95  	case "status":
    96  		for _, filterValue := range filterValues {
    97  			if !util.StringInSlice(filterValue, []string{"stopped", "running", "paused", "exited", "dead", "created", "degraded"}) {
    98  				return nil, errors.Errorf("%s is not a valid pod status", filterValue)
    99  			}
   100  		}
   101  		return func(p *libpod.Pod) bool {
   102  			status, err := p.GetPodStatus()
   103  			if err != nil {
   104  				return false
   105  			}
   106  			for _, filterValue := range filterValues {
   107  				if strings.ToLower(status) == filterValue {
   108  					return true
   109  				}
   110  			}
   111  			return false
   112  		}, nil
   113  	case "label":
   114  		return func(p *libpod.Pod) bool {
   115  			labels := p.Labels()
   116  			for _, filterValue := range filterValues {
   117  				matched := false
   118  				filterArray := strings.SplitN(filterValue, "=", 2)
   119  				filterKey := filterArray[0]
   120  				if len(filterArray) > 1 {
   121  					filterValue = filterArray[1]
   122  				} else {
   123  					filterValue = ""
   124  				}
   125  				for labelKey, labelValue := range labels {
   126  					if labelKey == filterKey && ("" == filterValue || labelValue == filterValue) {
   127  						matched = true
   128  						break
   129  					}
   130  				}
   131  				if !matched {
   132  					return false
   133  				}
   134  			}
   135  			return true
   136  		}, nil
   137  	}
   138  	return nil, errors.Errorf("%s is an invalid filter", filter)
   139  }