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