From 4c9c43a611a65e1a8e0d27e451d0d54ce72bd94f Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 8 Nov 2013 11:56:34 -0800 Subject: [PATCH 1/5] Use tmp dir in driver home Upstream-commit: 6669c86fdf1ae07b66a6e178e269d797f6397bca Component: engine --- components/engine/aufs/aufs.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/components/engine/aufs/aufs.go b/components/engine/aufs/aufs.go index 22fa487f3a..f47c65e661 100644 --- a/components/engine/aufs/aufs.go +++ b/components/engine/aufs/aufs.go @@ -158,7 +158,10 @@ func (a *AufsDriver) Remove(id string) error { // Remove the dirs atomically for _, p := range tmpDirs { - tmp := path.Join(os.TempDir(), p, id) + // We need to use a temp dir in the same dir as the driver so Rename + // does not fall back to the slow copy if /tmp and the driver dir + // are on different devices + tmp := path.Join(a.rootPath(), "tmp", p, id) if err := os.MkdirAll(tmp, 0755); err != nil { return err } From c94da34819fcf99408f3f77d37c3c2279cd70ab6 Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 8 Nov 2013 12:06:15 -0800 Subject: [PATCH 2/5] Make sure dirs are created before injecting file Upstream-commit: 20f690f1762e369e9ad761e166f22ff57a17275a Component: engine --- components/engine/container.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/components/engine/container.go b/components/engine/container.go index f388a18e2f..6dee2335ff 100644 --- a/components/engine/container.go +++ b/components/engine/container.go @@ -396,7 +396,8 @@ func (container *Container) Inject(file io.Reader, pth string) error { } // Return error if path exists - if _, err := os.Stat(path.Join(container.RootfsPath(), pth)); err == nil { + destPath := path.Join(container.RootfsPath(), pth) + if _, err := os.Stat(destPath); err == nil { // Since err is nil, the path could be stat'd and it exists return fmt.Errorf("%s exists", pth) } else if !os.IsNotExist(err) { @@ -405,10 +406,18 @@ func (container *Container) Inject(file io.Reader, pth string) error { return err } - dest, err := os.Create(path.Join(container.RootfsPath(), pth)) + + // Make sure the directory exists + if err := os.MkdirAll(path.Join(container.RootfsPath(), path.Dir(pth)), 0755); err != nil { + return err + } + + dest, err := os.Create(destPath) if err != nil { return err } + defer dest.Close() + if _, err := io.Copy(dest, file); err != nil { return err } From 4806ef83ebe98fabf12bed5e89d906f26f28355a Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 8 Nov 2013 12:25:17 -0800 Subject: [PATCH 3/5] Add unit test for child changes diff in aufs Upstream-commit: f512049c8f9e64848cd8b1be794619f01c5227f2 Component: engine --- components/engine/aufs/aufs_test.go | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/components/engine/aufs/aufs_test.go b/components/engine/aufs/aufs_test.go index b71f17f009..e4250d9e7b 100644 --- a/components/engine/aufs/aufs_test.go +++ b/components/engine/aufs/aufs_test.go @@ -384,6 +384,46 @@ func TestChanges(t *testing.T) { if change.Kind != archive.ChangeAdd { t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind) } + + if err := d.Create("3", "2"); err != nil { + t.Fatal(err) + } + mntPoint, err = d.Get("3") + if err != nil { + t.Fatal(err) + } + + // Create a file to save in the mountpoint + f, err = os.Create(path.Join(mntPoint, "test2.txt")) + if err != nil { + t.Fatal(err) + } + + if _, err := f.WriteString("testline"); err != nil { + t.Fatal(err) + } + if err := f.Close(); err != nil { + t.Fatal(err) + } + + changes, err = d.Changes("3") + if err != nil { + t.Fatal(err) + } + + if len(changes) != 1 { + t.Fatalf("Dir 2 should have one change from parent got %d", len(changes)) + } + change = changes[0] + + expectedPath = "/test2.txt" + if change.Path != expectedPath { + t.Fatalf("Expected path %s got %s", expectedPath, change.Path) + } + + if change.Kind != archive.ChangeAdd { + t.Fatalf("Change kind should be ChangeAdd got %s", change.Kind) + } } /* FIXME: How to properly test this? From f4f11a5ecbc0e657da0887eb30461cc9cf566a6c Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 8 Nov 2013 14:54:20 -0800 Subject: [PATCH 4/5] Allow driver to provide changes if it impl the Changer interface Upstream-commit: 95147675870e9e84deb354f09f0f670a5cb2b1e1 Component: engine --- components/engine/container_test.go | 4 ++-- components/engine/devmapper/driver.go | 4 ---- components/engine/graphdriver/driver.go | 5 ++++- components/engine/graphdriver/dummy/driver.go | 4 ---- components/engine/runtime.go | 3 +++ 5 files changed, 9 insertions(+), 11 deletions(-) diff --git a/components/engine/container_test.go b/components/engine/container_test.go index cbabffc364..6f39f9be8e 100644 --- a/components/engine/container_test.go +++ b/components/engine/container_test.go @@ -170,11 +170,11 @@ func TestDiff(t *testing.T) { // Commit the container rwTar, err := container1.ExportRw() if err != nil { - t.Error(err) + t.Fatal(err) } img, err := runtime.graph.Create(rwTar, container1, "unit test commited image - diff", "", nil) if err != nil { - t.Error(err) + t.Fatal(err) } // Create a new container from the commited image diff --git a/components/engine/devmapper/driver.go b/components/engine/devmapper/driver.go index c4bc5dcff2..e095b33be5 100644 --- a/components/engine/devmapper/driver.go +++ b/components/engine/devmapper/driver.go @@ -65,10 +65,6 @@ func (d *Driver) DiffSize(id string) (int64, error) { return -1, fmt.Errorf("Not implemented") } -func (d *Driver) Changes(id string) ([]archive.Change, error) { - return nil, fmt.Errorf("Not implemented") -} - func (d *Driver) mount(id, mp string) error { // Create the target directories if they don't exist if err := os.MkdirAll(mp, 0755); err != nil && !os.IsExist(err) { diff --git a/components/engine/graphdriver/driver.go b/components/engine/graphdriver/driver.go index 7149e22236..4bb129dfb2 100644 --- a/components/engine/graphdriver/driver.go +++ b/components/engine/graphdriver/driver.go @@ -18,11 +18,14 @@ type Driver interface { Diff(id string) (archive.Archive, error) DiffSize(id string) (bytes int64, err error) - Changes(id string) ([]archive.Change, error) Cleanup() error } +type Changer interface { + Changes(id string) ([]archive.Change, error) +} + var ( // All registred drivers drivers map[string]InitFunc diff --git a/components/engine/graphdriver/dummy/driver.go b/components/engine/graphdriver/dummy/driver.go index 986c89ae24..d62f7de27f 100644 --- a/components/engine/graphdriver/dummy/driver.go +++ b/components/engine/graphdriver/dummy/driver.go @@ -80,7 +80,3 @@ func (d *Driver) Diff(id string) (archive.Archive, error) { func (d *Driver) DiffSize(id string) (int64, error) { return -1, fmt.Errorf("Not implemented") } - -func (d *Driver) Changes(id string) ([]archive.Change, error) { - return nil, fmt.Errorf("Not implemented") -} diff --git a/components/engine/runtime.go b/components/engine/runtime.go index 7bc5084dab..bda59afce5 100644 --- a/components/engine/runtime.go +++ b/components/engine/runtime.go @@ -733,6 +733,9 @@ func (runtime *Runtime) Unmount(container *Container) error { } func (runtime *Runtime) Changes(container *Container) ([]archive.Change, error) { + if changer, ok := runtime.driver.(graphdriver.Changer); ok { + return changer.Changes(container.ID) + } cDir, err := runtime.driver.Get(container.ID) if err != nil { return nil, fmt.Errorf("Error getting container rootfs %s from driver %s: %s", container.ID, container.runtime.driver, err) From 28000adccb31b1442847f721d206075db5c1114c Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Fri, 8 Nov 2013 15:32:50 -0800 Subject: [PATCH 5/5] Allow drivers to export their own diff Upstream-commit: 1eb00e1d5b375cb79d492f1c5cd95d7317bc543c Component: engine --- components/engine/container.go | 6 +----- components/engine/graphdriver/dummy/driver.go | 6 +++++- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/components/engine/container.go b/components/engine/container.go index 6dee2335ff..32359b9cb7 100644 --- a/components/engine/container.go +++ b/components/engine/container.go @@ -1378,11 +1378,7 @@ func (container *Container) ExportRw() (archive.Archive, error) { if container.runtime == nil { return nil, fmt.Errorf("Can't load storage driver for unregistered container %s", container.ID) } - imgDir, err := container.runtime.driver.Get(container.Image) - if err != nil { - return nil, err - } - return archive.ExportChanges(container.RootfsPath(), imgDir) + return container.runtime.driver.Diff(container.ID) } func (container *Container) Export() (archive.Archive, error) { diff --git a/components/engine/graphdriver/dummy/driver.go b/components/engine/graphdriver/dummy/driver.go index d62f7de27f..41a3e62a1f 100644 --- a/components/engine/graphdriver/dummy/driver.go +++ b/components/engine/graphdriver/dummy/driver.go @@ -74,7 +74,11 @@ func (d *Driver) Get(id string) (string, error) { } func (d *Driver) Diff(id string) (archive.Archive, error) { - return nil, fmt.Errorf("Not implemented") + p, err := d.Get(id) + if err != nil { + return nil, err + } + return archive.Tar(p, archive.Uncompressed) } func (d *Driver) DiffSize(id string) (int64, error) {