filters: use new FilterID function from c/common

Remove code duplication and use the new FilterID function from
c/common. Also remove the duplicated ComputeUntilTimestamp in podman use
the one from c/common as well.

Signed-off-by: Paul Holzinger <pholzing@redhat.com>
This commit is contained in:
Paul Holzinger
2023-06-13 16:41:38 +02:00
parent 63f5116ad3
commit 8a90765b90
6 changed files with 23 additions and 124 deletions

View File

@ -5,7 +5,6 @@ import (
"io"
"github.com/containers/common/libnetwork/types"
"github.com/containers/storage/pkg/regexp"
)
var (
@ -18,9 +17,6 @@ var (
// This must NOT be changed from outside of Libpod. It should be a
// constant, but Go won't let us do that.
NameRegex = types.NameRegex
// NotHexRegex is a regular expression to check if a string is
// a hexadecimal string.
NotHexRegex = regexp.Delayed(`[^0-9a-fA-F]`)
// RegexError is thrown in presence of an invalid container/pod name.
RegexError = types.RegexError
)

View File

@ -3,16 +3,14 @@ package filters
import (
"errors"
"fmt"
"regexp"
"strconv"
"strings"
"time"
"github.com/containers/common/pkg/filters"
cutil "github.com/containers/common/pkg/util"
"github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/util"
)
// GenerateContainerFilterFuncs return ContainerFilter functions based of filter.
@ -20,18 +18,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
switch filter {
case "id":
return func(c *libpod.Container) bool {
for _, want := range filterValues {
isRegex := define.NotHexRegex.MatchString(want)
if isRegex {
match, err := regexp.MatchString(want, c.ID())
if err == nil && match {
return true
}
} else if strings.HasPrefix(c.ID(), strings.ToLower(want)) {
return true
}
}
return false
return util.FilterID(c.ID(), filterValues)
}, nil
case "label":
// we have to match that all given labels exits on that container
@ -270,7 +257,7 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo
return false
}
for _, net := range networks {
if cutil.StringInSlice(net, inputNetNames) {
if util.StringInSlice(net, inputNetNames) {
return true
}
}
@ -324,7 +311,7 @@ func GeneratePruneContainerFilterFuncs(filter string, filterValues []string, r *
}
func prepareUntilFilterFunc(filterValues []string) (func(container *libpod.Container) bool, error) {
until, err := util.ComputeUntilTimestamp(filterValues)
until, err := filters.ComputeUntilTimestamp(filterValues)
if err != nil {
return nil, err
}

View File

@ -3,15 +3,13 @@ package filters
import (
"errors"
"fmt"
"regexp"
"strconv"
"strings"
"github.com/containers/common/pkg/filters"
cutil "github.com/containers/common/pkg/util"
"github.com/containers/common/pkg/util"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/libpod/define"
"github.com/containers/podman/v4/pkg/util"
)
// GeneratePodFilterFunc takes a filter and filtervalue (key, value)
@ -26,26 +24,11 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
if err != nil {
return false
}
for _, want := range filterValues {
isRegex := define.NotHexRegex.MatchString(want)
if isRegex {
re, err := regexp.Compile(want)
if err != nil {
return false
}
for _, id := range ctrIds {
if re.MatchString(id) {
if util.FilterID(id, filterValues) {
return true
}
}
} else {
for _, id := range ctrIds {
if strings.HasPrefix(id, strings.ToLower(want)) {
return true
}
}
}
}
return false
}, nil
case "ctr-names":
@ -78,7 +61,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
}, nil
case "ctr-status":
for _, filterValue := range filterValues {
if !cutil.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
if !util.StringInSlice(filterValue, []string{"created", "running", "paused", "stopped", "exited", "unknown"}) {
return nil, fmt.Errorf("%s is not a valid status", filterValue)
}
}
@ -107,18 +90,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
}, nil
case "id":
return func(p *libpod.Pod) bool {
for _, want := range filterValues {
isRegex := define.NotHexRegex.MatchString(want)
if isRegex {
match, err := regexp.MatchString(want, p.ID())
if err == nil && match {
return true
}
} else if strings.HasPrefix(p.ID(), strings.ToLower(want)) {
return true
}
}
return false
return util.FilterID(p.ID(), filterValues)
}, nil
case "name":
return func(p *libpod.Pod) bool {
@ -126,7 +98,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
}, nil
case "status":
for _, filterValue := range filterValues {
if !cutil.StringInSlice(filterValue, []string{"stopped", "running", "paused", "exited", "dead", "created", "degraded"}) {
if !util.StringInSlice(filterValue, []string{"stopped", "running", "paused", "exited", "dead", "created", "degraded"}) {
return nil, fmt.Errorf("%s is not a valid pod status", filterValue)
}
}
@ -149,7 +121,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
}, nil
case "until":
return func(p *libpod.Pod) bool {
until, err := util.ComputeUntilTimestamp(filterValues)
until, err := filters.ComputeUntilTimestamp(filterValues)
if err != nil {
return false
}
@ -182,7 +154,7 @@ func GeneratePodFilterFunc(filter string, filterValues []string, r *libpod.Runti
return false
}
for _, net := range networks {
if cutil.StringInSlice(net, inputNetNames) {
if util.StringInSlice(net, inputNetNames) {
return true
}
}

View File

@ -6,14 +6,13 @@ import (
"regexp"
"strings"
pruneFilters "github.com/containers/common/pkg/filters"
"github.com/containers/common/pkg/filters"
"github.com/containers/podman/v4/libpod"
"github.com/containers/podman/v4/pkg/util"
)
func GenerateVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) {
func GenerateVolumeFilters(filtersValues url.Values) ([]libpod.VolumeFilter, error) {
var vf []libpod.VolumeFilter
for filter, v := range filters {
for filter, v := range filtersValues {
for _, val := range v {
switch filter {
case "name":
@ -37,12 +36,12 @@ func GenerateVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) {
case "label":
filter := val
vf = append(vf, func(v *libpod.Volume) bool {
return pruneFilters.MatchLabelFilters([]string{filter}, v.Labels())
return filters.MatchLabelFilters([]string{filter}, v.Labels())
})
case "label!":
filter := val
vf = append(vf, func(v *libpod.Volume) bool {
return !pruneFilters.MatchLabelFilters([]string{filter}, v.Labels())
return !filters.MatchLabelFilters([]string{filter}, v.Labels())
})
case "opt":
filterArray := strings.SplitN(val, "=", 2)
@ -98,20 +97,20 @@ func GenerateVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) {
return vf, nil
}
func GeneratePruneVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, error) {
func GeneratePruneVolumeFilters(filtersValues url.Values) ([]libpod.VolumeFilter, error) {
var vf []libpod.VolumeFilter
for filter, v := range filters {
for filter, v := range filtersValues {
for _, val := range v {
filterVal := val
switch filter {
case "label":
vf = append(vf, func(v *libpod.Volume) bool {
return pruneFilters.MatchLabelFilters([]string{filterVal}, v.Labels())
return filters.MatchLabelFilters([]string{filterVal}, v.Labels())
})
case "label!":
filter := val
vf = append(vf, func(v *libpod.Volume) bool {
return !pruneFilters.MatchLabelFilters([]string{filter}, v.Labels())
return !filters.MatchLabelFilters([]string{filter}, v.Labels())
})
case "until":
f, err := createUntilFilterVolumeFunction(filterVal)
@ -128,7 +127,7 @@ func GeneratePruneVolumeFilters(filters url.Values) ([]libpod.VolumeFilter, erro
}
func createUntilFilterVolumeFunction(filter string) (libpod.VolumeFilter, error) {
until, err := util.ComputeUntilTimestamp([]string{filter})
until, err := filters.ComputeUntilTimestamp([]string{filter})
if err != nil {
return nil, err
}

View File

@ -2,32 +2,11 @@ package util
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strings"
"time"
"github.com/containers/podman/v4/pkg/timetype"
)
// ComputeUntilTimestamp extracts until timestamp from filters
func ComputeUntilTimestamp(filterValues []string) (time.Time, error) {
invalid := time.Time{}
if len(filterValues) != 1 {
return invalid, errors.New("specify exactly one timestamp for until")
}
ts, err := timetype.GetTimestamp(filterValues[0], time.Now())
if err != nil {
return invalid, err
}
seconds, nanoseconds, err := timetype.ParseTimestamps(ts, 0)
if err != nil {
return invalid, err
}
return time.Unix(seconds, nanoseconds), nil
}
// filtersFromRequests extracts the "filters" parameter from the specified
// http.Request. The parameter can either be a `map[string][]string` as done
// in new versions of Docker and libpod, or a `map[string]map[string]bool` as

View File

@ -79,37 +79,3 @@ func TestMatchLabelFilters(t *testing.T) {
})
}
}
func TestComputeUntilTimestamp(t *testing.T) {
tests := []struct {
name string
args []string
wantErr bool
}{
{
name: "Return error when more values in list",
args: []string{"5h", "6s"},
wantErr: true,
},
{
name: "Return error when invalid time",
args: []string{"invalidTime"},
wantErr: true,
},
{
name: "Do not return error when correct time format supplied",
args: []string{"44m"},
wantErr: false,
},
}
for _, tt := range tests {
tt := tt
t.Run(tt.name, func(t *testing.T) {
_, err := ComputeUntilTimestamp(tt.args)
if (err != nil) != tt.wantErr {
t.Errorf("ComputeUntilTimestamp() error = %v, wantErr %v", err, tt.wantErr)
return
}
})
}
}