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 }