Browse code

Fix docker import on compressed data

Fixes #20296

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>

Tonis Tiigi authored on 2016/02/17 04:19:23
Showing 2 changed files
... ...
@@ -11,6 +11,7 @@ import (
11 11
 	"github.com/docker/docker/dockerversion"
12 12
 	"github.com/docker/docker/image"
13 13
 	"github.com/docker/docker/layer"
14
+	"github.com/docker/docker/pkg/archive"
14 15
 	"github.com/docker/docker/pkg/httputils"
15 16
 	"github.com/docker/docker/pkg/progress"
16 17
 	"github.com/docker/docker/pkg/streamformatter"
... ...
@@ -24,13 +25,13 @@ import (
24 24
 // the repo and tag arguments, respectively.
25 25
 func (daemon *Daemon) ImportImage(src string, newRef reference.Named, msg string, inConfig io.ReadCloser, outStream io.Writer, config *container.Config) error {
26 26
 	var (
27
-		sf      = streamformatter.NewJSONStreamFormatter()
28
-		archive io.ReadCloser
29
-		resp    *http.Response
27
+		sf   = streamformatter.NewJSONStreamFormatter()
28
+		rc   io.ReadCloser
29
+		resp *http.Response
30 30
 	)
31 31
 
32 32
 	if src == "-" {
33
-		archive = inConfig
33
+		rc = inConfig
34 34
 	} else {
35 35
 		inConfig.Close()
36 36
 		u, err := url.Parse(src)
... ...
@@ -48,15 +49,20 @@ func (daemon *Daemon) ImportImage(src string, newRef reference.Named, msg string
48 48
 			return err
49 49
 		}
50 50
 		progressOutput := sf.NewProgressOutput(outStream, true)
51
-		archive = progress.NewProgressReader(resp.Body, progressOutput, resp.ContentLength, "", "Importing")
51
+		rc = progress.NewProgressReader(resp.Body, progressOutput, resp.ContentLength, "", "Importing")
52 52
 	}
53 53
 
54
-	defer archive.Close()
54
+	defer rc.Close()
55 55
 	if len(msg) == 0 {
56 56
 		msg = "Imported from " + src
57 57
 	}
58
+
59
+	inflatedLayerData, err := archive.DecompressStream(rc)
60
+	if err != nil {
61
+		return err
62
+	}
58 63
 	// TODO: support windows baselayer?
59
-	l, err := daemon.layerStore.Register(archive, "")
64
+	l, err := daemon.layerStore.Register(inflatedLayerData, "")
60 65
 	if err != nil {
61 66
 		return err
62 67
 	}
... ...
@@ -2,6 +2,7 @@ package main
2 2
 
3 3
 import (
4 4
 	"bufio"
5
+	"compress/gzip"
5 6
 	"io/ioutil"
6 7
 	"os"
7 8
 	"os/exec"
... ...
@@ -59,6 +60,31 @@ func (s *DockerSuite) TestImportFile(c *check.C) {
59 59
 	c.Assert(out, checker.Equals, "", check.Commentf("command output should've been nothing."))
60 60
 }
61 61
 
62
+func (s *DockerSuite) TestImportGzipped(c *check.C) {
63
+	testRequires(c, DaemonIsLinux)
64
+	dockerCmd(c, "run", "--name", "test-import", "busybox", "true")
65
+
66
+	temporaryFile, err := ioutil.TempFile("", "exportImportTest")
67
+	c.Assert(err, checker.IsNil, check.Commentf("failed to create temporary file"))
68
+	defer os.Remove(temporaryFile.Name())
69
+
70
+	runCmd := exec.Command(dockerBinary, "export", "test-import")
71
+	w := gzip.NewWriter(temporaryFile)
72
+	runCmd.Stdout = w
73
+
74
+	_, err = runCommand(runCmd)
75
+	c.Assert(err, checker.IsNil, check.Commentf("failed to export a container"))
76
+	err = w.Close()
77
+	c.Assert(err, checker.IsNil, check.Commentf("failed to close gzip writer"))
78
+	temporaryFile.Close()
79
+	out, _ := dockerCmd(c, "import", temporaryFile.Name())
80
+	c.Assert(out, checker.Count, "\n", 1, check.Commentf("display is expected 1 '\\n' but didn't"))
81
+	image := strings.TrimSpace(out)
82
+
83
+	out, _ = dockerCmd(c, "run", "--rm", image, "true")
84
+	c.Assert(out, checker.Equals, "", check.Commentf("command output should've been nothing."))
85
+}
86
+
62 87
 func (s *DockerSuite) TestImportFileWithMessage(c *check.C) {
63 88
 	testRequires(c, DaemonIsLinux)
64 89
 	dockerCmd(c, "run", "--name", "test-import", "busybox", "true")