client: add Filters type

Add a new type to use for building filter predicates for API requests,
replacing "./api/types/filters".Args in the client. Remove the now
unused api/types/filters package.

Signed-off-by: Cory Snider <csnider@mirantis.com>
This commit is contained in:
Cory Snider
2025-10-06 15:18:41 -04:00
parent 778e5bfad3
commit 7ea066c8d1
106 changed files with 380 additions and 853 deletions

View File

@@ -1,24 +0,0 @@
package filters
import "fmt"
// invalidFilter indicates that the provided filter or its value is invalid
type invalidFilter struct {
Filter string
Value []string
}
func (e invalidFilter) Error() string {
msg := "invalid filter"
if e.Filter != "" {
msg += " '" + e.Filter
if e.Value != nil {
msg = fmt.Sprintf("%s=%s", msg, e.Value)
}
msg += "'"
}
return msg
}
// InvalidParameter marks this error as ErrInvalidParameter
func (e invalidFilter) InvalidParameter() {}

View File

@@ -1,65 +0,0 @@
/*
Package filters provides tools for encoding a mapping of keys to a set of
multiple values.
*/
package filters
import (
"encoding/json"
)
// Args stores a mapping of keys to a set of multiple values.
type Args struct {
fields map[string]map[string]bool
}
// KeyValuePair are used to initialize a new Args
type KeyValuePair struct {
Key string
Value string
}
// Arg creates a new KeyValuePair for initializing Args
func Arg(key, value string) KeyValuePair {
return KeyValuePair{Key: key, Value: value}
}
// NewArgs returns a new Args populated with the initial args
func NewArgs(initialArgs ...KeyValuePair) Args {
args := Args{fields: map[string]map[string]bool{}}
for _, arg := range initialArgs {
args.Add(arg.Key, arg.Value)
}
return args
}
// MarshalJSON returns a JSON byte representation of the Args
func (args Args) MarshalJSON() ([]byte, error) {
if len(args.fields) == 0 {
return []byte("{}"), nil
}
return json.Marshal(args.fields)
}
// ToJSON returns the Args as a JSON encoded string
func ToJSON(a Args) (string, error) {
if a.Len() == 0 {
return "", nil
}
buf, err := json.Marshal(a)
return string(buf), err
}
// Add a new value to the set of values
func (args Args) Add(key, value string) {
if _, ok := args.fields[key]; ok {
args.fields[key][value] = true
} else {
args.fields[key] = map[string]bool{value: true}
}
}
// Len returns the number of keys in the mapping
func (args Args) Len() int {
return len(args.fields)
}

View File

@@ -1,62 +0,0 @@
package filters
import (
"encoding/json"
"testing"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestMarshalJSON(t *testing.T) {
a := NewArgs(
Arg("created", "today"),
Arg("image.name", "ubuntu*"),
Arg("image.name", "*untu"),
)
s, err := a.MarshalJSON()
assert.Check(t, err)
const expected = `{"created":{"today":true},"image.name":{"*untu":true,"ubuntu*":true}}`
assert.Check(t, is.Equal(string(s), expected))
}
func TestMarshalJSONWithEmpty(t *testing.T) {
s, err := json.Marshal(NewArgs())
assert.Check(t, err)
const expected = `{}`
assert.Check(t, is.Equal(string(s), expected))
}
func TestToJSON(t *testing.T) {
a := NewArgs(
Arg("created", "today"),
Arg("image.name", "ubuntu*"),
Arg("image.name", "*untu"),
)
s, err := ToJSON(a)
assert.Check(t, err)
const expected = `{"created":{"today":true},"image.name":{"*untu":true,"ubuntu*":true}}`
assert.Check(t, is.Equal(s, expected))
}
func TestAdd(t *testing.T) {
f := NewArgs()
f.Add("status", "running")
v := f.fields["status"]
assert.Check(t, is.DeepEqual(v, []string{"running"}))
f.Add("status", "paused")
v = f.fields["status"]
assert.Check(t, is.Len(v, 2))
assert.Check(t, is.Contains(v, "running"))
assert.Check(t, is.Contains(v, "paused"))
}
func TestLen(t *testing.T) {
f := NewArgs()
assert.Check(t, is.Equal(f.Len(), 0))
f.Add("status", "running")
assert.Check(t, is.Equal(f.Len(), 1))
}

View File

@@ -8,7 +8,6 @@ import (
"strconv" "strconv"
"github.com/moby/moby/api/types/build" "github.com/moby/moby/api/types/build"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/versions" "github.com/moby/moby/api/types/versions"
) )
@@ -18,7 +17,7 @@ type BuildCachePruneOptions struct {
ReservedSpace int64 ReservedSpace int64
MaxUsedSpace int64 MaxUsedSpace int64
MinFreeSpace int64 MinFreeSpace int64
Filters filters.Args Filters Filters
} }
// BuildCachePruneResult holds the result from the BuildCachePrune method. // BuildCachePruneResult holds the result from the BuildCachePrune method.
@@ -49,11 +48,7 @@ func (cli *Client) BuildCachePrune(ctx context.Context, opts BuildCachePruneOpti
if opts.MinFreeSpace != 0 { if opts.MinFreeSpace != 0 {
query.Set("min-free-space", strconv.Itoa(int(opts.MinFreeSpace))) query.Set("min-free-space", strconv.Itoa(int(opts.MinFreeSpace)))
} }
f, err := filters.ToJSON(opts.Filters) opts.Filters.updateURLValues(query)
if err != nil {
return BuildCachePruneResult{}, fmt.Errorf("prune could not marshal filters option: %w", err)
}
query.Set("filters", f)
resp, err := cli.post(ctx, "/build/prune", query, nil, nil) resp, err := cli.post(ctx, "/build/prune", query, nil, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -8,7 +8,6 @@ import (
"github.com/moby/moby/api/types" "github.com/moby/moby/api/types"
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/events" "github.com/moby/moby/api/types/events"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/network" "github.com/moby/moby/api/types/network"
"github.com/moby/moby/api/types/plugin" "github.com/moby/moby/api/types/plugin"
@@ -89,7 +88,7 @@ type ContainerAPIClient interface {
ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error)
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options CopyToContainerOptions) error CopyToContainer(ctx context.Context, container, path string, content io.Reader, options CopyToContainerOptions) error
ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) ContainersPrune(ctx context.Context, pruneFilters Filters) (container.PruneReport, error)
} }
type ExecAPIClient interface { type ExecAPIClient interface {
@@ -119,7 +118,7 @@ type ImageAPIClient interface {
ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error) ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error)
ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, error) ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, error)
ImageTag(ctx context.Context, image, ref string) error ImageTag(ctx context.Context, image, ref string) error
ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error) ImagesPrune(ctx context.Context, pruneFilter Filters) (image.PruneReport, error)
ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (image.InspectResponse, error) ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (image.InspectResponse, error)
ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) ([]image.HistoryResponseItem, error) ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) ([]image.HistoryResponseItem, error)
@@ -136,7 +135,7 @@ type NetworkAPIClient interface {
NetworkInspectWithRaw(ctx context.Context, network string, options NetworkInspectOptions) (network.Inspect, []byte, error) NetworkInspectWithRaw(ctx context.Context, network string, options NetworkInspectOptions) (network.Inspect, []byte, error)
NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error) NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error)
NetworkRemove(ctx context.Context, network string) error NetworkRemove(ctx context.Context, network string) error
NetworksPrune(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error) NetworksPrune(ctx context.Context, pruneFilter Filters) (network.PruneReport, error)
} }
// NodeAPIClient defines API client methods for the nodes // NodeAPIClient defines API client methods for the nodes
@@ -149,7 +148,7 @@ type NodeAPIClient interface {
// PluginAPIClient defines API client methods for the plugins // PluginAPIClient defines API client methods for the plugins
type PluginAPIClient interface { type PluginAPIClient interface {
PluginList(ctx context.Context, filter filters.Args) (plugin.ListResponse, error) PluginList(ctx context.Context, filter Filters) (plugin.ListResponse, error)
PluginRemove(ctx context.Context, name string, options PluginRemoveOptions) error PluginRemove(ctx context.Context, name string, options PluginRemoveOptions) error
PluginEnable(ctx context.Context, name string, options PluginEnableOptions) error PluginEnable(ctx context.Context, name string, options PluginEnableOptions) error
PluginDisable(ctx context.Context, name string, options PluginDisableOptions) error PluginDisable(ctx context.Context, name string, options PluginDisableOptions) error
@@ -201,7 +200,7 @@ type VolumeAPIClient interface {
VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error) VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error)
VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, error) VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, error)
VolumeRemove(ctx context.Context, volumeID string, force bool) error VolumeRemove(ctx context.Context, volumeID string, force bool) error
VolumesPrune(ctx context.Context, pruneFilter filters.Args) (volume.PruneReport, error) VolumesPrune(ctx context.Context, pruneFilter Filters) (volume.PruneReport, error)
VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error
} }

View File

@@ -5,22 +5,13 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
) )
// ConfigList returns the list of configs. // ConfigList returns the list of configs.
func (cli *Client) ConfigList(ctx context.Context, options ConfigListOptions) ([]swarm.Config, error) { func (cli *Client) ConfigList(ctx context.Context, options ConfigListOptions) ([]swarm.Config, error) {
query := url.Values{} query := url.Values{}
options.Filters.updateURLValues(query)
if options.Filters.Len() > 0 {
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/configs", query, nil) resp, err := cli.get(ctx, "/configs", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -10,7 +10,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@@ -41,10 +40,9 @@ func TestConfigList(t *testing.T) {
}, },
{ {
options: ConfigListOptions{ options: ConfigListOptions{
Filters: filters.NewArgs( Filters: make(Filters).
filters.Arg("label", "label1"), Add("label", "label1").
filters.Arg("label", "label2"), Add("label", "label2"),
),
}, },
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"filters": `{"label":{"label1":true,"label2":true}}`, "filters": `{"label":{"label1":true,"label2":true}}`,

View File

@@ -7,7 +7,6 @@ import (
"strconv" "strconv"
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/filters"
) )
// ContainerListOptions holds parameters to list containers with. // ContainerListOptions holds parameters to list containers with.
@@ -18,7 +17,7 @@ type ContainerListOptions struct {
Since string Since string
Before string Before string
Limit int Limit int
Filters filters.Args Filters Filters
} }
// ContainerList returns the list of containers in the docker host. // ContainerList returns the list of containers in the docker host.
@@ -45,13 +44,7 @@ func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptio
query.Set("size", "1") query.Set("size", "1")
} }
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/containers/json", query, nil) resp, err := cli.get(ctx, "/containers/json", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -11,7 +11,6 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/filters"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
) )
@@ -86,11 +85,10 @@ func TestContainerList(t *testing.T) {
Size: true, Size: true,
All: true, All: true,
Since: "container", Since: "container",
Filters: filters.NewArgs( Filters: make(Filters).
filters.Arg("label", "label1"), Add("label", "label1").
filters.Arg("label", "label2"), Add("label", "label2").
filters.Arg("before", "container"), Add("before", "container"),
),
}) })
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Len(containers, 2)) assert.Check(t, is.Len(containers, 2))

View File

@@ -4,17 +4,15 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url"
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/filters"
) )
// ContainersPrune requests the daemon to delete unused data // ContainersPrune requests the daemon to delete unused data
func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) { func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters Filters) (container.PruneReport, error) {
query, err := getFiltersQuery(pruneFilters) query := url.Values{}
if err != nil { pruneFilters.updateURLValues(query)
return container.PruneReport{}, err
}
resp, err := cli.post(ctx, "/containers/prune", query, nil, nil) resp, err := cli.post(ctx, "/containers/prune", query, nil, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -10,7 +10,6 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/filters"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
) )
@@ -19,7 +18,7 @@ func TestContainersPruneError(t *testing.T) {
client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error"))) client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error")))
assert.NilError(t, err) assert.NilError(t, err)
_, err = client.ContainersPrune(context.Background(), filters.Args{}) _, err = client.ContainersPrune(context.Background(), Filters{})
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal)) assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
} }
@@ -27,11 +26,11 @@ func TestContainersPrune(t *testing.T) {
const expectedURL = "/containers/prune" const expectedURL = "/containers/prune"
listCases := []struct { listCases := []struct {
filters filters.Args filters Filters
expectedQueryParams map[string]string expectedQueryParams map[string]string
}{ }{
{ {
filters: filters.Args{}, filters: Filters{},
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",
@@ -39,7 +38,7 @@ func TestContainersPrune(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs(filters.Arg("dangling", "true")), filters: make(Filters).Add("dangling", "true"),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",
@@ -47,10 +46,9 @@ func TestContainersPrune(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs( filters: make(Filters).
filters.Arg("dangling", "true"), Add("dangling", "true").
filters.Arg("until", "2016-12-15T14:00"), Add("until", "2016-12-15T14:00"),
),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",
@@ -58,7 +56,7 @@ func TestContainersPrune(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs(filters.Arg("dangling", "false")), filters: make(Filters).Add("dangling", "false"),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",
@@ -66,11 +64,10 @@ func TestContainersPrune(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs( filters: make(Filters).
filters.Arg("dangling", "true"), Add("dangling", "true").
filters.Arg("label", "label1=foo"), Add("label", "label1=foo").
filters.Arg("label", "label2!=bar"), Add("label", "label2!=bar"),
),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",

46
client/filters.go Normal file
View File

@@ -0,0 +1,46 @@
package client
import (
"encoding/json"
"net/url"
)
// Filters describes a predicate for an API request.
//
// Each entry in the map is a filter term.
// Each term is evaluated against the set of values.
// A filter term is satisfied if any one of the values in the set is a match.
// An item matches the filters when all terms are satisfied.
//
// Like all other map types in Go, the zero value is empty and read-only.
type Filters map[string]map[string]bool
// Add appends values to the value-set of term.
//
// The receiver f is returned for chaining.
//
// f := make(Filters).Add("name", "foo", "bar").Add("status", "exited")
func (f Filters) Add(term string, values ...string) Filters {
if _, ok := f[term]; !ok {
f[term] = make(map[string]bool)
}
for _, v := range values {
f[term][v] = true
}
return f
}
// updateURLValues sets the "filters" key in values to the marshalled value of
// f, replacing any existing values. When f is empty, any existing "filters" key
// is removed.
func (f Filters) updateURLValues(values url.Values) {
if len(f) > 0 {
b, err := json.Marshal(f)
if err != nil {
panic(err) // Marshaling builtin types should never fail
}
values.Set("filters", string(b))
} else {
values.Del("filters")
}
}

48
client/filters_test.go Normal file
View File

@@ -0,0 +1,48 @@
package client
import (
"net/url"
"testing"
"gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp"
)
func TestFilters(t *testing.T) {
f := make(Filters).Add("foo", "bar", "baz", "bar").
Add("quux", "xyzzy").
Add("quux", "plugh")
f["lol"] = map[string]bool{"abc": true}
f.Add("lol", "def")
assert.Check(t, is.DeepEqual(f, Filters{
"foo": {"bar": true, "baz": true},
"quux": {"xyzzy": true, "plugh": true},
"lol": {"abc": true, "def": true},
}))
}
func TestFilters_UpdateURLValues(t *testing.T) {
v := url.Values{}
Filters(nil).updateURLValues(v)
assert.Check(t, is.DeepEqual(v, url.Values{}))
v = url.Values{"filters": []string{"bogus"}}
Filters(nil).updateURLValues(v)
assert.Check(t, is.DeepEqual(v, url.Values{}))
v = url.Values{}
Filters{}.updateURLValues(v)
assert.Check(t, is.DeepEqual(v, url.Values{}))
v = url.Values{"filters": []string{"bogus"}}
Filters{}.updateURLValues(v)
assert.Check(t, is.DeepEqual(v, url.Values{}))
v = url.Values{}
Filters{"foo": map[string]bool{"bar": true}}.updateURLValues(v)
assert.Check(t, is.DeepEqual(v, url.Values{"filters": []string{`{"foo":{"bar":true}}`}}))
v = url.Values{"filters": []string{"bogus"}}
Filters{"foo": map[string]bool{"bar": true}}.updateURLValues(v)
assert.Check(t, is.DeepEqual(v, url.Values{"filters": []string{`{"foo":{"bar":true}}`}}))
}

View File

@@ -5,7 +5,6 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/versions" "github.com/moby/moby/api/types/versions"
) )
@@ -30,13 +29,7 @@ func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]i
query := url.Values{} query := url.Values{}
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return images, err
}
query.Set("filters", filterJSON)
}
if options.All { if options.All {
query.Set("all", "1") query.Set("all", "1")
} }

View File

@@ -1,7 +1,5 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// ImageListOptions holds parameters to list images with. // ImageListOptions holds parameters to list images with.
type ImageListOptions struct { type ImageListOptions struct {
// All controls whether all images in the graph are filtered, or just // All controls whether all images in the graph are filtered, or just
@@ -9,7 +7,7 @@ type ImageListOptions struct {
All bool All bool
// Filters is a JSON-encoded set of filter arguments. // Filters is a JSON-encoded set of filter arguments.
Filters filters.Args Filters Filters
// SharedSize indicates whether the shared size of images should be computed. // SharedSize indicates whether the shared size of images should be computed.
SharedSize bool SharedSize bool

View File

@@ -12,7 +12,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@@ -55,11 +54,10 @@ func TestImageList(t *testing.T) {
}, },
{ {
options: ImageListOptions{ options: ImageListOptions{
Filters: filters.NewArgs( Filters: make(Filters).
filters.Arg("label", "label1"), Add("label", "label1").
filters.Arg("label", "label2"), Add("label", "label2").
filters.Arg("dangling", "true"), Add("dangling", "true"),
),
}, },
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"all": "", "all": "",
@@ -69,7 +67,7 @@ func TestImageList(t *testing.T) {
}, },
{ {
options: ImageListOptions{ options: ImageListOptions{
Filters: filters.NewArgs(filters.Arg("dangling", "false")), Filters: make(Filters).Add("dangling", "false"),
}, },
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"all": "", "all": "",

View File

@@ -4,17 +4,15 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
) )
// ImagesPrune requests the daemon to delete unused data // ImagesPrune requests the daemon to delete unused data
func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error) { func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters Filters) (image.PruneReport, error) {
query, err := getFiltersQuery(pruneFilters) query := url.Values{}
if err != nil { pruneFilters.updateURLValues(query)
return image.PruneReport{}, err
}
resp, err := cli.post(ctx, "/images/prune", query, nil, nil) resp, err := cli.post(ctx, "/images/prune", query, nil, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -11,7 +11,6 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/filters"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
) )
@@ -20,7 +19,7 @@ func TestImagesPruneError(t *testing.T) {
client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error"))) client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error")))
assert.NilError(t, err) assert.NilError(t, err)
_, err = client.ImagesPrune(context.Background(), filters.NewArgs()) _, err = client.ImagesPrune(context.Background(), nil)
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal)) assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
} }
@@ -28,11 +27,11 @@ func TestImagesPrune(t *testing.T) {
const expectedURL = "/images/prune" const expectedURL = "/images/prune"
listCases := []struct { listCases := []struct {
filters filters.Args filters Filters
expectedQueryParams map[string]string expectedQueryParams map[string]string
}{ }{
{ {
filters: filters.Args{}, filters: Filters{},
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",
@@ -40,7 +39,7 @@ func TestImagesPrune(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs(filters.Arg("dangling", "true")), filters: make(Filters).Add("dangling", "true"),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",
@@ -48,7 +47,7 @@ func TestImagesPrune(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs(filters.Arg("dangling", "false")), filters: make(Filters).Add("dangling", "false"),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",
@@ -56,11 +55,9 @@ func TestImagesPrune(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs( filters: make(Filters).
filters.Arg("dangling", "true"), Add("dangling", "true").
filters.Arg("label", "label1=foo"), Add("label", "label1=foo", "label2!=bar"),
filters.Arg("label", "label2!=bar"),
),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",

View File

@@ -8,7 +8,6 @@ import (
"strconv" "strconv"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/registry" "github.com/moby/moby/api/types/registry"
) )
@@ -22,13 +21,7 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options ImageSe
query.Set("limit", strconv.Itoa(options.Limit)) query.Set("limit", strconv.Itoa(options.Limit))
} }
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return results, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth) resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -2,8 +2,6 @@ package client
import ( import (
"context" "context"
"github.com/moby/moby/api/types/filters"
) )
// ImageSearchOptions holds parameters to search images with. // ImageSearchOptions holds parameters to search images with.
@@ -17,6 +15,6 @@ type ImageSearchOptions struct {
// //
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig]. // For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error) PrivilegeFunc func(context.Context) (string, error)
Filters filters.Args Filters Filters
Limit int Limit int
} }

View File

@@ -11,7 +11,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/registry" "github.com/moby/moby/api/types/registry"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@@ -133,10 +132,7 @@ func TestImageSearchWithoutErrors(t *testing.T) {
})) }))
assert.NilError(t, err) assert.NilError(t, err)
results, err := client.ImageSearch(context.Background(), "some-image", ImageSearchOptions{ results, err := client.ImageSearch(context.Background(), "some-image", ImageSearchOptions{
Filters: filters.NewArgs( Filters: make(Filters).Add("is-automated", "true").Add("stars", "3"),
filters.Arg("is-automated", "true"),
filters.Arg("stars", "3"),
),
}) })
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Len(results, 1)) assert.Check(t, is.Len(results, 1))

View File

@@ -5,20 +5,13 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/network" "github.com/moby/moby/api/types/network"
) )
// NetworkList returns the list of networks configured in the docker host. // NetworkList returns the list of networks configured in the docker host.
func (cli *Client) NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error) { func (cli *Client) NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error) {
query := url.Values{} query := url.Values{}
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
var networkResources []network.Summary var networkResources []network.Summary
resp, err := cli.get(ctx, "/networks", query, nil) resp, err := cli.get(ctx, "/networks", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -1,8 +1,6 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// NetworkListOptions holds parameters to filter the list of networks with. // NetworkListOptions holds parameters to filter the list of networks with.
type NetworkListOptions struct { type NetworkListOptions struct {
Filters filters.Args Filters Filters
} }

View File

@@ -10,7 +10,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/network" "github.com/moby/moby/api/types/network"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@@ -37,22 +36,21 @@ func TestNetworkList(t *testing.T) {
}, },
{ {
options: NetworkListOptions{ options: NetworkListOptions{
Filters: filters.NewArgs(filters.Arg("dangling", "false")), Filters: make(Filters).Add("dangling", "false"),
}, },
expectedFilters: `{"dangling":{"false":true}}`, expectedFilters: `{"dangling":{"false":true}}`,
}, },
{ {
options: NetworkListOptions{ options: NetworkListOptions{
Filters: filters.NewArgs(filters.Arg("dangling", "true")), Filters: make(Filters).Add("dangling", "true"),
}, },
expectedFilters: `{"dangling":{"true":true}}`, expectedFilters: `{"dangling":{"true":true}}`,
}, },
{ {
options: NetworkListOptions{ options: NetworkListOptions{
Filters: filters.NewArgs( Filters: make(Filters).
filters.Arg("label", "label1"), Add("label", "label1").
filters.Arg("label", "label2"), Add("label", "label2"),
),
}, },
expectedFilters: `{"label":{"label1":true,"label2":true}}`, expectedFilters: `{"label":{"label1":true,"label2":true}}`,
}, },

View File

@@ -4,17 +4,15 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/network" "github.com/moby/moby/api/types/network"
) )
// NetworksPrune requests the daemon to delete unused networks // NetworksPrune requests the daemon to delete unused networks
func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) { func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters Filters) (network.PruneReport, error) {
query, err := getFiltersQuery(pruneFilters) query := url.Values{}
if err != nil { pruneFilters.updateURLValues(query)
return network.PruneReport{}, err
}
resp, err := cli.post(ctx, "/networks/prune", query, nil, nil) resp, err := cli.post(ctx, "/networks/prune", query, nil, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -9,7 +9,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/network" "github.com/moby/moby/api/types/network"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@@ -21,7 +20,7 @@ func TestNetworksPruneError(t *testing.T) {
) )
assert.NilError(t, err) assert.NilError(t, err)
_, err = client.NetworksPrune(context.Background(), filters.NewArgs()) _, err = client.NetworksPrune(context.Background(), nil)
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal)) assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
} }
@@ -29,11 +28,11 @@ func TestNetworksPrune(t *testing.T) {
const expectedURL = "/networks/prune" const expectedURL = "/networks/prune"
listCases := []struct { listCases := []struct {
filters filters.Args filters Filters
expectedQueryParams map[string]string expectedQueryParams map[string]string
}{ }{
{ {
filters: filters.Args{}, filters: Filters{},
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",
@@ -41,7 +40,7 @@ func TestNetworksPrune(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs(filters.Arg("dangling", "true")), filters: make(Filters).Add("dangling", "true"),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",
@@ -49,7 +48,7 @@ func TestNetworksPrune(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs(filters.Arg("dangling", "false")), filters: make(Filters).Add("dangling", "false"),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",
@@ -57,11 +56,10 @@ func TestNetworksPrune(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs( filters: make(Filters).
filters.Arg("dangling", "true"), Add("dangling", "true").
filters.Arg("label", "label1=foo"), Add("label", "label1=foo").
filters.Arg("label", "label2!=bar"), Add("label", "label2!=bar"),
),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"until": "", "until": "",
"filter": "", "filter": "",

View File

@@ -5,23 +5,13 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
) )
// NodeList returns the list of nodes. // NodeList returns the list of nodes.
func (cli *Client) NodeList(ctx context.Context, options NodeListOptions) ([]swarm.Node, error) { func (cli *Client) NodeList(ctx context.Context, options NodeListOptions) ([]swarm.Node, error) {
query := url.Values{} query := url.Values{}
options.Filters.updateURLValues(query)
if options.Filters.Len() > 0 {
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/nodes", query, nil) resp, err := cli.get(ctx, "/nodes", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {

View File

@@ -10,7 +10,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@@ -39,10 +38,8 @@ func TestNodeList(t *testing.T) {
}, },
{ {
options: NodeListOptions{ options: NodeListOptions{
Filters: filters.NewArgs( Filters: make(Filters).
filters.Arg("label", "label1"), Add("label", "label1", "label2"),
filters.Arg("label", "label2"),
),
}, },
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"filters": `{"label":{"label1":true,"label2":true}}`, "filters": `{"label":{"label1":true,"label2":true}}`,

View File

@@ -5,22 +5,15 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/plugin" "github.com/moby/moby/api/types/plugin"
) )
// PluginList returns the installed plugins // PluginList returns the installed plugins
func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (plugin.ListResponse, error) { func (cli *Client) PluginList(ctx context.Context, filter Filters) (plugin.ListResponse, error) {
var plugins plugin.ListResponse var plugins plugin.ListResponse
query := url.Values{} query := url.Values{}
if filter.Len() > 0 { filter.updateURLValues(query)
filterJSON, err := filters.ToJSON(filter)
if err != nil {
return plugins, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/plugins", query, nil) resp, err := cli.get(ctx, "/plugins", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {

View File

@@ -10,7 +10,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/plugin" "github.com/moby/moby/api/types/plugin"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@@ -20,7 +19,7 @@ func TestPluginListError(t *testing.T) {
client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error"))) client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error")))
assert.NilError(t, err) assert.NilError(t, err)
_, err = client.PluginList(context.Background(), filters.NewArgs()) _, err = client.PluginList(context.Background(), nil)
assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal)) assert.Check(t, is.ErrorType(err, cerrdefs.IsInternal))
} }
@@ -28,11 +27,10 @@ func TestPluginList(t *testing.T) {
const expectedURL = "/plugins" const expectedURL = "/plugins"
listCases := []struct { listCases := []struct {
filters filters.Args filters Filters
expectedQueryParams map[string]string expectedQueryParams map[string]string
}{ }{
{ {
filters: filters.NewArgs(),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"all": "", "all": "",
"filter": "", "filter": "",
@@ -40,7 +38,7 @@ func TestPluginList(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs(filters.Arg("enabled", "true")), filters: make(Filters).Add("enabled", "true"),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"all": "", "all": "",
"filter": "", "filter": "",
@@ -48,10 +46,7 @@ func TestPluginList(t *testing.T) {
}, },
}, },
{ {
filters: filters.NewArgs( filters: make(Filters).Add("capability", "volumedriver", "authz"),
filters.Arg("capability", "volumedriver"),
filters.Arg("capability", "authz"),
),
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"all": "", "all": "",
"filter": "", "filter": "",

View File

@@ -5,7 +5,6 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
) )
@@ -13,15 +12,7 @@ import (
func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) { func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) {
query := url.Values{} query := url.Values{}
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/secrets", query, nil) resp, err := cli.get(ctx, "/secrets", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {

View File

@@ -1,8 +1,6 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// SecretListOptions holds parameters to list secrets // SecretListOptions holds parameters to list secrets
type SecretListOptions struct { type SecretListOptions struct {
Filters filters.Args Filters Filters
} }

View File

@@ -10,7 +10,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@@ -39,10 +38,7 @@ func TestSecretList(t *testing.T) {
}, },
{ {
options: SecretListOptions{ options: SecretListOptions{
Filters: filters.NewArgs( Filters: make(Filters).Add("label", "label1", "label2"),
filters.Arg("label", "label1"),
filters.Arg("label", "label2"),
),
}, },
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"filters": `{"label":{"label1":true,"label2":true}}`, "filters": `{"label":{"label1":true,"label2":true}}`,

View File

@@ -5,7 +5,6 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
) )
@@ -13,14 +12,7 @@ import (
func (cli *Client) ServiceList(ctx context.Context, options ServiceListOptions) ([]swarm.Service, error) { func (cli *Client) ServiceList(ctx context.Context, options ServiceListOptions) ([]swarm.Service, error) {
query := url.Values{} query := url.Values{}
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
if options.Status { if options.Status {
query.Set("status", "true") query.Set("status", "true")

View File

@@ -10,7 +10,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@@ -39,10 +38,7 @@ func TestServiceList(t *testing.T) {
}, },
{ {
options: ServiceListOptions{ options: ServiceListOptions{
Filters: filters.NewArgs( Filters: make(Filters).Add("label", "label1", "label2"),
filters.Arg("label", "label1"),
filters.Arg("label", "label2"),
),
}, },
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"filters": `{"label":{"label1":true,"label2":true}}`, "filters": `{"label":{"label1":true,"label2":true}}`,

View File

@@ -1,8 +1,6 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// ConfigListOptions holds parameters to list configs // ConfigListOptions holds parameters to list configs
type ConfigListOptions struct { type ConfigListOptions struct {
Filters filters.Args Filters Filters
} }

View File

@@ -1,8 +1,6 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// NodeListOptions holds parameters to list nodes with. // NodeListOptions holds parameters to list nodes with.
type NodeListOptions struct { type NodeListOptions struct {
Filters filters.Args Filters Filters
} }

View File

@@ -1,10 +1,8 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// ServiceListOptions holds parameters to list services with. // ServiceListOptions holds parameters to list services with.
type ServiceListOptions struct { type ServiceListOptions struct {
Filters filters.Args Filters Filters
// Status indicates whether the server should include the service task // Status indicates whether the server should include the service task
// count of running and desired tasks. // count of running and desired tasks.

View File

@@ -1,8 +1,6 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// TaskListOptions holds parameters to list tasks with. // TaskListOptions holds parameters to list tasks with.
type TaskListOptions struct { type TaskListOptions struct {
Filters filters.Args Filters Filters
} }

View File

@@ -8,7 +8,6 @@ import (
"github.com/moby/moby/api/types" "github.com/moby/moby/api/types"
"github.com/moby/moby/api/types/events" "github.com/moby/moby/api/types/events"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/client/internal" "github.com/moby/moby/client/internal"
"github.com/moby/moby/client/internal/timestamp" "github.com/moby/moby/client/internal/timestamp"
) )
@@ -17,7 +16,7 @@ import (
type EventsListOptions struct { type EventsListOptions struct {
Since string Since string
Until string Until string
Filters filters.Args Filters Filters
} }
// Events returns a stream of events in the daemon. It's up to the caller to close the stream // Events returns a stream of events in the daemon. It's up to the caller to close the stream
@@ -100,13 +99,7 @@ func buildEventsQueryParams(options EventsListOptions) (url.Values, error) {
query.Set("until", ts) query.Set("until", ts)
} }
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
return query, nil return query, nil
} }

View File

@@ -12,7 +12,6 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/events" "github.com/moby/moby/api/types/events"
"github.com/moby/moby/api/types/filters"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
) )
@@ -55,7 +54,7 @@ func TestEventsErrorFromServer(t *testing.T) {
func TestEvents(t *testing.T) { func TestEvents(t *testing.T) {
const expectedURL = "/events" const expectedURL = "/events"
fltrs := filters.NewArgs(filters.Arg("type", string(events.ContainerEventType))) fltrs := make(Filters).Add("type", string(events.ContainerEventType))
expectedFiltersJSON := fmt.Sprintf(`{"type":{%q:true}}`, events.ContainerEventType) expectedFiltersJSON := fmt.Sprintf(`{"type":{%q:true}}`, events.ContainerEventType)
eventsCases := []struct { eventsCases := []struct {

View File

@@ -5,7 +5,6 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
) )
@@ -13,14 +12,7 @@ import (
func (cli *Client) TaskList(ctx context.Context, options TaskListOptions) ([]swarm.Task, error) { func (cli *Client) TaskList(ctx context.Context, options TaskListOptions) ([]swarm.Task, error) {
query := url.Values{} query := url.Values{}
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/tasks", query, nil) resp, err := cli.get(ctx, "/tasks", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -10,7 +10,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@@ -39,10 +38,7 @@ func TestTaskList(t *testing.T) {
}, },
{ {
options: TaskListOptions{ options: TaskListOptions{
Filters: filters.NewArgs( Filters: make(Filters).Add("label", "label1", "label2"),
filters.Arg("label", "label1"),
filters.Arg("label", "label2"),
),
}, },
expectedQueryParams: map[string]string{ expectedQueryParams: map[string]string{
"filters": `{"label":{"label1":true,"label2":true}}`, "filters": `{"label":{"label1":true,"label2":true}}`,

View File

@@ -3,11 +3,9 @@ package client
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url"
"strings" "strings"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
ocispec "github.com/opencontainers/image-spec/specs-go/v1" ocispec "github.com/opencontainers/image-spec/specs-go/v1"
) )
@@ -28,20 +26,6 @@ func trimID(objType, id string) (string, error) {
return id, nil return id, nil
} }
// getFiltersQuery returns a url query with "filters" query term, based on the
// filters provided.
func getFiltersQuery(f filters.Args) (url.Values, error) {
query := url.Values{}
if f.Len() > 0 {
filterJSON, err := filters.ToJSON(f)
if err != nil {
return query, err
}
query.Set("filters", filterJSON)
}
return query, nil
}
// encodePlatforms marshals the given platform(s) to JSON format, to // encodePlatforms marshals the given platform(s) to JSON format, to
// be used for query-parameters for filtering / selecting platforms. // be used for query-parameters for filtering / selecting platforms.
func encodePlatforms(platform ...ocispec.Platform) ([]string, error) { func encodePlatforms(platform ...ocispec.Platform) ([]string, error) {

View File

@@ -5,7 +5,6 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/volume" "github.com/moby/moby/api/types/volume"
) )
@@ -13,13 +12,7 @@ import (
func (cli *Client) VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, error) { func (cli *Client) VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, error) {
query := url.Values{} query := url.Values{}
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return volume.ListResponse{}, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/volumes", query, nil) resp, err := cli.get(ctx, "/volumes", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {

View File

@@ -1,8 +1,6 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// VolumeListOptions holds parameters to list volumes. // VolumeListOptions holds parameters to list volumes.
type VolumeListOptions struct { type VolumeListOptions struct {
Filters filters.Args Filters Filters
} }

View File

@@ -10,7 +10,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/volume" "github.com/moby/moby/api/types/volume"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
is "gotest.tools/v3/assert/cmp" is "gotest.tools/v3/assert/cmp"
@@ -28,23 +27,19 @@ func TestVolumeList(t *testing.T) {
const expectedURL = "/volumes" const expectedURL = "/volumes"
listCases := []struct { listCases := []struct {
filters filters.Args filters Filters
expectedFilters string expectedFilters string
}{ }{
{ {
filters: filters.NewArgs(),
expectedFilters: "", expectedFilters: "",
}, { }, {
filters: filters.NewArgs(filters.Arg("dangling", "false")), filters: make(Filters).Add("dangling", "false"),
expectedFilters: `{"dangling":{"false":true}}`, expectedFilters: `{"dangling":{"false":true}}`,
}, { }, {
filters: filters.NewArgs(filters.Arg("dangling", "true")), filters: make(Filters).Add("dangling", "true"),
expectedFilters: `{"dangling":{"true":true}}`, expectedFilters: `{"dangling":{"true":true}}`,
}, { }, {
filters: filters.NewArgs( filters: make(Filters).Add("label", "label1", "label2"),
filters.Arg("label", "label1"),
filters.Arg("label", "label2"),
),
expectedFilters: `{"label":{"label1":true,"label2":true}}`, expectedFilters: `{"label":{"label1":true,"label2":true}}`,
}, },
} }

View File

@@ -4,17 +4,15 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/volume" "github.com/moby/moby/api/types/volume"
) )
// VolumesPrune requests the daemon to delete unused data // VolumesPrune requests the daemon to delete unused data
func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args) (volume.PruneReport, error) { func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters Filters) (volume.PruneReport, error) {
query, err := getFiltersQuery(pruneFilters) query := url.Values{}
if err != nil { pruneFilters.updateURLValues(query)
return volume.PruneReport{}, err
}
resp, err := cli.post(ctx, "/volumes/prune", query, nil, nil) resp, err := cli.post(ctx, "/volumes/prune", query, nil, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -8,7 +8,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
@@ -105,7 +104,7 @@ func (d *Daemon) CheckRunningTaskNetworks(ctx context.Context) func(t *testing.T
defer cli.Close() defer cli.Close()
tasks, err := cli.TaskList(ctx, client.TaskListOptions{ tasks, err := cli.TaskList(ctx, client.TaskListOptions{
Filters: filters.NewArgs(filters.Arg("desired-state", "running")), Filters: make(client.Filters).Add("desired-state", "running"),
}) })
assert.NilError(t, err) assert.NilError(t, err)
@@ -126,7 +125,7 @@ func (d *Daemon) CheckRunningTaskImages(ctx context.Context) func(t *testing.T)
defer cli.Close() defer cli.Close()
tasks, err := cli.TaskList(ctx, client.TaskListOptions{ tasks, err := cli.TaskList(ctx, client.TaskListOptions{
Filters: filters.NewArgs(filters.Arg("desired-state", "running")), Filters: make(client.Filters).Add("desired-state", "running"),
}) })
assert.NilError(t, err) assert.NilError(t, err)

View File

@@ -17,7 +17,6 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/build" "github.com/moby/moby/api/types/build"
"github.com/moby/moby/api/types/events" "github.com/moby/moby/api/types/events"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/client/pkg/jsonmessage" "github.com/moby/moby/client/pkg/jsonmessage"
@@ -122,9 +121,9 @@ func TestBuildWithRemoveAndForceRemove(t *testing.T) {
} }
} }
func buildContainerIdsFilter(buildOutput io.Reader) (filters.Args, error) { func buildContainerIdsFilter(buildOutput io.Reader) (client.Filters, error) {
const intermediateContainerPrefix = " ---> Running in " const intermediateContainerPrefix = " ---> Running in "
filter := filters.NewArgs() filter := client.Filters{}
dec := json.NewDecoder(buildOutput) dec := json.NewDecoder(buildOutput)
for { for {

View File

@@ -10,7 +10,6 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/pkg/stdcopy" "github.com/moby/moby/api/pkg/stdcopy"
"github.com/moby/moby/api/types/filters"
swarmtypes "github.com/moby/moby/api/types/swarm" swarmtypes "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/swarm" "github.com/moby/moby/v2/integration/internal/swarm"
@@ -76,32 +75,32 @@ func TestConfigList(t *testing.T) {
testCases := []struct { testCases := []struct {
desc string desc string
filters filters.Args filters client.Filters
expected []string expected []string
}{ }{
{ {
desc: "test filter by name", desc: "test filter by name",
filters: filters.NewArgs(filters.Arg("name", testName0)), filters: make(client.Filters).Add("name", testName0),
expected: []string{testName0}, expected: []string{testName0},
}, },
{ {
desc: "test filter by id", desc: "test filter by id",
filters: filters.NewArgs(filters.Arg("id", config1ID)), filters: make(client.Filters).Add("id", config1ID),
expected: []string{testName1}, expected: []string{testName1},
}, },
{ {
desc: "test filter by label key only", desc: "test filter by label key only",
filters: filters.NewArgs(filters.Arg("label", "type")), filters: make(client.Filters).Add("label", "type"),
expected: testNames, expected: testNames,
}, },
{ {
desc: "test filter by label key=value " + testName0, desc: "test filter by label key=value " + testName0,
filters: filters.NewArgs(filters.Arg("label", "type=test")), filters: make(client.Filters).Add("label", "type=test"),
expected: []string{testName0}, expected: []string{testName0},
}, },
{ {
desc: "test filter by label key=value " + testName1, desc: "test filter by label key=value " + testName1,
filters: filters.NewArgs(filters.Arg("label", "type=production")), filters: make(client.Filters).Add("label", "type=production"),
expected: []string{testName1}, expected: []string{testName1},
}, },
} }

View File

@@ -5,7 +5,6 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/client/pkg/jsonmessage" "github.com/moby/moby/client/pkg/jsonmessage"
"github.com/moby/moby/v2/integration/internal/container" "github.com/moby/moby/v2/integration/internal/container"
@@ -45,7 +44,7 @@ func TestExportContainerAndImportImage(t *testing.T) {
assert.NilError(t, err) assert.NilError(t, err)
images, err := apiClient.ImageList(ctx, client.ImageListOptions{ images, err := apiClient.ImageList(ctx, client.ImageListOptions{
Filters: filters.NewArgs(filters.Arg("reference", reference)), Filters: make(client.Filters).Add("reference", reference),
}) })
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Equal(jm.Status, images[0].ID)) assert.Check(t, is.Equal(jm.Status, images[0].ID))

View File

@@ -4,7 +4,6 @@ import (
"os" "os"
"testing" "testing"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/container" "github.com/moby/moby/v2/integration/internal/container"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
@@ -44,7 +43,7 @@ func TestLinksContainerNames(t *testing.T) {
container.Run(ctx, t, apiClient, container.WithName(containerB), container.WithLinks(containerA+":"+containerA)) container.Run(ctx, t, apiClient, container.WithName(containerB), container.WithLinks(containerA+":"+containerA))
containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
Filters: filters.NewArgs(filters.Arg("name", containerA)), Filters: make(client.Filters).Add("name", containerA),
}) })
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Equal(1, len(containers))) assert.Check(t, is.Equal(1, len(containers)))

View File

@@ -7,7 +7,6 @@ import (
"time" "time"
containertypes "github.com/moby/moby/api/types/container" containertypes "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/versions" "github.com/moby/moby/api/types/versions"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/container" "github.com/moby/moby/v2/integration/internal/container"
@@ -68,7 +67,7 @@ func TestContainerList_Annotations(t *testing.T) {
containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
All: true, All: true,
Filters: filters.NewArgs(filters.Arg("id", id)), Filters: make(client.Filters).Add("id", id),
}) })
assert.NilError(t, err) assert.NilError(t, err)
assert.Assert(t, is.Len(containers, 1)) assert.Assert(t, is.Len(containers, 1))
@@ -104,7 +103,7 @@ func TestContainerList_Filter(t *testing.T) {
ctx := testutil.StartSpan(ctx, t) ctx := testutil.StartSpan(ctx, t)
results, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ results, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
All: true, All: true,
Filters: filters.NewArgs(filters.Arg("since", top)), Filters: make(client.Filters).Add("since", top),
}) })
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Contains(containerIDs(results), next)) assert.Check(t, is.Contains(containerIDs(results), next))
@@ -114,7 +113,7 @@ func TestContainerList_Filter(t *testing.T) {
ctx := testutil.StartSpan(ctx, t) ctx := testutil.StartSpan(ctx, t)
results, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ results, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
All: true, All: true,
Filters: filters.NewArgs(filters.Arg("before", top)), Filters: make(client.Filters).Add("before", top),
}) })
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Contains(containerIDs(results), prev)) assert.Check(t, is.Contains(containerIDs(results), prev))
@@ -152,7 +151,7 @@ func pollForHealthStatusSummary(ctx context.Context, apiClient client.APIClient,
return func(log poll.LogT) poll.Result { return func(log poll.LogT) poll.Result {
containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
All: true, All: true,
Filters: filters.NewArgs(filters.Arg("id", containerID)), Filters: make(client.Filters).Add("id", containerID),
}) })
if err != nil { if err != nil {
return poll.Error(err) return poll.Error(err)

View File

@@ -7,7 +7,6 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/events" "github.com/moby/moby/api/types/events"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/container" "github.com/moby/moby/v2/integration/internal/container"
"github.com/moby/moby/v2/internal/testutil/request" "github.com/moby/moby/v2/internal/testutil/request"
@@ -43,7 +42,7 @@ func TestPause(t *testing.T) {
messages, errs := apiClient.Events(ctx, client.EventsListOptions{ messages, errs := apiClient.Events(ctx, client.EventsListOptions{
Since: since, Since: since,
Until: until, Until: until,
Filters: filters.NewArgs(filters.Arg(string(events.ContainerEventType), cID)), Filters: make(client.Filters).Add(string(events.ContainerEventType), cID),
}) })
assert.Check(t, is.DeepEqual([]events.Action{events.ActionPause, events.ActionUnPause}, getEventActions(t, messages, errs))) assert.Check(t, is.DeepEqual([]events.Action{events.ActionPause, events.ActionUnPause}, getEventActions(t, messages, errs)))
} }

View File

@@ -9,7 +9,6 @@ import (
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/events" "github.com/moby/moby/api/types/events"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/client" "github.com/moby/moby/client"
testContainer "github.com/moby/moby/v2/integration/internal/container" testContainer "github.com/moby/moby/v2/integration/internal/container"
"github.com/moby/moby/v2/internal/testutil" "github.com/moby/moby/v2/internal/testutil"
@@ -242,10 +241,7 @@ func TestContainerRestartWithCancelledRequest(t *testing.T) {
// Start listening for events. // Start listening for events.
messages, errs := apiClient.Events(ctx, client.EventsListOptions{ messages, errs := apiClient.Events(ctx, client.EventsListOptions{
Filters: filters.NewArgs( Filters: make(client.Filters).Add("container", cID).Add("event", string(events.ActionRestart)),
filters.Arg("container", cID),
filters.Arg("event", string(events.ActionRestart)),
),
}) })
// Make restart request, but cancel the request before the container // Make restart request, but cancel the request before the container

View File

@@ -8,7 +8,6 @@ import (
"time" "time"
"github.com/google/go-cmp/cmp/cmpopts" "github.com/google/go-cmp/cmp/cmpopts"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/versions" "github.com/moby/moby/api/types/versions"
"github.com/moby/moby/client" "github.com/moby/moby/client"
@@ -43,12 +42,8 @@ func TestImagesFilterMultiReference(t *testing.T) {
assert.NilError(t, err) assert.NilError(t, err)
} }
filter := filters.NewArgs()
filter.Add("reference", repoTags[0])
filter.Add("reference", repoTags[1])
filter.Add("reference", repoTags[2])
options := client.ImageListOptions{ options := client.ImageListOptions{
Filters: filter, Filters: make(client.Filters).Add("reference", repoTags[:3]...),
} }
images, err := apiClient.ImageList(ctx, options) images, err := apiClient.ImageList(ctx, options)
assert.NilError(t, err) assert.NilError(t, err)
@@ -89,12 +84,11 @@ func TestImagesFilterUntil(t *testing.T) {
assert.NilError(t, err) assert.NilError(t, err)
laterUntil := laterImage.Created laterUntil := laterImage.Created
filter := filters.NewArgs( filter := make(client.Filters).
filters.Arg("since", imgs[0]), Add("since", imgs[0]).
filters.Arg("until", olderUntil), Add("until", olderUntil).
filters.Arg("until", laterUntil), Add("until", laterUntil).
filters.Arg("before", imgs[len(imgs)-1]), Add("before", imgs[len(imgs)-1])
)
list, err := apiClient.ImageList(ctx, client.ImageListOptions{Filters: filter}) list, err := apiClient.ImageList(ctx, client.ImageListOptions{Filters: filter})
assert.NilError(t, err) assert.NilError(t, err)
@@ -125,10 +119,9 @@ func TestImagesFilterBeforeSince(t *testing.T) {
imgs[i] = id.ID imgs[i] = id.ID
} }
filter := filters.NewArgs( filter := make(client.Filters).
filters.Arg("since", imgs[0]), Add("since", imgs[0]).
filters.Arg("before", imgs[len(imgs)-1]), Add("before", imgs[len(imgs)-1])
)
list, err := apiClient.ImageList(ctx, client.ImageListOptions{Filters: filter}) list, err := apiClient.ImageList(ctx, client.ImageListOptions{Filters: filter})
assert.NilError(t, err) assert.NilError(t, err)
@@ -155,31 +148,31 @@ func TestAPIImagesFilters(t *testing.T) {
testcases := []struct { testcases := []struct {
name string name string
filters []filters.KeyValuePair filters client.Filters
expectedImages int expectedImages int
expectedRepoTags int expectedRepoTags int
}{ }{
{ {
name: "repository regex", name: "repository regex",
filters: []filters.KeyValuePair{filters.Arg("reference", "utest*/*")}, filters: make(client.Filters).Add("reference", "utest*/*"),
expectedImages: 1, expectedImages: 1,
expectedRepoTags: 2, expectedRepoTags: 2,
}, },
{ {
name: "image name regex", name: "image name regex",
filters: []filters.KeyValuePair{filters.Arg("reference", "utest*")}, filters: make(client.Filters).Add("reference", "utest*"),
expectedImages: 1, expectedImages: 1,
expectedRepoTags: 1, expectedRepoTags: 1,
}, },
{ {
name: "image name without a tag", name: "image name without a tag",
filters: []filters.KeyValuePair{filters.Arg("reference", "utest")}, filters: make(client.Filters).Add("reference", "utest"),
expectedImages: 1, expectedImages: 1,
expectedRepoTags: 1, expectedRepoTags: 1,
}, },
{ {
name: "registry port regex", name: "registry port regex",
filters: []filters.KeyValuePair{filters.Arg("reference", "*5000*/*")}, filters: make(client.Filters).Add("reference", "*5000*/*"),
expectedImages: 1, expectedImages: 1,
expectedRepoTags: 1, expectedRepoTags: 1,
}, },
@@ -191,7 +184,7 @@ func TestAPIImagesFilters(t *testing.T) {
ctx := testutil.StartSpan(ctx, t) ctx := testutil.StartSpan(ctx, t)
images, err := apiClient.ImageList(ctx, client.ImageListOptions{ images, err := apiClient.ImageList(ctx, client.ImageListOptions{
Filters: filters.NewArgs(tc.filters...), Filters: tc.filters,
}) })
assert.Check(t, err) assert.Check(t, err)
assert.Assert(t, is.Len(images, tc.expectedImages)) assert.Assert(t, is.Len(images, tc.expectedImages))

View File

@@ -4,7 +4,6 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/container" "github.com/moby/moby/v2/integration/internal/container"
@@ -40,7 +39,7 @@ func TestPruneDontDeleteUsedDangling(t *testing.T) {
container.WithImage(danglingID), container.WithImage(danglingID),
container.WithCmd("sleep", "60")) container.WithCmd("sleep", "60"))
pruned, err := apiClient.ImagesPrune(ctx, filters.NewArgs(filters.Arg("dangling", "true"))) pruned, err := apiClient.ImagesPrune(ctx, make(client.Filters).Add("dangling", "true"))
assert.NilError(t, err) assert.NilError(t, err)
for _, deleted := range pruned.ImagesDeleted { for _, deleted := range pruned.ImagesDeleted {
@@ -88,7 +87,7 @@ func TestPruneLexographicalOrder(t *testing.T) {
cid := container.Create(ctx, t, apiClient, container.WithImage(id)) cid := container.Create(ctx, t, apiClient, container.WithImage(id))
defer container.Remove(ctx, t, apiClient, cid, client.ContainerRemoveOptions{Force: true}) defer container.Remove(ctx, t, apiClient, cid, client.ContainerRemoveOptions{Force: true})
pruned, err := apiClient.ImagesPrune(ctx, filters.NewArgs(filters.Arg("dangling", "false"))) pruned, err := apiClient.ImagesPrune(ctx, make(client.Filters).Add("dangling", "false"))
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Len(pruned.ImagesDeleted, len(tags))) assert.Check(t, is.Len(pruned.ImagesDeleted, len(tags)))
@@ -218,7 +217,7 @@ func TestPruneDontDeleteUsedImage(t *testing.T) {
defer container.Remove(ctx, t, apiClient, cid, client.ContainerRemoveOptions{Force: true}) defer container.Remove(ctx, t, apiClient, cid, client.ContainerRemoveOptions{Force: true})
// dangling=false also prunes unused images // dangling=false also prunes unused images
pruned, err := apiClient.ImagesPrune(ctx, filters.NewArgs(filters.Arg("dangling", "false"))) pruned, err := apiClient.ImagesPrune(ctx, make(client.Filters).Add("dangling", "false"))
assert.NilError(t, err) assert.NilError(t, err)
env.check(t, apiClient, pruned) env.check(t, apiClient, pruned)

View File

@@ -6,7 +6,6 @@ import (
"testing" "testing"
"time" "time"
"github.com/moby/moby/api/types/filters"
swarmtypes "github.com/moby/moby/api/types/swarm" swarmtypes "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/internal/testutil/daemon" "github.com/moby/moby/v2/internal/testutil/daemon"
@@ -206,10 +205,9 @@ func GetRunningTasks(ctx context.Context, t *testing.T, c client.ServiceAPIClien
t.Helper() t.Helper()
tasks, err := c.TaskList(ctx, client.TaskListOptions{ tasks, err := c.TaskList(ctx, client.TaskListOptions{
Filters: filters.NewArgs( Filters: make(client.Filters).
filters.Arg("service", serviceID), Add("service", serviceID).
filters.Arg("desired-state", "running"), Add("desired-state", "running"),
),
}) })
assert.NilError(t, err) assert.NilError(t, err)

View File

@@ -4,7 +4,6 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/moby/moby/api/types/filters"
swarmtypes "github.com/moby/moby/api/types/swarm" swarmtypes "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"gotest.tools/v3/poll" "gotest.tools/v3/poll"
@@ -14,9 +13,7 @@ import (
func NoTasksForService(ctx context.Context, apiClient client.ServiceAPIClient, serviceID string) func(log poll.LogT) poll.Result { func NoTasksForService(ctx context.Context, apiClient client.ServiceAPIClient, serviceID string) func(log poll.LogT) poll.Result {
return func(log poll.LogT) poll.Result { return func(log poll.LogT) poll.Result {
tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{ tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{
Filters: filters.NewArgs( Filters: make(client.Filters).Add("service", serviceID),
filters.Arg("service", serviceID),
),
}) })
if err == nil { if err == nil {
if len(tasks) == 0 { if len(tasks) == 0 {
@@ -50,10 +47,8 @@ func NoTasks(ctx context.Context, apiClient client.ServiceAPIClient) func(log po
// RunningTasksCount verifies there are `instances` tasks running for `serviceID` // RunningTasksCount verifies there are `instances` tasks running for `serviceID`
func RunningTasksCount(ctx context.Context, apiClient client.ServiceAPIClient, serviceID string, instances uint64) func(log poll.LogT) poll.Result { func RunningTasksCount(ctx context.Context, apiClient client.ServiceAPIClient, serviceID string, instances uint64) func(log poll.LogT) poll.Result {
return func(log poll.LogT) poll.Result { return func(log poll.LogT) poll.Result {
filter := filters.NewArgs()
filter.Add("service", serviceID)
tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{ tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{
Filters: filter, Filters: make(client.Filters).Add("service", serviceID),
}) })
var running int var running int
var taskError string var taskError string
@@ -90,7 +85,7 @@ func RunningTasksCount(ctx context.Context, apiClient client.ServiceAPIClient, s
// completed additionally, while polling, it verifies that the job never // completed additionally, while polling, it verifies that the job never
// exceeds MaxConcurrent running tasks // exceeds MaxConcurrent running tasks
func JobComplete(ctx context.Context, apiClient client.ServiceAPIClient, service swarmtypes.Service) func(log poll.LogT) poll.Result { func JobComplete(ctx context.Context, apiClient client.ServiceAPIClient, service swarmtypes.Service) func(log poll.LogT) poll.Result {
filter := filters.NewArgs(filters.Arg("service", service.ID)) filter := make(client.Filters).Add("service", service.ID)
var jobIteration swarmtypes.Version var jobIteration swarmtypes.Version
if service.JobStatus != nil { if service.JobStatus != nil {
@@ -165,7 +160,7 @@ func JobComplete(ctx context.Context, apiClient client.ServiceAPIClient, service
func HasLeader(ctx context.Context, apiClient client.NodeAPIClient) func(log poll.LogT) poll.Result { func HasLeader(ctx context.Context, apiClient client.NodeAPIClient) func(log poll.LogT) poll.Result {
return func(log poll.LogT) poll.Result { return func(log poll.LogT) poll.Result {
nodes, err := apiClient.NodeList(ctx, client.NodeListOptions{ nodes, err := apiClient.NodeList(ctx, client.NodeListOptions{
Filters: filters.NewArgs(filters.Arg("role", "manager")), Filters: make(client.Filters).Add("role", "manager"),
}) })
if err != nil { if err != nil {
return poll.Error(err) return poll.Error(err)

View File

@@ -5,7 +5,6 @@ import (
"strconv" "strconv"
"testing" "testing"
"github.com/moby/moby/api/types/filters"
networktypes "github.com/moby/moby/api/types/network" networktypes "github.com/moby/moby/api/types/network"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/network" "github.com/moby/moby/v2/integration/internal/network"
@@ -166,7 +165,7 @@ func TestInspectNetwork(t *testing.T) {
leaderID := func() string { leaderID := func() string {
ls, err := c1.NodeList(ctx, client.NodeListOptions{ ls, err := c1.NodeList(ctx, client.NodeListOptions{
Filters: filters.NewArgs(filters.Arg("role", "manager")), Filters: make(client.Filters).Add("role", "manager"),
}) })
assert.NilError(t, err) assert.NilError(t, err)
for _, node := range ls { for _, node := range ls {

View File

@@ -6,7 +6,6 @@ import (
"net/http" "net/http"
"testing" "testing"
"github.com/moby/moby/api/types/filters"
networktypes "github.com/moby/moby/api/types/network" networktypes "github.com/moby/moby/api/types/network"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/internal/testutil" "github.com/moby/moby/v2/internal/testutil"
@@ -132,7 +131,7 @@ func TestAPINetworkFilter(t *testing.T) {
apiClient := testEnv.APIClient() apiClient := testEnv.APIClient()
networks, err := apiClient.NetworkList(ctx, client.NetworkListOptions{ networks, err := apiClient.NetworkList(ctx, client.NetworkListOptions{
Filters: filters.NewArgs(filters.Arg("name", networkName)), Filters: make(client.Filters).Add("name", networkName),
}) })
assert.NilError(t, err) assert.NilError(t, err)

View File

@@ -8,7 +8,6 @@ import (
"io" "io"
"testing" "testing"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/volume" "github.com/moby/moby/api/types/volume"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/container" "github.com/moby/moby/v2/integration/internal/container"
@@ -111,7 +110,7 @@ func TestAuthZPluginV2RejectVolumeRequests(t *testing.T) {
assert.Assert(t, err != nil) assert.Assert(t, err != nil)
assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag)) assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
_, err = c.VolumesPrune(ctx, filters.Args{}) _, err = c.VolumesPrune(ctx, nil)
assert.Assert(t, err != nil) assert.Assert(t, err != nil)
assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag)) assert.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag))
} }

View File

@@ -10,7 +10,6 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/pkg/stdcopy" "github.com/moby/moby/api/pkg/stdcopy"
"github.com/moby/moby/api/types/filters"
swarmtypes "github.com/moby/moby/api/types/swarm" swarmtypes "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/swarm" "github.com/moby/moby/v2/integration/internal/swarm"
@@ -73,30 +72,30 @@ func TestSecretList(t *testing.T) {
assert.Check(t, is.DeepEqual(secretNamesFromList(entries), testNames)) assert.Check(t, is.DeepEqual(secretNamesFromList(entries), testNames))
testCases := []struct { testCases := []struct {
filters filters.Args filters client.Filters
expected []string expected []string
}{ }{
// test filter by name `secret ls --filter name=xxx` // test filter by name `secret ls --filter name=xxx`
{ {
filters: filters.NewArgs(filters.Arg("name", testName0)), filters: make(client.Filters).Add("name", testName0),
expected: []string{testName0}, expected: []string{testName0},
}, },
// test filter by id `secret ls --filter id=xxx` // test filter by id `secret ls --filter id=xxx`
{ {
filters: filters.NewArgs(filters.Arg("id", secret1ID)), filters: make(client.Filters).Add("id", secret1ID),
expected: []string{testName1}, expected: []string{testName1},
}, },
// test filter by label `secret ls --filter label=xxx` // test filter by label `secret ls --filter label=xxx`
{ {
filters: filters.NewArgs(filters.Arg("label", "type")), filters: make(client.Filters).Add("label", "type"),
expected: testNames, expected: testNames,
}, },
{ {
filters: filters.NewArgs(filters.Arg("label", "type=test")), filters: make(client.Filters).Add("label", "type=test"),
expected: []string{testName0}, expected: []string{testName0},
}, },
{ {
filters: filters.NewArgs(filters.Arg("label", "type=production")), filters: make(client.Filters).Add("label", "type=production"),
expected: []string{testName1}, expected: []string{testName1},
}, },
} }

View File

@@ -9,7 +9,6 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/filters"
swarmtypes "github.com/moby/moby/api/types/swarm" swarmtypes "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/network" "github.com/moby/moby/v2/integration/internal/network"
@@ -65,7 +64,7 @@ func testServiceCreateInit(ctx context.Context, daemonEnabled bool) func(t *test
func inspectServiceContainer(ctx context.Context, t *testing.T, apiClient client.APIClient, serviceID string) container.InspectResponse { func inspectServiceContainer(ctx context.Context, t *testing.T, apiClient client.APIClient, serviceID string) container.InspectResponse {
t.Helper() t.Helper()
containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
Filters: filters.NewArgs(filters.Arg("label", "com.docker.swarm.service.id="+serviceID)), Filters: make(client.Filters).Add("label", "com.docker.swarm.service.id="+serviceID),
}) })
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Len(containers, 1)) assert.Check(t, is.Len(containers, 1))
@@ -368,7 +367,7 @@ func TestCreateServiceSysctls(t *testing.T) {
// get all tasks of the service, so we can get the container // get all tasks of the service, so we can get the container
tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{ tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{
Filters: filters.NewArgs(filters.Arg("service", serviceID)), Filters: make(client.Filters).Add("service", serviceID),
}) })
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Equal(len(tasks), 1)) assert.Check(t, is.Equal(len(tasks), 1))
@@ -438,7 +437,7 @@ func TestCreateServiceCapabilities(t *testing.T) {
// get all tasks of the service, so we can get the container // get all tasks of the service, so we can get the container
tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{ tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{
Filters: filters.NewArgs(filters.Arg("service", serviceID)), Filters: make(client.Filters).Add("service", serviceID),
}) })
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Equal(len(tasks), 1)) assert.Check(t, is.Equal(len(tasks), 1))

View File

@@ -4,7 +4,6 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/moby/moby/api/types/filters"
swarmtypes "github.com/moby/moby/api/types/swarm" swarmtypes "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/swarm" "github.com/moby/moby/v2/integration/internal/swarm"
@@ -54,7 +53,7 @@ func TestServiceListWithStatuses(t *testing.T) {
// bespoke closure right here. // bespoke closure right here.
poll.WaitOn(t, func(log poll.LogT) poll.Result { poll.WaitOn(t, func(log poll.LogT) poll.Result {
tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{ tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{
Filters: filters.NewArgs(filters.Arg("service", id)), Filters: make(client.Filters).Add("service", id),
}) })
running := 0 running := 0

View File

@@ -6,7 +6,6 @@ import (
"strings" "strings"
"testing" "testing"
"github.com/moby/moby/api/types/filters"
swarmtypes "github.com/moby/moby/api/types/swarm" swarmtypes "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/swarm" "github.com/moby/moby/v2/integration/internal/swarm"
@@ -68,7 +67,7 @@ func TestServicePlugin(t *testing.T) {
// test that environment variables are passed from plugin service to plugin instance // test that environment variables are passed from plugin service to plugin instance
service := d1.GetService(ctx, t, id) service := d1.GetService(ctx, t, id)
tasks := d1.GetServiceTasks(ctx, t, service.Spec.Annotations.Name, filters.Arg("runtime", "plugin")) tasks := d1.GetServiceTasksWithFilters(ctx, t, service.Spec.Annotations.Name, make(client.Filters).Add("runtime", "plugin"))
if len(tasks) == 0 { if len(tasks) == 0 {
t.Log("No tasks found for plugin service") t.Log("No tasks found for plugin service")
t.Fail() t.Fail()

View File

@@ -5,7 +5,6 @@ import (
"testing" "testing"
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/filters"
swarmtypes "github.com/moby/moby/api/types/swarm" swarmtypes "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/network" "github.com/moby/moby/v2/integration/internal/network"
@@ -325,10 +324,7 @@ func TestServiceUpdatePidsLimit(t *testing.T) {
func getServiceTaskContainer(ctx context.Context, t *testing.T, cli client.APIClient, serviceID string) container.InspectResponse { func getServiceTaskContainer(ctx context.Context, t *testing.T, cli client.APIClient, serviceID string) container.InspectResponse {
t.Helper() t.Helper()
tasks, err := cli.TaskList(ctx, client.TaskListOptions{ tasks, err := cli.TaskList(ctx, client.TaskListOptions{
Filters: filters.NewArgs( Filters: make(client.Filters).Add("service", serviceID).Add("desired-state", "running"),
filters.Arg("service", serviceID),
filters.Arg("desired-state", "running"),
),
}) })
assert.NilError(t, err) assert.NilError(t, err)
assert.Assert(t, len(tasks) > 0) assert.Assert(t, len(tasks) > 0)

View File

@@ -9,7 +9,6 @@ import (
"time" "time"
"github.com/moby/moby/api/types/events" "github.com/moby/moby/api/types/events"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/mount" "github.com/moby/moby/api/types/mount"
"github.com/moby/moby/api/types/volume" "github.com/moby/moby/api/types/volume"
"github.com/moby/moby/client" "github.com/moby/moby/client"
@@ -33,10 +32,7 @@ func TestEventsExecDie(t *testing.T) {
assert.NilError(t, err) assert.NilError(t, err)
msg, errs := apiClient.Events(ctx, client.EventsListOptions{ msg, errs := apiClient.Events(ctx, client.EventsListOptions{
Filters: filters.NewArgs( Filters: make(client.Filters).Add("container", cID).Add("event", string(events.ActionExecDie)),
filters.Arg("container", cID),
filters.Arg("event", string(events.ActionExecDie)),
),
}) })
err = apiClient.ContainerExecStart(ctx, id.ID, client.ExecStartOptions{ err = apiClient.ContainerExecStart(ctx, id.ID, client.ExecStartOptions{
@@ -108,11 +104,10 @@ func TestEventsVolumeCreate(t *testing.T) {
_, err := apiClient.VolumeCreate(ctx, volume.CreateOptions{Name: volName}) _, err := apiClient.VolumeCreate(ctx, volume.CreateOptions{Name: volName})
assert.NilError(t, err) assert.NilError(t, err)
filter := filters.NewArgs( filter := make(client.Filters).
filters.Arg("type", "volume"), Add("type", "volume").
filters.Arg("event", "create"), Add("event", "create").
filters.Arg("volume", volName), Add("volume", volName)
)
messages, errs := apiClient.Events(ctx, client.EventsListOptions{ messages, errs := apiClient.Events(ctx, client.EventsListOptions{
Since: since, Since: since,
Until: request.DaemonUnixTime(ctx, t, apiClient, testEnv), Until: request.DaemonUnixTime(ctx, t, apiClient, testEnv),

View File

@@ -10,7 +10,6 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/google/go-cmp/cmp/cmpopts" "github.com/google/go-cmp/cmp/cmpopts"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/volume" "github.com/moby/moby/api/types/volume"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/integration/internal/build" "github.com/moby/moby/v2/integration/internal/build"
@@ -271,7 +270,7 @@ func TestVolumePruneAnonymous(t *testing.T) {
assert.NilError(t, err) assert.NilError(t, err)
// Prune anonymous volumes // Prune anonymous volumes
pruneReport, err := apiClient.VolumesPrune(ctx, filters.Args{}) pruneReport, err := apiClient.VolumesPrune(ctx, nil)
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Equal(len(pruneReport.VolumesDeleted), 1)) assert.Check(t, is.Equal(len(pruneReport.VolumesDeleted), 1))
assert.Check(t, is.Equal(pruneReport.VolumesDeleted[0], v.Name)) assert.Check(t, is.Equal(pruneReport.VolumesDeleted[0], v.Name))
@@ -283,7 +282,7 @@ func TestVolumePruneAnonymous(t *testing.T) {
_, err = apiClient.VolumeCreate(ctx, volume.CreateOptions{}) _, err = apiClient.VolumeCreate(ctx, volume.CreateOptions{})
assert.NilError(t, err) assert.NilError(t, err)
pruneReport, err = apiClient.VolumesPrune(ctx, filters.NewArgs(filters.Arg("all", "1"))) pruneReport, err = apiClient.VolumesPrune(ctx, make(client.Filters).Add("all", "1"))
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Equal(len(pruneReport.VolumesDeleted), 2)) assert.Check(t, is.Equal(len(pruneReport.VolumesDeleted), 2))
@@ -298,7 +297,7 @@ func TestVolumePruneAnonymous(t *testing.T) {
vNamed, err = apiClient.VolumeCreate(ctx, volume.CreateOptions{Name: "test-api141"}) vNamed, err = apiClient.VolumeCreate(ctx, volume.CreateOptions{Name: "test-api141"})
assert.NilError(t, err) assert.NilError(t, err)
pruneReport, err = clientOld.VolumesPrune(ctx, filters.Args{}) pruneReport, err = clientOld.VolumesPrune(ctx, nil)
assert.NilError(t, err) assert.NilError(t, err)
assert.Check(t, is.Equal(len(pruneReport.VolumesDeleted), 2)) assert.Check(t, is.Equal(len(pruneReport.VolumesDeleted), 2))
assert.Check(t, is.Contains(pruneReport.VolumesDeleted, v.Name)) assert.Check(t, is.Contains(pruneReport.VolumesDeleted, v.Name))
@@ -333,7 +332,7 @@ VOLUME ` + volDest
err = apiClient.ContainerRemove(ctx, id, client.ContainerRemoveOptions{}) err = apiClient.ContainerRemove(ctx, id, client.ContainerRemoveOptions{})
assert.NilError(t, err) assert.NilError(t, err)
pruneReport, err := apiClient.VolumesPrune(ctx, filters.Args{}) pruneReport, err := apiClient.VolumesPrune(ctx, nil)
assert.NilError(t, err) assert.NilError(t, err)
assert.Assert(t, is.Contains(pruneReport.VolumesDeleted, volumeName)) assert.Assert(t, is.Contains(pruneReport.VolumesDeleted, volumeName))
} }

View File

@@ -2,10 +2,11 @@ package daemon
import ( import (
"context" "context"
"maps"
"slices"
"testing" "testing"
"time" "time"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"gotest.tools/v3/assert" "gotest.tools/v3/assert"
@@ -50,17 +51,19 @@ func (d *Daemon) GetService(ctx context.Context, t testing.TB, id string) *swarm
} }
// GetServiceTasks returns the swarm tasks for the specified service // GetServiceTasks returns the swarm tasks for the specified service
func (d *Daemon) GetServiceTasks(ctx context.Context, t testing.TB, service string, additionalFilters ...filters.KeyValuePair) []swarm.Task { func (d *Daemon) GetServiceTasks(ctx context.Context, t testing.TB, service string) []swarm.Task {
return d.GetServiceTasksWithFilters(ctx, t, service, nil)
}
// GetServiceTasksWithFilters returns the swarm tasks for the specified service with additional filters
func (d *Daemon) GetServiceTasksWithFilters(ctx context.Context, t testing.TB, service string, additionalFilters client.Filters) []swarm.Task {
t.Helper() t.Helper()
cli := d.NewClientT(t) cli := d.NewClientT(t)
defer cli.Close() defer cli.Close()
filterArgs := filters.NewArgs( filterArgs := make(client.Filters).Add("desired-state", "running").Add("service", service)
filters.Arg("desired-state", "running"), for term, values := range additionalFilters {
filters.Arg("service", service), filterArgs.Add(term, slices.Collect(maps.Keys(values))...)
)
for _, filter := range additionalFilters {
filterArgs.Add(filter.Key, filter.Value)
} }
options := client.TaskListOptions{ options := client.TaskListOptions{

View File

@@ -7,7 +7,6 @@ import (
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/network" "github.com/moby/moby/api/types/network"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"go.opentelemetry.io/otel" "go.opentelemetry.io/otel"
@@ -53,7 +52,7 @@ func unpauseAllContainers(ctx context.Context, t testing.TB, client client.Conta
func getPausedContainers(ctx context.Context, t testing.TB, apiClient client.ContainerAPIClient) []container.Summary { func getPausedContainers(ctx context.Context, t testing.TB, apiClient client.ContainerAPIClient) []container.Summary {
t.Helper() t.Helper()
containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{
Filters: filters.NewArgs(filters.Arg("status", "paused")), Filters: make(client.Filters).Add("status", "paused"),
All: true, All: true,
}) })
assert.Check(t, err, "failed to list containers") assert.Check(t, err, "failed to list containers")
@@ -163,7 +162,7 @@ func deleteAllNetworks(ctx context.Context, t testing.TB, c client.NetworkAPICli
func deleteAllPlugins(ctx context.Context, t testing.TB, c client.PluginAPIClient, protectedPlugins map[string]struct{}) { func deleteAllPlugins(ctx context.Context, t testing.TB, c client.PluginAPIClient, protectedPlugins map[string]struct{}) {
t.Helper() t.Helper()
plugins, err := c.PluginList(ctx, filters.Args{}) plugins, err := c.PluginList(ctx, nil)
// Docker EE does not allow cluster-wide plugin management. // Docker EE does not allow cluster-wide plugin management.
if cerrdefs.IsNotImplemented(err) { if cerrdefs.IsNotImplemented(err) {
return return

View File

@@ -10,7 +10,6 @@ import (
"testing" "testing"
"github.com/moby/moby/api/types" "github.com/moby/moby/api/types"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/system" "github.com/moby/moby/api/types/system"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/internal/testutil/fixtures/load" "github.com/moby/moby/v2/internal/testutil/fixtures/load"
@@ -200,10 +199,9 @@ func (e *Execution) UsingSnapshotter() bool {
func (e *Execution) HasExistingImage(t testing.TB, reference string) bool { func (e *Execution) HasExistingImage(t testing.TB, reference string) bool {
imageList, err := e.APIClient().ImageList(context.Background(), client.ImageListOptions{ imageList, err := e.APIClient().ImageList(context.Background(), client.ImageListOptions{
All: true, All: true,
Filters: filters.NewArgs( Filters: make(client.Filters).
filters.Arg("dangling", "false"), Add("dangling", "false").
filters.Arg("reference", reference), Add("reference", reference),
),
}) })
assert.NilError(t, err, "failed to list images") assert.NilError(t, err, "failed to list images")

View File

@@ -5,7 +5,6 @@ import (
"testing" "testing"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
"github.com/moby/moby/client" "github.com/moby/moby/client"
"github.com/moby/moby/v2/internal/testutil" "github.com/moby/moby/v2/internal/testutil"
@@ -117,7 +116,7 @@ func getExistingImages(ctx context.Context, t testing.TB, testEnv *Execution) []
apiClient := testEnv.APIClient() apiClient := testEnv.APIClient()
imageList, err := apiClient.ImageList(ctx, client.ImageListOptions{ imageList, err := apiClient.ImageList(ctx, client.ImageListOptions{
All: true, All: true,
Filters: filters.NewArgs(filters.Arg("dangling", "false")), Filters: make(client.Filters).Add("dangling", "false"),
}) })
assert.NilError(t, err, "failed to list images") assert.NilError(t, err, "failed to list images")
@@ -195,7 +194,7 @@ func ProtectPlugins(ctx context.Context, t testing.TB, testEnv *Execution) {
func getExistingPlugins(ctx context.Context, t testing.TB, testEnv *Execution) []string { func getExistingPlugins(ctx context.Context, t testing.TB, testEnv *Execution) []string {
t.Helper() t.Helper()
client := testEnv.APIClient() client := testEnv.APIClient()
pluginList, err := client.PluginList(ctx, filters.Args{}) pluginList, err := client.PluginList(ctx, nil)
// Docker EE does not allow cluster-wide plugin management. // Docker EE does not allow cluster-wide plugin management.
if cerrdefs.IsNotImplemented(err) { if cerrdefs.IsNotImplemented(err) {
return []string{} return []string{}

View File

@@ -1,24 +0,0 @@
package filters
import "fmt"
// invalidFilter indicates that the provided filter or its value is invalid
type invalidFilter struct {
Filter string
Value []string
}
func (e invalidFilter) Error() string {
msg := "invalid filter"
if e.Filter != "" {
msg += " '" + e.Filter
if e.Value != nil {
msg = fmt.Sprintf("%s=%s", msg, e.Value)
}
msg += "'"
}
return msg
}
// InvalidParameter marks this error as ErrInvalidParameter
func (e invalidFilter) InvalidParameter() {}

View File

@@ -1,65 +0,0 @@
/*
Package filters provides tools for encoding a mapping of keys to a set of
multiple values.
*/
package filters
import (
"encoding/json"
)
// Args stores a mapping of keys to a set of multiple values.
type Args struct {
fields map[string]map[string]bool
}
// KeyValuePair are used to initialize a new Args
type KeyValuePair struct {
Key string
Value string
}
// Arg creates a new KeyValuePair for initializing Args
func Arg(key, value string) KeyValuePair {
return KeyValuePair{Key: key, Value: value}
}
// NewArgs returns a new Args populated with the initial args
func NewArgs(initialArgs ...KeyValuePair) Args {
args := Args{fields: map[string]map[string]bool{}}
for _, arg := range initialArgs {
args.Add(arg.Key, arg.Value)
}
return args
}
// MarshalJSON returns a JSON byte representation of the Args
func (args Args) MarshalJSON() ([]byte, error) {
if len(args.fields) == 0 {
return []byte("{}"), nil
}
return json.Marshal(args.fields)
}
// ToJSON returns the Args as a JSON encoded string
func ToJSON(a Args) (string, error) {
if a.Len() == 0 {
return "", nil
}
buf, err := json.Marshal(a)
return string(buf), err
}
// Add a new value to the set of values
func (args Args) Add(key, value string) {
if _, ok := args.fields[key]; ok {
args.fields[key][value] = true
} else {
args.fields[key] = map[string]bool{value: true}
}
}
// Len returns the number of keys in the mapping
func (args Args) Len() int {
return len(args.fields)
}

View File

@@ -8,7 +8,6 @@ import (
"strconv" "strconv"
"github.com/moby/moby/api/types/build" "github.com/moby/moby/api/types/build"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/versions" "github.com/moby/moby/api/types/versions"
) )
@@ -18,7 +17,7 @@ type BuildCachePruneOptions struct {
ReservedSpace int64 ReservedSpace int64
MaxUsedSpace int64 MaxUsedSpace int64
MinFreeSpace int64 MinFreeSpace int64
Filters filters.Args Filters Filters
} }
// BuildCachePruneResult holds the result from the BuildCachePrune method. // BuildCachePruneResult holds the result from the BuildCachePrune method.
@@ -49,11 +48,7 @@ func (cli *Client) BuildCachePrune(ctx context.Context, opts BuildCachePruneOpti
if opts.MinFreeSpace != 0 { if opts.MinFreeSpace != 0 {
query.Set("min-free-space", strconv.Itoa(int(opts.MinFreeSpace))) query.Set("min-free-space", strconv.Itoa(int(opts.MinFreeSpace)))
} }
f, err := filters.ToJSON(opts.Filters) opts.Filters.updateURLValues(query)
if err != nil {
return BuildCachePruneResult{}, fmt.Errorf("prune could not marshal filters option: %w", err)
}
query.Set("filters", f)
resp, err := cli.post(ctx, "/build/prune", query, nil, nil) resp, err := cli.post(ctx, "/build/prune", query, nil, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -8,7 +8,6 @@ import (
"github.com/moby/moby/api/types" "github.com/moby/moby/api/types"
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/events" "github.com/moby/moby/api/types/events"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/network" "github.com/moby/moby/api/types/network"
"github.com/moby/moby/api/types/plugin" "github.com/moby/moby/api/types/plugin"
@@ -89,7 +88,7 @@ type ContainerAPIClient interface {
ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error) ContainerWait(ctx context.Context, container string, condition container.WaitCondition) (<-chan container.WaitResponse, <-chan error)
CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error) CopyFromContainer(ctx context.Context, container, srcPath string) (io.ReadCloser, container.PathStat, error)
CopyToContainer(ctx context.Context, container, path string, content io.Reader, options CopyToContainerOptions) error CopyToContainer(ctx context.Context, container, path string, content io.Reader, options CopyToContainerOptions) error
ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) ContainersPrune(ctx context.Context, pruneFilters Filters) (container.PruneReport, error)
} }
type ExecAPIClient interface { type ExecAPIClient interface {
@@ -119,7 +118,7 @@ type ImageAPIClient interface {
ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error) ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error)
ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, error) ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, error)
ImageTag(ctx context.Context, image, ref string) error ImageTag(ctx context.Context, image, ref string) error
ImagesPrune(ctx context.Context, pruneFilter filters.Args) (image.PruneReport, error) ImagesPrune(ctx context.Context, pruneFilter Filters) (image.PruneReport, error)
ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (image.InspectResponse, error) ImageInspect(ctx context.Context, image string, _ ...ImageInspectOption) (image.InspectResponse, error)
ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) ([]image.HistoryResponseItem, error) ImageHistory(ctx context.Context, image string, _ ...ImageHistoryOption) ([]image.HistoryResponseItem, error)
@@ -136,7 +135,7 @@ type NetworkAPIClient interface {
NetworkInspectWithRaw(ctx context.Context, network string, options NetworkInspectOptions) (network.Inspect, []byte, error) NetworkInspectWithRaw(ctx context.Context, network string, options NetworkInspectOptions) (network.Inspect, []byte, error)
NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error) NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error)
NetworkRemove(ctx context.Context, network string) error NetworkRemove(ctx context.Context, network string) error
NetworksPrune(ctx context.Context, pruneFilter filters.Args) (network.PruneReport, error) NetworksPrune(ctx context.Context, pruneFilter Filters) (network.PruneReport, error)
} }
// NodeAPIClient defines API client methods for the nodes // NodeAPIClient defines API client methods for the nodes
@@ -149,7 +148,7 @@ type NodeAPIClient interface {
// PluginAPIClient defines API client methods for the plugins // PluginAPIClient defines API client methods for the plugins
type PluginAPIClient interface { type PluginAPIClient interface {
PluginList(ctx context.Context, filter filters.Args) (plugin.ListResponse, error) PluginList(ctx context.Context, filter Filters) (plugin.ListResponse, error)
PluginRemove(ctx context.Context, name string, options PluginRemoveOptions) error PluginRemove(ctx context.Context, name string, options PluginRemoveOptions) error
PluginEnable(ctx context.Context, name string, options PluginEnableOptions) error PluginEnable(ctx context.Context, name string, options PluginEnableOptions) error
PluginDisable(ctx context.Context, name string, options PluginDisableOptions) error PluginDisable(ctx context.Context, name string, options PluginDisableOptions) error
@@ -201,7 +200,7 @@ type VolumeAPIClient interface {
VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error) VolumeInspectWithRaw(ctx context.Context, volumeID string) (volume.Volume, []byte, error)
VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, error) VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, error)
VolumeRemove(ctx context.Context, volumeID string, force bool) error VolumeRemove(ctx context.Context, volumeID string, force bool) error
VolumesPrune(ctx context.Context, pruneFilter filters.Args) (volume.PruneReport, error) VolumesPrune(ctx context.Context, pruneFilter Filters) (volume.PruneReport, error)
VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error VolumeUpdate(ctx context.Context, volumeID string, version swarm.Version, options volume.UpdateOptions) error
} }

View File

@@ -5,22 +5,13 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
) )
// ConfigList returns the list of configs. // ConfigList returns the list of configs.
func (cli *Client) ConfigList(ctx context.Context, options ConfigListOptions) ([]swarm.Config, error) { func (cli *Client) ConfigList(ctx context.Context, options ConfigListOptions) ([]swarm.Config, error) {
query := url.Values{} query := url.Values{}
options.Filters.updateURLValues(query)
if options.Filters.Len() > 0 {
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/configs", query, nil) resp, err := cli.get(ctx, "/configs", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -7,7 +7,6 @@ import (
"strconv" "strconv"
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/filters"
) )
// ContainerListOptions holds parameters to list containers with. // ContainerListOptions holds parameters to list containers with.
@@ -18,7 +17,7 @@ type ContainerListOptions struct {
Since string Since string
Before string Before string
Limit int Limit int
Filters filters.Args Filters Filters
} }
// ContainerList returns the list of containers in the docker host. // ContainerList returns the list of containers in the docker host.
@@ -45,13 +44,7 @@ func (cli *Client) ContainerList(ctx context.Context, options ContainerListOptio
query.Set("size", "1") query.Set("size", "1")
} }
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/containers/json", query, nil) resp, err := cli.get(ctx, "/containers/json", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -4,17 +4,15 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url"
"github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/container"
"github.com/moby/moby/api/types/filters"
) )
// ContainersPrune requests the daemon to delete unused data // ContainersPrune requests the daemon to delete unused data
func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) { func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters Filters) (container.PruneReport, error) {
query, err := getFiltersQuery(pruneFilters) query := url.Values{}
if err != nil { pruneFilters.updateURLValues(query)
return container.PruneReport{}, err
}
resp, err := cli.post(ctx, "/containers/prune", query, nil, nil) resp, err := cli.post(ctx, "/containers/prune", query, nil, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

46
vendor/github.com/moby/moby/client/filters.go generated vendored Normal file
View File

@@ -0,0 +1,46 @@
package client
import (
"encoding/json"
"net/url"
)
// Filters describes a predicate for an API request.
//
// Each entry in the map is a filter term.
// Each term is evaluated against the set of values.
// A filter term is satisfied if any one of the values in the set is a match.
// An item matches the filters when all terms are satisfied.
//
// Like all other map types in Go, the zero value is empty and read-only.
type Filters map[string]map[string]bool
// Add appends values to the value-set of term.
//
// The receiver f is returned for chaining.
//
// f := make(Filters).Add("name", "foo", "bar").Add("status", "exited")
func (f Filters) Add(term string, values ...string) Filters {
if _, ok := f[term]; !ok {
f[term] = make(map[string]bool)
}
for _, v := range values {
f[term][v] = true
}
return f
}
// updateURLValues sets the "filters" key in values to the marshalled value of
// f, replacing any existing values. When f is empty, any existing "filters" key
// is removed.
func (f Filters) updateURLValues(values url.Values) {
if len(f) > 0 {
b, err := json.Marshal(f)
if err != nil {
panic(err) // Marshaling builtin types should never fail
}
values.Set("filters", string(b))
} else {
values.Del("filters")
}
}

View File

@@ -5,7 +5,6 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
"github.com/moby/moby/api/types/versions" "github.com/moby/moby/api/types/versions"
) )
@@ -30,13 +29,7 @@ func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]i
query := url.Values{} query := url.Values{}
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return images, err
}
query.Set("filters", filterJSON)
}
if options.All { if options.All {
query.Set("all", "1") query.Set("all", "1")
} }

View File

@@ -1,7 +1,5 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// ImageListOptions holds parameters to list images with. // ImageListOptions holds parameters to list images with.
type ImageListOptions struct { type ImageListOptions struct {
// All controls whether all images in the graph are filtered, or just // All controls whether all images in the graph are filtered, or just
@@ -9,7 +7,7 @@ type ImageListOptions struct {
All bool All bool
// Filters is a JSON-encoded set of filter arguments. // Filters is a JSON-encoded set of filter arguments.
Filters filters.Args Filters Filters
// SharedSize indicates whether the shared size of images should be computed. // SharedSize indicates whether the shared size of images should be computed.
SharedSize bool SharedSize bool

View File

@@ -4,17 +4,15 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/image"
) )
// ImagesPrune requests the daemon to delete unused data // ImagesPrune requests the daemon to delete unused data
func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error) { func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters Filters) (image.PruneReport, error) {
query, err := getFiltersQuery(pruneFilters) query := url.Values{}
if err != nil { pruneFilters.updateURLValues(query)
return image.PruneReport{}, err
}
resp, err := cli.post(ctx, "/images/prune", query, nil, nil) resp, err := cli.post(ctx, "/images/prune", query, nil, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -8,7 +8,6 @@ import (
"strconv" "strconv"
cerrdefs "github.com/containerd/errdefs" cerrdefs "github.com/containerd/errdefs"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/registry" "github.com/moby/moby/api/types/registry"
) )
@@ -22,13 +21,7 @@ func (cli *Client) ImageSearch(ctx context.Context, term string, options ImageSe
query.Set("limit", strconv.Itoa(options.Limit)) query.Set("limit", strconv.Itoa(options.Limit))
} }
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return results, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth) resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -2,8 +2,6 @@ package client
import ( import (
"context" "context"
"github.com/moby/moby/api/types/filters"
) )
// ImageSearchOptions holds parameters to search images with. // ImageSearchOptions holds parameters to search images with.
@@ -17,6 +15,6 @@ type ImageSearchOptions struct {
// //
// For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig]. // For details, refer to [github.com/moby/moby/api/types/registry.RequestAuthConfig].
PrivilegeFunc func(context.Context) (string, error) PrivilegeFunc func(context.Context) (string, error)
Filters filters.Args Filters Filters
Limit int Limit int
} }

View File

@@ -5,20 +5,13 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/network" "github.com/moby/moby/api/types/network"
) )
// NetworkList returns the list of networks configured in the docker host. // NetworkList returns the list of networks configured in the docker host.
func (cli *Client) NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error) { func (cli *Client) NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error) {
query := url.Values{} query := url.Values{}
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
var networkResources []network.Summary var networkResources []network.Summary
resp, err := cli.get(ctx, "/networks", query, nil) resp, err := cli.get(ctx, "/networks", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -1,8 +1,6 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// NetworkListOptions holds parameters to filter the list of networks with. // NetworkListOptions holds parameters to filter the list of networks with.
type NetworkListOptions struct { type NetworkListOptions struct {
Filters filters.Args Filters Filters
} }

View File

@@ -4,17 +4,15 @@ import (
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/network" "github.com/moby/moby/api/types/network"
) )
// NetworksPrune requests the daemon to delete unused networks // NetworksPrune requests the daemon to delete unused networks
func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) { func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters Filters) (network.PruneReport, error) {
query, err := getFiltersQuery(pruneFilters) query := url.Values{}
if err != nil { pruneFilters.updateURLValues(query)
return network.PruneReport{}, err
}
resp, err := cli.post(ctx, "/networks/prune", query, nil, nil) resp, err := cli.post(ctx, "/networks/prune", query, nil, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)

View File

@@ -5,23 +5,13 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
) )
// NodeList returns the list of nodes. // NodeList returns the list of nodes.
func (cli *Client) NodeList(ctx context.Context, options NodeListOptions) ([]swarm.Node, error) { func (cli *Client) NodeList(ctx context.Context, options NodeListOptions) ([]swarm.Node, error) {
query := url.Values{} query := url.Values{}
options.Filters.updateURLValues(query)
if options.Filters.Len() > 0 {
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/nodes", query, nil) resp, err := cli.get(ctx, "/nodes", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {

View File

@@ -5,22 +5,15 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/plugin" "github.com/moby/moby/api/types/plugin"
) )
// PluginList returns the installed plugins // PluginList returns the installed plugins
func (cli *Client) PluginList(ctx context.Context, filter filters.Args) (plugin.ListResponse, error) { func (cli *Client) PluginList(ctx context.Context, filter Filters) (plugin.ListResponse, error) {
var plugins plugin.ListResponse var plugins plugin.ListResponse
query := url.Values{} query := url.Values{}
if filter.Len() > 0 { filter.updateURLValues(query)
filterJSON, err := filters.ToJSON(filter)
if err != nil {
return plugins, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/plugins", query, nil) resp, err := cli.get(ctx, "/plugins", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {

View File

@@ -5,7 +5,6 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
) )
@@ -13,15 +12,7 @@ import (
func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) { func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) {
query := url.Values{} query := url.Values{}
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
resp, err := cli.get(ctx, "/secrets", query, nil) resp, err := cli.get(ctx, "/secrets", query, nil)
defer ensureReaderClosed(resp) defer ensureReaderClosed(resp)
if err != nil { if err != nil {

View File

@@ -1,8 +1,6 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// SecretListOptions holds parameters to list secrets // SecretListOptions holds parameters to list secrets
type SecretListOptions struct { type SecretListOptions struct {
Filters filters.Args Filters Filters
} }

View File

@@ -5,7 +5,6 @@ import (
"encoding/json" "encoding/json"
"net/url" "net/url"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/api/types/swarm" "github.com/moby/moby/api/types/swarm"
) )
@@ -13,14 +12,7 @@ import (
func (cli *Client) ServiceList(ctx context.Context, options ServiceListOptions) ([]swarm.Service, error) { func (cli *Client) ServiceList(ctx context.Context, options ServiceListOptions) ([]swarm.Service, error) {
query := url.Values{} query := url.Values{}
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
if options.Status { if options.Status {
query.Set("status", "true") query.Set("status", "true")

View File

@@ -1,8 +1,6 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// ConfigListOptions holds parameters to list configs // ConfigListOptions holds parameters to list configs
type ConfigListOptions struct { type ConfigListOptions struct {
Filters filters.Args Filters Filters
} }

View File

@@ -1,8 +1,6 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// NodeListOptions holds parameters to list nodes with. // NodeListOptions holds parameters to list nodes with.
type NodeListOptions struct { type NodeListOptions struct {
Filters filters.Args Filters Filters
} }

View File

@@ -1,10 +1,8 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// ServiceListOptions holds parameters to list services with. // ServiceListOptions holds parameters to list services with.
type ServiceListOptions struct { type ServiceListOptions struct {
Filters filters.Args Filters Filters
// Status indicates whether the server should include the service task // Status indicates whether the server should include the service task
// count of running and desired tasks. // count of running and desired tasks.

View File

@@ -1,8 +1,6 @@
package client package client
import "github.com/moby/moby/api/types/filters"
// TaskListOptions holds parameters to list tasks with. // TaskListOptions holds parameters to list tasks with.
type TaskListOptions struct { type TaskListOptions struct {
Filters filters.Args Filters Filters
} }

View File

@@ -8,7 +8,6 @@ import (
"github.com/moby/moby/api/types" "github.com/moby/moby/api/types"
"github.com/moby/moby/api/types/events" "github.com/moby/moby/api/types/events"
"github.com/moby/moby/api/types/filters"
"github.com/moby/moby/client/internal" "github.com/moby/moby/client/internal"
"github.com/moby/moby/client/internal/timestamp" "github.com/moby/moby/client/internal/timestamp"
) )
@@ -17,7 +16,7 @@ import (
type EventsListOptions struct { type EventsListOptions struct {
Since string Since string
Until string Until string
Filters filters.Args Filters Filters
} }
// Events returns a stream of events in the daemon. It's up to the caller to close the stream // Events returns a stream of events in the daemon. It's up to the caller to close the stream
@@ -100,13 +99,7 @@ func buildEventsQueryParams(options EventsListOptions) (url.Values, error) {
query.Set("until", ts) query.Set("until", ts)
} }
if options.Filters.Len() > 0 { options.Filters.updateURLValues(query)
filterJSON, err := filters.ToJSON(options.Filters)
if err != nil {
return nil, err
}
query.Set("filters", filterJSON)
}
return query, nil return query, nil
} }

Some files were not shown because too many files have changed in this diff Show More