github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/domain/filters/pods.go (about)

     1  package filters
     2  
     3  import (
     4  	"strconv"
     5  	"strings"
     6  
     7  	cutil "github.com/containers/common/pkg/util"
     8  	"github.com/hanks177/podman/v4/libpod"
     9  	"github.com/hanks177/podman/v4/libpod/define"
    10  	"github.com/hanks177/podman/v4/pkg/util"
    11  	"github.com/pkg/errors"
    12  )
    13  
    14  // GeneratePodFilterFunc takes a filter and filtervalue (key, value)
    15  // and generates a libpod function that can be used to filter
    16  // pods
    17  func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runtime) (
    18  	func(pod *libpod.Pod) bool, error) {
    19  	switch filter {
    20  	case "ctr-ids":
    21  		return func(p *libpod.Pod) bool {
    22  			ctrIds, err := p.AllContainersByID()
    23  			if err != nil {
    24  				return false
    25  			}
    26  			for _, id := range ctrIds {
    27  				return util.StringMatchRegexSlice(id, filterValues)
    28  			}
    29  			return false
    30  		}, nil
    31  	case "ctr-names":
    32  		return func(p *libpod.Pod) bool {
    33  			ctrs, err := p.AllContainers()
    34  			if err != nil {
    35  				return false
    36  			}
    37  			for _, ctr := range ctrs {
    38  				return util.StringMatchRegexSlice(ctr.Name(), filterValues)
    39  			}
    40  			return false
    41  		}, nil
    42  	case "ctr-number":
    43  		return func(p *libpod.Pod) bool {
    44  			ctrIds, err := p.AllContainersByID()
    45  			if err != nil {
    46  				return false
    47  			}
    48  			for _, filterValue := range filterValues {
    49  				fVint, err2 := strconv.Atoi(filterValue)
    50  				if err2 != nil {
    51  					return false
    52  				}
    53  				if len(ctrIds) == fVint {
    54  					return true
    55  				}
    56  			}
    57  			return false
    58  		}, nil
    59  	case "ctr-status":
    60  		for _, filterValue := range filterValues {
    61  			if !cutil.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
    62  				return nil, errors.Errorf("%s is not a valid status", filterValue)
    63  			}
    64  		}
    65  		return func(p *libpod.Pod) bool {
    66  			ctrStatuses, err := p.Status()
    67  			if err != nil {
    68  				return false
    69  			}
    70  			for _, ctrStatus := range ctrStatuses {
    71  				state := ctrStatus.String()
    72  				if ctrStatus == define.ContainerStateConfigured {
    73  					state = "created"
    74  				} else if ctrStatus == define.ContainerStateStopped {
    75  					state = "exited"
    76  				}
    77  				for _, filterValue := range filterValues {
    78  					if filterValue == "stopped" {
    79  						filterValue = "exited"
    80  					}
    81  					if state == filterValue {
    82  						return true
    83  					}
    84  				}
    85  			}
    86  			return false
    87  		}, nil
    88  	case "id":
    89  		return func(p *libpod.Pod) bool {
    90  			return util.StringMatchRegexSlice(p.ID(), filterValues)
    91  		}, nil
    92  	case "name":
    93  		return func(p *libpod.Pod) bool {
    94  			return util.StringMatchRegexSlice(p.Name(), filterValues)
    95  		}, nil
    96  	case "status":
    97  		for _, filterValue := range filterValues {
    98  			if !cutil.StringInSlice(filterValue, []string{"stopped", "running", "paused", "exited", "dead", "created", "degraded"}) {
    99  				return nil, errors.Errorf("%s is not a valid pod status", filterValue)
   100  			}
   101  		}
   102  		return func(p *libpod.Pod) bool {
   103  			status, err := p.GetPodStatus()
   104  			if err != nil {
   105  				return false
   106  			}
   107  			for _, filterValue := range filterValues {
   108  				if strings.ToLower(status) == filterValue {
   109  					return true
   110  				}
   111  			}
   112  			return false
   113  		}, nil
   114  	case "label":
   115  		return func(p *libpod.Pod) bool {
   116  			labels := p.Labels()
   117  			return util.MatchLabelFilters(filterValues, labels)
   118  		}, nil
   119  	case "until":
   120  		return func(p *libpod.Pod) bool {
   121  			until, err := util.ComputeUntilTimestamp(filterValues)
   122  			if err != nil {
   123  				return false
   124  			}
   125  			if p.CreatedTime().Before(until) {
   126  				return true
   127  			}
   128  			return false
   129  		}, nil
   130  	case "network":
   131  		var inputNetNames []string
   132  		for _, val := range filterValues {
   133  			net, err := r.Network().NetworkInspect(val)
   134  			if err != nil {
   135  				if errors.Is(err, define.ErrNoSuchNetwork) {
   136  					continue
   137  				}
   138  				return nil, err
   139  			}
   140  			inputNetNames = append(inputNetNames, net.Name)
   141  		}
   142  		return func(p *libpod.Pod) bool {
   143  			infra, err := p.InfraContainer()
   144  			// no infra, quick out
   145  			if err != nil {
   146  				return false
   147  			}
   148  			networks, err := infra.Networks()
   149  			// if err or no networks, quick out
   150  			if err != nil || len(networks) == 0 {
   151  				return false
   152  			}
   153  			for _, net := range networks {
   154  				if cutil.StringInSlice(net, inputNetNames) {
   155  					return true
   156  				}
   157  			}
   158  			return false
   159  		}, nil
   160  	}
   161  	return nil, errors.Errorf("%s is an invalid filter", filter)
   162  }