From c6e31454ba2f053bc6831651663cf538d142afaa Mon Sep 17 00:00:00 2001 From: Vincent Demeester Date: Mon, 28 Nov 2016 22:15:50 +0100 Subject: [PATCH] Fixes ImageList to be retro-compatible with older API Make sure current client code can talk for ImageList can still talk to older daemon. Signed-off-by: Vincent Demeester --- api/types/filters/parse.go | 3 +++ client/image_list.go | 13 +++++++++-- client/image_list_test.go | 48 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/api/types/filters/parse.go b/api/types/filters/parse.go index b0aa824618..e01a41deb8 100644 --- a/api/types/filters/parse.go +++ b/api/types/filters/parse.go @@ -144,6 +144,9 @@ func (filters Args) Add(name, value string) { func (filters Args) Del(name, value string) { if _, ok := filters.fields[name]; ok { delete(filters.fields[name], value) + if len(filters.fields[name]) == 0 { + delete(filters.fields, name) + } } } diff --git a/client/image_list.go b/client/image_list.go index 63c71b1dd1..f26464f67c 100644 --- a/client/image_list.go +++ b/client/image_list.go @@ -6,6 +6,7 @@ import ( "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" + "github.com/docker/docker/api/types/versions" "golang.org/x/net/context" ) @@ -14,8 +15,16 @@ func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions var images []types.ImageSummary query := url.Values{} - if options.Filters.Len() > 0 { - filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) + optionFilters := options.Filters + referenceFilters := optionFilters.Get("reference") + if versions.LessThan(cli.version, "1.25") && len(referenceFilters) > 0 { + query.Set("filter", referenceFilters[0]) + for _, filterValue := range referenceFilters { + optionFilters.Del("reference", filterValue) + } + } + if optionFilters.Len() > 0 { + filterJSON, err := filters.ToParamWithVersion(cli.version, optionFilters) if err != nil { return images, err } diff --git a/client/image_list_test.go b/client/image_list_test.go index 1c9406ddda..7c4a46414d 100644 --- a/client/image_list_test.go +++ b/client/image_list_test.go @@ -109,3 +109,51 @@ func TestImageList(t *testing.T) { } } } + +func TestImageListApiBefore125(t *testing.T) { + expectedFilter := "image:tag" + client := &Client{ + client: newMockClient(func(req *http.Request) (*http.Response, error) { + query := req.URL.Query() + actualFilter := query.Get("filter") + if actualFilter != expectedFilter { + return nil, fmt.Errorf("filter not set in URL query properly. Expected '%s', got %s", expectedFilter, actualFilter) + } + actualFilters := query.Get("filters") + if actualFilters != "" { + return nil, fmt.Errorf("filters should have not been present, were with value: %s", actualFilters) + } + content, err := json.Marshal([]types.ImageSummary{ + { + ID: "image_id2", + }, + { + ID: "image_id2", + }, + }) + if err != nil { + return nil, err + } + return &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(bytes.NewReader(content)), + }, nil + }), + version: "1.24", + } + + filters := filters.NewArgs() + filters.Add("reference", "image:tag") + + options := types.ImageListOptions{ + Filters: filters, + } + + images, err := client.ImageList(context.Background(), options) + if err != nil { + t.Fatal(err) + } + if len(images) != 2 { + t.Fatalf("expected 2 images, got %v", images) + } +}