Docker-DCO-1.1-Signed-off-by: Solomon Hykes <solomon@docker.com> (github: shykes)
| ... | ... |
@@ -181,27 +181,19 @@ func getImagesJSON(srv *Server, version float64, w http.ResponseWriter, r *http. |
| 181 | 181 |
if err := parseForm(r); err != nil {
|
| 182 | 182 |
return err |
| 183 | 183 |
} |
| 184 |
- |
|
| 185 |
- all, err := getBoolParam(r.Form.Get("all"))
|
|
| 186 |
- if err != nil {
|
|
| 187 |
- return err |
|
| 188 |
- } |
|
| 189 |
- filter := r.Form.Get("filter")
|
|
| 190 |
- |
|
| 191 |
- outs, err := srv.Images(all, filter) |
|
| 192 |
- if err != nil {
|
|
| 184 |
+ fmt.Printf("getImagesJSON\n")
|
|
| 185 |
+ job := srv.Eng.Job("images")
|
|
| 186 |
+ job.Setenv("filter", r.Form.Get("filter"))
|
|
| 187 |
+ job.Setenv("all", r.Form.Get("all"))
|
|
| 188 |
+ // FIXME: 1.7 clients expect a single json list |
|
| 189 |
+ job.Stdout.Add(w) |
|
| 190 |
+ w.WriteHeader(http.StatusOK) |
|
| 191 |
+ fmt.Printf("running images job\n")
|
|
| 192 |
+ if err := job.Run(); err != nil {
|
|
| 193 | 193 |
return err |
| 194 | 194 |
} |
| 195 |
- |
|
| 196 |
- if version < 1.7 {
|
|
| 197 |
- outs2 := []APIImagesOld{}
|
|
| 198 |
- for _, ctnr := range outs {
|
|
| 199 |
- outs2 = append(outs2, ctnr.ToLegacy()...) |
|
| 200 |
- } |
|
| 201 |
- |
|
| 202 |
- return writeJSON(w, http.StatusOK, outs2) |
|
| 203 |
- } |
|
| 204 |
- return writeJSON(w, http.StatusOK, outs) |
|
| 195 |
+ fmt.Printf("job has been run\n")
|
|
| 196 |
+ return nil |
|
| 205 | 197 |
} |
| 206 | 198 |
|
| 207 | 199 |
func getImagesViz(srv *Server, version float64, w http.ResponseWriter, r *http.Request, vars map[string]string) error {
|
| ... | ... |
@@ -5,6 +5,7 @@ import ( |
| 5 | 5 |
"encoding/json" |
| 6 | 6 |
"fmt" |
| 7 | 7 |
"io" |
| 8 |
+ "sort" |
|
| 8 | 9 |
"strconv" |
| 9 | 10 |
"strings" |
| 10 | 11 |
) |
| ... | ... |
@@ -232,3 +233,76 @@ func (env *Env) Map() map[string]string {
|
| 232 | 232 |
} |
| 233 | 233 |
return m |
| 234 | 234 |
} |
| 235 |
+ |
|
| 236 |
+type Table struct {
|
|
| 237 |
+ Data []*Env |
|
| 238 |
+ sortKey string |
|
| 239 |
+} |
|
| 240 |
+ |
|
| 241 |
+func NewTable(sortKey string, sizeHint int) *Table {
|
|
| 242 |
+ return &Table{
|
|
| 243 |
+ make([]*Env, 0, sizeHint), |
|
| 244 |
+ sortKey, |
|
| 245 |
+ } |
|
| 246 |
+} |
|
| 247 |
+ |
|
| 248 |
+func (t *Table) Add(env *Env) {
|
|
| 249 |
+ t.Data = append(t.Data, env) |
|
| 250 |
+} |
|
| 251 |
+ |
|
| 252 |
+func (t *Table) Len() int {
|
|
| 253 |
+ return len(t.Data) |
|
| 254 |
+} |
|
| 255 |
+ |
|
| 256 |
+func (t *Table) Less(a, b int) bool {
|
|
| 257 |
+ return t.lessBy(a, b, t.sortKey) |
|
| 258 |
+} |
|
| 259 |
+ |
|
| 260 |
+func (t *Table) lessBy(a, b int, by string) bool {
|
|
| 261 |
+ keyA := t.Data[a].Get(by) |
|
| 262 |
+ keyB := t.Data[b].Get(by) |
|
| 263 |
+ intA, errA := strconv.ParseInt(keyA, 10, 64) |
|
| 264 |
+ intB, errB := strconv.ParseInt(keyB, 10, 64) |
|
| 265 |
+ if errA == nil && errB == nil {
|
|
| 266 |
+ return intA < intB |
|
| 267 |
+ } |
|
| 268 |
+ return keyA < keyB |
|
| 269 |
+} |
|
| 270 |
+ |
|
| 271 |
+func (t *Table) Swap(a, b int) {
|
|
| 272 |
+ tmp := t.Data[a] |
|
| 273 |
+ t.Data[a] = t.Data[b] |
|
| 274 |
+ t.Data[b] = tmp |
|
| 275 |
+} |
|
| 276 |
+ |
|
| 277 |
+func (t *Table) Sort() {
|
|
| 278 |
+ sort.Sort(t) |
|
| 279 |
+} |
|
| 280 |
+ |
|
| 281 |
+func (t *Table) WriteTo(dst io.Writer) (n int64, err error) {
|
|
| 282 |
+ for _, env := range t.Data {
|
|
| 283 |
+ bytes, err := env.WriteTo(dst) |
|
| 284 |
+ if err != nil {
|
|
| 285 |
+ return -1, err |
|
| 286 |
+ } |
|
| 287 |
+ if _, err := dst.Write([]byte{'\n'}); err != nil {
|
|
| 288 |
+ return -1, err |
|
| 289 |
+ } |
|
| 290 |
+ n += bytes + 1 |
|
| 291 |
+ } |
|
| 292 |
+ return n, nil |
|
| 293 |
+} |
|
| 294 |
+ |
|
| 295 |
+func (t *Table) ReadFrom(src io.Reader) (n int64, err error) {
|
|
| 296 |
+ decoder := NewDecoder(src) |
|
| 297 |
+ for {
|
|
| 298 |
+ env, err := decoder.Decode() |
|
| 299 |
+ if err == io.EOF {
|
|
| 300 |
+ return 0, nil |
|
| 301 |
+ } else if err != nil {
|
|
| 302 |
+ return -1, err |
|
| 303 |
+ } |
|
| 304 |
+ t.Add(env) |
|
| 305 |
+ } |
|
| 306 |
+ return 0, nil |
|
| 307 |
+} |
| ... | ... |
@@ -190,3 +190,19 @@ func (o *Output) AddEnv() (dst *Env, err error) {
|
| 190 | 190 |
}() |
| 191 | 191 |
return dst, nil |
| 192 | 192 |
} |
| 193 |
+ |
|
| 194 |
+func (o *Output) AddTable() (dst *Table, err error) {
|
|
| 195 |
+ src, err := o.AddPipe() |
|
| 196 |
+ if err != nil {
|
|
| 197 |
+ return nil, err |
|
| 198 |
+ } |
|
| 199 |
+ dst = NewTable("", 0)
|
|
| 200 |
+ o.tasks.Add(1) |
|
| 201 |
+ go func() {
|
|
| 202 |
+ defer o.tasks.Done() |
|
| 203 |
+ if _, err := dst.ReadFrom(src); err != nil {
|
|
| 204 |
+ return |
|
| 205 |
+ } |
|
| 206 |
+ }() |
|
| 207 |
+ return dst, nil |
|
| 208 |
+} |
| 193 | 209 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,28 @@ |
| 0 |
+package engine |
|
| 1 |
+ |
|
| 2 |
+import ( |
|
| 3 |
+ "testing" |
|
| 4 |
+ "bytes" |
|
| 5 |
+ "encoding/json" |
|
| 6 |
+) |
|
| 7 |
+ |
|
| 8 |
+func TestTableWriteTo(t *testing.T) {
|
|
| 9 |
+ table := NewTable("", 0)
|
|
| 10 |
+ e := &Env{}
|
|
| 11 |
+ e.Set("foo", "bar")
|
|
| 12 |
+ table.Add(e) |
|
| 13 |
+ var buf bytes.Buffer |
|
| 14 |
+ if _, err := table.WriteTo(&buf); err != nil {
|
|
| 15 |
+ t.Fatal(err) |
|
| 16 |
+ } |
|
| 17 |
+ output := make(map[string]string) |
|
| 18 |
+ if err := json.Unmarshal(buf.Bytes(), &output); err != nil {
|
|
| 19 |
+ t.Fatal(err) |
|
| 20 |
+ } |
|
| 21 |
+ if len(output) != 1 {
|
|
| 22 |
+ t.Fatalf("Incorrect output: %v", output)
|
|
| 23 |
+ } |
|
| 24 |
+ if val, exists := output["foo"]; !exists || val != "bar" {
|
|
| 25 |
+ t.Fatalf("Inccorect output: %v", output)
|
|
| 26 |
+ } |
|
| 27 |
+} |
| ... | ... |
@@ -60,11 +60,14 @@ func TestGetInfo(t *testing.T) {
|
| 60 | 60 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 61 | 61 |
srv := mkServerFromEngine(eng, t) |
| 62 | 62 |
|
| 63 |
- initialImages, err := srv.Images(false, "") |
|
| 63 |
+ job := eng.Job("images")
|
|
| 64 |
+ initialImages, err := job.Stdout.AddTable() |
|
| 64 | 65 |
if err != nil {
|
| 65 | 66 |
t.Fatal(err) |
| 66 | 67 |
} |
| 67 |
- |
|
| 68 |
+ if err := job.Run(); err != nil {
|
|
| 69 |
+ t.Fatal(err) |
|
| 70 |
+ } |
|
| 68 | 71 |
req, err := http.NewRequest("GET", "/info", nil)
|
| 69 | 72 |
if err != nil {
|
| 70 | 73 |
t.Fatal(err) |
| ... | ... |
@@ -85,8 +88,8 @@ func TestGetInfo(t *testing.T) {
|
| 85 | 85 |
t.Fatal(err) |
| 86 | 86 |
} |
| 87 | 87 |
out.Close() |
| 88 |
- if images := i.GetInt("Images"); images != len(initialImages) {
|
|
| 89 |
- t.Errorf("Expected images: %d, %d found", len(initialImages), images)
|
|
| 88 |
+ if images := i.GetInt("Images"); images != initialImages.Len() {
|
|
| 89 |
+ t.Errorf("Expected images: %d, %d found", initialImages.Len(), images)
|
|
| 90 | 90 |
} |
| 91 | 91 |
expected := "application/json" |
| 92 | 92 |
if result := r.HeaderMap.Get("Content-Type"); result != expected {
|
| ... | ... |
@@ -145,12 +148,14 @@ func TestGetImagesJSON(t *testing.T) {
|
| 145 | 145 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 146 | 146 |
srv := mkServerFromEngine(eng, t) |
| 147 | 147 |
|
| 148 |
- // all=0 |
|
| 149 |
- |
|
| 150 |
- initialImages, err := srv.Images(false, "") |
|
| 148 |
+ job := eng.Job("images")
|
|
| 149 |
+ initialImages, err := job.Stdout.AddTable() |
|
| 151 | 150 |
if err != nil {
|
| 152 | 151 |
t.Fatal(err) |
| 153 | 152 |
} |
| 153 |
+ if err := job.Run(); err != nil {
|
|
| 154 |
+ t.Fatal(err) |
|
| 155 |
+ } |
|
| 154 | 156 |
|
| 155 | 157 |
req, err := http.NewRequest("GET", "/images/json?all=0", nil)
|
| 156 | 158 |
if err != nil {
|
| ... | ... |
@@ -164,18 +169,18 @@ func TestGetImagesJSON(t *testing.T) {
|
| 164 | 164 |
} |
| 165 | 165 |
assertHttpNotError(r, t) |
| 166 | 166 |
|
| 167 |
- images := []docker.APIImages{}
|
|
| 168 |
- if err := json.Unmarshal(r.Body.Bytes(), &images); err != nil {
|
|
| 167 |
+ images := engine.NewTable("Created", 0)
|
|
| 168 |
+ if _, err := images.ReadFrom(r.Body); err != nil {
|
|
| 169 | 169 |
t.Fatal(err) |
| 170 | 170 |
} |
| 171 | 171 |
|
| 172 |
- if len(images) != len(initialImages) {
|
|
| 173 |
- t.Errorf("Expected %d image, %d found", len(initialImages), len(images))
|
|
| 172 |
+ if images.Len() != initialImages.Len() {
|
|
| 173 |
+ t.Errorf("Expected %d image, %d found", initialImages.Len(), images.Len())
|
|
| 174 | 174 |
} |
| 175 | 175 |
|
| 176 | 176 |
found := false |
| 177 |
- for _, img := range images {
|
|
| 178 |
- if strings.Contains(img.RepoTags[0], unitTestImageName) {
|
|
| 177 |
+ for _, img := range images.Data {
|
|
| 178 |
+ if strings.Contains(img.GetList("RepoTags")[0], unitTestImageName) {
|
|
| 179 | 179 |
found = true |
| 180 | 180 |
break |
| 181 | 181 |
} |
| ... | ... |
@@ -188,10 +193,7 @@ func TestGetImagesJSON(t *testing.T) {
|
| 188 | 188 |
|
| 189 | 189 |
// all=1 |
| 190 | 190 |
|
| 191 |
- initialImages, err = srv.Images(true, "") |
|
| 192 |
- if err != nil {
|
|
| 193 |
- t.Fatal(err) |
|
| 194 |
- } |
|
| 191 |
+ initialImages = getAllImages(eng, t) |
|
| 195 | 192 |
|
| 196 | 193 |
req2, err := http.NewRequest("GET", "/images/json?all=true", nil)
|
| 197 | 194 |
if err != nil {
|
| ... | ... |
@@ -207,8 +209,8 @@ func TestGetImagesJSON(t *testing.T) {
|
| 207 | 207 |
t.Fatal(err) |
| 208 | 208 |
} |
| 209 | 209 |
|
| 210 |
- if len(images2) != len(initialImages) {
|
|
| 211 |
- t.Errorf("Expected %d image, %d found", len(initialImages), len(images2))
|
|
| 210 |
+ if len(images2) != initialImages.Len() {
|
|
| 211 |
+ t.Errorf("Expected %d image, %d found", initialImages.Len(), len(images2))
|
|
| 212 | 212 |
} |
| 213 | 213 |
|
| 214 | 214 |
found = false |
| ... | ... |
@@ -1126,21 +1128,16 @@ func TestDeleteImages(t *testing.T) {
|
| 1126 | 1126 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 1127 | 1127 |
srv := mkServerFromEngine(eng, t) |
| 1128 | 1128 |
|
| 1129 |
- initialImages, err := srv.Images(false, "") |
|
| 1130 |
- if err != nil {
|
|
| 1131 |
- t.Fatal(err) |
|
| 1132 |
- } |
|
| 1129 |
+ initialImages := getImages(eng, t, true, "") |
|
| 1133 | 1130 |
|
| 1134 | 1131 |
if err := eng.Job("tag", unitTestImageName, "test", "test").Run(); err != nil {
|
| 1135 | 1132 |
t.Fatal(err) |
| 1136 | 1133 |
} |
| 1137 |
- images, err := srv.Images(false, "") |
|
| 1138 |
- if err != nil {
|
|
| 1139 |
- t.Fatal(err) |
|
| 1140 |
- } |
|
| 1141 | 1134 |
|
| 1142 |
- if len(images[0].RepoTags) != len(initialImages[0].RepoTags)+1 {
|
|
| 1143 |
- t.Errorf("Expected %d images, %d found", len(initialImages)+1, len(images))
|
|
| 1135 |
+ images := getImages(eng, t, true, "") |
|
| 1136 |
+ |
|
| 1137 |
+ if images.Len() != initialImages.Len()+1 {
|
|
| 1138 |
+ t.Errorf("Expected %d images, %d found", initialImages.Len()+1, images.Len())
|
|
| 1144 | 1139 |
} |
| 1145 | 1140 |
|
| 1146 | 1141 |
req, err := http.NewRequest("DELETE", "/images/"+unitTestImageID, nil)
|
| ... | ... |
@@ -1177,13 +1174,10 @@ func TestDeleteImages(t *testing.T) {
|
| 1177 | 1177 |
if len(outs) != 1 {
|
| 1178 | 1178 |
t.Fatalf("Expected %d event (untagged), got %d", 1, len(outs))
|
| 1179 | 1179 |
} |
| 1180 |
- images, err = srv.Images(false, "") |
|
| 1181 |
- if err != nil {
|
|
| 1182 |
- t.Fatal(err) |
|
| 1183 |
- } |
|
| 1180 |
+ images = getImages(eng, t, false, "") |
|
| 1184 | 1181 |
|
| 1185 |
- if len(images[0].RepoTags) != len(initialImages[0].RepoTags) {
|
|
| 1186 |
- t.Errorf("Expected %d image, %d found", len(initialImages), len(images))
|
|
| 1182 |
+ if images.Len() != initialImages.Len() {
|
|
| 1183 |
+ t.Errorf("Expected %d image, %d found", initialImages.Len(), images.Len())
|
|
| 1187 | 1184 |
} |
| 1188 | 1185 |
} |
| 1189 | 1186 |
|
| ... | ... |
@@ -51,14 +51,17 @@ func cleanup(eng *engine.Engine, t *testing.T) error {
|
| 51 | 51 |
container.Kill() |
| 52 | 52 |
runtime.Destroy(container) |
| 53 | 53 |
} |
| 54 |
- srv := mkServerFromEngine(eng, t) |
|
| 55 |
- images, err := srv.Images(true, "") |
|
| 54 |
+ job := eng.Job("images")
|
|
| 55 |
+ images, err := job.Stdout.AddTable() |
|
| 56 | 56 |
if err != nil {
|
| 57 |
- return err |
|
| 57 |
+ t.Fatal(err) |
|
| 58 |
+ } |
|
| 59 |
+ if err := job.Run(); err != nil {
|
|
| 60 |
+ t.Fatal(err) |
|
| 58 | 61 |
} |
| 59 |
- for _, image := range images {
|
|
| 60 |
- if image.ID != unitTestImageID {
|
|
| 61 |
- srv.ImageDelete(image.ID, false) |
|
| 62 |
+ for _, image := range images.Data {
|
|
| 63 |
+ if image.Get("ID") != unitTestImageID {
|
|
| 64 |
+ mkServerFromEngine(eng, t).ImageDelete(image.Get("ID"), false)
|
|
| 62 | 65 |
} |
| 63 | 66 |
} |
| 64 | 67 |
return nil |
| ... | ... |
@@ -158,7 +161,7 @@ func spawnGlobalDaemon() {
|
| 158 | 158 |
Host: testDaemonAddr, |
| 159 | 159 |
} |
| 160 | 160 |
job := eng.Job("serveapi", listenURL.String())
|
| 161 |
- job.SetenvBool("Logging", os.Getenv("DEBUG") != "")
|
|
| 161 |
+ job.SetenvBool("Logging", true)
|
|
| 162 | 162 |
if err := job.Run(); err != nil {
|
| 163 | 163 |
log.Fatalf("Unable to spawn the test daemon: %s", err)
|
| 164 | 164 |
} |
| ... | ... |
@@ -14,10 +14,7 @@ func TestImageTagImageDelete(t *testing.T) {
|
| 14 | 14 |
|
| 15 | 15 |
srv := mkServerFromEngine(eng, t) |
| 16 | 16 |
|
| 17 |
- initialImages, err := srv.Images(false, "") |
|
| 18 |
- if err != nil {
|
|
| 19 |
- t.Fatal(err) |
|
| 20 |
- } |
|
| 17 |
+ initialImages := getAllImages(eng, t) |
|
| 21 | 18 |
if err := eng.Job("tag", unitTestImageName, "utest", "tag1").Run(); err != nil {
|
| 22 | 19 |
t.Fatal(err) |
| 23 | 20 |
} |
| ... | ... |
@@ -30,52 +27,43 @@ func TestImageTagImageDelete(t *testing.T) {
|
| 30 | 30 |
t.Fatal(err) |
| 31 | 31 |
} |
| 32 | 32 |
|
| 33 |
- images, err := srv.Images(false, "") |
|
| 34 |
- if err != nil {
|
|
| 35 |
- t.Fatal(err) |
|
| 36 |
- } |
|
| 33 |
+ images := getAllImages(eng, t) |
|
| 37 | 34 |
|
| 38 |
- if len(images[0].RepoTags) != len(initialImages[0].RepoTags)+3 {
|
|
| 39 |
- t.Errorf("Expected %d images, %d found", len(initialImages)+3, len(images))
|
|
| 35 |
+ nExpected := len(initialImages.Data[0].GetList("RepoTags")) + 3
|
|
| 36 |
+ nActual := len(images.Data[0].GetList("RepoTags"))
|
|
| 37 |
+ if nExpected != nActual {
|
|
| 38 |
+ t.Errorf("Expected %d images, %d found", nExpected, nActual)
|
|
| 40 | 39 |
} |
| 41 | 40 |
|
| 42 | 41 |
if _, err := srv.ImageDelete("utest/docker:tag2", true); err != nil {
|
| 43 | 42 |
t.Fatal(err) |
| 44 | 43 |
} |
| 45 | 44 |
|
| 46 |
- images, err = srv.Images(false, "") |
|
| 47 |
- if err != nil {
|
|
| 48 |
- t.Fatal(err) |
|
| 49 |
- } |
|
| 45 |
+ images = getAllImages(eng, t) |
|
| 50 | 46 |
|
| 51 |
- if len(images[0].RepoTags) != len(initialImages[0].RepoTags)+2 {
|
|
| 52 |
- t.Errorf("Expected %d images, %d found", len(initialImages)+2, len(images))
|
|
| 47 |
+ nExpected = len(initialImages.Data[0].GetList("RepoTags")) + 2
|
|
| 48 |
+ nActual = len(images.Data[0].GetList("RepoTags"))
|
|
| 49 |
+ if nExpected != nActual {
|
|
| 50 |
+ t.Errorf("Expected %d images, %d found", nExpected, nActual)
|
|
| 53 | 51 |
} |
| 54 | 52 |
|
| 55 | 53 |
if _, err := srv.ImageDelete("utest:5000/docker:tag3", true); err != nil {
|
| 56 | 54 |
t.Fatal(err) |
| 57 | 55 |
} |
| 58 | 56 |
|
| 59 |
- images, err = srv.Images(false, "") |
|
| 60 |
- if err != nil {
|
|
| 61 |
- t.Fatal(err) |
|
| 62 |
- } |
|
| 57 |
+ images = getAllImages(eng, t) |
|
| 63 | 58 |
|
| 64 |
- if len(images[0].RepoTags) != len(initialImages[0].RepoTags)+1 {
|
|
| 65 |
- t.Errorf("Expected %d images, %d found", len(initialImages)+1, len(images))
|
|
| 66 |
- } |
|
| 59 |
+ nExpected = len(initialImages.Data[0].GetList("RepoTags")) + 1
|
|
| 60 |
+ nActual = len(images.Data[0].GetList("RepoTags"))
|
|
| 67 | 61 |
|
| 68 | 62 |
if _, err := srv.ImageDelete("utest:tag1", true); err != nil {
|
| 69 | 63 |
t.Fatal(err) |
| 70 | 64 |
} |
| 71 | 65 |
|
| 72 |
- images, err = srv.Images(false, "") |
|
| 73 |
- if err != nil {
|
|
| 74 |
- t.Fatal(err) |
|
| 75 |
- } |
|
| 66 |
+ images = getAllImages(eng, t) |
|
| 76 | 67 |
|
| 77 |
- if len(images) != len(initialImages) {
|
|
| 78 |
- t.Errorf("Expected %d image, %d found", len(initialImages), len(images))
|
|
| 68 |
+ if images.Len() != initialImages.Len() {
|
|
| 69 |
+ t.Errorf("Expected %d image, %d found", initialImages.Len(), images.Len())
|
|
| 79 | 70 |
} |
| 80 | 71 |
} |
| 81 | 72 |
|
| ... | ... |
@@ -250,10 +238,7 @@ func TestRmi(t *testing.T) {
|
| 250 | 250 |
srv := mkServerFromEngine(eng, t) |
| 251 | 251 |
defer mkRuntimeFromEngine(eng, t).Nuke() |
| 252 | 252 |
|
| 253 |
- initialImages, err := srv.Images(false, "") |
|
| 254 |
- if err != nil {
|
|
| 255 |
- t.Fatal(err) |
|
| 256 |
- } |
|
| 253 |
+ initialImages := getAllImages(eng, t) |
|
| 257 | 254 |
|
| 258 | 255 |
config, hostConfig, _, err := docker.ParseRun([]string{unitTestImageID, "echo", "test"}, nil)
|
| 259 | 256 |
if err != nil {
|
| ... | ... |
@@ -308,13 +293,10 @@ func TestRmi(t *testing.T) {
|
| 308 | 308 |
t.Fatal(err) |
| 309 | 309 |
} |
| 310 | 310 |
|
| 311 |
- images, err := srv.Images(false, "") |
|
| 312 |
- if err != nil {
|
|
| 313 |
- t.Fatal(err) |
|
| 314 |
- } |
|
| 311 |
+ images := getAllImages(eng, t) |
|
| 315 | 312 |
|
| 316 |
- if len(images)-len(initialImages) != 2 {
|
|
| 317 |
- t.Fatalf("Expected 2 new images, found %d.", len(images)-len(initialImages))
|
|
| 313 |
+ if images.Len()-initialImages.Len() != 2 {
|
|
| 314 |
+ t.Fatalf("Expected 2 new images, found %d.", images.Len()-initialImages.Len())
|
|
| 318 | 315 |
} |
| 319 | 316 |
|
| 320 | 317 |
_, err = srv.ImageDelete(imageID, true) |
| ... | ... |
@@ -322,20 +304,17 @@ func TestRmi(t *testing.T) {
|
| 322 | 322 |
t.Fatal(err) |
| 323 | 323 |
} |
| 324 | 324 |
|
| 325 |
- images, err = srv.Images(false, "") |
|
| 326 |
- if err != nil {
|
|
| 327 |
- t.Fatal(err) |
|
| 328 |
- } |
|
| 325 |
+ images = getAllImages(eng, t) |
|
| 329 | 326 |
|
| 330 |
- if len(images)-len(initialImages) != 1 {
|
|
| 331 |
- t.Fatalf("Expected 1 new image, found %d.", len(images)-len(initialImages))
|
|
| 327 |
+ if images.Len()-initialImages.Len() != 1 {
|
|
| 328 |
+ t.Fatalf("Expected 1 new image, found %d.", images.Len()-initialImages.Len())
|
|
| 332 | 329 |
} |
| 333 | 330 |
|
| 334 |
- for _, image := range images {
|
|
| 335 |
- if strings.Contains(unitTestImageID, image.ID) {
|
|
| 331 |
+ for _, image := range images.Data {
|
|
| 332 |
+ if strings.Contains(unitTestImageID, image.Get("ID")) {
|
|
| 336 | 333 |
continue |
| 337 | 334 |
} |
| 338 |
- if image.RepoTags[0] == "<none>:<none>" {
|
|
| 335 |
+ if image.GetList("RepoTags")[0] == "<none>:<none>" {
|
|
| 339 | 336 |
t.Fatalf("Expected tagged image, got untagged one.")
|
| 340 | 337 |
} |
| 341 | 338 |
} |
| ... | ... |
@@ -359,39 +338,27 @@ func TestImagesFilter(t *testing.T) {
|
| 359 | 359 |
t.Fatal(err) |
| 360 | 360 |
} |
| 361 | 361 |
|
| 362 |
- images, err := srv.Images(false, "utest*/*") |
|
| 363 |
- if err != nil {
|
|
| 364 |
- t.Fatal(err) |
|
| 365 |
- } |
|
| 362 |
+ images := getImages(eng, t, false, "utest*/*") |
|
| 366 | 363 |
|
| 367 |
- if len(images[0].RepoTags) != 2 {
|
|
| 364 |
+ if len(images.Data[0].GetList("RepoTags")) != 2 {
|
|
| 368 | 365 |
t.Fatal("incorrect number of matches returned")
|
| 369 | 366 |
} |
| 370 | 367 |
|
| 371 |
- images, err = srv.Images(false, "utest") |
|
| 372 |
- if err != nil {
|
|
| 373 |
- t.Fatal(err) |
|
| 374 |
- } |
|
| 368 |
+ images = getImages(eng, t, false, "utest") |
|
| 375 | 369 |
|
| 376 |
- if len(images[0].RepoTags) != 1 {
|
|
| 370 |
+ if len(images.Data[0].GetList("RepoTags")) != 1 {
|
|
| 377 | 371 |
t.Fatal("incorrect number of matches returned")
|
| 378 | 372 |
} |
| 379 | 373 |
|
| 380 |
- images, err = srv.Images(false, "utest*") |
|
| 381 |
- if err != nil {
|
|
| 382 |
- t.Fatal(err) |
|
| 383 |
- } |
|
| 374 |
+ images = getImages(eng, t, false, "utest*") |
|
| 384 | 375 |
|
| 385 |
- if len(images[0].RepoTags) != 1 {
|
|
| 376 |
+ if len(images.Data[0].GetList("RepoTags")) != 1 {
|
|
| 386 | 377 |
t.Fatal("incorrect number of matches returned")
|
| 387 | 378 |
} |
| 388 | 379 |
|
| 389 |
- images, err = srv.Images(false, "*5000*/*") |
|
| 390 |
- if err != nil {
|
|
| 391 |
- t.Fatal(err) |
|
| 392 |
- } |
|
| 380 |
+ images = getImages(eng, t, false, "*5000*/*") |
|
| 393 | 381 |
|
| 394 |
- if len(images[0].RepoTags) != 1 {
|
|
| 382 |
+ if len(images.Data[0].GetList("RepoTags")) != 1 {
|
|
| 395 | 383 |
t.Fatal("incorrect number of matches returned")
|
| 396 | 384 |
} |
| 397 | 385 |
} |
| ... | ... |
@@ -17,13 +17,10 @@ func TestServerListOrderedImagesByCreationDate(t *testing.T) {
|
| 17 | 17 |
t.Fatal(err) |
| 18 | 18 |
} |
| 19 | 19 |
|
| 20 |
- images, err := srv.Images(true, "") |
|
| 21 |
- if err != nil {
|
|
| 22 |
- t.Fatal(err) |
|
| 23 |
- } |
|
| 20 |
+ images := getImages(eng, t, true, "") |
|
| 24 | 21 |
|
| 25 |
- if images[0].Created < images[1].Created {
|
|
| 26 |
- t.Error("Expected []APIImges to be ordered by most recent creation date.")
|
|
| 22 |
+ if images.Data[0].GetInt("Created") < images.Data[1].GetInt("Created") {
|
|
| 23 |
+ t.Error("Expected images to be ordered by most recent creation date.")
|
|
| 27 | 24 |
} |
| 28 | 25 |
} |
| 29 | 26 |
|
| ... | ... |
@@ -44,12 +41,9 @@ func TestServerListOrderedImagesByCreationDateAndTag(t *testing.T) {
|
| 44 | 44 |
t.Fatal(err) |
| 45 | 45 |
} |
| 46 | 46 |
|
| 47 |
- images, err := srv.Images(true, "") |
|
| 48 |
- if err != nil {
|
|
| 49 |
- t.Fatal(err) |
|
| 50 |
- } |
|
| 47 |
+ images := getImages(eng, t, true, "") |
|
| 51 | 48 |
|
| 52 |
- if images[0].RepoTags[0] != "repo:zed" && images[0].RepoTags[0] != "repo:bar" {
|
|
| 49 |
+ if images.Data[0].GetList("RepoTags")[0] != "repo:zed" && images.Data[0].GetList("RepoTags")[0] != "repo:bar" {
|
|
| 53 | 50 |
t.Errorf("Expected []APIImges to be ordered by most recent creation date. %s", images)
|
| 54 | 51 |
} |
| 55 | 52 |
} |
| ... | ... |
@@ -186,8 +186,6 @@ func NewTestEngine(t utils.Fataler) *engine.Engine {
|
| 186 | 186 |
if err != nil {
|
| 187 | 187 |
t.Fatal(err) |
| 188 | 188 |
} |
| 189 |
- eng.Stdout = ioutil.Discard |
|
| 190 |
- eng.Stderr = ioutil.Discard |
|
| 191 | 189 |
// Load default plugins |
| 192 | 190 |
// (This is manually copied and modified from main() until we have a more generic plugin system) |
| 193 | 191 |
job := eng.Job("initapi")
|
| ... | ... |
@@ -329,3 +327,22 @@ func fakeTar() (io.Reader, error) {
|
| 329 | 329 |
tw.Close() |
| 330 | 330 |
return buf, nil |
| 331 | 331 |
} |
| 332 |
+ |
|
| 333 |
+func getAllImages(eng *engine.Engine, t *testing.T) *engine.Table {
|
|
| 334 |
+ return getImages(eng, t, true, "") |
|
| 335 |
+} |
|
| 336 |
+ |
|
| 337 |
+func getImages(eng *engine.Engine, t *testing.T, all bool, filter string) *engine.Table {
|
|
| 338 |
+ job := eng.Job("images")
|
|
| 339 |
+ job.SetenvBool("all", all)
|
|
| 340 |
+ job.Setenv("filter", filter)
|
|
| 341 |
+ images, err := job.Stdout.AddTable() |
|
| 342 |
+ if err != nil {
|
|
| 343 |
+ t.Fatal(err) |
|
| 344 |
+ } |
|
| 345 |
+ if err := job.Run(); err != nil {
|
|
| 346 |
+ t.Fatal(err) |
|
| 347 |
+ } |
|
| 348 |
+ return images |
|
| 349 |
+ |
|
| 350 |
+} |
| ... | ... |
@@ -127,6 +127,10 @@ func jobInitApi(job *engine.Job) engine.Status {
|
| 127 | 127 |
job.Error(err) |
| 128 | 128 |
return engine.StatusErr |
| 129 | 129 |
} |
| 130 |
+ if err := job.Eng.Register("images", srv.Images); err != nil {
|
|
| 131 |
+ job.Error(err) |
|
| 132 |
+ return engine.StatusErr |
|
| 133 |
+ } |
|
| 130 | 134 |
return engine.StatusOK |
| 131 | 135 |
} |
| 132 | 136 |
|
| ... | ... |
@@ -568,23 +572,26 @@ func (srv *Server) ImagesViz(out io.Writer) error {
|
| 568 | 568 |
return nil |
| 569 | 569 |
} |
| 570 | 570 |
|
| 571 |
-func (srv *Server) Images(all bool, filter string) ([]APIImages, error) {
|
|
| 571 |
+func (srv *Server) Images(job *engine.Job) engine.Status {
|
|
| 572 |
+ fmt.Printf("Images()\n")
|
|
| 573 |
+ srv.Eng.Job("version").Run()
|
|
| 572 | 574 |
var ( |
| 573 | 575 |
allImages map[string]*Image |
| 574 | 576 |
err error |
| 575 | 577 |
) |
| 576 |
- if all {
|
|
| 578 |
+ if job.GetenvBool("all") {
|
|
| 577 | 579 |
allImages, err = srv.runtime.graph.Map() |
| 578 | 580 |
} else {
|
| 579 | 581 |
allImages, err = srv.runtime.graph.Heads() |
| 580 | 582 |
} |
| 581 | 583 |
if err != nil {
|
| 582 |
- return nil, err |
|
| 584 |
+ job.Errorf("%s", err)
|
|
| 585 |
+ return engine.StatusErr |
|
| 583 | 586 |
} |
| 584 |
- lookup := make(map[string]APIImages) |
|
| 587 |
+ lookup := make(map[string]*engine.Env) |
|
| 585 | 588 |
for name, repository := range srv.runtime.repositories.Repositories {
|
| 586 |
- if filter != "" {
|
|
| 587 |
- if match, _ := path.Match(filter, name); !match {
|
|
| 589 |
+ if job.Getenv("filter") != "" {
|
|
| 590 |
+ if match, _ := path.Match(job.Getenv("filter"), name); !match {
|
|
| 588 | 591 |
continue |
| 589 | 592 |
} |
| 590 | 593 |
} |
| ... | ... |
@@ -596,48 +603,51 @@ func (srv *Server) Images(all bool, filter string) ([]APIImages, error) {
|
| 596 | 596 |
} |
| 597 | 597 |
|
| 598 | 598 |
if out, exists := lookup[id]; exists {
|
| 599 |
- out.RepoTags = append(out.RepoTags, fmt.Sprintf("%s:%s", name, tag))
|
|
| 600 |
- |
|
| 601 |
- lookup[id] = out |
|
| 599 |
+ repotag := fmt.Sprintf("%s:%s", name, tag)
|
|
| 600 |
+ out.SetList("RepoTags", append(out.GetList("RepoTags"), repotag))
|
|
| 602 | 601 |
} else {
|
| 603 |
- var out APIImages |
|
| 604 |
- |
|
| 602 |
+ out := &engine.Env{}
|
|
| 605 | 603 |
delete(allImages, id) |
| 606 |
- |
|
| 607 |
- out.ParentId = image.Parent |
|
| 608 |
- out.RepoTags = []string{fmt.Sprintf("%s:%s", name, tag)}
|
|
| 609 |
- out.ID = image.ID |
|
| 610 |
- out.Created = image.Created.Unix() |
|
| 611 |
- out.Size = image.Size |
|
| 612 |
- out.VirtualSize = image.getParentsSize(0) + image.Size |
|
| 613 |
- |
|
| 604 |
+ out.Set("ParentId", image.Parent)
|
|
| 605 |
+ out.SetList("RepoTags", []string{fmt.Sprintf("%s:%s", name, tag)})
|
|
| 606 |
+ out.Set("ID", image.ID)
|
|
| 607 |
+ out.SetInt64("Created", image.Created.Unix())
|
|
| 608 |
+ out.SetInt64("Size", image.Size)
|
|
| 609 |
+ out.SetInt64("VirtualSize", image.getParentsSize(0)+image.Size)
|
|
| 614 | 610 |
lookup[id] = out |
| 615 | 611 |
} |
| 616 | 612 |
|
| 617 | 613 |
} |
| 618 | 614 |
} |
| 619 | 615 |
|
| 620 |
- outs := make([]APIImages, 0, len(lookup)) |
|
| 616 |
+ outs := engine.NewTable("Created", len(lookup))
|
|
| 621 | 617 |
for _, value := range lookup {
|
| 622 |
- outs = append(outs, value) |
|
| 618 |
+ outs.Add(value) |
|
| 623 | 619 |
} |
| 624 | 620 |
|
| 625 | 621 |
// Display images which aren't part of a repository/tag |
| 626 |
- if filter == "" {
|
|
| 622 |
+ if job.Getenv("filter") == "" {
|
|
| 627 | 623 |
for _, image := range allImages {
|
| 628 |
- var out APIImages |
|
| 629 |
- out.ID = image.ID |
|
| 630 |
- out.ParentId = image.Parent |
|
| 631 |
- out.RepoTags = []string{"<none>:<none>"}
|
|
| 632 |
- out.Created = image.Created.Unix() |
|
| 633 |
- out.Size = image.Size |
|
| 634 |
- out.VirtualSize = image.getParentsSize(0) + image.Size |
|
| 635 |
- outs = append(outs, out) |
|
| 624 |
+ out := &engine.Env{}
|
|
| 625 |
+ out.Set("ParentId", image.Parent)
|
|
| 626 |
+ out.SetList("RepoTags", []string{"<none>:<none>"})
|
|
| 627 |
+ out.Set("ID", image.ID)
|
|
| 628 |
+ out.SetInt64("Created", image.Created.Unix())
|
|
| 629 |
+ out.SetInt64("Size", image.Size)
|
|
| 630 |
+ out.SetInt64("VirtualSize", image.getParentsSize(0)+image.Size)
|
|
| 631 |
+ outs.Add(out) |
|
| 636 | 632 |
} |
| 637 | 633 |
} |
| 638 | 634 |
|
| 639 |
- sortImagesByCreationAndTag(outs) |
|
| 640 |
- return outs, nil |
|
| 635 |
+ outs.Sort() |
|
| 636 |
+ job.Logf("Sending %d images to stdout", outs.Len())
|
|
| 637 |
+ if n, err := outs.WriteTo(job.Stdout); err != nil {
|
|
| 638 |
+ job.Errorf("%s", err)
|
|
| 639 |
+ return engine.StatusErr |
|
| 640 |
+ } else {
|
|
| 641 |
+ job.Logf("%d bytes sent", n)
|
|
| 642 |
+ } |
|
| 643 |
+ return engine.StatusOK |
|
| 641 | 644 |
} |
| 642 | 645 |
|
| 643 | 646 |
func (srv *Server) DockerInfo(job *engine.Job) engine.Status {
|