github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/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/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 (i *ImageService) ImageHistory(name string) ([]*image.HistoryResponseItem, error) {
    16  	ctx := context.TODO()
    17  	start := time.Now()
    18  	img, err := i.GetImage(ctx, name, image.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  		history = append([]*image.HistoryResponseItem{{
    47  			ID:        "<missing>",
    48  			Created:   h.Created.Unix(),
    49  			CreatedBy: h.CreatedBy,
    50  			Comment:   h.Comment,
    51  			Size:      layerSize,
    52  		}}, history...)
    53  	}
    54  
    55  	// Fill in image IDs and tags
    56  	histImg := img
    57  	id := img.ID()
    58  	for _, h := range history {
    59  		h.ID = id.String()
    60  
    61  		var tags []string
    62  		for _, r := range i.referenceStore.References(id.Digest()) {
    63  			if _, ok := r.(reference.NamedTagged); ok {
    64  				tags = append(tags, reference.FamiliarString(r))
    65  			}
    66  		}
    67  
    68  		h.Tags = tags
    69  
    70  		id = histImg.Parent
    71  		if id == "" {
    72  			break
    73  		}
    74  		histImg, err = i.GetImage(ctx, id.String(), image.GetImageOpts{})
    75  		if err != nil {
    76  			break
    77  		}
    78  	}
    79  	imageActions.WithValues("history").UpdateSince(start)
    80  	return history, nil
    81  }