add image load/save support

Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Nicolas De Loof 2022-07-11 11:46:07 +02:00 committed by Sebastiaan van Stijn
parent 7e8df0e2c9
commit 50fb999bb1
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
5 changed files with 37 additions and 13 deletions

View file

@ -30,9 +30,9 @@ type imageBackend interface {
}
type importExportBackend interface {
LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error
LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error
ImportImage(src string, repository string, platform *specs.Platform, tag string, msg string, inConfig io.ReadCloser, outStream io.Writer, changes []string) error
ExportImage(names []string, outStream io.Writer) error
ExportImage(ctx context.Context, names []string, outStream io.Writer) error
}
type registryBackend interface {

View file

@ -137,7 +137,7 @@ func (s *imageRouter) getImagesGet(ctx context.Context, w http.ResponseWriter, r
names = r.Form["names"]
}
if err := s.backend.ExportImage(names, output); err != nil {
if err := s.backend.ExportImage(ctx, names, output); err != nil {
if !output.Flushed() {
return err
}
@ -156,7 +156,7 @@ func (s *imageRouter) postImagesLoad(ctx context.Context, w http.ResponseWriter,
output := ioutils.NewWriteFlusher(w)
defer output.Close()
if err := s.backend.LoadImage(r.Body, output, quiet); err != nil {
if err := s.backend.LoadImage(ctx, r.Body, output, quiet); err != nil {
_, _ = output.Write(streamformatter.FormatError(err))
}
return nil

View file

@ -1,19 +1,42 @@
package containerd
import "io"
import (
"context"
"io"
"github.com/containerd/containerd"
"github.com/containerd/containerd/images/archive"
"github.com/containerd/containerd/platforms"
"github.com/docker/distribution/reference"
)
// ExportImage exports a list of images to the given output stream. The
// exported images are archived into a tar when written to the output
// stream. All images with the given tag and all versions containing
// the same tag are exported. names is the set of tags to export, and
// outStream is the writer which the images are written to.
func (i *ImageService) ExportImage(names []string, outStream io.Writer) error {
panic("not implemented")
func (i *ImageService) ExportImage(ctx context.Context, names []string, outStream io.Writer) error {
opts := []archive.ExportOpt{
archive.WithPlatform(platforms.Ordered(platforms.DefaultSpec())),
archive.WithSkipNonDistributableBlobs(),
}
is := i.client.ImageService()
for _, imageRef := range names {
named, err := reference.ParseDockerRef(imageRef)
if err != nil {
return err
}
opts = append(opts, archive.WithImage(is, named.String()))
}
return i.client.Export(ctx, outStream, opts...)
}
// LoadImage uploads a set of images into the repository. This is the
// complement of ExportImage. The input stream is an uncompressed tar
// ball containing images and metadata.
func (i *ImageService) LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
panic("not implemented")
func (i *ImageService) LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
_, err := i.client.Import(ctx, inTar,
containerd.WithImportPlatform(platforms.DefaultStrict()),
)
return err
}

View file

@ -29,8 +29,8 @@ type ImageService interface {
PushImage(ctx context.Context, image, tag string, metaHeaders map[string][]string, authConfig *registry.AuthConfig, outStream io.Writer) error
CreateImage(config []byte, parent string) (builder.Image, error)
ImageDelete(ctx context.Context, imageRef string, force, prune bool) ([]types.ImageDeleteResponseItem, error)
ExportImage(names []string, outStream io.Writer) error
LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error
ExportImage(ctx context.Context, names []string, outStream io.Writer) error
LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error
Images(ctx context.Context, opts types.ImageListOptions) ([]*types.ImageSummary, error)
LogImageEvent(imageID, refName, action string)
LogImageEventWithAttributes(imageID, refName, action string, attributes map[string]string)

View file

@ -1,6 +1,7 @@
package images // import "github.com/docker/docker/daemon/images"
import (
"context"
"io"
"github.com/docker/docker/image/tarexport"
@ -11,7 +12,7 @@ import (
// stream. All images with the given tag and all versions containing
// the same tag are exported. names is the set of tags to export, and
// outStream is the writer which the images are written to.
func (i *ImageService) ExportImage(names []string, outStream io.Writer) error {
func (i *ImageService) ExportImage(ctx context.Context, names []string, outStream io.Writer) error {
imageExporter := tarexport.NewTarExporter(i.imageStore, i.layerStore, i.referenceStore, i)
return imageExporter.Save(names, outStream)
}
@ -19,7 +20,7 @@ func (i *ImageService) ExportImage(names []string, outStream io.Writer) error {
// LoadImage uploads a set of images into the repository. This is the
// complement of ExportImage. The input stream is an uncompressed tar
// ball containing images and metadata.
func (i *ImageService) LoadImage(inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
func (i *ImageService) LoadImage(ctx context.Context, inTar io.ReadCloser, outStream io.Writer, quiet bool) error {
imageExporter := tarexport.NewTarExporter(i.imageStore, i.layerStore, i.referenceStore, i)
return imageExporter.Load(inTar, outStream, quiet)
}