From d0546cf48483feca2f6b74d12fd34ed9b7c0f1b0 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Tue, 27 Jun 2017 10:38:01 -0700 Subject: [PATCH] build: fix add from remote url Signed-off-by: Tonis Tiigi (cherry picked from commit 2981667e11e24e9e1e61252a40ceb11fd7cb9811) Signed-off-by: Tonis Tiigi --- components/engine/builder/dockerfile/copy.go | 11 +++-- .../engine/builder/dockerfile/dispatchers.go | 5 +++ .../integration-cli/docker_api_build_test.go | 45 +++++++++++++++++++ 3 files changed, 57 insertions(+), 4 deletions(-) diff --git a/components/engine/builder/dockerfile/copy.go b/components/engine/builder/dockerfile/copy.go index 77f0a44d55..016e4efba3 100644 --- a/components/engine/builder/dockerfile/copy.go +++ b/components/engine/builder/dockerfile/copy.go @@ -30,9 +30,10 @@ type pathCache interface { // copyInfo is a data object which stores the metadata about each source file in // a copyInstruction type copyInfo struct { - root string - path string - hash string + root string + path string + hash string + noDecompress bool } func newCopyInfoFromSource(source builder.Source, path string, hash string) copyInfo { @@ -118,7 +119,9 @@ func (o *copier) getCopyInfoForSourcePath(orig string) ([]copyInfo, error) { o.tmpPaths = append(o.tmpPaths, remote.Root()) hash, err := remote.Hash(path) - return newCopyInfos(newCopyInfoFromSource(remote, path, hash)), err + ci := newCopyInfoFromSource(remote, path, hash) + ci.noDecompress = true // data from http shouldn't be extracted even on ADD + return newCopyInfos(ci), err } // Cleanup removes any temporary directories created as part of downloading diff --git a/components/engine/builder/dockerfile/dispatchers.go b/components/engine/builder/dockerfile/dispatchers.go index 7aeec98074..d50012d8e3 100644 --- a/components/engine/builder/dockerfile/dispatchers.go +++ b/components/engine/builder/dockerfile/dispatchers.go @@ -156,6 +156,11 @@ func add(req dispatchRequest) error { return err } copyInstruction.allowLocalDecompression = true + for _, ci := range copyInstruction.infos { + if ci.noDecompress { + copyInstruction.allowLocalDecompression = false + } + } return req.builder.performCopy(req.state, copyInstruction) } diff --git a/components/engine/integration-cli/docker_api_build_test.go b/components/engine/integration-cli/docker_api_build_test.go index 64ad7c3251..55893a1c75 100644 --- a/components/engine/integration-cli/docker_api_build_test.go +++ b/components/engine/integration-cli/docker_api_build_test.go @@ -4,6 +4,7 @@ import ( "archive/tar" "bytes" "encoding/json" + "fmt" "io/ioutil" "net/http" "regexp" @@ -322,6 +323,50 @@ func (s *DockerSuite) TestBuildOnBuildCache(c *check.C) { assert.Equal(c, parentID, image.Parent) } +func (s *DockerSuite) TestBuildAddRemoteNoDecompress(c *check.C) { + buffer := new(bytes.Buffer) + tw := tar.NewWriter(buffer) + dt := []byte("contents") + err := tw.WriteHeader(&tar.Header{ + Name: "foo", + Size: int64(len(dt)), + Mode: 0600, + Typeflag: tar.TypeReg, + }) + require.NoError(c, err) + _, err = tw.Write(dt) + require.NoError(c, err) + err = tw.Close() + require.NoError(c, err) + + server := fakestorage.New(c, "", fakecontext.WithBinaryFiles(map[string]*bytes.Buffer{ + "test.tar": buffer, + })) + defer server.Close() + + dockerfile := fmt.Sprintf(` + FROM busybox + ADD %s/test.tar / + RUN [ -f test.tar ] + `, server.URL()) + + ctx := fakecontext.New(c, "", + fakecontext.WithDockerfile(dockerfile), + ) + defer ctx.Close() + + res, body, err := request.Post( + "/build", + request.RawContent(ctx.AsTarReader(c)), + request.ContentType("application/x-tar")) + require.NoError(c, err) + assert.Equal(c, http.StatusOK, res.StatusCode) + + out, err := testutil.ReadBody(body) + require.NoError(c, err) + assert.Contains(c, string(out), "Successfully built") +} + type buildLine struct { Stream string Aux struct {