Преглед изворни кода

Implement fallback operation for driver.Diff()

This moves the Diff() operation to a separate Differ interface and
implements a fallback that uses the Changes() results to encode
a diff tar.
Alexander Larsson пре 11 година
родитељ
комит
e82f8c1661
5 измењених фајлова са 38 додато и 15 уклоњено
  1. 2 1
      container.go
  2. 0 5
      devmapper/driver.go
  3. 4 1
      graphdriver/driver.go
  4. 0 8
      graphdriver/dummy/driver.go
  5. 32 0
      runtime.go

+ 2 - 1
container.go

@@ -1382,7 +1382,8 @@ 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)
 	}
-	return container.runtime.driver.Diff(container.ID)
+
+	return container.runtime.Diff(container)
 }
 
 func (container *Container) Export() (archive.Archive, error) {

+ 0 - 5
devmapper/driver.go

@@ -2,7 +2,6 @@ package devmapper
 
 import (
 	"fmt"
-	"github.com/dotcloud/docker/archive"
 	"github.com/dotcloud/docker/graphdriver"
 	"os"
 	"path"
@@ -57,10 +56,6 @@ func (d *Driver) Get(id string) (string, error) {
 	return mp, nil
 }
 
-func (d *Driver) Diff(id string) (archive.Archive, error) {
-	return nil, fmt.Errorf("Not implemented")
-}
-
 func (d *Driver) DiffSize(id string) (int64, error) {
 	return -1, fmt.Errorf("Not implemented")
 }

+ 4 - 1
graphdriver/driver.go

@@ -16,7 +16,6 @@ type Driver interface {
 
 	Get(id string) (dir string, err error)
 
-	Diff(id string) (archive.Archive, error)
 	DiffSize(id string) (bytes int64, err error)
 
 	Cleanup() error
@@ -26,6 +25,10 @@ type Changer interface {
 	Changes(id string) ([]archive.Change, error)
 }
 
+type Differ interface {
+	Diff(id string) (archive.Archive, error)
+}
+
 var (
 	// All registred drivers
 	drivers map[string]InitFunc

+ 0 - 8
graphdriver/dummy/driver.go

@@ -73,14 +73,6 @@ func (d *Driver) Get(id string) (string, error) {
 	return dir, nil
 }
 
-func (d *Driver) Diff(id string) (archive.Archive, error) {
-	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) {
 	return -1, fmt.Errorf("Not implemented")
 }

+ 32 - 0
runtime.go

@@ -18,6 +18,7 @@ import (
 	"os"
 	"os/exec"
 	"path"
+	"path/filepath"
 	"sort"
 	"strings"
 	"time"
@@ -747,6 +748,37 @@ func (runtime *Runtime) Changes(container *Container) ([]archive.Change, error)
 	return archive.ChangesDirs(cDir, initDir)
 }
 
+func (runtime *Runtime) Diff(container *Container) (archive.Archive, error) {
+	if differ, ok := runtime.driver.(graphdriver.Differ); ok {
+		return differ.Diff(container.ID)
+	}
+
+	changes, err := runtime.Changes(container)
+	if err != nil {
+		return nil, err
+	}
+
+	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)
+	}
+
+	files := make([]string, 0)
+	deletions := make([]string, 0)
+	for _, change := range changes {
+		if change.Kind == archive.ChangeModify || change.Kind == archive.ChangeAdd {
+			files = append(files, change.Path)
+		}
+		if change.Kind == archive.ChangeDelete {
+			base := filepath.Base(change.Path)
+			dir := filepath.Dir(change.Path)
+			deletions = append(deletions, filepath.Join(dir, ".wh."+base))
+		}
+	}
+
+	return archive.TarFilter(cDir, archive.Uncompressed, files, false, deletions)
+}
+
 func linkLxcStart(root string) error {
 	sourcePath, err := exec.LookPath("lxc-start")
 	if err != nil {