Browse code

Remove Job from `docker images`

Also removes engine.Table

Signed-off-by: Doug Davis <dug@us.ibm.com>

Doug Davis authored on 2015/04/08 10:57:54
Showing 13 changed files
... ...
@@ -24,6 +24,7 @@ import (
24 24
 	"github.com/docker/docker/daemon"
25 25
 	"github.com/docker/docker/daemon/networkdriver/bridge"
26 26
 	"github.com/docker/docker/engine"
27
+	"github.com/docker/docker/graph"
27 28
 	"github.com/docker/docker/pkg/jsonmessage"
28 29
 	"github.com/docker/docker/pkg/parsers"
29 30
 	"github.com/docker/docker/pkg/parsers/filters"
... ...
@@ -264,48 +265,40 @@ func getImagesJSON(eng *engine.Engine, version version.Version, w http.ResponseW
264 264
 		return err
265 265
 	}
266 266
 
267
-	var (
268
-		err  error
269
-		outs *engine.Table
270
-		job  = eng.Job("images")
271
-	)
272
-
273
-	job.Setenv("filters", r.Form.Get("filters"))
274
-	// FIXME this parameter could just be a match filter
275
-	job.Setenv("filter", r.Form.Get("filter"))
276
-	job.Setenv("all", r.Form.Get("all"))
267
+	imagesConfig := graph.ImagesConfig{
268
+		Filters: r.Form.Get("filters"),
269
+		// FIXME this parameter could just be a match filter
270
+		Filter: r.Form.Get("filter"),
271
+		All:    toBool(r.Form.Get("all")),
272
+	}
277 273
 
278
-	if version.GreaterThanOrEqualTo("1.7") {
279
-		streamJSON(job, w, false)
280
-	} else if outs, err = job.Stdout.AddListTable(); err != nil {
274
+	images, err := getDaemon(eng).Repositories().Images(&imagesConfig)
275
+	if err != nil {
281 276
 		return err
282 277
 	}
283 278
 
284
-	if err := job.Run(); err != nil {
285
-		return err
279
+	if version.GreaterThanOrEqualTo("1.7") {
280
+		return writeJSON(w, http.StatusOK, images)
286 281
 	}
287 282
 
288
-	if version.LessThan("1.7") && outs != nil { // Convert to legacy format
289
-		outsLegacy := engine.NewTable("Created", 0)
290
-		for _, out := range outs.Data {
291
-			for _, repoTag := range out.GetList("RepoTags") {
292
-				repo, tag := parsers.ParseRepositoryTag(repoTag)
293
-				outLegacy := &engine.Env{}
294
-				outLegacy.Set("Repository", repo)
295
-				outLegacy.SetJson("Tag", tag)
296
-				outLegacy.Set("Id", out.Get("Id"))
297
-				outLegacy.SetInt64("Created", out.GetInt64("Created"))
298
-				outLegacy.SetInt64("Size", out.GetInt64("Size"))
299
-				outLegacy.SetInt64("VirtualSize", out.GetInt64("VirtualSize"))
300
-				outsLegacy.Add(outLegacy)
283
+	legacyImages := []types.LegacyImage{}
284
+
285
+	for _, image := range images {
286
+		for _, repoTag := range image.RepoTags {
287
+			repo, tag := parsers.ParseRepositoryTag(repoTag)
288
+			legacyImage := types.LegacyImage{
289
+				Repository:  repo,
290
+				Tag:         tag,
291
+				ID:          image.ID,
292
+				Created:     image.Created,
293
+				Size:        image.Size,
294
+				VirtualSize: image.VirtualSize,
301 295
 			}
302
-		}
303
-		w.Header().Set("Content-Type", "application/json")
304
-		if _, err := outsLegacy.WriteListTo(w); err != nil {
305
-			return err
296
+			legacyImages = append(legacyImages, legacyImage)
306 297
 		}
307 298
 	}
308
-	return nil
299
+
300
+	return writeJSON(w, http.StatusOK, legacyImages)
309 301
 }
310 302
 
311 303
 func getImagesViz(eng *engine.Engine, version version.Version, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
... ...
@@ -488,8 +481,8 @@ func getContainersJSON(eng *engine.Engine, version version.Version, w http.Respo
488 488
 	}
489 489
 
490 490
 	config := &daemon.ContainersConfig{
491
-		All:     r.Form.Get("all") == "1",
492
-		Size:    r.Form.Get("size") == "1",
491
+		All:     toBool(r.Form.Get("all")),
492
+		Size:    toBool(r.Form.Get("size")),
493 493
 		Since:   r.Form.Get("since"),
494 494
 		Before:  r.Form.Get("before"),
495 495
 		Filters: r.Form.Get("filters"),
... ...
@@ -1140,14 +1133,14 @@ func postBuild(eng *engine.Engine, version version.Version, w http.ResponseWrite
1140 1140
 		job.Stdout.Add(utils.NewWriteFlusher(w))
1141 1141
 	}
1142 1142
 
1143
-	if r.FormValue("forcerm") == "1" && version.GreaterThanOrEqualTo("1.12") {
1143
+	if toBool(r.FormValue("forcerm")) && version.GreaterThanOrEqualTo("1.12") {
1144 1144
 		job.Setenv("rm", "1")
1145 1145
 	} else if r.FormValue("rm") == "" && version.GreaterThanOrEqualTo("1.12") {
1146 1146
 		job.Setenv("rm", "1")
1147 1147
 	} else {
1148 1148
 		job.Setenv("rm", r.FormValue("rm"))
1149 1149
 	}
1150
-	if r.FormValue("pull") == "1" && version.GreaterThanOrEqualTo("1.16") {
1150
+	if toBool(r.FormValue("pull")) && version.GreaterThanOrEqualTo("1.16") {
1151 1151
 		job.Setenv("pull", "1")
1152 1152
 	}
1153 1153
 	job.Stdin.Add(r.Body)
... ...
@@ -1557,3 +1550,8 @@ func ServeApi(job *engine.Job) error {
1557 1557
 
1558 1558
 	return nil
1559 1559
 }
1560
+
1561
+func toBool(s string) bool {
1562
+	s = strings.ToLower(strings.TrimSpace(s))
1563
+	return !(s == "" || s == "0" || s == "no" || s == "false" || s == "none")
1564
+}
... ...
@@ -7,7 +7,6 @@ import (
7 7
 	"io"
8 8
 	"net/http"
9 9
 	"net/http/httptest"
10
-	"reflect"
11 10
 	"strings"
12 11
 	"testing"
13 12
 
... ...
@@ -117,106 +116,6 @@ func TestGetInfo(t *testing.T) {
117 117
 	assertContentType(r, "application/json", t)
118 118
 }
119 119
 
120
-func TestGetImagesJSON(t *testing.T) {
121
-	eng := engine.New()
122
-	var called bool
123
-	eng.Register("images", func(job *engine.Job) error {
124
-		called = true
125
-		v := createEnvFromGetImagesJSONStruct(sampleImage)
126
-		if err := json.NewEncoder(job.Stdout).Encode(v); err != nil {
127
-			return err
128
-		}
129
-		return nil
130
-	})
131
-	r := serveRequest("GET", "/images/json", nil, eng, t)
132
-	if !called {
133
-		t.Fatal("handler was not called")
134
-	}
135
-	assertHttpNotError(r, t)
136
-	assertContentType(r, "application/json", t)
137
-	var observed getImagesJSONStruct
138
-	if err := json.Unmarshal(r.Body.Bytes(), &observed); err != nil {
139
-		t.Fatal(err)
140
-	}
141
-	if !reflect.DeepEqual(observed, sampleImage) {
142
-		t.Errorf("Expected %#v but got %#v", sampleImage, observed)
143
-	}
144
-}
145
-
146
-func TestGetImagesJSONFilter(t *testing.T) {
147
-	eng := engine.New()
148
-	filter := "nothing"
149
-	eng.Register("images", func(job *engine.Job) error {
150
-		filter = job.Getenv("filter")
151
-		return nil
152
-	})
153
-	serveRequest("GET", "/images/json?filter=aaaa", nil, eng, t)
154
-	if filter != "aaaa" {
155
-		t.Errorf("%#v", filter)
156
-	}
157
-}
158
-
159
-func TestGetImagesJSONFilters(t *testing.T) {
160
-	eng := engine.New()
161
-	filter := "nothing"
162
-	eng.Register("images", func(job *engine.Job) error {
163
-		filter = job.Getenv("filters")
164
-		return nil
165
-	})
166
-	serveRequest("GET", "/images/json?filters=nnnn", nil, eng, t)
167
-	if filter != "nnnn" {
168
-		t.Errorf("%#v", filter)
169
-	}
170
-}
171
-
172
-func TestGetImagesJSONAll(t *testing.T) {
173
-	eng := engine.New()
174
-	allFilter := "-1"
175
-	eng.Register("images", func(job *engine.Job) error {
176
-		allFilter = job.Getenv("all")
177
-		return nil
178
-	})
179
-	serveRequest("GET", "/images/json?all=1", nil, eng, t)
180
-	if allFilter != "1" {
181
-		t.Errorf("%#v", allFilter)
182
-	}
183
-}
184
-
185
-func TestGetImagesJSONLegacyFormat(t *testing.T) {
186
-	eng := engine.New()
187
-	var called bool
188
-	eng.Register("images", func(job *engine.Job) error {
189
-		called = true
190
-		images := []types.Image{
191
-			createEnvFromGetImagesJSONStruct(sampleImage),
192
-		}
193
-		if err := json.NewEncoder(job.Stdout).Encode(images); err != nil {
194
-			return err
195
-		}
196
-		return nil
197
-	})
198
-	r := serveRequestUsingVersion("GET", "/images/json", "1.6", nil, eng, t)
199
-	if !called {
200
-		t.Fatal("handler was not called")
201
-	}
202
-	assertHttpNotError(r, t)
203
-	assertContentType(r, "application/json", t)
204
-	images := engine.NewTable("Created", 0)
205
-	if _, err := images.ReadListFrom(r.Body.Bytes()); err != nil {
206
-		t.Fatal(err)
207
-	}
208
-	if images.Len() != 1 {
209
-		t.Fatalf("Expected 1 image, %d found", images.Len())
210
-	}
211
-	image := images.Data[0]
212
-	if image.Get("Tag") != "test-tag" {
213
-		t.Errorf("Expected tag 'test-tag', found '%s'", image.Get("Tag"))
214
-	}
215
-	if image.Get("Repository") != "test-name" {
216
-		t.Errorf("Expected repository 'test-name', found '%s'", image.Get("Repository"))
217
-	}
218
-}
219
-
220 120
 func TestGetContainersByName(t *testing.T) {
221 121
 	eng := engine.New()
222 122
 	name := "container_name"
... ...
@@ -69,6 +69,15 @@ type Image struct {
69 69
 	Labels      map[string]string
70 70
 }
71 71
 
72
+type LegacyImage struct {
73
+	ID          string `json:"Id"`
74
+	Repository  string
75
+	Tag         string
76
+	Created     int
77
+	Size        int
78
+	VirtualSize int
79
+}
80
+
72 81
 // GET  "/containers/json"
73 82
 type Port struct {
74 83
 	IP          string
... ...
@@ -4,7 +4,6 @@ import (
4 4
 	"bytes"
5 5
 	"fmt"
6 6
 	"io"
7
-	"io/ioutil"
8 7
 	"strings"
9 8
 	"sync"
10 9
 	"unicode"
... ...
@@ -187,39 +186,3 @@ func (o *Output) AddEnv() (dst *Env, err error) {
187 187
 	}()
188 188
 	return dst, nil
189 189
 }
190
-
191
-func (o *Output) AddListTable() (dst *Table, err error) {
192
-	src, err := o.AddPipe()
193
-	if err != nil {
194
-		return nil, err
195
-	}
196
-	dst = NewTable("", 0)
197
-	o.tasks.Add(1)
198
-	go func() {
199
-		defer o.tasks.Done()
200
-		content, err := ioutil.ReadAll(src)
201
-		if err != nil {
202
-			return
203
-		}
204
-		if _, err := dst.ReadListFrom(content); err != nil {
205
-			return
206
-		}
207
-	}()
208
-	return dst, nil
209
-}
210
-
211
-func (o *Output) AddTable() (dst *Table, err error) {
212
-	src, err := o.AddPipe()
213
-	if err != nil {
214
-		return nil, err
215
-	}
216
-	dst = NewTable("", 0)
217
-	o.tasks.Add(1)
218
-	go func() {
219
-		defer o.tasks.Done()
220
-		if _, err := dst.ReadFrom(src); err != nil {
221
-			return
222
-		}
223
-	}()
224
-	return dst, nil
225
-}
226 190
deleted file mode 100644
... ...
@@ -1,140 +0,0 @@
1
-package engine
2
-
3
-import (
4
-	"bytes"
5
-	"encoding/json"
6
-	"io"
7
-	"sort"
8
-	"strconv"
9
-)
10
-
11
-type Table struct {
12
-	Data    []*Env
13
-	sortKey string
14
-	Chan    chan *Env
15
-}
16
-
17
-func NewTable(sortKey string, sizeHint int) *Table {
18
-	return &Table{
19
-		make([]*Env, 0, sizeHint),
20
-		sortKey,
21
-		make(chan *Env),
22
-	}
23
-}
24
-
25
-func (t *Table) SetKey(sortKey string) {
26
-	t.sortKey = sortKey
27
-}
28
-
29
-func (t *Table) Add(env *Env) {
30
-	t.Data = append(t.Data, env)
31
-}
32
-
33
-func (t *Table) Len() int {
34
-	return len(t.Data)
35
-}
36
-
37
-func (t *Table) Less(a, b int) bool {
38
-	return t.lessBy(a, b, t.sortKey)
39
-}
40
-
41
-func (t *Table) lessBy(a, b int, by string) bool {
42
-	keyA := t.Data[a].Get(by)
43
-	keyB := t.Data[b].Get(by)
44
-	intA, errA := strconv.ParseInt(keyA, 10, 64)
45
-	intB, errB := strconv.ParseInt(keyB, 10, 64)
46
-	if errA == nil && errB == nil {
47
-		return intA < intB
48
-	}
49
-	return keyA < keyB
50
-}
51
-
52
-func (t *Table) Swap(a, b int) {
53
-	tmp := t.Data[a]
54
-	t.Data[a] = t.Data[b]
55
-	t.Data[b] = tmp
56
-}
57
-
58
-func (t *Table) Sort() {
59
-	sort.Sort(t)
60
-}
61
-
62
-func (t *Table) ReverseSort() {
63
-	sort.Sort(sort.Reverse(t))
64
-}
65
-
66
-func (t *Table) WriteListTo(dst io.Writer) (n int64, err error) {
67
-	if _, err := dst.Write([]byte{'['}); err != nil {
68
-		return -1, err
69
-	}
70
-	n = 1
71
-	for i, env := range t.Data {
72
-		bytes, err := env.WriteTo(dst)
73
-		if err != nil {
74
-			return -1, err
75
-		}
76
-		n += bytes
77
-		if i != len(t.Data)-1 {
78
-			if _, err := dst.Write([]byte{','}); err != nil {
79
-				return -1, err
80
-			}
81
-			n++
82
-		}
83
-	}
84
-	if _, err := dst.Write([]byte{']'}); err != nil {
85
-		return -1, err
86
-	}
87
-	return n + 1, nil
88
-}
89
-
90
-func (t *Table) ToListString() (string, error) {
91
-	buffer := bytes.NewBuffer(nil)
92
-	if _, err := t.WriteListTo(buffer); err != nil {
93
-		return "", err
94
-	}
95
-	return buffer.String(), nil
96
-}
97
-
98
-func (t *Table) WriteTo(dst io.Writer) (n int64, err error) {
99
-	for _, env := range t.Data {
100
-		bytes, err := env.WriteTo(dst)
101
-		if err != nil {
102
-			return -1, err
103
-		}
104
-		n += bytes
105
-	}
106
-	return n, nil
107
-}
108
-
109
-func (t *Table) ReadListFrom(src []byte) (n int64, err error) {
110
-	var array []interface{}
111
-
112
-	if err := json.Unmarshal(src, &array); err != nil {
113
-		return -1, err
114
-	}
115
-
116
-	for _, item := range array {
117
-		if m, ok := item.(map[string]interface{}); ok {
118
-			env := &Env{}
119
-			for key, value := range m {
120
-				env.SetAuto(key, value)
121
-			}
122
-			t.Add(env)
123
-		}
124
-	}
125
-
126
-	return int64(len(src)), nil
127
-}
128
-
129
-func (t *Table) ReadFrom(src io.Reader) (n int64, err error) {
130
-	decoder := NewDecoder(src)
131
-	for {
132
-		env, err := decoder.Decode()
133
-		if err == io.EOF {
134
-			return 0, nil
135
-		} else if err != nil {
136
-			return -1, err
137
-		}
138
-		t.Add(env)
139
-	}
140
-}
141 1
deleted file mode 100644
... ...
@@ -1,112 +0,0 @@
1
-package engine
2
-
3
-import (
4
-	"bytes"
5
-	"encoding/json"
6
-	"testing"
7
-)
8
-
9
-func TestTableWriteTo(t *testing.T) {
10
-	table := NewTable("", 0)
11
-	e := &Env{}
12
-	e.Set("foo", "bar")
13
-	table.Add(e)
14
-	var buf bytes.Buffer
15
-	if _, err := table.WriteTo(&buf); err != nil {
16
-		t.Fatal(err)
17
-	}
18
-	output := make(map[string]string)
19
-	if err := json.Unmarshal(buf.Bytes(), &output); err != nil {
20
-		t.Fatal(err)
21
-	}
22
-	if len(output) != 1 {
23
-		t.Fatalf("Incorrect output: %v", output)
24
-	}
25
-	if val, exists := output["foo"]; !exists || val != "bar" {
26
-		t.Fatalf("Inccorect output: %v", output)
27
-	}
28
-}
29
-
30
-func TestTableSortStringValue(t *testing.T) {
31
-	table := NewTable("Key", 0)
32
-
33
-	e := &Env{}
34
-	e.Set("Key", "A")
35
-	table.Add(e)
36
-
37
-	e = &Env{}
38
-	e.Set("Key", "D")
39
-	table.Add(e)
40
-
41
-	e = &Env{}
42
-	e.Set("Key", "B")
43
-	table.Add(e)
44
-
45
-	e = &Env{}
46
-	e.Set("Key", "C")
47
-	table.Add(e)
48
-
49
-	table.Sort()
50
-
51
-	if len := table.Len(); len != 4 {
52
-		t.Fatalf("Expected 4, got %d", len)
53
-	}
54
-
55
-	if value := table.Data[0].Get("Key"); value != "A" {
56
-		t.Fatalf("Expected A, got %s", value)
57
-	}
58
-
59
-	if value := table.Data[1].Get("Key"); value != "B" {
60
-		t.Fatalf("Expected B, got %s", value)
61
-	}
62
-
63
-	if value := table.Data[2].Get("Key"); value != "C" {
64
-		t.Fatalf("Expected C, got %s", value)
65
-	}
66
-
67
-	if value := table.Data[3].Get("Key"); value != "D" {
68
-		t.Fatalf("Expected D, got %s", value)
69
-	}
70
-}
71
-
72
-func TestTableReverseSortStringValue(t *testing.T) {
73
-	table := NewTable("Key", 0)
74
-
75
-	e := &Env{}
76
-	e.Set("Key", "A")
77
-	table.Add(e)
78
-
79
-	e = &Env{}
80
-	e.Set("Key", "D")
81
-	table.Add(e)
82
-
83
-	e = &Env{}
84
-	e.Set("Key", "B")
85
-	table.Add(e)
86
-
87
-	e = &Env{}
88
-	e.Set("Key", "C")
89
-	table.Add(e)
90
-
91
-	table.ReverseSort()
92
-
93
-	if len := table.Len(); len != 4 {
94
-		t.Fatalf("Expected 4, got %d", len)
95
-	}
96
-
97
-	if value := table.Data[0].Get("Key"); value != "D" {
98
-		t.Fatalf("Expected D, got %s", value)
99
-	}
100
-
101
-	if value := table.Data[1].Get("Key"); value != "C" {
102
-		t.Fatalf("Expected B, got %s", value)
103
-	}
104
-
105
-	if value := table.Data[2].Get("Key"); value != "B" {
106
-		t.Fatalf("Expected C, got %s", value)
107
-	}
108
-
109
-	if value := table.Data[3].Get("Key"); value != "A" {
110
-		t.Fatalf("Expected A, got %s", value)
111
-	}
112
-}
... ...
@@ -1,7 +1,6 @@
1 1
 package graph
2 2
 
3 3
 import (
4
-	"encoding/json"
5 4
 	"fmt"
6 5
 	"log"
7 6
 	"path"
... ...
@@ -9,7 +8,6 @@ import (
9 9
 	"strings"
10 10
 
11 11
 	"github.com/docker/docker/api/types"
12
-	"github.com/docker/docker/engine"
13 12
 	"github.com/docker/docker/image"
14 13
 	"github.com/docker/docker/pkg/parsers/filters"
15 14
 	"github.com/docker/docker/utils"
... ...
@@ -20,13 +18,19 @@ var acceptedImageFilterTags = map[string]struct{}{
20 20
 	"label":    {},
21 21
 }
22 22
 
23
+type ImagesConfig struct {
24
+	Filters string
25
+	Filter  string
26
+	All     bool
27
+}
28
+
23 29
 type ByCreated []*types.Image
24 30
 
25 31
 func (r ByCreated) Len() int           { return len(r) }
26 32
 func (r ByCreated) Swap(i, j int)      { r[i], r[j] = r[j], r[i] }
27 33
 func (r ByCreated) Less(i, j int) bool { return r[i].Created < r[j].Created }
28 34
 
29
-func (s *TagStore) CmdImages(job *engine.Job) error {
35
+func (s *TagStore) Images(config *ImagesConfig) ([]*types.Image, error) {
30 36
 	var (
31 37
 		allImages  map[string]*image.Image
32 38
 		err        error
... ...
@@ -34,13 +38,13 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
34 34
 		filtLabel  = false
35 35
 	)
36 36
 
37
-	imageFilters, err := filters.FromParam(job.Getenv("filters"))
37
+	imageFilters, err := filters.FromParam(config.Filters)
38 38
 	if err != nil {
39
-		return err
39
+		return nil, err
40 40
 	}
41 41
 	for name := range imageFilters {
42 42
 		if _, ok := acceptedImageFilterTags[name]; !ok {
43
-			return fmt.Errorf("Invalid filter '%s'", name)
43
+			return nil, fmt.Errorf("Invalid filter '%s'", name)
44 44
 		}
45 45
 	}
46 46
 
... ...
@@ -54,20 +58,20 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
54 54
 
55 55
 	_, filtLabel = imageFilters["label"]
56 56
 
57
-	if job.GetenvBool("all") && filtTagged {
57
+	if config.All && filtTagged {
58 58
 		allImages, err = s.graph.Map()
59 59
 	} else {
60 60
 		allImages, err = s.graph.Heads()
61 61
 	}
62 62
 	if err != nil {
63
-		return err
63
+		return nil, err
64 64
 	}
65 65
 
66 66
 	lookup := make(map[string]*types.Image)
67 67
 	s.Lock()
68 68
 	for repoName, repository := range s.Repositories {
69
-		if job.Getenv("filter") != "" {
70
-			if match, _ := path.Match(job.Getenv("filter"), repoName); !match {
69
+		if config.Filter != "" {
70
+			if match, _ := path.Match(config.Filter, repoName); !match {
71 71
 				continue
72 72
 			}
73 73
 		}
... ...
@@ -124,7 +128,7 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
124 124
 	}
125 125
 
126 126
 	// Display images which aren't part of a repository/tag
127
-	if job.Getenv("filter") == "" || filtLabel {
127
+	if config.Filter == "" || filtLabel {
128 128
 		for _, image := range allImages {
129 129
 			if !imageFilters.MatchKVList("label", image.ContainerConfig.Labels) {
130 130
 				continue
... ...
@@ -145,8 +149,5 @@ func (s *TagStore) CmdImages(job *engine.Job) error {
145 145
 
146 146
 	sort.Sort(sort.Reverse(ByCreated(images)))
147 147
 
148
-	if err = json.NewEncoder(job.Stdout).Encode(images); err != nil {
149
-		return err
150
-	}
151
-	return nil
148
+	return images, nil
152 149
 }
... ...
@@ -18,7 +18,6 @@ func (s *TagStore) Install(eng *engine.Engine) error {
18 18
 		"image_tarlayer": s.CmdTarLayer,
19 19
 		"image_export":   s.CmdImageExport,
20 20
 		"history":        s.CmdHistory,
21
-		"images":         s.CmdImages,
22 21
 		"viz":            s.CmdViz,
23 22
 		"load":           s.CmdLoad,
24 23
 		"import":         s.CmdImport,
25 24
new file mode 100644
... ...
@@ -0,0 +1,26 @@
0
+package main
1
+
2
+import (
3
+	"encoding/json"
4
+	"testing"
5
+
6
+	"github.com/docker/docker/api/types"
7
+)
8
+
9
+func TestLegacyImages(t *testing.T) {
10
+	body, err := sockRequest("GET", "/v1.6/images/json", nil)
11
+	if err != nil {
12
+		t.Fatalf("Error on GET: %s", err)
13
+	}
14
+
15
+	images := []types.LegacyImage{}
16
+	if err = json.Unmarshal(body, &images); err != nil {
17
+		t.Fatalf("Error on unmarshal: %s", err)
18
+	}
19
+
20
+	if len(images) == 0 || images[0].Tag == "" || images[0].Repository == "" {
21
+		t.Fatalf("Bad data: %q", images)
22
+	}
23
+
24
+	logDone("images - checking legacy json")
25
+}
... ...
@@ -767,8 +767,8 @@ func TestDeleteImages(t *testing.T) {
767 767
 
768 768
 	images := getImages(eng, t, true, "")
769 769
 
770
-	if len(images.Data[0].GetList("RepoTags")) != len(initialImages.Data[0].GetList("RepoTags"))+1 {
771
-		t.Errorf("Expected %d images, %d found", len(initialImages.Data[0].GetList("RepoTags"))+1, len(images.Data[0].GetList("RepoTags")))
770
+	if len(images[0].RepoTags) != len(initialImages[0].RepoTags)+1 {
771
+		t.Errorf("Expected %d images, %d found", len(initialImages[0].RepoTags)+1, len(images[0].RepoTags))
772 772
 	}
773 773
 
774 774
 	req, err := http.NewRequest("DELETE", "/images/"+unitTestImageID, nil)
... ...
@@ -805,8 +805,8 @@ func TestDeleteImages(t *testing.T) {
805 805
 	}
806 806
 	images = getImages(eng, t, false, "")
807 807
 
808
-	if images.Len() != initialImages.Len() {
809
-		t.Errorf("Expected %d image, %d found", initialImages.Len(), images.Len())
808
+	if len(images) != len(initialImages) {
809
+		t.Errorf("Expected %d image, %d found", len(initialImages), len(images))
810 810
 	}
811 811
 }
812 812
 
... ...
@@ -20,6 +20,7 @@ import (
20 20
 	"github.com/docker/docker/daemon"
21 21
 	"github.com/docker/docker/daemon/execdriver"
22 22
 	"github.com/docker/docker/engine"
23
+	"github.com/docker/docker/graph"
23 24
 	"github.com/docker/docker/image"
24 25
 	"github.com/docker/docker/nat"
25 26
 	"github.com/docker/docker/pkg/ioutils"
... ...
@@ -65,17 +66,13 @@ func cleanup(eng *engine.Engine, t *testing.T) error {
65 65
 		container.Kill()
66 66
 		daemon.Rm(container)
67 67
 	}
68
-	job := eng.Job("images")
69
-	images, err := job.Stdout.AddTable()
68
+	images, err := daemon.Repositories().Images(&graph.ImagesConfig{})
70 69
 	if err != nil {
71 70
 		t.Fatal(err)
72 71
 	}
73
-	if err := job.Run(); err != nil {
74
-		t.Fatal(err)
75
-	}
76
-	for _, image := range images.Data {
77
-		if image.Get("Id") != unitTestImageID {
78
-			eng.Job("image_delete", image.Get("Id")).Run()
72
+	for _, image := range images {
73
+		if image.ID != unitTestImageID {
74
+			eng.Job("image_delete", image.ID).Run()
79 75
 		}
80 76
 	}
81 77
 	return nil
... ...
@@ -253,25 +253,25 @@ func TestImagesFilter(t *testing.T) {
253 253
 
254 254
 	images := getImages(eng, t, false, "utest*/*")
255 255
 
256
-	if len(images.Data[0].GetList("RepoTags")) != 2 {
256
+	if len(images[0].RepoTags) != 2 {
257 257
 		t.Fatal("incorrect number of matches returned")
258 258
 	}
259 259
 
260 260
 	images = getImages(eng, t, false, "utest")
261 261
 
262
-	if len(images.Data[0].GetList("RepoTags")) != 1 {
262
+	if len(images[0].RepoTags) != 1 {
263 263
 		t.Fatal("incorrect number of matches returned")
264 264
 	}
265 265
 
266 266
 	images = getImages(eng, t, false, "utest*")
267 267
 
268
-	if len(images.Data[0].GetList("RepoTags")) != 1 {
268
+	if len(images[0].RepoTags) != 1 {
269 269
 		t.Fatal("incorrect number of matches returned")
270 270
 	}
271 271
 
272 272
 	images = getImages(eng, t, false, "*5000*/*")
273 273
 
274
-	if len(images.Data[0].GetList("RepoTags")) != 1 {
274
+	if len(images[0].RepoTags) != 1 {
275 275
 		t.Fatal("incorrect number of matches returned")
276 276
 	}
277 277
 }
... ...
@@ -16,9 +16,11 @@ import (
16 16
 
17 17
 	"github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar"
18 18
 
19
+	"github.com/docker/docker/api/types"
19 20
 	"github.com/docker/docker/builtins"
20 21
 	"github.com/docker/docker/daemon"
21 22
 	"github.com/docker/docker/engine"
23
+	"github.com/docker/docker/graph"
22 24
 	flag "github.com/docker/docker/pkg/mflag"
23 25
 	"github.com/docker/docker/registry"
24 26
 	"github.com/docker/docker/runconfig"
... ...
@@ -329,19 +331,17 @@ func fakeTar() (io.ReadCloser, error) {
329 329
 	return ioutil.NopCloser(buf), nil
330 330
 }
331 331
 
332
-func getImages(eng *engine.Engine, t *testing.T, all bool, filter string) *engine.Table {
333
-	job := eng.Job("images")
334
-	job.SetenvBool("all", all)
335
-	job.Setenv("filter", filter)
336
-	images, err := job.Stdout.AddListTable()
337
-	if err != nil {
338
-		t.Fatal(err)
332
+func getImages(eng *engine.Engine, t *testing.T, all bool, filter string) []*types.Image {
333
+	config := graph.ImagesConfig{
334
+		Filter: filter,
335
+		All:    all,
339 336
 	}
340
-	if err := job.Run(); err != nil {
337
+	images, err := getDaemon(eng).Repositories().Images(&config)
338
+	if err != nil {
341 339
 		t.Fatal(err)
342 340
 	}
343
-	return images
344 341
 
342
+	return images
345 343
 }
346 344
 
347 345
 func parseRun(args []string) (*runconfig.Config, *runconfig.HostConfig, *flag.FlagSet, error) {
... ...
@@ -350,3 +350,7 @@ func parseRun(args []string) (*runconfig.Config, *runconfig.HostConfig, *flag.Fl
350 350
 	cmd.Usage = nil
351 351
 	return runconfig.Parse(cmd, args)
352 352
 }
353
+
354
+func getDaemon(eng *engine.Engine) *daemon.Daemon {
355
+	return eng.HackGetGlobalVar("httpapi.daemon").(*daemon.Daemon)
356
+}