From 7ea066c8d1e035e8577cee33a4ececfea57e4e7f Mon Sep 17 00:00:00 2001 From: Cory Snider Date: Mon, 6 Oct 2025 15:18:41 -0400 Subject: [PATCH] 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 --- api/types/filters/errors.go | 24 ------- api/types/filters/parse.go | 65 ------------------- api/types/filters/parse_test.go | 62 ------------------ client/build_prune.go | 9 +-- client/client_interfaces.go | 11 ++-- client/config_list.go | 11 +--- client/config_list_test.go | 8 +-- client/container_list.go | 11 +--- client/container_list_test.go | 10 ++- client/container_prune.go | 10 ++- client/container_prune_test.go | 27 ++++---- client/filters.go | 46 +++++++++++++ client/filters_test.go | 48 ++++++++++++++ client/image_list.go | 9 +-- client/image_list_opts.go | 4 +- client/image_list_test.go | 12 ++-- client/image_prune.go | 10 ++- client/image_prune_test.go | 19 +++--- client/image_search.go | 9 +-- client/image_search_opts.go | 4 +- client/image_search_test.go | 6 +- client/network_list.go | 9 +-- client/network_list_opts.go | 4 +- client/network_list_test.go | 12 ++-- client/network_prune.go | 10 ++- client/network_prune_test.go | 20 +++--- client/node_list.go | 12 +--- client/node_list_test.go | 7 +- client/plugin_list.go | 11 +--- client/plugin_list_test.go | 13 ++-- client/secret_list.go | 11 +--- client/secret_list_opts.go | 4 +- client/secret_list_test.go | 6 +- client/service_list.go | 10 +-- client/service_list_test.go | 6 +- client/swarm_config_list_options.go | 4 +- client/swarm_node_list_opts.go | 4 +- client/swarm_service_list_opts.go | 4 +- client/swarm_task_list_opts.go | 4 +- client/system_events.go | 11 +--- client/system_events_test.go | 3 +- client/task_list.go | 10 +-- client/task_list_test.go | 6 +- client/utils.go | 16 ----- client/volume_list.go | 9 +-- client/volume_list_opts.go | 4 +- client/volume_list_test.go | 13 ++-- client/volume_prune.go | 10 ++- integration-cli/daemon/daemon_swarm.go | 5 +- integration/build/build_test.go | 5 +- integration/config/config_test.go | 13 ++-- integration/container/export_test.go | 3 +- integration/container/links_linux_test.go | 3 +- integration/container/list_test.go | 9 ++- integration/container/pause_test.go | 3 +- integration/container/restart_test.go | 6 +- integration/image/list_test.go | 37 +++++------ integration/image/prune_test.go | 7 +- integration/internal/swarm/service.go | 8 +-- integration/internal/swarm/states.go | 13 ++-- integration/network/inspect_test.go | 3 +- integration/network/network_test.go | 3 +- .../plugin/authz/authz_plugin_v2_test.go | 3 +- integration/secret/secret_test.go | 13 ++-- integration/service/create_test.go | 7 +- integration/service/list_test.go | 3 +- integration/service/plugin_test.go | 3 +- integration/service/update_test.go | 6 +- integration/system/event_test.go | 15 ++--- integration/volume/volume_test.go | 9 ++- internal/testutil/daemon/service.go | 19 +++--- internal/testutil/environment/clean.go | 5 +- internal/testutil/environment/environment.go | 8 +-- internal/testutil/environment/protect.go | 5 +- .../moby/moby/api/types/filters/errors.go | 24 ------- .../moby/moby/api/types/filters/parse.go | 65 ------------------- .../moby/moby/client/build_prune.go | 9 +-- .../moby/moby/client/client_interfaces.go | 11 ++-- .../moby/moby/client/config_list.go | 11 +--- .../moby/moby/client/container_list.go | 11 +--- .../moby/moby/client/container_prune.go | 10 ++- vendor/github.com/moby/moby/client/filters.go | 46 +++++++++++++ .../github.com/moby/moby/client/image_list.go | 9 +-- .../moby/moby/client/image_list_opts.go | 4 +- .../moby/moby/client/image_prune.go | 10 ++- .../moby/moby/client/image_search.go | 9 +-- .../moby/moby/client/image_search_opts.go | 4 +- .../moby/moby/client/network_list.go | 9 +-- .../moby/moby/client/network_list_opts.go | 4 +- .../moby/moby/client/network_prune.go | 10 ++- .../github.com/moby/moby/client/node_list.go | 12 +--- .../moby/moby/client/plugin_list.go | 11 +--- .../moby/moby/client/secret_list.go | 11 +--- .../moby/moby/client/secret_list_opts.go | 4 +- .../moby/moby/client/service_list.go | 10 +-- .../moby/client/swarm_config_list_options.go | 4 +- .../moby/moby/client/swarm_node_list_opts.go | 4 +- .../moby/client/swarm_service_list_opts.go | 4 +- .../moby/moby/client/swarm_task_list_opts.go | 4 +- .../moby/moby/client/system_events.go | 11 +--- .../github.com/moby/moby/client/task_list.go | 10 +-- vendor/github.com/moby/moby/client/utils.go | 16 ----- .../moby/moby/client/volume_list.go | 9 +-- .../moby/moby/client/volume_list_opts.go | 4 +- .../moby/moby/client/volume_prune.go | 10 ++- vendor/modules.txt | 1 - 106 files changed, 380 insertions(+), 853 deletions(-) delete mode 100644 api/types/filters/errors.go delete mode 100644 api/types/filters/parse.go delete mode 100644 api/types/filters/parse_test.go create mode 100644 client/filters.go create mode 100644 client/filters_test.go delete mode 100644 vendor/github.com/moby/moby/api/types/filters/errors.go delete mode 100644 vendor/github.com/moby/moby/api/types/filters/parse.go create mode 100644 vendor/github.com/moby/moby/client/filters.go diff --git a/api/types/filters/errors.go b/api/types/filters/errors.go deleted file mode 100644 index b8a690d67a..0000000000 --- a/api/types/filters/errors.go +++ /dev/null @@ -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() {} diff --git a/api/types/filters/parse.go b/api/types/filters/parse.go deleted file mode 100644 index 5b9facb935..0000000000 --- a/api/types/filters/parse.go +++ /dev/null @@ -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) -} diff --git a/api/types/filters/parse_test.go b/api/types/filters/parse_test.go deleted file mode 100644 index 55706f19d6..0000000000 --- a/api/types/filters/parse_test.go +++ /dev/null @@ -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)) -} diff --git a/client/build_prune.go b/client/build_prune.go index 9ea3bb6a77..ec17b5a6f3 100644 --- a/client/build_prune.go +++ b/client/build_prune.go @@ -8,7 +8,6 @@ import ( "strconv" "github.com/moby/moby/api/types/build" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/versions" ) @@ -18,7 +17,7 @@ type BuildCachePruneOptions struct { ReservedSpace int64 MaxUsedSpace int64 MinFreeSpace int64 - Filters filters.Args + Filters Filters } // 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 { query.Set("min-free-space", strconv.Itoa(int(opts.MinFreeSpace))) } - f, err := filters.ToJSON(opts.Filters) - if err != nil { - return BuildCachePruneResult{}, fmt.Errorf("prune could not marshal filters option: %w", err) - } - query.Set("filters", f) + opts.Filters.updateURLValues(query) resp, err := cli.post(ctx, "/build/prune", query, nil, nil) defer ensureReaderClosed(resp) diff --git a/client/client_interfaces.go b/client/client_interfaces.go index 70a7e2331e..a2da96536a 100644 --- a/client/client_interfaces.go +++ b/client/client_interfaces.go @@ -8,7 +8,6 @@ import ( "github.com/moby/moby/api/types" "github.com/moby/moby/api/types/container" "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/network" "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) 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 - ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) + ContainersPrune(ctx context.Context, pruneFilters Filters) (container.PruneReport, error) } type ExecAPIClient interface { @@ -119,7 +118,7 @@ type ImageAPIClient interface { ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error) ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, 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) 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) NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, 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 @@ -149,7 +148,7 @@ type NodeAPIClient interface { // PluginAPIClient defines API client methods for the plugins 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 PluginEnable(ctx context.Context, name string, options PluginEnableOptions) 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) VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, 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 } diff --git a/client/config_list.go b/client/config_list.go index a347676fb4..9d30eb4c2c 100644 --- a/client/config_list.go +++ b/client/config_list.go @@ -5,22 +5,13 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" ) // ConfigList returns the list of configs. func (cli *Client) ConfigList(ctx context.Context, options ConfigListOptions) ([]swarm.Config, error) { query := url.Values{} - - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/configs", query, nil) defer ensureReaderClosed(resp) diff --git a/client/config_list_test.go b/client/config_list_test.go index b4a1d3593a..c5b9f68dfd 100644 --- a/client/config_list_test.go +++ b/client/config_list_test.go @@ -10,7 +10,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -41,10 +40,9 @@ func TestConfigList(t *testing.T) { }, { options: ConfigListOptions{ - Filters: filters.NewArgs( - filters.Arg("label", "label1"), - filters.Arg("label", "label2"), - ), + Filters: make(Filters). + Add("label", "label1"). + Add("label", "label2"), }, expectedQueryParams: map[string]string{ "filters": `{"label":{"label1":true,"label2":true}}`, diff --git a/client/container_list.go b/client/container_list.go index 9e1c3ab3ea..0b181aafaf 100644 --- a/client/container_list.go +++ b/client/container_list.go @@ -7,7 +7,6 @@ import ( "strconv" "github.com/moby/moby/api/types/container" - "github.com/moby/moby/api/types/filters" ) // ContainerListOptions holds parameters to list containers with. @@ -18,7 +17,7 @@ type ContainerListOptions struct { Since string Before string Limit int - Filters filters.Args + Filters Filters } // 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") } - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/containers/json", query, nil) defer ensureReaderClosed(resp) diff --git a/client/container_list_test.go b/client/container_list_test.go index 4ddb2a7fdf..c4a80cb71c 100644 --- a/client/container_list_test.go +++ b/client/container_list_test.go @@ -11,7 +11,6 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/moby/moby/api/types/container" - "github.com/moby/moby/api/types/filters" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -86,11 +85,10 @@ func TestContainerList(t *testing.T) { Size: true, All: true, Since: "container", - Filters: filters.NewArgs( - filters.Arg("label", "label1"), - filters.Arg("label", "label2"), - filters.Arg("before", "container"), - ), + Filters: make(Filters). + Add("label", "label1"). + Add("label", "label2"). + Add("before", "container"), }) assert.NilError(t, err) assert.Check(t, is.Len(containers, 2)) diff --git a/client/container_prune.go b/client/container_prune.go index 78966fbe64..fcc32b43f3 100644 --- a/client/container_prune.go +++ b/client/container_prune.go @@ -4,17 +4,15 @@ import ( "context" "encoding/json" "fmt" + "net/url" "github.com/moby/moby/api/types/container" - "github.com/moby/moby/api/types/filters" ) // ContainersPrune requests the daemon to delete unused data -func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) { - query, err := getFiltersQuery(pruneFilters) - if err != nil { - return container.PruneReport{}, err - } +func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters Filters) (container.PruneReport, error) { + query := url.Values{} + pruneFilters.updateURLValues(query) resp, err := cli.post(ctx, "/containers/prune", query, nil, nil) defer ensureReaderClosed(resp) diff --git a/client/container_prune_test.go b/client/container_prune_test.go index 5ecc73c391..e9c832491b 100644 --- a/client/container_prune_test.go +++ b/client/container_prune_test.go @@ -10,7 +10,6 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/moby/moby/api/types/container" - "github.com/moby/moby/api/types/filters" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -19,7 +18,7 @@ func TestContainersPruneError(t *testing.T) { client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error"))) 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)) } @@ -27,11 +26,11 @@ func TestContainersPrune(t *testing.T) { const expectedURL = "/containers/prune" listCases := []struct { - filters filters.Args + filters Filters expectedQueryParams map[string]string }{ { - filters: filters.Args{}, + filters: Filters{}, expectedQueryParams: map[string]string{ "until": "", "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{ "until": "", "filter": "", @@ -47,10 +46,9 @@ func TestContainersPrune(t *testing.T) { }, }, { - filters: filters.NewArgs( - filters.Arg("dangling", "true"), - filters.Arg("until", "2016-12-15T14:00"), - ), + filters: make(Filters). + Add("dangling", "true"). + Add("until", "2016-12-15T14:00"), expectedQueryParams: map[string]string{ "until": "", "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{ "until": "", "filter": "", @@ -66,11 +64,10 @@ func TestContainersPrune(t *testing.T) { }, }, { - filters: filters.NewArgs( - filters.Arg("dangling", "true"), - filters.Arg("label", "label1=foo"), - filters.Arg("label", "label2!=bar"), - ), + filters: make(Filters). + Add("dangling", "true"). + Add("label", "label1=foo"). + Add("label", "label2!=bar"), expectedQueryParams: map[string]string{ "until": "", "filter": "", diff --git a/client/filters.go b/client/filters.go new file mode 100644 index 0000000000..ac9202e2c5 --- /dev/null +++ b/client/filters.go @@ -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") + } +} diff --git a/client/filters_test.go b/client/filters_test.go new file mode 100644 index 0000000000..93c78097d3 --- /dev/null +++ b/client/filters_test.go @@ -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}}`}})) +} diff --git a/client/image_list.go b/client/image_list.go index 8001d10332..0248fa5ae3 100644 --- a/client/image_list.go +++ b/client/image_list.go @@ -5,7 +5,6 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/versions" ) @@ -30,13 +29,7 @@ func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]i query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return images, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) if options.All { query.Set("all", "1") } diff --git a/client/image_list_opts.go b/client/image_list_opts.go index 8e15d3feb1..2bd6deb897 100644 --- a/client/image_list_opts.go +++ b/client/image_list_opts.go @@ -1,7 +1,5 @@ package client -import "github.com/moby/moby/api/types/filters" - // ImageListOptions holds parameters to list images with. type ImageListOptions struct { // All controls whether all images in the graph are filtered, or just @@ -9,7 +7,7 @@ type ImageListOptions struct { All bool // 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 bool diff --git a/client/image_list_test.go b/client/image_list_test.go index 7ac3d0df38..85fc1f8d03 100644 --- a/client/image_list_test.go +++ b/client/image_list_test.go @@ -12,7 +12,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/image" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -55,11 +54,10 @@ func TestImageList(t *testing.T) { }, { options: ImageListOptions{ - Filters: filters.NewArgs( - filters.Arg("label", "label1"), - filters.Arg("label", "label2"), - filters.Arg("dangling", "true"), - ), + Filters: make(Filters). + Add("label", "label1"). + Add("label", "label2"). + Add("dangling", "true"), }, expectedQueryParams: map[string]string{ "all": "", @@ -69,7 +67,7 @@ func TestImageList(t *testing.T) { }, { options: ImageListOptions{ - Filters: filters.NewArgs(filters.Arg("dangling", "false")), + Filters: make(Filters).Add("dangling", "false"), }, expectedQueryParams: map[string]string{ "all": "", diff --git a/client/image_prune.go b/client/image_prune.go index 7f806e519e..0ac6ffe76a 100644 --- a/client/image_prune.go +++ b/client/image_prune.go @@ -4,17 +4,15 @@ import ( "context" "encoding/json" "fmt" + "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/image" ) // ImagesPrune requests the daemon to delete unused data -func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error) { - query, err := getFiltersQuery(pruneFilters) - if err != nil { - return image.PruneReport{}, err - } +func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters Filters) (image.PruneReport, error) { + query := url.Values{} + pruneFilters.updateURLValues(query) resp, err := cli.post(ctx, "/images/prune", query, nil, nil) defer ensureReaderClosed(resp) diff --git a/client/image_prune_test.go b/client/image_prune_test.go index f125816e4a..a673d64a3a 100644 --- a/client/image_prune_test.go +++ b/client/image_prune_test.go @@ -11,7 +11,6 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/moby/moby/api/types/image" - "github.com/moby/moby/api/types/filters" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -20,7 +19,7 @@ func TestImagesPruneError(t *testing.T) { client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error"))) 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)) } @@ -28,11 +27,11 @@ func TestImagesPrune(t *testing.T) { const expectedURL = "/images/prune" listCases := []struct { - filters filters.Args + filters Filters expectedQueryParams map[string]string }{ { - filters: filters.Args{}, + filters: Filters{}, expectedQueryParams: map[string]string{ "until": "", "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{ "until": "", "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{ "until": "", "filter": "", @@ -56,11 +55,9 @@ func TestImagesPrune(t *testing.T) { }, }, { - filters: filters.NewArgs( - filters.Arg("dangling", "true"), - filters.Arg("label", "label1=foo"), - filters.Arg("label", "label2!=bar"), - ), + filters: make(Filters). + Add("dangling", "true"). + Add("label", "label1=foo", "label2!=bar"), expectedQueryParams: map[string]string{ "until": "", "filter": "", diff --git a/client/image_search.go b/client/image_search.go index a2fca5deda..d7154ab961 100644 --- a/client/image_search.go +++ b/client/image_search.go @@ -8,7 +8,6 @@ import ( "strconv" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "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)) } - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return results, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth) defer ensureReaderClosed(resp) diff --git a/client/image_search_opts.go b/client/image_search_opts.go index d2e9b7bdfe..61b94117db 100644 --- a/client/image_search_opts.go +++ b/client/image_search_opts.go @@ -2,8 +2,6 @@ package client import ( "context" - - "github.com/moby/moby/api/types/filters" ) // 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]. PrivilegeFunc func(context.Context) (string, error) - Filters filters.Args + Filters Filters Limit int } diff --git a/client/image_search_test.go b/client/image_search_test.go index af7d6fc605..529bab84b8 100644 --- a/client/image_search_test.go +++ b/client/image_search_test.go @@ -11,7 +11,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/registry" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -133,10 +132,7 @@ func TestImageSearchWithoutErrors(t *testing.T) { })) assert.NilError(t, err) results, err := client.ImageSearch(context.Background(), "some-image", ImageSearchOptions{ - Filters: filters.NewArgs( - filters.Arg("is-automated", "true"), - filters.Arg("stars", "3"), - ), + Filters: make(Filters).Add("is-automated", "true").Add("stars", "3"), }) assert.NilError(t, err) assert.Check(t, is.Len(results, 1)) diff --git a/client/network_list.go b/client/network_list.go index 2eefe4cfa6..7eeebcaf23 100644 --- a/client/network_list.go +++ b/client/network_list.go @@ -5,20 +5,13 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/network" ) // NetworkList returns the list of networks configured in the docker host. func (cli *Client) NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error) { query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) var networkResources []network.Summary resp, err := cli.get(ctx, "/networks", query, nil) defer ensureReaderClosed(resp) diff --git a/client/network_list_opts.go b/client/network_list_opts.go index d42c908d2d..0d21ab3138 100644 --- a/client/network_list_opts.go +++ b/client/network_list_opts.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // NetworkListOptions holds parameters to filter the list of networks with. type NetworkListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/client/network_list_test.go b/client/network_list_test.go index 947214944c..41d37e54c3 100644 --- a/client/network_list_test.go +++ b/client/network_list_test.go @@ -10,7 +10,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/network" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -37,22 +36,21 @@ func TestNetworkList(t *testing.T) { }, { options: NetworkListOptions{ - Filters: filters.NewArgs(filters.Arg("dangling", "false")), + Filters: make(Filters).Add("dangling", "false"), }, expectedFilters: `{"dangling":{"false":true}}`, }, { options: NetworkListOptions{ - Filters: filters.NewArgs(filters.Arg("dangling", "true")), + Filters: make(Filters).Add("dangling", "true"), }, expectedFilters: `{"dangling":{"true":true}}`, }, { options: NetworkListOptions{ - Filters: filters.NewArgs( - filters.Arg("label", "label1"), - filters.Arg("label", "label2"), - ), + Filters: make(Filters). + Add("label", "label1"). + Add("label", "label2"), }, expectedFilters: `{"label":{"label1":true,"label2":true}}`, }, diff --git a/client/network_prune.go b/client/network_prune.go index d56a5c9db6..4e49497064 100644 --- a/client/network_prune.go +++ b/client/network_prune.go @@ -4,17 +4,15 @@ import ( "context" "encoding/json" "fmt" + "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/network" ) // NetworksPrune requests the daemon to delete unused networks -func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) { - query, err := getFiltersQuery(pruneFilters) - if err != nil { - return network.PruneReport{}, err - } +func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters Filters) (network.PruneReport, error) { + query := url.Values{} + pruneFilters.updateURLValues(query) resp, err := cli.post(ctx, "/networks/prune", query, nil, nil) defer ensureReaderClosed(resp) diff --git a/client/network_prune_test.go b/client/network_prune_test.go index 8b049bb88a..1764081bd9 100644 --- a/client/network_prune_test.go +++ b/client/network_prune_test.go @@ -9,7 +9,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/network" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -21,7 +20,7 @@ func TestNetworksPruneError(t *testing.T) { ) 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)) } @@ -29,11 +28,11 @@ func TestNetworksPrune(t *testing.T) { const expectedURL = "/networks/prune" listCases := []struct { - filters filters.Args + filters Filters expectedQueryParams map[string]string }{ { - filters: filters.Args{}, + filters: Filters{}, expectedQueryParams: map[string]string{ "until": "", "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{ "until": "", "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{ "until": "", "filter": "", @@ -57,11 +56,10 @@ func TestNetworksPrune(t *testing.T) { }, }, { - filters: filters.NewArgs( - filters.Arg("dangling", "true"), - filters.Arg("label", "label1=foo"), - filters.Arg("label", "label2!=bar"), - ), + filters: make(Filters). + Add("dangling", "true"). + Add("label", "label1=foo"). + Add("label", "label2!=bar"), expectedQueryParams: map[string]string{ "until": "", "filter": "", diff --git a/client/node_list.go b/client/node_list.go index 96e9caba1d..74224305a9 100644 --- a/client/node_list.go +++ b/client/node_list.go @@ -5,23 +5,13 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" ) // NodeList returns the list of nodes. func (cli *Client) NodeList(ctx context.Context, options NodeListOptions) ([]swarm.Node, error) { query := url.Values{} - - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } - + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/nodes", query, nil) defer ensureReaderClosed(resp) if err != nil { diff --git a/client/node_list_test.go b/client/node_list_test.go index 54130855e6..01336d5ac5 100644 --- a/client/node_list_test.go +++ b/client/node_list_test.go @@ -10,7 +10,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -39,10 +38,8 @@ func TestNodeList(t *testing.T) { }, { options: NodeListOptions{ - Filters: filters.NewArgs( - filters.Arg("label", "label1"), - filters.Arg("label", "label2"), - ), + Filters: make(Filters). + Add("label", "label1", "label2"), }, expectedQueryParams: map[string]string{ "filters": `{"label":{"label1":true,"label2":true}}`, diff --git a/client/plugin_list.go b/client/plugin_list.go index 238aed70e3..b87bcd91d8 100644 --- a/client/plugin_list.go +++ b/client/plugin_list.go @@ -5,22 +5,15 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/plugin" ) // 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 query := url.Values{} - if filter.Len() > 0 { - filterJSON, err := filters.ToJSON(filter) - if err != nil { - return plugins, err - } - query.Set("filters", filterJSON) - } + filter.updateURLValues(query) resp, err := cli.get(ctx, "/plugins", query, nil) defer ensureReaderClosed(resp) if err != nil { diff --git a/client/plugin_list_test.go b/client/plugin_list_test.go index 35dbc3daa9..5c89b48fb5 100644 --- a/client/plugin_list_test.go +++ b/client/plugin_list_test.go @@ -10,7 +10,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/plugin" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -20,7 +19,7 @@ func TestPluginListError(t *testing.T) { client, err := NewClientWithOpts(WithMockClient(errorMock(http.StatusInternalServerError, "Server error"))) 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)) } @@ -28,11 +27,10 @@ func TestPluginList(t *testing.T) { const expectedURL = "/plugins" listCases := []struct { - filters filters.Args + filters Filters expectedQueryParams map[string]string }{ { - filters: filters.NewArgs(), expectedQueryParams: map[string]string{ "all": "", "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{ "all": "", "filter": "", @@ -48,10 +46,7 @@ func TestPluginList(t *testing.T) { }, }, { - filters: filters.NewArgs( - filters.Arg("capability", "volumedriver"), - filters.Arg("capability", "authz"), - ), + filters: make(Filters).Add("capability", "volumedriver", "authz"), expectedQueryParams: map[string]string{ "all": "", "filter": "", diff --git a/client/secret_list.go b/client/secret_list.go index 2d14a6bed6..57fceb9a5b 100644 --- a/client/secret_list.go +++ b/client/secret_list.go @@ -5,7 +5,6 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" ) @@ -13,15 +12,7 @@ import ( func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) { query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } - + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/secrets", query, nil) defer ensureReaderClosed(resp) if err != nil { diff --git a/client/secret_list_opts.go b/client/secret_list_opts.go index 313eeefe39..f23c5fc68b 100644 --- a/client/secret_list_opts.go +++ b/client/secret_list_opts.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // SecretListOptions holds parameters to list secrets type SecretListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/client/secret_list_test.go b/client/secret_list_test.go index 7dfc0ad682..c2a147deb6 100644 --- a/client/secret_list_test.go +++ b/client/secret_list_test.go @@ -10,7 +10,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -39,10 +38,7 @@ func TestSecretList(t *testing.T) { }, { options: SecretListOptions{ - Filters: filters.NewArgs( - filters.Arg("label", "label1"), - filters.Arg("label", "label2"), - ), + Filters: make(Filters).Add("label", "label1", "label2"), }, expectedQueryParams: map[string]string{ "filters": `{"label":{"label1":true,"label2":true}}`, diff --git a/client/service_list.go b/client/service_list.go index 5eaeae8ee5..d4b77b4256 100644 --- a/client/service_list.go +++ b/client/service_list.go @@ -5,7 +5,6 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" ) @@ -13,14 +12,7 @@ import ( func (cli *Client) ServiceList(ctx context.Context, options ServiceListOptions) ([]swarm.Service, error) { query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) if options.Status { query.Set("status", "true") diff --git a/client/service_list_test.go b/client/service_list_test.go index 8e778aa924..f8d7a663b1 100644 --- a/client/service_list_test.go +++ b/client/service_list_test.go @@ -10,7 +10,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -39,10 +38,7 @@ func TestServiceList(t *testing.T) { }, { options: ServiceListOptions{ - Filters: filters.NewArgs( - filters.Arg("label", "label1"), - filters.Arg("label", "label2"), - ), + Filters: make(Filters).Add("label", "label1", "label2"), }, expectedQueryParams: map[string]string{ "filters": `{"label":{"label1":true,"label2":true}}`, diff --git a/client/swarm_config_list_options.go b/client/swarm_config_list_options.go index 91d4690c6a..b66fb359fc 100644 --- a/client/swarm_config_list_options.go +++ b/client/swarm_config_list_options.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // ConfigListOptions holds parameters to list configs type ConfigListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/client/swarm_node_list_opts.go b/client/swarm_node_list_opts.go index 9fb8c4245d..c5293cd174 100644 --- a/client/swarm_node_list_opts.go +++ b/client/swarm_node_list_opts.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // NodeListOptions holds parameters to list nodes with. type NodeListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/client/swarm_service_list_opts.go b/client/swarm_service_list_opts.go index 9b82376ac1..8a06f1bd3c 100644 --- a/client/swarm_service_list_opts.go +++ b/client/swarm_service_list_opts.go @@ -1,10 +1,8 @@ package client -import "github.com/moby/moby/api/types/filters" - // ServiceListOptions holds parameters to list services with. type ServiceListOptions struct { - Filters filters.Args + Filters Filters // Status indicates whether the server should include the service task // count of running and desired tasks. diff --git a/client/swarm_task_list_opts.go b/client/swarm_task_list_opts.go index 87e38135cd..d33f38e1e4 100644 --- a/client/swarm_task_list_opts.go +++ b/client/swarm_task_list_opts.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // TaskListOptions holds parameters to list tasks with. type TaskListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/client/system_events.go b/client/system_events.go index bee7402b59..598c2e25d3 100644 --- a/client/system_events.go +++ b/client/system_events.go @@ -8,7 +8,6 @@ import ( "github.com/moby/moby/api/types" "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/timestamp" ) @@ -17,7 +16,7 @@ import ( type EventsListOptions struct { Since 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 @@ -100,13 +99,7 @@ func buildEventsQueryParams(options EventsListOptions) (url.Values, error) { query.Set("until", ts) } - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) return query, nil } diff --git a/client/system_events_test.go b/client/system_events_test.go index c26b57d2bc..8acd827728 100644 --- a/client/system_events_test.go +++ b/client/system_events_test.go @@ -12,7 +12,6 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/moby/moby/api/types/events" - "github.com/moby/moby/api/types/filters" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" ) @@ -55,7 +54,7 @@ func TestEventsErrorFromServer(t *testing.T) { func TestEvents(t *testing.T) { 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) eventsCases := []struct { diff --git a/client/task_list.go b/client/task_list.go index 67ba443c54..bea82ad1bf 100644 --- a/client/task_list.go +++ b/client/task_list.go @@ -5,7 +5,6 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" ) @@ -13,14 +12,7 @@ import ( func (cli *Client) TaskList(ctx context.Context, options TaskListOptions) ([]swarm.Task, error) { query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/tasks", query, nil) defer ensureReaderClosed(resp) diff --git a/client/task_list_test.go b/client/task_list_test.go index afcd3ab0ad..23b90a957a 100644 --- a/client/task_list_test.go +++ b/client/task_list_test.go @@ -10,7 +10,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -39,10 +38,7 @@ func TestTaskList(t *testing.T) { }, { options: TaskListOptions{ - Filters: filters.NewArgs( - filters.Arg("label", "label1"), - filters.Arg("label", "label2"), - ), + Filters: make(Filters).Add("label", "label1", "label2"), }, expectedQueryParams: map[string]string{ "filters": `{"label":{"label1":true,"label2":true}}`, diff --git a/client/utils.go b/client/utils.go index 6908542419..3b5ef20bf9 100644 --- a/client/utils.go +++ b/client/utils.go @@ -3,11 +3,9 @@ package client import ( "encoding/json" "fmt" - "net/url" "strings" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -28,20 +26,6 @@ func trimID(objType, id string) (string, error) { 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 // be used for query-parameters for filtering / selecting platforms. func encodePlatforms(platform ...ocispec.Platform) ([]string, error) { diff --git a/client/volume_list.go b/client/volume_list.go index 975d3330c1..2676fddbf5 100644 --- a/client/volume_list.go +++ b/client/volume_list.go @@ -5,7 +5,6 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/volume" ) @@ -13,13 +12,7 @@ import ( func (cli *Client) VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, error) { query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return volume.ListResponse{}, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/volumes", query, nil) defer ensureReaderClosed(resp) if err != nil { diff --git a/client/volume_list_opts.go b/client/volume_list_opts.go index f59aef94cd..6bb48963c6 100644 --- a/client/volume_list_opts.go +++ b/client/volume_list_opts.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // VolumeListOptions holds parameters to list volumes. type VolumeListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/client/volume_list_test.go b/client/volume_list_test.go index 3f9a426cc9..10b1d5b228 100644 --- a/client/volume_list_test.go +++ b/client/volume_list_test.go @@ -10,7 +10,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/volume" "gotest.tools/v3/assert" is "gotest.tools/v3/assert/cmp" @@ -28,23 +27,19 @@ func TestVolumeList(t *testing.T) { const expectedURL = "/volumes" listCases := []struct { - filters filters.Args + filters Filters expectedFilters string }{ { - filters: filters.NewArgs(), expectedFilters: "", }, { - filters: filters.NewArgs(filters.Arg("dangling", "false")), + filters: make(Filters).Add("dangling", "false"), expectedFilters: `{"dangling":{"false":true}}`, }, { - filters: filters.NewArgs(filters.Arg("dangling", "true")), + filters: make(Filters).Add("dangling", "true"), expectedFilters: `{"dangling":{"true":true}}`, }, { - filters: filters.NewArgs( - filters.Arg("label", "label1"), - filters.Arg("label", "label2"), - ), + filters: make(Filters).Add("label", "label1", "label2"), expectedFilters: `{"label":{"label1":true,"label2":true}}`, }, } diff --git a/client/volume_prune.go b/client/volume_prune.go index 1a04e85c5f..14ee71d3ae 100644 --- a/client/volume_prune.go +++ b/client/volume_prune.go @@ -4,17 +4,15 @@ import ( "context" "encoding/json" "fmt" + "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/volume" ) // VolumesPrune requests the daemon to delete unused data -func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args) (volume.PruneReport, error) { - query, err := getFiltersQuery(pruneFilters) - if err != nil { - return volume.PruneReport{}, err - } +func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters Filters) (volume.PruneReport, error) { + query := url.Values{} + pruneFilters.updateURLValues(query) resp, err := cli.post(ctx, "/volumes/prune", query, nil, nil) defer ensureReaderClosed(resp) diff --git a/integration-cli/daemon/daemon_swarm.go b/integration-cli/daemon/daemon_swarm.go index 693b6165fc..ffdf73f094 100644 --- a/integration-cli/daemon/daemon_swarm.go +++ b/integration-cli/daemon/daemon_swarm.go @@ -8,7 +8,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" "github.com/moby/moby/client" "gotest.tools/v3/assert" @@ -105,7 +104,7 @@ func (d *Daemon) CheckRunningTaskNetworks(ctx context.Context) func(t *testing.T defer cli.Close() 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) @@ -126,7 +125,7 @@ func (d *Daemon) CheckRunningTaskImages(ctx context.Context) func(t *testing.T) defer cli.Close() 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) diff --git a/integration/build/build_test.go b/integration/build/build_test.go index 9bcc5c1c62..af2fe63b4d 100644 --- a/integration/build/build_test.go +++ b/integration/build/build_test.go @@ -17,7 +17,6 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/moby/moby/api/types/build" "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/client" "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 " - filter := filters.NewArgs() + filter := client.Filters{} dec := json.NewDecoder(buildOutput) for { diff --git a/integration/config/config_test.go b/integration/config/config_test.go index 98e8a74648..7d728270c8 100644 --- a/integration/config/config_test.go +++ b/integration/config/config_test.go @@ -10,7 +10,6 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/moby/moby/api/pkg/stdcopy" - "github.com/moby/moby/api/types/filters" swarmtypes "github.com/moby/moby/api/types/swarm" "github.com/moby/moby/client" "github.com/moby/moby/v2/integration/internal/swarm" @@ -76,32 +75,32 @@ func TestConfigList(t *testing.T) { testCases := []struct { desc string - filters filters.Args + filters client.Filters expected []string }{ { desc: "test filter by name", - filters: filters.NewArgs(filters.Arg("name", testName0)), + filters: make(client.Filters).Add("name", testName0), expected: []string{testName0}, }, { desc: "test filter by id", - filters: filters.NewArgs(filters.Arg("id", config1ID)), + filters: make(client.Filters).Add("id", config1ID), expected: []string{testName1}, }, { desc: "test filter by label key only", - filters: filters.NewArgs(filters.Arg("label", "type")), + filters: make(client.Filters).Add("label", "type"), expected: testNames, }, { 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}, }, { 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}, }, } diff --git a/integration/container/export_test.go b/integration/container/export_test.go index 1023afad43..dda6305648 100644 --- a/integration/container/export_test.go +++ b/integration/container/export_test.go @@ -5,7 +5,6 @@ import ( "strings" "testing" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/client" "github.com/moby/moby/client/pkg/jsonmessage" "github.com/moby/moby/v2/integration/internal/container" @@ -45,7 +44,7 @@ func TestExportContainerAndImportImage(t *testing.T) { assert.NilError(t, err) 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.Check(t, is.Equal(jm.Status, images[0].ID)) diff --git a/integration/container/links_linux_test.go b/integration/container/links_linux_test.go index 3c06d5308a..2c1f7fe2e6 100644 --- a/integration/container/links_linux_test.go +++ b/integration/container/links_linux_test.go @@ -4,7 +4,6 @@ import ( "os" "testing" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/client" "github.com/moby/moby/v2/integration/internal/container" "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)) 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.Check(t, is.Equal(1, len(containers))) diff --git a/integration/container/list_test.go b/integration/container/list_test.go index af7c271e6d..7cc2ae14c4 100644 --- a/integration/container/list_test.go +++ b/integration/container/list_test.go @@ -7,7 +7,6 @@ import ( "time" 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/client" "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{ All: true, - Filters: filters.NewArgs(filters.Arg("id", id)), + Filters: make(client.Filters).Add("id", id), }) assert.NilError(t, err) assert.Assert(t, is.Len(containers, 1)) @@ -104,7 +103,7 @@ func TestContainerList_Filter(t *testing.T) { ctx := testutil.StartSpan(ctx, t) results, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ All: true, - Filters: filters.NewArgs(filters.Arg("since", top)), + Filters: make(client.Filters).Add("since", top), }) assert.NilError(t, err) assert.Check(t, is.Contains(containerIDs(results), next)) @@ -114,7 +113,7 @@ func TestContainerList_Filter(t *testing.T) { ctx := testutil.StartSpan(ctx, t) results, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ All: true, - Filters: filters.NewArgs(filters.Arg("before", top)), + Filters: make(client.Filters).Add("before", top), }) assert.NilError(t, err) 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 { containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ All: true, - Filters: filters.NewArgs(filters.Arg("id", containerID)), + Filters: make(client.Filters).Add("id", containerID), }) if err != nil { return poll.Error(err) diff --git a/integration/container/pause_test.go b/integration/container/pause_test.go index a1bd25bff8..3ee4fee49b 100644 --- a/integration/container/pause_test.go +++ b/integration/container/pause_test.go @@ -7,7 +7,6 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/moby/moby/api/types/events" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/client" "github.com/moby/moby/v2/integration/internal/container" "github.com/moby/moby/v2/internal/testutil/request" @@ -43,7 +42,7 @@ func TestPause(t *testing.T) { messages, errs := apiClient.Events(ctx, client.EventsListOptions{ Since: since, 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))) } diff --git a/integration/container/restart_test.go b/integration/container/restart_test.go index 7bd304b911..631802015e 100644 --- a/integration/container/restart_test.go +++ b/integration/container/restart_test.go @@ -9,7 +9,6 @@ import ( "github.com/moby/moby/api/types/container" "github.com/moby/moby/api/types/events" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/client" testContainer "github.com/moby/moby/v2/integration/internal/container" "github.com/moby/moby/v2/internal/testutil" @@ -242,10 +241,7 @@ func TestContainerRestartWithCancelledRequest(t *testing.T) { // Start listening for events. messages, errs := apiClient.Events(ctx, client.EventsListOptions{ - Filters: filters.NewArgs( - filters.Arg("container", cID), - filters.Arg("event", string(events.ActionRestart)), - ), + Filters: make(client.Filters).Add("container", cID).Add("event", string(events.ActionRestart)), }) // Make restart request, but cancel the request before the container diff --git a/integration/image/list_test.go b/integration/image/list_test.go index 9f38523e4d..81c9d65ee6 100644 --- a/integration/image/list_test.go +++ b/integration/image/list_test.go @@ -8,7 +8,6 @@ import ( "time" "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/versions" "github.com/moby/moby/client" @@ -43,12 +42,8 @@ func TestImagesFilterMultiReference(t *testing.T) { 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{ - Filters: filter, + Filters: make(client.Filters).Add("reference", repoTags[:3]...), } images, err := apiClient.ImageList(ctx, options) assert.NilError(t, err) @@ -89,12 +84,11 @@ func TestImagesFilterUntil(t *testing.T) { assert.NilError(t, err) laterUntil := laterImage.Created - filter := filters.NewArgs( - filters.Arg("since", imgs[0]), - filters.Arg("until", olderUntil), - filters.Arg("until", laterUntil), - filters.Arg("before", imgs[len(imgs)-1]), - ) + filter := make(client.Filters). + Add("since", imgs[0]). + Add("until", olderUntil). + Add("until", laterUntil). + Add("before", imgs[len(imgs)-1]) list, err := apiClient.ImageList(ctx, client.ImageListOptions{Filters: filter}) assert.NilError(t, err) @@ -125,10 +119,9 @@ func TestImagesFilterBeforeSince(t *testing.T) { imgs[i] = id.ID } - filter := filters.NewArgs( - filters.Arg("since", imgs[0]), - filters.Arg("before", imgs[len(imgs)-1]), - ) + filter := make(client.Filters). + Add("since", imgs[0]). + Add("before", imgs[len(imgs)-1]) list, err := apiClient.ImageList(ctx, client.ImageListOptions{Filters: filter}) assert.NilError(t, err) @@ -155,31 +148,31 @@ func TestAPIImagesFilters(t *testing.T) { testcases := []struct { name string - filters []filters.KeyValuePair + filters client.Filters expectedImages int expectedRepoTags int }{ { name: "repository regex", - filters: []filters.KeyValuePair{filters.Arg("reference", "utest*/*")}, + filters: make(client.Filters).Add("reference", "utest*/*"), expectedImages: 1, expectedRepoTags: 2, }, { name: "image name regex", - filters: []filters.KeyValuePair{filters.Arg("reference", "utest*")}, + filters: make(client.Filters).Add("reference", "utest*"), expectedImages: 1, expectedRepoTags: 1, }, { name: "image name without a tag", - filters: []filters.KeyValuePair{filters.Arg("reference", "utest")}, + filters: make(client.Filters).Add("reference", "utest"), expectedImages: 1, expectedRepoTags: 1, }, { name: "registry port regex", - filters: []filters.KeyValuePair{filters.Arg("reference", "*5000*/*")}, + filters: make(client.Filters).Add("reference", "*5000*/*"), expectedImages: 1, expectedRepoTags: 1, }, @@ -191,7 +184,7 @@ func TestAPIImagesFilters(t *testing.T) { ctx := testutil.StartSpan(ctx, t) images, err := apiClient.ImageList(ctx, client.ImageListOptions{ - Filters: filters.NewArgs(tc.filters...), + Filters: tc.filters, }) assert.Check(t, err) assert.Assert(t, is.Len(images, tc.expectedImages)) diff --git a/integration/image/prune_test.go b/integration/image/prune_test.go index 8c19610f8f..bafeb1f0c7 100644 --- a/integration/image/prune_test.go +++ b/integration/image/prune_test.go @@ -4,7 +4,6 @@ import ( "strings" "testing" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/image" "github.com/moby/moby/client" "github.com/moby/moby/v2/integration/internal/container" @@ -40,7 +39,7 @@ func TestPruneDontDeleteUsedDangling(t *testing.T) { container.WithImage(danglingID), 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) for _, deleted := range pruned.ImagesDeleted { @@ -88,7 +87,7 @@ func TestPruneLexographicalOrder(t *testing.T) { cid := container.Create(ctx, t, apiClient, container.WithImage(id)) 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.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}) // 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) env.check(t, apiClient, pruned) diff --git a/integration/internal/swarm/service.go b/integration/internal/swarm/service.go index fcb4b42438..614e93ef6f 100644 --- a/integration/internal/swarm/service.go +++ b/integration/internal/swarm/service.go @@ -6,7 +6,6 @@ import ( "testing" "time" - "github.com/moby/moby/api/types/filters" swarmtypes "github.com/moby/moby/api/types/swarm" "github.com/moby/moby/client" "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() tasks, err := c.TaskList(ctx, client.TaskListOptions{ - Filters: filters.NewArgs( - filters.Arg("service", serviceID), - filters.Arg("desired-state", "running"), - ), + Filters: make(client.Filters). + Add("service", serviceID). + Add("desired-state", "running"), }) assert.NilError(t, err) diff --git a/integration/internal/swarm/states.go b/integration/internal/swarm/states.go index bca2972c7f..b00b87d71b 100644 --- a/integration/internal/swarm/states.go +++ b/integration/internal/swarm/states.go @@ -4,7 +4,6 @@ import ( "context" "fmt" - "github.com/moby/moby/api/types/filters" swarmtypes "github.com/moby/moby/api/types/swarm" "github.com/moby/moby/client" "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 { return func(log poll.LogT) poll.Result { tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{ - Filters: filters.NewArgs( - filters.Arg("service", serviceID), - ), + Filters: make(client.Filters).Add("service", serviceID), }) if err == nil { 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` 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 { - filter := filters.NewArgs() - filter.Add("service", serviceID) tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{ - Filters: filter, + Filters: make(client.Filters).Add("service", serviceID), }) var running int 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 // exceeds MaxConcurrent running tasks 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 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 { return func(log poll.LogT) poll.Result { nodes, err := apiClient.NodeList(ctx, client.NodeListOptions{ - Filters: filters.NewArgs(filters.Arg("role", "manager")), + Filters: make(client.Filters).Add("role", "manager"), }) if err != nil { return poll.Error(err) diff --git a/integration/network/inspect_test.go b/integration/network/inspect_test.go index e92ba6dbac..c977159bc8 100644 --- a/integration/network/inspect_test.go +++ b/integration/network/inspect_test.go @@ -5,7 +5,6 @@ import ( "strconv" "testing" - "github.com/moby/moby/api/types/filters" networktypes "github.com/moby/moby/api/types/network" "github.com/moby/moby/client" "github.com/moby/moby/v2/integration/internal/network" @@ -166,7 +165,7 @@ func TestInspectNetwork(t *testing.T) { leaderID := func() string { 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) for _, node := range ls { diff --git a/integration/network/network_test.go b/integration/network/network_test.go index d174cbe8d8..16ce896f3a 100644 --- a/integration/network/network_test.go +++ b/integration/network/network_test.go @@ -6,7 +6,6 @@ import ( "net/http" "testing" - "github.com/moby/moby/api/types/filters" networktypes "github.com/moby/moby/api/types/network" "github.com/moby/moby/client" "github.com/moby/moby/v2/internal/testutil" @@ -132,7 +131,7 @@ func TestAPINetworkFilter(t *testing.T) { apiClient := testEnv.APIClient() 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) diff --git a/integration/plugin/authz/authz_plugin_v2_test.go b/integration/plugin/authz/authz_plugin_v2_test.go index e61202a0fc..18fc287051 100644 --- a/integration/plugin/authz/authz_plugin_v2_test.go +++ b/integration/plugin/authz/authz_plugin_v2_test.go @@ -8,7 +8,6 @@ import ( "io" "testing" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/volume" "github.com/moby/moby/client" "github.com/moby/moby/v2/integration/internal/container" @@ -111,7 +110,7 @@ func TestAuthZPluginV2RejectVolumeRequests(t *testing.T) { assert.Assert(t, err != nil) 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.ErrorContains(t, err, fmt.Sprintf("Error response from daemon: plugin %s failed with error:", authzPluginNameWithTag)) } diff --git a/integration/secret/secret_test.go b/integration/secret/secret_test.go index 463767dcd0..06687c9faa 100644 --- a/integration/secret/secret_test.go +++ b/integration/secret/secret_test.go @@ -10,7 +10,6 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/moby/moby/api/pkg/stdcopy" - "github.com/moby/moby/api/types/filters" swarmtypes "github.com/moby/moby/api/types/swarm" "github.com/moby/moby/client" "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)) testCases := []struct { - filters filters.Args + filters client.Filters expected []string }{ // 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}, }, // 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}, }, // 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, }, { - filters: filters.NewArgs(filters.Arg("label", "type=test")), + filters: make(client.Filters).Add("label", "type=test"), expected: []string{testName0}, }, { - filters: filters.NewArgs(filters.Arg("label", "type=production")), + filters: make(client.Filters).Add("label", "type=production"), expected: []string{testName1}, }, } diff --git a/integration/service/create_test.go b/integration/service/create_test.go index 189f12c8e5..531c79dc8a 100644 --- a/integration/service/create_test.go +++ b/integration/service/create_test.go @@ -9,7 +9,6 @@ import ( cerrdefs "github.com/containerd/errdefs" "github.com/moby/moby/api/types/container" - "github.com/moby/moby/api/types/filters" swarmtypes "github.com/moby/moby/api/types/swarm" "github.com/moby/moby/client" "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 { t.Helper() 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.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 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.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 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.Check(t, is.Equal(len(tasks), 1)) diff --git a/integration/service/list_test.go b/integration/service/list_test.go index 829f4b212f..5e897f2624 100644 --- a/integration/service/list_test.go +++ b/integration/service/list_test.go @@ -4,7 +4,6 @@ import ( "fmt" "testing" - "github.com/moby/moby/api/types/filters" swarmtypes "github.com/moby/moby/api/types/swarm" "github.com/moby/moby/client" "github.com/moby/moby/v2/integration/internal/swarm" @@ -54,7 +53,7 @@ func TestServiceListWithStatuses(t *testing.T) { // bespoke closure right here. poll.WaitOn(t, func(log poll.LogT) poll.Result { tasks, err := apiClient.TaskList(ctx, client.TaskListOptions{ - Filters: filters.NewArgs(filters.Arg("service", id)), + Filters: make(client.Filters).Add("service", id), }) running := 0 diff --git a/integration/service/plugin_test.go b/integration/service/plugin_test.go index 47010cccb3..67cdc89fdb 100644 --- a/integration/service/plugin_test.go +++ b/integration/service/plugin_test.go @@ -6,7 +6,6 @@ import ( "strings" "testing" - "github.com/moby/moby/api/types/filters" swarmtypes "github.com/moby/moby/api/types/swarm" "github.com/moby/moby/client" "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 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 { t.Log("No tasks found for plugin service") t.Fail() diff --git a/integration/service/update_test.go b/integration/service/update_test.go index fc737cd00a..a45b8a0a53 100644 --- a/integration/service/update_test.go +++ b/integration/service/update_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/moby/moby/api/types/container" - "github.com/moby/moby/api/types/filters" swarmtypes "github.com/moby/moby/api/types/swarm" "github.com/moby/moby/client" "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 { t.Helper() tasks, err := cli.TaskList(ctx, client.TaskListOptions{ - Filters: filters.NewArgs( - filters.Arg("service", serviceID), - filters.Arg("desired-state", "running"), - ), + Filters: make(client.Filters).Add("service", serviceID).Add("desired-state", "running"), }) assert.NilError(t, err) assert.Assert(t, len(tasks) > 0) diff --git a/integration/system/event_test.go b/integration/system/event_test.go index 19cb6802d9..942013e001 100644 --- a/integration/system/event_test.go +++ b/integration/system/event_test.go @@ -9,7 +9,6 @@ import ( "time" "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/volume" "github.com/moby/moby/client" @@ -33,10 +32,7 @@ func TestEventsExecDie(t *testing.T) { assert.NilError(t, err) msg, errs := apiClient.Events(ctx, client.EventsListOptions{ - Filters: filters.NewArgs( - filters.Arg("container", cID), - filters.Arg("event", string(events.ActionExecDie)), - ), + Filters: make(client.Filters).Add("container", cID).Add("event", string(events.ActionExecDie)), }) 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}) assert.NilError(t, err) - filter := filters.NewArgs( - filters.Arg("type", "volume"), - filters.Arg("event", "create"), - filters.Arg("volume", volName), - ) + filter := make(client.Filters). + Add("type", "volume"). + Add("event", "create"). + Add("volume", volName) messages, errs := apiClient.Events(ctx, client.EventsListOptions{ Since: since, Until: request.DaemonUnixTime(ctx, t, apiClient, testEnv), diff --git a/integration/volume/volume_test.go b/integration/volume/volume_test.go index e00c66ba91..00f78b0cc4 100644 --- a/integration/volume/volume_test.go +++ b/integration/volume/volume_test.go @@ -10,7 +10,6 @@ import ( cerrdefs "github.com/containerd/errdefs" "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/client" "github.com/moby/moby/v2/integration/internal/build" @@ -271,7 +270,7 @@ func TestVolumePruneAnonymous(t *testing.T) { assert.NilError(t, err) // Prune anonymous volumes - pruneReport, err := apiClient.VolumesPrune(ctx, filters.Args{}) + pruneReport, err := apiClient.VolumesPrune(ctx, nil) assert.NilError(t, err) assert.Check(t, is.Equal(len(pruneReport.VolumesDeleted), 1)) 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{}) 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.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"}) assert.NilError(t, err) - pruneReport, err = clientOld.VolumesPrune(ctx, filters.Args{}) + pruneReport, err = clientOld.VolumesPrune(ctx, nil) assert.NilError(t, err) assert.Check(t, is.Equal(len(pruneReport.VolumesDeleted), 2)) assert.Check(t, is.Contains(pruneReport.VolumesDeleted, v.Name)) @@ -333,7 +332,7 @@ VOLUME ` + volDest err = apiClient.ContainerRemove(ctx, id, client.ContainerRemoveOptions{}) assert.NilError(t, err) - pruneReport, err := apiClient.VolumesPrune(ctx, filters.Args{}) + pruneReport, err := apiClient.VolumesPrune(ctx, nil) assert.NilError(t, err) assert.Assert(t, is.Contains(pruneReport.VolumesDeleted, volumeName)) } diff --git a/internal/testutil/daemon/service.go b/internal/testutil/daemon/service.go index 5c9bb2dcd8..4365ff4880 100644 --- a/internal/testutil/daemon/service.go +++ b/internal/testutil/daemon/service.go @@ -2,10 +2,11 @@ package daemon import ( "context" + "maps" + "slices" "testing" "time" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" "github.com/moby/moby/client" "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 -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() cli := d.NewClientT(t) defer cli.Close() - filterArgs := filters.NewArgs( - filters.Arg("desired-state", "running"), - filters.Arg("service", service), - ) - for _, filter := range additionalFilters { - filterArgs.Add(filter.Key, filter.Value) + filterArgs := make(client.Filters).Add("desired-state", "running").Add("service", service) + for term, values := range additionalFilters { + filterArgs.Add(term, slices.Collect(maps.Keys(values))...) } options := client.TaskListOptions{ diff --git a/internal/testutil/environment/clean.go b/internal/testutil/environment/clean.go index 04ca648ff6..e3265ff16f 100644 --- a/internal/testutil/environment/clean.go +++ b/internal/testutil/environment/clean.go @@ -7,7 +7,6 @@ import ( cerrdefs "github.com/containerd/errdefs" "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/client" "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 { t.Helper() containers, err := apiClient.ContainerList(ctx, client.ContainerListOptions{ - Filters: filters.NewArgs(filters.Arg("status", "paused")), + Filters: make(client.Filters).Add("status", "paused"), All: true, }) 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{}) { t.Helper() - plugins, err := c.PluginList(ctx, filters.Args{}) + plugins, err := c.PluginList(ctx, nil) // Docker EE does not allow cluster-wide plugin management. if cerrdefs.IsNotImplemented(err) { return diff --git a/internal/testutil/environment/environment.go b/internal/testutil/environment/environment.go index 7e0bac5f0e..4e89658118 100644 --- a/internal/testutil/environment/environment.go +++ b/internal/testutil/environment/environment.go @@ -10,7 +10,6 @@ import ( "testing" "github.com/moby/moby/api/types" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/system" "github.com/moby/moby/client" "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 { imageList, err := e.APIClient().ImageList(context.Background(), client.ImageListOptions{ All: true, - Filters: filters.NewArgs( - filters.Arg("dangling", "false"), - filters.Arg("reference", reference), - ), + Filters: make(client.Filters). + Add("dangling", "false"). + Add("reference", reference), }) assert.NilError(t, err, "failed to list images") diff --git a/internal/testutil/environment/protect.go b/internal/testutil/environment/protect.go index 82cd9b8a23..224b5aa1e9 100644 --- a/internal/testutil/environment/protect.go +++ b/internal/testutil/environment/protect.go @@ -5,7 +5,6 @@ import ( "testing" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/image" "github.com/moby/moby/client" "github.com/moby/moby/v2/internal/testutil" @@ -117,7 +116,7 @@ func getExistingImages(ctx context.Context, t testing.TB, testEnv *Execution) [] apiClient := testEnv.APIClient() imageList, err := apiClient.ImageList(ctx, client.ImageListOptions{ All: true, - Filters: filters.NewArgs(filters.Arg("dangling", "false")), + Filters: make(client.Filters).Add("dangling", "false"), }) 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 { t.Helper() 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. if cerrdefs.IsNotImplemented(err) { return []string{} diff --git a/vendor/github.com/moby/moby/api/types/filters/errors.go b/vendor/github.com/moby/moby/api/types/filters/errors.go deleted file mode 100644 index b8a690d67a..0000000000 --- a/vendor/github.com/moby/moby/api/types/filters/errors.go +++ /dev/null @@ -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() {} diff --git a/vendor/github.com/moby/moby/api/types/filters/parse.go b/vendor/github.com/moby/moby/api/types/filters/parse.go deleted file mode 100644 index 5b9facb935..0000000000 --- a/vendor/github.com/moby/moby/api/types/filters/parse.go +++ /dev/null @@ -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) -} diff --git a/vendor/github.com/moby/moby/client/build_prune.go b/vendor/github.com/moby/moby/client/build_prune.go index 9ea3bb6a77..ec17b5a6f3 100644 --- a/vendor/github.com/moby/moby/client/build_prune.go +++ b/vendor/github.com/moby/moby/client/build_prune.go @@ -8,7 +8,6 @@ import ( "strconv" "github.com/moby/moby/api/types/build" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/versions" ) @@ -18,7 +17,7 @@ type BuildCachePruneOptions struct { ReservedSpace int64 MaxUsedSpace int64 MinFreeSpace int64 - Filters filters.Args + Filters Filters } // 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 { query.Set("min-free-space", strconv.Itoa(int(opts.MinFreeSpace))) } - f, err := filters.ToJSON(opts.Filters) - if err != nil { - return BuildCachePruneResult{}, fmt.Errorf("prune could not marshal filters option: %w", err) - } - query.Set("filters", f) + opts.Filters.updateURLValues(query) resp, err := cli.post(ctx, "/build/prune", query, nil, nil) defer ensureReaderClosed(resp) diff --git a/vendor/github.com/moby/moby/client/client_interfaces.go b/vendor/github.com/moby/moby/client/client_interfaces.go index 70a7e2331e..a2da96536a 100644 --- a/vendor/github.com/moby/moby/client/client_interfaces.go +++ b/vendor/github.com/moby/moby/client/client_interfaces.go @@ -8,7 +8,6 @@ import ( "github.com/moby/moby/api/types" "github.com/moby/moby/api/types/container" "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/network" "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) 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 - ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) + ContainersPrune(ctx context.Context, pruneFilters Filters) (container.PruneReport, error) } type ExecAPIClient interface { @@ -119,7 +118,7 @@ type ImageAPIClient interface { ImageRemove(ctx context.Context, image string, options ImageRemoveOptions) ([]image.DeleteResponse, error) ImageSearch(ctx context.Context, term string, options ImageSearchOptions) ([]registry.SearchResult, 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) 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) NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, 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 @@ -149,7 +148,7 @@ type NodeAPIClient interface { // PluginAPIClient defines API client methods for the plugins 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 PluginEnable(ctx context.Context, name string, options PluginEnableOptions) 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) VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, 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 } diff --git a/vendor/github.com/moby/moby/client/config_list.go b/vendor/github.com/moby/moby/client/config_list.go index a347676fb4..9d30eb4c2c 100644 --- a/vendor/github.com/moby/moby/client/config_list.go +++ b/vendor/github.com/moby/moby/client/config_list.go @@ -5,22 +5,13 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" ) // ConfigList returns the list of configs. func (cli *Client) ConfigList(ctx context.Context, options ConfigListOptions) ([]swarm.Config, error) { query := url.Values{} - - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/configs", query, nil) defer ensureReaderClosed(resp) diff --git a/vendor/github.com/moby/moby/client/container_list.go b/vendor/github.com/moby/moby/client/container_list.go index 9e1c3ab3ea..0b181aafaf 100644 --- a/vendor/github.com/moby/moby/client/container_list.go +++ b/vendor/github.com/moby/moby/client/container_list.go @@ -7,7 +7,6 @@ import ( "strconv" "github.com/moby/moby/api/types/container" - "github.com/moby/moby/api/types/filters" ) // ContainerListOptions holds parameters to list containers with. @@ -18,7 +17,7 @@ type ContainerListOptions struct { Since string Before string Limit int - Filters filters.Args + Filters Filters } // 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") } - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/containers/json", query, nil) defer ensureReaderClosed(resp) diff --git a/vendor/github.com/moby/moby/client/container_prune.go b/vendor/github.com/moby/moby/client/container_prune.go index 78966fbe64..fcc32b43f3 100644 --- a/vendor/github.com/moby/moby/client/container_prune.go +++ b/vendor/github.com/moby/moby/client/container_prune.go @@ -4,17 +4,15 @@ import ( "context" "encoding/json" "fmt" + "net/url" "github.com/moby/moby/api/types/container" - "github.com/moby/moby/api/types/filters" ) // ContainersPrune requests the daemon to delete unused data -func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters filters.Args) (container.PruneReport, error) { - query, err := getFiltersQuery(pruneFilters) - if err != nil { - return container.PruneReport{}, err - } +func (cli *Client) ContainersPrune(ctx context.Context, pruneFilters Filters) (container.PruneReport, error) { + query := url.Values{} + pruneFilters.updateURLValues(query) resp, err := cli.post(ctx, "/containers/prune", query, nil, nil) defer ensureReaderClosed(resp) diff --git a/vendor/github.com/moby/moby/client/filters.go b/vendor/github.com/moby/moby/client/filters.go new file mode 100644 index 0000000000..ac9202e2c5 --- /dev/null +++ b/vendor/github.com/moby/moby/client/filters.go @@ -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") + } +} diff --git a/vendor/github.com/moby/moby/client/image_list.go b/vendor/github.com/moby/moby/client/image_list.go index 8001d10332..0248fa5ae3 100644 --- a/vendor/github.com/moby/moby/client/image_list.go +++ b/vendor/github.com/moby/moby/client/image_list.go @@ -5,7 +5,6 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/image" "github.com/moby/moby/api/types/versions" ) @@ -30,13 +29,7 @@ func (cli *Client) ImageList(ctx context.Context, options ImageListOptions) ([]i query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return images, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) if options.All { query.Set("all", "1") } diff --git a/vendor/github.com/moby/moby/client/image_list_opts.go b/vendor/github.com/moby/moby/client/image_list_opts.go index 8e15d3feb1..2bd6deb897 100644 --- a/vendor/github.com/moby/moby/client/image_list_opts.go +++ b/vendor/github.com/moby/moby/client/image_list_opts.go @@ -1,7 +1,5 @@ package client -import "github.com/moby/moby/api/types/filters" - // ImageListOptions holds parameters to list images with. type ImageListOptions struct { // All controls whether all images in the graph are filtered, or just @@ -9,7 +7,7 @@ type ImageListOptions struct { All bool // 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 bool diff --git a/vendor/github.com/moby/moby/client/image_prune.go b/vendor/github.com/moby/moby/client/image_prune.go index 7f806e519e..0ac6ffe76a 100644 --- a/vendor/github.com/moby/moby/client/image_prune.go +++ b/vendor/github.com/moby/moby/client/image_prune.go @@ -4,17 +4,15 @@ import ( "context" "encoding/json" "fmt" + "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/image" ) // ImagesPrune requests the daemon to delete unused data -func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters filters.Args) (image.PruneReport, error) { - query, err := getFiltersQuery(pruneFilters) - if err != nil { - return image.PruneReport{}, err - } +func (cli *Client) ImagesPrune(ctx context.Context, pruneFilters Filters) (image.PruneReport, error) { + query := url.Values{} + pruneFilters.updateURLValues(query) resp, err := cli.post(ctx, "/images/prune", query, nil, nil) defer ensureReaderClosed(resp) diff --git a/vendor/github.com/moby/moby/client/image_search.go b/vendor/github.com/moby/moby/client/image_search.go index a2fca5deda..d7154ab961 100644 --- a/vendor/github.com/moby/moby/client/image_search.go +++ b/vendor/github.com/moby/moby/client/image_search.go @@ -8,7 +8,6 @@ import ( "strconv" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" "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)) } - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return results, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) resp, err := cli.tryImageSearch(ctx, query, options.RegistryAuth) defer ensureReaderClosed(resp) diff --git a/vendor/github.com/moby/moby/client/image_search_opts.go b/vendor/github.com/moby/moby/client/image_search_opts.go index d2e9b7bdfe..61b94117db 100644 --- a/vendor/github.com/moby/moby/client/image_search_opts.go +++ b/vendor/github.com/moby/moby/client/image_search_opts.go @@ -2,8 +2,6 @@ package client import ( "context" - - "github.com/moby/moby/api/types/filters" ) // 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]. PrivilegeFunc func(context.Context) (string, error) - Filters filters.Args + Filters Filters Limit int } diff --git a/vendor/github.com/moby/moby/client/network_list.go b/vendor/github.com/moby/moby/client/network_list.go index 2eefe4cfa6..7eeebcaf23 100644 --- a/vendor/github.com/moby/moby/client/network_list.go +++ b/vendor/github.com/moby/moby/client/network_list.go @@ -5,20 +5,13 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/network" ) // NetworkList returns the list of networks configured in the docker host. func (cli *Client) NetworkList(ctx context.Context, options NetworkListOptions) ([]network.Summary, error) { query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) var networkResources []network.Summary resp, err := cli.get(ctx, "/networks", query, nil) defer ensureReaderClosed(resp) diff --git a/vendor/github.com/moby/moby/client/network_list_opts.go b/vendor/github.com/moby/moby/client/network_list_opts.go index d42c908d2d..0d21ab3138 100644 --- a/vendor/github.com/moby/moby/client/network_list_opts.go +++ b/vendor/github.com/moby/moby/client/network_list_opts.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // NetworkListOptions holds parameters to filter the list of networks with. type NetworkListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/vendor/github.com/moby/moby/client/network_prune.go b/vendor/github.com/moby/moby/client/network_prune.go index d56a5c9db6..4e49497064 100644 --- a/vendor/github.com/moby/moby/client/network_prune.go +++ b/vendor/github.com/moby/moby/client/network_prune.go @@ -4,17 +4,15 @@ import ( "context" "encoding/json" "fmt" + "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/network" ) // NetworksPrune requests the daemon to delete unused networks -func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters filters.Args) (network.PruneReport, error) { - query, err := getFiltersQuery(pruneFilters) - if err != nil { - return network.PruneReport{}, err - } +func (cli *Client) NetworksPrune(ctx context.Context, pruneFilters Filters) (network.PruneReport, error) { + query := url.Values{} + pruneFilters.updateURLValues(query) resp, err := cli.post(ctx, "/networks/prune", query, nil, nil) defer ensureReaderClosed(resp) diff --git a/vendor/github.com/moby/moby/client/node_list.go b/vendor/github.com/moby/moby/client/node_list.go index 96e9caba1d..74224305a9 100644 --- a/vendor/github.com/moby/moby/client/node_list.go +++ b/vendor/github.com/moby/moby/client/node_list.go @@ -5,23 +5,13 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" ) // NodeList returns the list of nodes. func (cli *Client) NodeList(ctx context.Context, options NodeListOptions) ([]swarm.Node, error) { query := url.Values{} - - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } - + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/nodes", query, nil) defer ensureReaderClosed(resp) if err != nil { diff --git a/vendor/github.com/moby/moby/client/plugin_list.go b/vendor/github.com/moby/moby/client/plugin_list.go index 238aed70e3..b87bcd91d8 100644 --- a/vendor/github.com/moby/moby/client/plugin_list.go +++ b/vendor/github.com/moby/moby/client/plugin_list.go @@ -5,22 +5,15 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/plugin" ) // 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 query := url.Values{} - if filter.Len() > 0 { - filterJSON, err := filters.ToJSON(filter) - if err != nil { - return plugins, err - } - query.Set("filters", filterJSON) - } + filter.updateURLValues(query) resp, err := cli.get(ctx, "/plugins", query, nil) defer ensureReaderClosed(resp) if err != nil { diff --git a/vendor/github.com/moby/moby/client/secret_list.go b/vendor/github.com/moby/moby/client/secret_list.go index 2d14a6bed6..57fceb9a5b 100644 --- a/vendor/github.com/moby/moby/client/secret_list.go +++ b/vendor/github.com/moby/moby/client/secret_list.go @@ -5,7 +5,6 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" ) @@ -13,15 +12,7 @@ import ( func (cli *Client) SecretList(ctx context.Context, options SecretListOptions) ([]swarm.Secret, error) { query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } - + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/secrets", query, nil) defer ensureReaderClosed(resp) if err != nil { diff --git a/vendor/github.com/moby/moby/client/secret_list_opts.go b/vendor/github.com/moby/moby/client/secret_list_opts.go index 313eeefe39..f23c5fc68b 100644 --- a/vendor/github.com/moby/moby/client/secret_list_opts.go +++ b/vendor/github.com/moby/moby/client/secret_list_opts.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // SecretListOptions holds parameters to list secrets type SecretListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/vendor/github.com/moby/moby/client/service_list.go b/vendor/github.com/moby/moby/client/service_list.go index 5eaeae8ee5..d4b77b4256 100644 --- a/vendor/github.com/moby/moby/client/service_list.go +++ b/vendor/github.com/moby/moby/client/service_list.go @@ -5,7 +5,6 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" ) @@ -13,14 +12,7 @@ import ( func (cli *Client) ServiceList(ctx context.Context, options ServiceListOptions) ([]swarm.Service, error) { query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) if options.Status { query.Set("status", "true") diff --git a/vendor/github.com/moby/moby/client/swarm_config_list_options.go b/vendor/github.com/moby/moby/client/swarm_config_list_options.go index 91d4690c6a..b66fb359fc 100644 --- a/vendor/github.com/moby/moby/client/swarm_config_list_options.go +++ b/vendor/github.com/moby/moby/client/swarm_config_list_options.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // ConfigListOptions holds parameters to list configs type ConfigListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/vendor/github.com/moby/moby/client/swarm_node_list_opts.go b/vendor/github.com/moby/moby/client/swarm_node_list_opts.go index 9fb8c4245d..c5293cd174 100644 --- a/vendor/github.com/moby/moby/client/swarm_node_list_opts.go +++ b/vendor/github.com/moby/moby/client/swarm_node_list_opts.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // NodeListOptions holds parameters to list nodes with. type NodeListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/vendor/github.com/moby/moby/client/swarm_service_list_opts.go b/vendor/github.com/moby/moby/client/swarm_service_list_opts.go index 9b82376ac1..8a06f1bd3c 100644 --- a/vendor/github.com/moby/moby/client/swarm_service_list_opts.go +++ b/vendor/github.com/moby/moby/client/swarm_service_list_opts.go @@ -1,10 +1,8 @@ package client -import "github.com/moby/moby/api/types/filters" - // ServiceListOptions holds parameters to list services with. type ServiceListOptions struct { - Filters filters.Args + Filters Filters // Status indicates whether the server should include the service task // count of running and desired tasks. diff --git a/vendor/github.com/moby/moby/client/swarm_task_list_opts.go b/vendor/github.com/moby/moby/client/swarm_task_list_opts.go index 87e38135cd..d33f38e1e4 100644 --- a/vendor/github.com/moby/moby/client/swarm_task_list_opts.go +++ b/vendor/github.com/moby/moby/client/swarm_task_list_opts.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // TaskListOptions holds parameters to list tasks with. type TaskListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/vendor/github.com/moby/moby/client/system_events.go b/vendor/github.com/moby/moby/client/system_events.go index bee7402b59..598c2e25d3 100644 --- a/vendor/github.com/moby/moby/client/system_events.go +++ b/vendor/github.com/moby/moby/client/system_events.go @@ -8,7 +8,6 @@ import ( "github.com/moby/moby/api/types" "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/timestamp" ) @@ -17,7 +16,7 @@ import ( type EventsListOptions struct { Since 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 @@ -100,13 +99,7 @@ func buildEventsQueryParams(options EventsListOptions) (url.Values, error) { query.Set("until", ts) } - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) return query, nil } diff --git a/vendor/github.com/moby/moby/client/task_list.go b/vendor/github.com/moby/moby/client/task_list.go index 67ba443c54..bea82ad1bf 100644 --- a/vendor/github.com/moby/moby/client/task_list.go +++ b/vendor/github.com/moby/moby/client/task_list.go @@ -5,7 +5,6 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/swarm" ) @@ -13,14 +12,7 @@ import ( func (cli *Client) TaskList(ctx context.Context, options TaskListOptions) ([]swarm.Task, error) { query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return nil, err - } - - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/tasks", query, nil) defer ensureReaderClosed(resp) diff --git a/vendor/github.com/moby/moby/client/utils.go b/vendor/github.com/moby/moby/client/utils.go index 6908542419..3b5ef20bf9 100644 --- a/vendor/github.com/moby/moby/client/utils.go +++ b/vendor/github.com/moby/moby/client/utils.go @@ -3,11 +3,9 @@ package client import ( "encoding/json" "fmt" - "net/url" "strings" cerrdefs "github.com/containerd/errdefs" - "github.com/moby/moby/api/types/filters" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -28,20 +26,6 @@ func trimID(objType, id string) (string, error) { 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 // be used for query-parameters for filtering / selecting platforms. func encodePlatforms(platform ...ocispec.Platform) ([]string, error) { diff --git a/vendor/github.com/moby/moby/client/volume_list.go b/vendor/github.com/moby/moby/client/volume_list.go index 975d3330c1..2676fddbf5 100644 --- a/vendor/github.com/moby/moby/client/volume_list.go +++ b/vendor/github.com/moby/moby/client/volume_list.go @@ -5,7 +5,6 @@ import ( "encoding/json" "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/volume" ) @@ -13,13 +12,7 @@ import ( func (cli *Client) VolumeList(ctx context.Context, options VolumeListOptions) (volume.ListResponse, error) { query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToJSON(options.Filters) - if err != nil { - return volume.ListResponse{}, err - } - query.Set("filters", filterJSON) - } + options.Filters.updateURLValues(query) resp, err := cli.get(ctx, "/volumes", query, nil) defer ensureReaderClosed(resp) if err != nil { diff --git a/vendor/github.com/moby/moby/client/volume_list_opts.go b/vendor/github.com/moby/moby/client/volume_list_opts.go index f59aef94cd..6bb48963c6 100644 --- a/vendor/github.com/moby/moby/client/volume_list_opts.go +++ b/vendor/github.com/moby/moby/client/volume_list_opts.go @@ -1,8 +1,6 @@ package client -import "github.com/moby/moby/api/types/filters" - // VolumeListOptions holds parameters to list volumes. type VolumeListOptions struct { - Filters filters.Args + Filters Filters } diff --git a/vendor/github.com/moby/moby/client/volume_prune.go b/vendor/github.com/moby/moby/client/volume_prune.go index 1a04e85c5f..14ee71d3ae 100644 --- a/vendor/github.com/moby/moby/client/volume_prune.go +++ b/vendor/github.com/moby/moby/client/volume_prune.go @@ -4,17 +4,15 @@ import ( "context" "encoding/json" "fmt" + "net/url" - "github.com/moby/moby/api/types/filters" "github.com/moby/moby/api/types/volume" ) // VolumesPrune requests the daemon to delete unused data -func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters filters.Args) (volume.PruneReport, error) { - query, err := getFiltersQuery(pruneFilters) - if err != nil { - return volume.PruneReport{}, err - } +func (cli *Client) VolumesPrune(ctx context.Context, pruneFilters Filters) (volume.PruneReport, error) { + query := url.Values{} + pruneFilters.updateURLValues(query) resp, err := cli.post(ctx, "/volumes/prune", query, nil, nil) defer ensureReaderClosed(resp) diff --git a/vendor/modules.txt b/vendor/modules.txt index b258dc7118..cb4a1c122b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -951,7 +951,6 @@ github.com/moby/moby/api/types/checkpoint github.com/moby/moby/api/types/common github.com/moby/moby/api/types/container 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/jsonstream github.com/moby/moby/api/types/mount