github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/daemon/containerd/image_exporter.go (about)

     1  package containerd
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  
     7  	"github.com/containerd/containerd"
     8  	"github.com/containerd/containerd/images/archive"
     9  	"github.com/containerd/containerd/platforms"
    10  	"github.com/docker/distribution/reference"
    11  	"github.com/pkg/errors"
    12  	"github.com/sirupsen/logrus"
    13  )
    14  
    15  // ExportImage exports a list of images to the given output stream. The
    16  // exported images are archived into a tar when written to the output
    17  // stream. All images with the given tag and all versions containing
    18  // the same tag are exported. names is the set of tags to export, and
    19  // outStream is the writer which the images are written to.
    20  //
    21  // TODO(thaJeztah): produce JSON stream progress response and image events; see https://github.com/moby/moby/issues/43910
    22  func (i *ImageService) ExportImage(ctx context.Context, names []string, outStream io.Writer) error {
    23  	opts := []archive.ExportOpt{
    24  		archive.WithPlatform(platforms.Ordered(platforms.DefaultSpec())),
    25  		archive.WithSkipNonDistributableBlobs(),
    26  	}
    27  	is := i.client.ImageService()
    28  	for _, imageRef := range names {
    29  		named, err := reference.ParseDockerRef(imageRef)
    30  		if err != nil {
    31  			return err
    32  		}
    33  		opts = append(opts, archive.WithImage(is, named.String()))
    34  	}
    35  	return i.client.Export(ctx, outStream, opts...)
    36  }
    37  
    38  // LoadImage uploads a set of images into the repository. This is the
    39  // complement of ExportImage.  The input stream is an uncompressed tar
    40  // ball containing images and metadata.
    41  //
    42  // TODO(thaJeztah): produce JSON stream progress response and image events; see https://github.com/moby/moby/issues/43910
    43  func (i *ImageService) LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
    44  	platform := platforms.All
    45  	imgs, err := i.client.Import(ctx, inTar, containerd.WithImportPlatform(platform))
    46  
    47  	if err != nil {
    48  		// TODO(thaJeztah): remove this log or change to debug once we can; see https://github.com/moby/moby/pull/43822#discussion_r937502405
    49  		logrus.WithError(err).Warn("failed to import image to containerd")
    50  		return errors.Wrap(err, "failed to import image")
    51  	}
    52  
    53  	for _, img := range imgs {
    54  		platformImg := containerd.NewImageWithPlatform(i.client, img, platform)
    55  
    56  		unpacked, err := platformImg.IsUnpacked(ctx, i.snapshotter)
    57  		if err != nil {
    58  			// TODO(thaJeztah): remove this log or change to debug once we can; see https://github.com/moby/moby/pull/43822#discussion_r937502405
    59  			logrus.WithError(err).WithField("image", img.Name).Debug("failed to check if image is unpacked")
    60  			continue
    61  		}
    62  
    63  		if !unpacked {
    64  			err := platformImg.Unpack(ctx, i.snapshotter)
    65  			if err != nil {
    66  				// TODO(thaJeztah): remove this log or change to debug once we can; see https://github.com/moby/moby/pull/43822#discussion_r937502405
    67  				logrus.WithError(err).WithField("image", img.Name).Warn("failed to unpack image")
    68  				return errors.Wrap(err, "failed to unpack image")
    69  			}
    70  		}
    71  	}
    72  	return nil
    73  }