github.com/rawahars/moby@v24.0.4+incompatible/daemon/containerd/image_changes.go (about)

     1  package containerd
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  
     7  	"github.com/containerd/containerd/content"
     8  	"github.com/containerd/containerd/mount"
     9  	"github.com/docker/docker/container"
    10  	"github.com/docker/docker/pkg/archive"
    11  	"github.com/google/uuid"
    12  	"github.com/opencontainers/image-spec/identity"
    13  	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
    14  	"github.com/sirupsen/logrus"
    15  )
    16  
    17  func (i *ImageService) Changes(ctx context.Context, container *container.Container) ([]archive.Change, error) {
    18  	cs := i.client.ContentStore()
    19  
    20  	imageManifest, err := getContainerImageManifest(container)
    21  	if err != nil {
    22  		return nil, err
    23  	}
    24  
    25  	imageManifestBytes, err := content.ReadBlob(ctx, cs, imageManifest)
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  	var manifest ocispec.Manifest
    30  	if err := json.Unmarshal(imageManifestBytes, &manifest); err != nil {
    31  		return nil, err
    32  	}
    33  
    34  	imageConfigBytes, err := content.ReadBlob(ctx, cs, manifest.Config)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	var image ocispec.Image
    39  	if err := json.Unmarshal(imageConfigBytes, &image); err != nil {
    40  		return nil, err
    41  	}
    42  
    43  	rnd, err := uuid.NewRandom()
    44  	if err != nil {
    45  		return nil, err
    46  	}
    47  
    48  	snapshotter := i.client.SnapshotService(container.Driver)
    49  
    50  	diffIDs := image.RootFS.DiffIDs
    51  	parent, err := snapshotter.View(ctx, rnd.String(), identity.ChainID(diffIDs).String())
    52  	if err != nil {
    53  		return nil, err
    54  	}
    55  	defer func() {
    56  		if err := snapshotter.Remove(ctx, rnd.String()); err != nil {
    57  			logrus.WithError(err).WithField("key", rnd.String()).Warn("remove temporary snapshot")
    58  		}
    59  	}()
    60  
    61  	mounts, err := snapshotter.Mounts(ctx, container.ID)
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	var changes []archive.Change
    67  	err = mount.WithReadonlyTempMount(ctx, mounts, func(fs string) error {
    68  		return mount.WithTempMount(ctx, parent, func(root string) error {
    69  			changes, err = archive.ChangesDirs(fs, root)
    70  			return err
    71  		})
    72  	})
    73  	return changes, err
    74  }