history.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. package graph
  2. import (
  3. "strings"
  4. "github.com/docker/docker/engine"
  5. "github.com/docker/docker/image"
  6. )
  7. func (s *TagStore) CmdHistory(job *engine.Job) engine.Status {
  8. if n := len(job.Args); n != 1 {
  9. return job.Errorf("Usage: %s IMAGE", job.Name)
  10. }
  11. name := job.Args[0]
  12. foundImage, err := s.LookupImage(name)
  13. if err != nil {
  14. return job.Error(err)
  15. }
  16. lookupMap := make(map[string][]string)
  17. for name, repository := range s.Repositories {
  18. for tag, id := range repository {
  19. // If the ID already has a reverse lookup, do not update it unless for "latest"
  20. if _, exists := lookupMap[id]; !exists {
  21. lookupMap[id] = []string{}
  22. }
  23. lookupMap[id] = append(lookupMap[id], name+":"+tag)
  24. }
  25. }
  26. outs := engine.NewTable("Created", 0)
  27. err = foundImage.WalkHistory(func(img *image.Image) error {
  28. out := &engine.Env{}
  29. out.SetJson("Id", img.ID)
  30. out.SetInt64("Created", img.Created.Unix())
  31. out.Set("CreatedBy", strings.Join(img.ContainerConfig.Cmd, " "))
  32. out.SetList("Tags", lookupMap[img.ID])
  33. out.SetInt64("Size", img.Size)
  34. outs.Add(out)
  35. return nil
  36. })
  37. if _, err := outs.WriteListTo(job.Stdout); err != nil {
  38. return job.Error(err)
  39. }
  40. return engine.StatusOK
  41. }