... | ... |
@@ -117,6 +117,10 @@ func (container *Container) Cmd() *exec.Cmd { |
117 | 117 |
return container.cmd |
118 | 118 |
} |
119 | 119 |
|
120 |
+func (container *Container) When() time.Time { |
|
121 |
+ return container.Created |
|
122 |
+} |
|
123 |
+ |
|
120 | 124 |
func (container *Container) loadUserData() (map[string]string, error) { |
121 | 125 |
jsonData, err := ioutil.ReadFile(path.Join(container.Root, "userdata.json")) |
122 | 126 |
if err != nil { |
... | ... |
@@ -7,6 +7,7 @@ import ( |
7 | 7 |
"log" |
8 | 8 |
"os" |
9 | 9 |
"path" |
10 |
+ "github.com/dotcloud/docker/image" // For sorting utility |
|
10 | 11 |
) |
11 | 12 |
|
12 | 13 |
type Docker struct { |
... | ... |
@@ -16,9 +17,13 @@ type Docker struct { |
16 | 16 |
} |
17 | 17 |
|
18 | 18 |
func (docker *Docker) List() []*Container { |
19 |
- containers := []*Container{} |
|
19 |
+ history := new(image.History) |
|
20 | 20 |
for e := docker.containers.Front(); e != nil; e = e.Next() { |
21 |
- containers = append(containers, e.Value.(*Container)) |
|
21 |
+ history.Add(e.Value.(*Container)) |
|
22 |
+ } |
|
23 |
+ containers := make([]*Container, len(*history)) |
|
24 |
+ for i := range *history { |
|
25 |
+ containers[i] = (*history)[i].(*Container) |
|
22 | 26 |
} |
23 | 27 |
return containers |
24 | 28 |
} |
... | ... |
@@ -288,7 +288,8 @@ func (srv *Server) CmdImages(stdin io.ReadCloser, stdout io.Writer, args ...stri |
288 | 288 |
if nameFilter != "" && nameFilter != name { |
289 | 289 |
continue |
290 | 290 |
} |
291 |
- for idx, img := range *srv.images.ByName[name] { |
|
291 |
+ for idx, evt := range *srv.images.ByName[name] { |
|
292 |
+ img := evt.(*image.Image) |
|
292 | 293 |
if *limit > 0 && idx >= *limit { |
293 | 294 |
break |
294 | 295 |
} |
... | ... |
@@ -102,7 +102,7 @@ func (index *Index) Find(idOrName string) *Image { |
102 | 102 |
} |
103 | 103 |
// Lookup by name |
104 | 104 |
if history, exists := index.ByName[idOrName]; exists && history.Len() > 0 { |
105 |
- return (*history)[0] |
|
105 |
+ return (*history)[0].(*Image) |
|
106 | 106 |
} |
107 | 107 |
return nil |
108 | 108 |
} |
... | ... |
@@ -116,7 +116,7 @@ func (index *Index) Add(name string, image *Image) error { |
116 | 116 |
index.ByName[name] = new(History) |
117 | 117 |
} else { |
118 | 118 |
// If this image is already the latest version, don't add it. |
119 |
- if (*index.ByName[name])[0].Id == image.Id { |
|
119 |
+ if (*index.ByName[name])[0].(*Image).Id == image.Id { |
|
120 | 120 |
return nil |
121 | 121 |
} |
122 | 122 |
} |
... | ... |
@@ -169,7 +169,8 @@ func (index *Index) Rename(oldName, newName string) error { |
169 | 169 |
index.ByName[newName] = index.ByName[oldName] |
170 | 170 |
delete(index.ByName, oldName) |
171 | 171 |
// Change the ID of all images, since they include the name |
172 |
- for _, image := range *index.ByName[newName] { |
|
172 |
+ for _, event := range *index.ByName[newName] { |
|
173 |
+ image := event.(*Image) |
|
173 | 174 |
if id, err := generateImageId(newName, image.Layers); err != nil { |
174 | 175 |
return err |
175 | 176 |
} else { |
... | ... |
@@ -227,37 +228,33 @@ func (index *Index) save() error { |
227 | 227 |
|
228 | 228 |
// History wraps an array of images so they can be sorted by date (most recent first) |
229 | 229 |
|
230 |
-type History []*Image |
|
230 |
+type Event interface { |
|
231 |
+ When() time.Time |
|
232 |
+} |
|
233 |
+ |
|
234 |
+type History []Event |
|
231 | 235 |
|
232 | 236 |
func (history *History) Len() int { |
233 | 237 |
return len(*history) |
234 | 238 |
} |
235 | 239 |
|
236 | 240 |
func (history *History) Less(i, j int) bool { |
237 |
- images := *history |
|
238 |
- return images[j].Created.Before(images[i].Created) |
|
241 |
+ events := *history |
|
242 |
+ return events[j].When().Before(events[i].When()) |
|
239 | 243 |
} |
240 | 244 |
|
241 | 245 |
func (history *History) Swap(i, j int) { |
242 |
- images := *history |
|
243 |
- tmp := images[i] |
|
244 |
- images[i] = images[j] |
|
245 |
- images[j] = tmp |
|
246 |
+ events := *history |
|
247 |
+ tmp := events[i] |
|
248 |
+ events[i] = events[j] |
|
249 |
+ events[j] = tmp |
|
246 | 250 |
} |
247 | 251 |
|
248 |
-func (history *History) Add(image *Image) { |
|
249 |
- *history = append(*history, image) |
|
252 |
+func (history *History) Add(event Event) { |
|
253 |
+ *history = append(*history, event) |
|
250 | 254 |
sort.Sort(history) |
251 | 255 |
} |
252 | 256 |
|
253 |
-func (history *History) Del(id string) { |
|
254 |
- for idx, image := range *history { |
|
255 |
- if image.Id == id { |
|
256 |
- *history = append((*history)[:idx], (*history)[idx + 1:]...) |
|
257 |
- } |
|
258 |
- } |
|
259 |
-} |
|
260 |
- |
|
261 | 257 |
type Image struct { |
262 | 258 |
Id string // Globally unique identifier |
263 | 259 |
Layers []string // Absolute paths |
... | ... |
@@ -265,6 +262,10 @@ type Image struct { |
265 | 265 |
Parent string |
266 | 266 |
} |
267 | 267 |
|
268 |
+func (image *Image) When() time.Time { |
|
269 |
+ return image.Created |
|
270 |
+} |
|
271 |
+ |
|
268 | 272 |
func (image *Image) IdParts() (string, string) { |
269 | 273 |
if len(image.Id) < 8 { |
270 | 274 |
return "", image.Id |