image_history.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package images // import "github.com/docker/docker/daemon/images"
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. "github.com/distribution/reference"
  7. "github.com/docker/docker/api/types/image"
  8. "github.com/docker/docker/layer"
  9. )
  10. // ImageHistory returns a slice of ImageHistory structures for the specified image
  11. // name by walking the image lineage.
  12. func (i *ImageService) ImageHistory(ctx context.Context, name string) ([]*image.HistoryResponseItem, error) {
  13. start := time.Now()
  14. img, err := i.GetImage(ctx, name, image.GetImageOpts{})
  15. if err != nil {
  16. return nil, err
  17. }
  18. history := []*image.HistoryResponseItem{}
  19. layerCounter := 0
  20. rootFS := *img.RootFS
  21. rootFS.DiffIDs = nil
  22. for _, h := range img.History {
  23. var layerSize int64
  24. if !h.EmptyLayer {
  25. if len(img.RootFS.DiffIDs) <= layerCounter {
  26. return nil, fmt.Errorf("too many non-empty layers in History section")
  27. }
  28. rootFS.Append(img.RootFS.DiffIDs[layerCounter])
  29. l, err := i.layerStore.Get(rootFS.ChainID())
  30. if err != nil {
  31. return nil, err
  32. }
  33. layerSize = l.DiffSize()
  34. layer.ReleaseAndLog(i.layerStore, l)
  35. layerCounter++
  36. }
  37. history = append([]*image.HistoryResponseItem{{
  38. ID: "<missing>",
  39. Created: h.Created.Unix(),
  40. CreatedBy: h.CreatedBy,
  41. Comment: h.Comment,
  42. Size: layerSize,
  43. }}, history...)
  44. }
  45. // Fill in image IDs and tags
  46. histImg := img
  47. id := img.ID()
  48. for _, h := range history {
  49. h.ID = id.String()
  50. var tags []string
  51. for _, r := range i.referenceStore.References(id.Digest()) {
  52. if _, ok := r.(reference.NamedTagged); ok {
  53. tags = append(tags, reference.FamiliarString(r))
  54. }
  55. }
  56. h.Tags = tags
  57. id = histImg.Parent
  58. if id == "" {
  59. break
  60. }
  61. histImg, err = i.GetImage(ctx, id.String(), image.GetImageOpts{})
  62. if err != nil {
  63. break
  64. }
  65. }
  66. imageActions.WithValues("history").UpdateSince(start)
  67. return history, nil
  68. }