Browse Source

Fix docker import on compressed data

Fixes #20296

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Tonis Tiigi 9 years ago
parent
commit
e1c2eb0d35
2 changed files with 39 additions and 7 deletions
  1. 13 7
      daemon/import.go
  2. 26 0
      integration-cli/docker_cli_import_test.go

+ 13 - 7
daemon/import.go

@@ -11,6 +11,7 @@ import (
 	"github.com/docker/docker/dockerversion"
 	"github.com/docker/docker/image"
 	"github.com/docker/docker/layer"
+	"github.com/docker/docker/pkg/archive"
 	"github.com/docker/docker/pkg/httputils"
 	"github.com/docker/docker/pkg/progress"
 	"github.com/docker/docker/pkg/streamformatter"
@@ -24,13 +25,13 @@ import (
 // the repo and tag arguments, respectively.
 func (daemon *Daemon) ImportImage(src string, newRef reference.Named, msg string, inConfig io.ReadCloser, outStream io.Writer, config *container.Config) error {
 	var (
-		sf      = streamformatter.NewJSONStreamFormatter()
-		archive io.ReadCloser
-		resp    *http.Response
+		sf   = streamformatter.NewJSONStreamFormatter()
+		rc   io.ReadCloser
+		resp *http.Response
 	)
 
 	if src == "-" {
-		archive = inConfig
+		rc = inConfig
 	} else {
 		inConfig.Close()
 		u, err := url.Parse(src)
@@ -48,15 +49,20 @@ func (daemon *Daemon) ImportImage(src string, newRef reference.Named, msg string
 			return err
 		}
 		progressOutput := sf.NewProgressOutput(outStream, true)
-		archive = progress.NewProgressReader(resp.Body, progressOutput, resp.ContentLength, "", "Importing")
+		rc = progress.NewProgressReader(resp.Body, progressOutput, resp.ContentLength, "", "Importing")
 	}
 
-	defer archive.Close()
+	defer rc.Close()
 	if len(msg) == 0 {
 		msg = "Imported from " + src
 	}
+
+	inflatedLayerData, err := archive.DecompressStream(rc)
+	if err != nil {
+		return err
+	}
 	// TODO: support windows baselayer?
-	l, err := daemon.layerStore.Register(archive, "")
+	l, err := daemon.layerStore.Register(inflatedLayerData, "")
 	if err != nil {
 		return err
 	}

+ 26 - 0
integration-cli/docker_cli_import_test.go

@@ -2,6 +2,7 @@ package main
 
 import (
 	"bufio"
+	"compress/gzip"
 	"io/ioutil"
 	"os"
 	"os/exec"
@@ -59,6 +60,31 @@ func (s *DockerSuite) TestImportFile(c *check.C) {
 	c.Assert(out, checker.Equals, "", check.Commentf("command output should've been nothing."))
 }
 
+func (s *DockerSuite) TestImportGzipped(c *check.C) {
+	testRequires(c, DaemonIsLinux)
+	dockerCmd(c, "run", "--name", "test-import", "busybox", "true")
+
+	temporaryFile, err := ioutil.TempFile("", "exportImportTest")
+	c.Assert(err, checker.IsNil, check.Commentf("failed to create temporary file"))
+	defer os.Remove(temporaryFile.Name())
+
+	runCmd := exec.Command(dockerBinary, "export", "test-import")
+	w := gzip.NewWriter(temporaryFile)
+	runCmd.Stdout = w
+
+	_, err = runCommand(runCmd)
+	c.Assert(err, checker.IsNil, check.Commentf("failed to export a container"))
+	err = w.Close()
+	c.Assert(err, checker.IsNil, check.Commentf("failed to close gzip writer"))
+	temporaryFile.Close()
+	out, _ := dockerCmd(c, "import", temporaryFile.Name())
+	c.Assert(out, checker.Count, "\n", 1, check.Commentf("display is expected 1 '\\n' but didn't"))
+	image := strings.TrimSpace(out)
+
+	out, _ = dockerCmd(c, "run", "--rm", image, "true")
+	c.Assert(out, checker.Equals, "", check.Commentf("command output should've been nothing."))
+}
+
 func (s *DockerSuite) TestImportFileWithMessage(c *check.C) {
 	testRequires(c, DaemonIsLinux)
 	dockerCmd(c, "run", "--name", "test-import", "busybox", "true")