github.com/docker/docker@v299999999.0.0-20200612211812-aaf470eca7b5+incompatible/daemon/images/image_history.go (about)

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