Merge pull request #189 from tonistiigi/extraction
dockerfile: Add ADD from archive supportdocker-18.09
commit
9397eb2373
|
@ -332,14 +332,17 @@ func dispatchWorkdir(d *dispatchState, c *instructions.WorkdirCommand) error {
|
|||
}
|
||||
|
||||
func dispatchCopy(d *dispatchState, c instructions.SourcesAndDest, sourceState llb.State, isAddCommand bool) error {
|
||||
// TODO: this should use CopyOp instead. Current implementation is inefficient and doesn't match Dockerfile path suffixes rules
|
||||
img := llb.Image("tonistiigi/copy@sha256:260a4355be76e0609518ebd7c0e026831c80b8908d4afd3f8e8c942645b1e5cf")
|
||||
// TODO: this should use CopyOp instead. Current implementation is inefficient
|
||||
img := llb.Image("tonistiigi/copy@sha256:ca6620946b2db7ad92f80cc5834f5d0724e6ede1f00004c965f6ded61592553a")
|
||||
|
||||
dest := path.Join("/dest", pathRelativeToWorkingDir(d.state, c.Dest()))
|
||||
if c.Dest() == "." || c.Dest()[len(c.Dest())-1] == filepath.Separator {
|
||||
dest += string(filepath.Separator)
|
||||
}
|
||||
args := []string{"copy"}
|
||||
if isAddCommand {
|
||||
args = append(args, "--unpack")
|
||||
}
|
||||
mounts := make([]llb.RunOption, 0, len(c.Sources()))
|
||||
for i, src := range c.Sources() {
|
||||
if isAddCommand && urlutil.IsURL(src) {
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package dockerfile
|
||||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
@ -22,6 +24,7 @@ func TestIntegration(t *testing.T) {
|
|||
testDockerfileDirs,
|
||||
testDockerfileInvalidCommand,
|
||||
testDockerfileADDFromURL,
|
||||
testDockerfileAddArchive,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -197,6 +200,148 @@ ADD %s /dest/
|
|||
require.Equal(t, fi.ModTime().Format(http.TimeFormat), modTime.Format(http.TimeFormat))
|
||||
}
|
||||
|
||||
func testDockerfileAddArchive(t *testing.T, sb integration.Sandbox) {
|
||||
t.Parallel()
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
tw := tar.NewWriter(buf)
|
||||
expectedContent := []byte("content0")
|
||||
err := tw.WriteHeader(&tar.Header{
|
||||
Name: "foo",
|
||||
Typeflag: tar.TypeReg,
|
||||
Size: int64(len(expectedContent)),
|
||||
Mode: 0644,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
_, err = tw.Write(expectedContent)
|
||||
require.NoError(t, err)
|
||||
err = tw.Close()
|
||||
require.NoError(t, err)
|
||||
|
||||
dockerfile := []byte(`
|
||||
FROM scratch
|
||||
ADD t.tar /
|
||||
`)
|
||||
|
||||
dir, err := tmpdir(
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
fstest.CreateFile("t.tar", buf.Bytes(), 0600),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
args, trace := dfCmdArgs(dir, dir)
|
||||
defer os.RemoveAll(trace)
|
||||
|
||||
destDir, err := tmpdir()
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
||||
cmd := sb.Cmd(args + fmt.Sprintf(" --exporter=local --exporter-opt output=%s", destDir))
|
||||
require.NoError(t, cmd.Run())
|
||||
|
||||
dt, err := ioutil.ReadFile(filepath.Join(destDir, "foo"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expectedContent, dt)
|
||||
|
||||
// add gzip tar
|
||||
buf2 := bytes.NewBuffer(nil)
|
||||
gz := gzip.NewWriter(buf2)
|
||||
_, err = gz.Write(buf.Bytes())
|
||||
require.NoError(t, err)
|
||||
err = gz.Close()
|
||||
require.NoError(t, err)
|
||||
|
||||
dockerfile = []byte(`
|
||||
FROM scratch
|
||||
ADD t.tar.gz /
|
||||
`)
|
||||
|
||||
dir, err = tmpdir(
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
fstest.CreateFile("t.tar.gz", buf2.Bytes(), 0600),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
args, trace = dfCmdArgs(dir, dir)
|
||||
defer os.RemoveAll(trace)
|
||||
|
||||
destDir, err = tmpdir()
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
||||
cmd = sb.Cmd(args + fmt.Sprintf(" --exporter=local --exporter-opt output=%s", destDir))
|
||||
require.NoError(t, cmd.Run())
|
||||
|
||||
dt, err = ioutil.ReadFile(filepath.Join(destDir, "foo"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expectedContent, dt)
|
||||
|
||||
// COPY doesn't extract
|
||||
dockerfile = []byte(`
|
||||
FROM scratch
|
||||
COPY t.tar.gz /
|
||||
`)
|
||||
|
||||
dir, err = tmpdir(
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
fstest.CreateFile("t.tar.gz", buf2.Bytes(), 0600),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
args, trace = dfCmdArgs(dir, dir)
|
||||
defer os.RemoveAll(trace)
|
||||
|
||||
destDir, err = tmpdir()
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
||||
cmd = sb.Cmd(args + fmt.Sprintf(" --exporter=local --exporter-opt output=%s", destDir))
|
||||
require.NoError(t, cmd.Run())
|
||||
|
||||
dt, err = ioutil.ReadFile(filepath.Join(destDir, "t.tar.gz"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, buf2.Bytes(), dt)
|
||||
|
||||
// ADD from URL doesn't extract
|
||||
resp := httpserver.Response{
|
||||
Etag: identity.NewID(),
|
||||
Content: buf2.Bytes(),
|
||||
}
|
||||
|
||||
server := httpserver.NewTestServer(map[string]httpserver.Response{
|
||||
"/t.tar.gz": resp,
|
||||
})
|
||||
defer server.Close()
|
||||
|
||||
dockerfile = []byte(fmt.Sprintf(`
|
||||
FROM scratch
|
||||
ADD %s /
|
||||
`, server.URL+"/t.tar.gz"))
|
||||
|
||||
dir, err = tmpdir(
|
||||
fstest.CreateFile("Dockerfile", dockerfile, 0600),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
args, trace = dfCmdArgs(dir, dir)
|
||||
defer os.RemoveAll(trace)
|
||||
|
||||
destDir, err = tmpdir()
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(destDir)
|
||||
|
||||
cmd = sb.Cmd(args + fmt.Sprintf(" --exporter=local --exporter-opt output=%s", destDir))
|
||||
require.NoError(t, cmd.Run())
|
||||
|
||||
dt, err = ioutil.ReadFile(filepath.Join(destDir, "t.tar.gz"))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, buf2.Bytes(), dt)
|
||||
}
|
||||
|
||||
func tmpdir(appliers ...fstest.Applier) (string, error) {
|
||||
tmpdir, err := ioutil.TempDir("", "buildkit-dockerfile")
|
||||
if err != nil {
|
||||
|
|
Loading…
Reference in New Issue