123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- package daemon
- import (
- "fmt"
- "time"
- "github.com/docker/distribution/reference"
- "github.com/docker/docker/api/types/image"
- "github.com/docker/docker/layer"
- )
- // ImageHistory returns a slice of ImageHistory structures for the specified image
- // name by walking the image lineage.
- func (daemon *Daemon) ImageHistory(name string) ([]*image.HistoryResponseItem, error) {
- start := time.Now()
- img, err := daemon.GetImage(name)
- if err != nil {
- return nil, err
- }
- history := []*image.HistoryResponseItem{}
- layerCounter := 0
- rootFS := *img.RootFS
- rootFS.DiffIDs = nil
- for _, h := range img.History {
- var layerSize int64
- if !h.EmptyLayer {
- if len(img.RootFS.DiffIDs) <= layerCounter {
- return nil, fmt.Errorf("too many non-empty layers in History section")
- }
- rootFS.Append(img.RootFS.DiffIDs[layerCounter])
- l, err := daemon.layerStore.Get(rootFS.ChainID())
- if err != nil {
- return nil, err
- }
- layerSize, err = l.DiffSize()
- layer.ReleaseAndLog(daemon.layerStore, l)
- if err != nil {
- return nil, err
- }
- layerCounter++
- }
- history = append([]*image.HistoryResponseItem{{
- ID: "<missing>",
- Created: h.Created.Unix(),
- CreatedBy: h.CreatedBy,
- Comment: h.Comment,
- Size: layerSize,
- }}, history...)
- }
- // Fill in image IDs and tags
- histImg := img
- id := img.ID()
- for _, h := range history {
- h.ID = id.String()
- var tags []string
- for _, r := range daemon.referenceStore.References(id.Digest()) {
- if _, ok := r.(reference.NamedTagged); ok {
- tags = append(tags, reference.FamiliarString(r))
- }
- }
- h.Tags = tags
- id = histImg.Parent
- if id == "" {
- break
- }
- histImg, err = daemon.GetImage(id.String())
- if err != nil {
- break
- }
- }
- imageActions.WithValues("history").UpdateSince(start)
- return history, nil
- }
|