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