github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/libpod/events/filters.go (about) 1 package events 2 3 import ( 4 "strings" 5 "time" 6 7 "github.com/hanks177/podman/v4/pkg/util" 8 "github.com/pkg/errors" 9 ) 10 11 func generateEventFilter(filter, filterValue string) (func(e *Event) bool, error) { 12 switch strings.ToUpper(filter) { 13 case "CONTAINER": 14 return func(e *Event) bool { 15 if e.Type != Container { 16 return false 17 } 18 if e.Name == filterValue { 19 return true 20 } 21 return strings.HasPrefix(e.ID, filterValue) 22 }, nil 23 case "EVENT", "STATUS": 24 return func(e *Event) bool { 25 return string(e.Status) == filterValue 26 }, nil 27 case "IMAGE": 28 return func(e *Event) bool { 29 if e.Type != Image { 30 return false 31 } 32 if e.Name == filterValue { 33 return true 34 } 35 return strings.HasPrefix(e.ID, filterValue) 36 }, nil 37 case "POD": 38 return func(e *Event) bool { 39 if e.Type != Pod { 40 return false 41 } 42 if e.Name == filterValue { 43 return true 44 } 45 return strings.HasPrefix(e.ID, filterValue) 46 }, nil 47 case "VOLUME": 48 return func(e *Event) bool { 49 if e.Type != Volume { 50 return false 51 } 52 return strings.HasPrefix(e.ID, filterValue) 53 }, nil 54 case "TYPE": 55 return func(e *Event) bool { 56 return string(e.Type) == filterValue 57 }, nil 58 59 case "LABEL": 60 return func(e *Event) bool { 61 var found bool 62 // iterate labels and see if we match a key and value 63 for eventKey, eventValue := range e.Attributes { 64 filterValueSplit := strings.SplitN(filterValue, "=", 2) 65 // if the filter isn't right, just return false 66 if len(filterValueSplit) < 2 { 67 return false 68 } 69 if eventKey == filterValueSplit[0] && eventValue == filterValueSplit[1] { 70 found = true 71 break 72 } 73 } 74 return found 75 }, nil 76 } 77 return nil, errors.Errorf("%s is an invalid filter", filter) 78 } 79 80 func generateEventSinceOption(timeSince time.Time) func(e *Event) bool { 81 return func(e *Event) bool { 82 return e.Time.After(timeSince) 83 } 84 } 85 86 func generateEventUntilOption(timeUntil time.Time) func(e *Event) bool { 87 return func(e *Event) bool { 88 return e.Time.Before(timeUntil) 89 } 90 } 91 92 func parseFilter(filter string) (string, string, error) { 93 filterSplit := strings.SplitN(filter, "=", 2) 94 if len(filterSplit) != 2 { 95 return "", "", errors.Errorf("%s is an invalid filter", filter) 96 } 97 return filterSplit[0], filterSplit[1], nil 98 } 99 100 // applyFilters applies the EventFilter slices in sequence. Filters under the 101 // same key are disjunctive while each key must match (conjuctive). 102 func applyFilters(event *Event, filterMap map[string][]EventFilter) bool { 103 for _, filters := range filterMap { 104 success := false 105 for _, filter := range filters { 106 if filter(event) { 107 success = true 108 break 109 } 110 } 111 if !success { 112 return false 113 } 114 } 115 return true 116 } 117 118 // generateEventFilter parses the specified filters into a filter map that can 119 // later on be used to filter events. Keys are conjunctive, values are 120 // disjunctive. 121 func generateEventFilters(filters []string, since, until string) (map[string][]EventFilter, error) { 122 filterMap := make(map[string][]EventFilter) 123 for _, filter := range filters { 124 key, val, err := parseFilter(filter) 125 if err != nil { 126 return nil, err 127 } 128 filterFunc, err := generateEventFilter(key, val) 129 if err != nil { 130 return nil, err 131 } 132 filterSlice := filterMap[key] 133 filterSlice = append(filterSlice, filterFunc) 134 filterMap[key] = filterSlice 135 } 136 137 if len(since) > 0 { 138 timeSince, err := util.ParseInputTime(since, true) 139 if err != nil { 140 return nil, errors.Wrapf(err, "unable to convert since time of %s", since) 141 } 142 filterFunc := generateEventSinceOption(timeSince) 143 filterMap["since"] = []EventFilter{filterFunc} 144 } 145 146 if len(until) > 0 { 147 timeUntil, err := util.ParseInputTime(until, false) 148 if err != nil { 149 return nil, errors.Wrapf(err, "unable to convert until time of %s", until) 150 } 151 filterFunc := generateEventUntilOption(timeUntil) 152 filterMap["until"] = []EventFilter{filterFunc} 153 } 154 return filterMap, nil 155 }