Make sure current client code can talk for ImageList can still talk to
older daemon.
Signed-off-by: Vincent Demeester <vincent@sbr.pm>
| ... | ... |
@@ -144,6 +144,9 @@ func (filters Args) Add(name, value string) {
|
| 144 | 144 |
func (filters Args) Del(name, value string) {
|
| 145 | 145 |
if _, ok := filters.fields[name]; ok {
|
| 146 | 146 |
delete(filters.fields[name], value) |
| 147 |
+ if len(filters.fields[name]) == 0 {
|
|
| 148 |
+ delete(filters.fields, name) |
|
| 149 |
+ } |
|
| 147 | 150 |
} |
| 148 | 151 |
} |
| 149 | 152 |
|
| ... | ... |
@@ -6,6 +6,7 @@ import ( |
| 6 | 6 |
|
| 7 | 7 |
"github.com/docker/docker/api/types" |
| 8 | 8 |
"github.com/docker/docker/api/types/filters" |
| 9 |
+ "github.com/docker/docker/api/types/versions" |
|
| 9 | 10 |
"golang.org/x/net/context" |
| 10 | 11 |
) |
| 11 | 12 |
|
| ... | ... |
@@ -14,8 +15,16 @@ func (cli *Client) ImageList(ctx context.Context, options types.ImageListOptions |
| 14 | 14 |
var images []types.ImageSummary |
| 15 | 15 |
query := url.Values{}
|
| 16 | 16 |
|
| 17 |
- if options.Filters.Len() > 0 {
|
|
| 18 |
- filterJSON, err := filters.ToParamWithVersion(cli.version, options.Filters) |
|
| 17 |
+ optionFilters := options.Filters |
|
| 18 |
+ referenceFilters := optionFilters.Get("reference")
|
|
| 19 |
+ if versions.LessThan(cli.version, "1.25") && len(referenceFilters) > 0 {
|
|
| 20 |
+ query.Set("filter", referenceFilters[0])
|
|
| 21 |
+ for _, filterValue := range referenceFilters {
|
|
| 22 |
+ optionFilters.Del("reference", filterValue)
|
|
| 23 |
+ } |
|
| 24 |
+ } |
|
| 25 |
+ if optionFilters.Len() > 0 {
|
|
| 26 |
+ filterJSON, err := filters.ToParamWithVersion(cli.version, optionFilters) |
|
| 19 | 27 |
if err != nil {
|
| 20 | 28 |
return images, err |
| 21 | 29 |
} |
| ... | ... |
@@ -109,3 +109,51 @@ func TestImageList(t *testing.T) {
|
| 109 | 109 |
} |
| 110 | 110 |
} |
| 111 | 111 |
} |
| 112 |
+ |
|
| 113 |
+func TestImageListApiBefore125(t *testing.T) {
|
|
| 114 |
+ expectedFilter := "image:tag" |
|
| 115 |
+ client := &Client{
|
|
| 116 |
+ client: newMockClient(func(req *http.Request) (*http.Response, error) {
|
|
| 117 |
+ query := req.URL.Query() |
|
| 118 |
+ actualFilter := query.Get("filter")
|
|
| 119 |
+ if actualFilter != expectedFilter {
|
|
| 120 |
+ return nil, fmt.Errorf("filter not set in URL query properly. Expected '%s', got %s", expectedFilter, actualFilter)
|
|
| 121 |
+ } |
|
| 122 |
+ actualFilters := query.Get("filters")
|
|
| 123 |
+ if actualFilters != "" {
|
|
| 124 |
+ return nil, fmt.Errorf("filters should have not been present, were with value: %s", actualFilters)
|
|
| 125 |
+ } |
|
| 126 |
+ content, err := json.Marshal([]types.ImageSummary{
|
|
| 127 |
+ {
|
|
| 128 |
+ ID: "image_id2", |
|
| 129 |
+ }, |
|
| 130 |
+ {
|
|
| 131 |
+ ID: "image_id2", |
|
| 132 |
+ }, |
|
| 133 |
+ }) |
|
| 134 |
+ if err != nil {
|
|
| 135 |
+ return nil, err |
|
| 136 |
+ } |
|
| 137 |
+ return &http.Response{
|
|
| 138 |
+ StatusCode: http.StatusOK, |
|
| 139 |
+ Body: ioutil.NopCloser(bytes.NewReader(content)), |
|
| 140 |
+ }, nil |
|
| 141 |
+ }), |
|
| 142 |
+ version: "1.24", |
|
| 143 |
+ } |
|
| 144 |
+ |
|
| 145 |
+ filters := filters.NewArgs() |
|
| 146 |
+ filters.Add("reference", "image:tag")
|
|
| 147 |
+ |
|
| 148 |
+ options := types.ImageListOptions{
|
|
| 149 |
+ Filters: filters, |
|
| 150 |
+ } |
|
| 151 |
+ |
|
| 152 |
+ images, err := client.ImageList(context.Background(), options) |
|
| 153 |
+ if err != nil {
|
|
| 154 |
+ t.Fatal(err) |
|
| 155 |
+ } |
|
| 156 |
+ if len(images) != 2 {
|
|
| 157 |
+ t.Fatalf("expected 2 images, got %v", images)
|
|
| 158 |
+ } |
|
| 159 |
+} |