From 111ab125b954c8d28503e1922e742eb271cc5d04 Mon Sep 17 00:00:00 2001 From: Travis Cline Date: Thu, 13 Feb 2014 16:05:36 -0800 Subject: [PATCH] Change misnamed TarFilter to TarWithOptions Docker-DCO-1.1-Signed-off-by: Travis Cline (github: tmc) --- archive/archive.go | 29 ++++++++++---- archive/archive_test.go | 68 ++++++++++++++++++++++++--------- daemon/container.go | 2 +- daemon/graphdriver/aufs/aufs.go | 2 +- 4 files changed, 73 insertions(+), 28 deletions(-) diff --git a/archive/archive.go b/archive/archive.go index 628d425ea1..65a5b495eb 100644 --- a/archive/archive.go +++ b/archive/archive.go @@ -27,6 +27,7 @@ type ( Compression int TarOptions struct { Includes []string + Excludes []string Compression Compression NoLchown bool } @@ -286,7 +287,7 @@ func createTarFile(path, extractDir string, hdr *tar.Header, reader io.Reader, L // Tar creates an archive from the directory at `path`, and returns it as a // stream of bytes. func Tar(path string, compression Compression) (io.ReadCloser, error) { - return TarFilter(path, &TarOptions{Compression: compression}) + return TarWithOptions(path, &TarOptions{Compression: compression}) } func escapeName(name string) string { @@ -305,12 +306,9 @@ func escapeName(name string) string { return string(escaped) } -// TarFilter creates an archive from the directory at `srcPath` with `options`, and returns it as a -// stream of bytes. -// -// Files are included according to `options.Includes`, default to including all files. -// Stream is compressed according to `options.Compression', default to Uncompressed. -func TarFilter(srcPath string, options *TarOptions) (io.ReadCloser, error) { +// TarWithOptions creates an archive from the directory at `path`, only including files whose relative +// paths are included in `options.Includes` (if non-nil) or not in `options.Excludes`. +func TarWithOptions(srcPath string, options *TarOptions) (io.ReadCloser, error) { pipeReader, pipeWriter := io.Pipe() compressWriter, err := CompressStream(pipeWriter, options.Compression) @@ -342,6 +340,21 @@ func TarFilter(srcPath string, options *TarOptions) (io.ReadCloser, error) { return nil } + for _, exclude := range options.Excludes { + matched, err := filepath.Match(exclude, relFilePath) + if err != nil { + utils.Errorf("Error matching: %s (pattern: %s)\n", relFilePath, exclude) + return err + } + if matched { + utils.Debugf("Skipping excluded path: %s\n", relFilePath) + if f.IsDir() { + return filepath.SkipDir + } + return nil + } + } + if err := addTarFile(filePath, relFilePath, tw); err != nil { utils.Debugf("Can't add file %s to tar: %s\n", srcPath, err) } @@ -482,7 +495,7 @@ func Untar(archive io.Reader, dest string, options *TarOptions) error { // TarUntar aborts and returns the error. func TarUntar(src string, dst string) error { utils.Debugf("TarUntar(%s %s)", src, dst) - archive, err := TarFilter(src, &TarOptions{Compression: Uncompressed}) + archive, err := TarWithOptions(src, &TarOptions{Compression: Uncompressed}) if err != nil { return err } diff --git a/archive/archive_test.go b/archive/archive_test.go index 8c9ed6e552..b9051fe6ae 100644 --- a/archive/archive_test.go +++ b/archive/archive_test.go @@ -63,8 +63,8 @@ func TestCmdStreamGood(t *testing.T) { } } -func tarUntar(t *testing.T, origin string, compression Compression) error { - archive, err := Tar(origin, compression) +func tarUntar(t *testing.T, origin string, options *TarOptions) ([]Change, error) { + archive, err := TarWithOptions(origin, options) if err != nil { t.Fatal(err) } @@ -72,37 +72,29 @@ func tarUntar(t *testing.T, origin string, compression Compression) error { buf := make([]byte, 10) if _, err := archive.Read(buf); err != nil { - return err + return nil, err } wrap := io.MultiReader(bytes.NewReader(buf), archive) detectedCompression := DetectCompression(buf) + compression := options.Compression if detectedCompression.Extension() != compression.Extension() { - return fmt.Errorf("Wrong compression detected. Actual compression: %s, found %s", compression.Extension(), detectedCompression.Extension()) + return nil, fmt.Errorf("Wrong compression detected. Actual compression: %s, found %s", compression.Extension(), detectedCompression.Extension()) } tmp, err := ioutil.TempDir("", "docker-test-untar") if err != nil { - return err + return nil, err } defer os.RemoveAll(tmp) if err := Untar(wrap, tmp, nil); err != nil { - return err + return nil, err } if _, err := os.Stat(tmp); err != nil { - return err + return nil, err } - changes, err := ChangesDirs(origin, tmp) - if err != nil { - return err - } - - if len(changes) != 0 { - t.Fatalf("Unexpected differences after tarUntar: %v", changes) - } - - return nil + return ChangesDirs(origin, tmp) } func TestTarUntar(t *testing.T) { @@ -122,9 +114,49 @@ func TestTarUntar(t *testing.T) { Uncompressed, Gzip, } { - if err := tarUntar(t, origin, c); err != nil { + changes, err := tarUntar(t, origin, &TarOptions{ + Compression: c, + }) + + if err != nil { t.Fatalf("Error tar/untar for compression %s: %s", c.Extension(), err) } + + if len(changes) != 0 { + t.Fatalf("Unexpected differences after tarUntar: %v", changes) + } + } +} + +func TestTarWithOptions(t *testing.T) { + origin, err := ioutil.TempDir("", "docker-test-untar-origin") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(origin) + if err := ioutil.WriteFile(path.Join(origin, "1"), []byte("hello world"), 0700); err != nil { + t.Fatal(err) + } + if err := ioutil.WriteFile(path.Join(origin, "2"), []byte("welcome!"), 0700); err != nil { + t.Fatal(err) + } + + cases := []struct { + opts *TarOptions + numChanges int + }{ + {&TarOptions{Includes: []string{"1"}}, 1}, + {&TarOptions{Excludes: []string{"2"}}, 1}, + } + for _, testCase := range cases { + changes, err := tarUntar(t, origin, testCase.opts) + if err != nil { + t.Fatalf("Error tar/untar when testing inclusion/exclusion: %s", err) + } + if len(changes) != testCase.numChanges { + t.Errorf("Expected %d changes, got %d for %+v:", + testCase.numChanges, len(changes), testCase.opts) + } } } diff --git a/daemon/container.go b/daemon/container.go index 2fd827eb9c..d9c809cee5 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -813,7 +813,7 @@ func (container *Container) Copy(resource string) (io.ReadCloser, error) { basePath = path.Dir(basePath) } - archive, err := archive.TarFilter(basePath, &archive.TarOptions{ + archive, err := archive.TarWithOptions(basePath, &archive.TarOptions{ Compression: archive.Uncompressed, Includes: filter, }) diff --git a/daemon/graphdriver/aufs/aufs.go b/daemon/graphdriver/aufs/aufs.go index eb8ff77cde..0206b92e17 100644 --- a/daemon/graphdriver/aufs/aufs.go +++ b/daemon/graphdriver/aufs/aufs.go @@ -295,7 +295,7 @@ func (a *Driver) Put(id string) { // Returns an archive of the contents for the id func (a *Driver) Diff(id string) (archive.Archive, error) { - return archive.TarFilter(path.Join(a.rootPath(), "diff", id), &archive.TarOptions{ + return archive.TarWithOptions(path.Join(a.rootPath(), "diff", id), &archive.TarOptions{ Compression: archive.Uncompressed, }) }