Skip to content

Commit

Permalink
cli/daemon/apis/test: support to load docker images without name
Browse files Browse the repository at this point in the history
For the docker image format, the tar file will contain the image
reference information. For this case, when we load the docker images, we
should not set the image name. If there are too many images and you just
want to load one of them, you can set the name.

Signed-off-by: Wei Fu <fuweid89@gmail.com>
  • Loading branch information
fuweid authored and rudyfly committed May 13, 2019
1 parent 1e283c0 commit ba02aa6
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 17 deletions.
3 changes: 0 additions & 3 deletions apis/server/image_bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,6 @@ func (s *Server) postImageTag(ctx context.Context, rw http.ResponseWriter, req *
// loadImage loads an image by http tar stream.
func (s *Server) loadImage(ctx context.Context, rw http.ResponseWriter, req *http.Request) error {
imageName := req.FormValue("name")
if imageName == "" {
imageName = "unknown/unknown"
}

if err := s.ImageMgr.LoadImage(ctx, imageName, req.Body); err != nil {
return err
Expand Down
4 changes: 3 additions & 1 deletion cli/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ import (
)

// loadDescription is used to describe load command in detail and auto generate command doc.
var loadDescription = "load a set of images by tar stream"
var loadDescription = "load a set of images by tar stream.\n" +
"for docker image format, no need to set the image name because pouch" +
" will parse image name from tar stream."

// LoadCommand use to implement 'load' command.
type LoadCommand struct {
Expand Down
39 changes: 26 additions & 13 deletions daemon/mgr/image_load.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"io"
"time"

"github.com/alibaba/pouch/pkg/multierror"
"github.com/alibaba/pouch/pkg/reference"
Expand All @@ -17,22 +18,34 @@ import (
func (mgr *ImageManager) LoadImage(ctx context.Context, imageName string, tarstream io.ReadCloser) error {
defer tarstream.Close()

namedRef, err := reference.Parse(imageName)
if err != nil {
return pkgerrors.Wrapf(err, "failed to parse image name %s", imageName)
}
var opts []containerd.ImportOpt

// NOTE: for the docker image, we should pass empty image name because
// the containerd will help us to get the original name.
if imageName == "" {
imageName = fmt.Sprintf("import-%s", time.Now().Format("2006-01-02"))
opts = append(opts, containerd.WithImageRefTranslator(archive.AddRefPrefix(imageName)))
} else {
// When provided, filter out references which do not match

// NOTE: in the image ocispec.v1, the org.opencontainers.image.ref.name
// annotation represents a "tag" for image. For example, an image may
// have a tag for different versions or builds of the software.
// And containerd.importer will append ":" and annotation to the name
// so that we don't allow imageName to contains any digest or tag
// information, like foo/bar:latest:v1.2.
if !reference.IsNamedOnly(namedRef) {
return fmt.Errorf("the image name should not contains any digest or tag information")
namedRef, err := reference.Parse(imageName)
if err != nil {
return pkgerrors.Wrapf(err, "failed to parse image name %s", imageName)
}

// NOTE: in the image ocispec.v1, the org.opencontainers.image.ref.name
// annotation represents a "tag" for image. For example, an image may
// have a tag for different versions or builds of the software.
// And containerd.importer will append ":" and annotation to the name
// so that we don't allow imageName to contains any digest or tag
// information, like foo/bar:latest:v1.2.
if !reference.IsNamedOnly(namedRef) {
return fmt.Errorf("the image name should not contains any digest or tag information")
}
opts = append(opts, containerd.WithImageRefTranslator(archive.FilterRefPrefix(imageName)))
}

imgs, err := mgr.client.ImportImage(ctx, tarstream, containerd.WithImageRefTranslator(archive.FilterRefPrefix(imageName)))
imgs, err := mgr.client.ImportImage(ctx, tarstream, opts...)
if err != nil {
return pkgerrors.Wrap(err, "failed to import image into containerd by tarstream")
}
Expand Down
29 changes: 29 additions & 0 deletions test/cli_save_and_load_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,35 @@ func (suite *PouchSaveLoadSuite) SetUpSuite(c *check.C) {
environment.PruneAllContainers(apiClient)
}

// TestSaveLoadDockerImages tests "pouch load" docker images.
func (suite *PouchSaveLoadSuite) TestSaveLoadDockerImages(c *check.C) {
environment.PruneAllImages(apiClient)

// the tar file contains the busybox:1.25 and alpine:3.7
filename := filepath.Join("testdata", "images", "docker-busybox_1_25-and-alpine_3_7.tar")
command.PouchRun("load", "-i", filename).Assert(c, icmd.Success)

command.PouchRun("image", "inspect", "docker.io/library/busybox:1.25").Assert(c, icmd.Success)
command.PouchRun("image", "inspect", "docker.io/library/alpine:3.7").Assert(c, icmd.Success)
}

// TestSaveLoadOneDockerImage tests "pouch load -i <docker images> one-image.
func (suite *PouchSaveLoadSuite) TestSaveLoadOneDockerImage(c *check.C) {
environment.PruneAllImages(apiClient)

// the tar file contains the busybox:1.25 and alpine:3.7
filename := filepath.Join("testdata", "images", "docker-busybox_1_25-and-alpine_3_7.tar")

// only load alpine
command.PouchRun("load", "-i", filename, "docker.io/library/alpine").Assert(c, icmd.Success)

command.PouchRun("image", "inspect", "docker.io/library/alpine:3.7").Assert(c, icmd.Success)

// busybox should be ignored
res := command.PouchRun("image", "inspect", "docker.io/library/busybox:1.25")
c.Assert(res.ExitCode, check.Not(check.Equals), 0)
}

// TestSaveLoadWorks tests "pouch save" and "pouch load" work.
func (suite *PouchSaveLoadSuite) TestSaveLoadWorks(c *check.C) {
res := command.PouchRun("pull", busyboxImage125)
Expand Down
Binary file not shown.

0 comments on commit ba02aa6

Please sign in to comment.