This moves the Diff() operation to a separate Differ interface and
implements a fallback that uses the Changes() results to encode
a diff tar.
| ... | ... |
@@ -1382,7 +1382,8 @@ func (container *Container) ExportRw() (archive.Archive, error) {
|
| 1382 | 1382 |
if container.runtime == nil {
|
| 1383 | 1383 |
return nil, fmt.Errorf("Can't load storage driver for unregistered container %s", container.ID)
|
| 1384 | 1384 |
} |
| 1385 |
- return container.runtime.driver.Diff(container.ID) |
|
| 1385 |
+ |
|
| 1386 |
+ return container.runtime.Diff(container) |
|
| 1386 | 1387 |
} |
| 1387 | 1388 |
|
| 1388 | 1389 |
func (container *Container) Export() (archive.Archive, error) {
|
| ... | ... |
@@ -2,7 +2,6 @@ package devmapper |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"fmt" |
| 5 |
- "github.com/dotcloud/docker/archive" |
|
| 6 | 5 |
"github.com/dotcloud/docker/graphdriver" |
| 7 | 6 |
"os" |
| 8 | 7 |
"path" |
| ... | ... |
@@ -57,10 +56,6 @@ func (d *Driver) Get(id string) (string, error) {
|
| 57 | 57 |
return mp, nil |
| 58 | 58 |
} |
| 59 | 59 |
|
| 60 |
-func (d *Driver) Diff(id string) (archive.Archive, error) {
|
|
| 61 |
- return nil, fmt.Errorf("Not implemented")
|
|
| 62 |
-} |
|
| 63 |
- |
|
| 64 | 60 |
func (d *Driver) DiffSize(id string) (int64, error) {
|
| 65 | 61 |
return -1, fmt.Errorf("Not implemented")
|
| 66 | 62 |
} |
| ... | ... |
@@ -16,7 +16,6 @@ type Driver interface {
|
| 16 | 16 |
|
| 17 | 17 |
Get(id string) (dir string, err error) |
| 18 | 18 |
|
| 19 |
- Diff(id string) (archive.Archive, error) |
|
| 20 | 19 |
DiffSize(id string) (bytes int64, err error) |
| 21 | 20 |
|
| 22 | 21 |
Cleanup() error |
| ... | ... |
@@ -26,6 +25,10 @@ type Changer interface {
|
| 26 | 26 |
Changes(id string) ([]archive.Change, error) |
| 27 | 27 |
} |
| 28 | 28 |
|
| 29 |
+type Differ interface {
|
|
| 30 |
+ Diff(id string) (archive.Archive, error) |
|
| 31 |
+} |
|
| 32 |
+ |
|
| 29 | 33 |
var ( |
| 30 | 34 |
// All registred drivers |
| 31 | 35 |
drivers map[string]InitFunc |
| ... | ... |
@@ -73,14 +73,6 @@ func (d *Driver) Get(id string) (string, error) {
|
| 73 | 73 |
return dir, nil |
| 74 | 74 |
} |
| 75 | 75 |
|
| 76 |
-func (d *Driver) Diff(id string) (archive.Archive, error) {
|
|
| 77 |
- p, err := d.Get(id) |
|
| 78 |
- if err != nil {
|
|
| 79 |
- return nil, err |
|
| 80 |
- } |
|
| 81 |
- return archive.Tar(p, archive.Uncompressed) |
|
| 82 |
-} |
|
| 83 |
- |
|
| 84 | 76 |
func (d *Driver) DiffSize(id string) (int64, error) {
|
| 85 | 77 |
return -1, fmt.Errorf("Not implemented")
|
| 86 | 78 |
} |
| ... | ... |
@@ -18,6 +18,7 @@ import ( |
| 18 | 18 |
"os" |
| 19 | 19 |
"os/exec" |
| 20 | 20 |
"path" |
| 21 |
+ "path/filepath" |
|
| 21 | 22 |
"sort" |
| 22 | 23 |
"strings" |
| 23 | 24 |
"time" |
| ... | ... |
@@ -747,6 +748,37 @@ func (runtime *Runtime) Changes(container *Container) ([]archive.Change, error) |
| 747 | 747 |
return archive.ChangesDirs(cDir, initDir) |
| 748 | 748 |
} |
| 749 | 749 |
|
| 750 |
+func (runtime *Runtime) Diff(container *Container) (archive.Archive, error) {
|
|
| 751 |
+ if differ, ok := runtime.driver.(graphdriver.Differ); ok {
|
|
| 752 |
+ return differ.Diff(container.ID) |
|
| 753 |
+ } |
|
| 754 |
+ |
|
| 755 |
+ changes, err := runtime.Changes(container) |
|
| 756 |
+ if err != nil {
|
|
| 757 |
+ return nil, err |
|
| 758 |
+ } |
|
| 759 |
+ |
|
| 760 |
+ cDir, err := runtime.driver.Get(container.ID) |
|
| 761 |
+ if err != nil {
|
|
| 762 |
+ return nil, fmt.Errorf("Error getting container rootfs %s from driver %s: %s", container.ID, container.runtime.driver, err)
|
|
| 763 |
+ } |
|
| 764 |
+ |
|
| 765 |
+ files := make([]string, 0) |
|
| 766 |
+ deletions := make([]string, 0) |
|
| 767 |
+ for _, change := range changes {
|
|
| 768 |
+ if change.Kind == archive.ChangeModify || change.Kind == archive.ChangeAdd {
|
|
| 769 |
+ files = append(files, change.Path) |
|
| 770 |
+ } |
|
| 771 |
+ if change.Kind == archive.ChangeDelete {
|
|
| 772 |
+ base := filepath.Base(change.Path) |
|
| 773 |
+ dir := filepath.Dir(change.Path) |
|
| 774 |
+ deletions = append(deletions, filepath.Join(dir, ".wh."+base)) |
|
| 775 |
+ } |
|
| 776 |
+ } |
|
| 777 |
+ |
|
| 778 |
+ return archive.TarFilter(cDir, archive.Uncompressed, files, false, deletions) |
|
| 779 |
+} |
|
| 780 |
+ |
|
| 750 | 781 |
func linkLxcStart(root string) error {
|
| 751 | 782 |
sourcePath, err := exec.LookPath("lxc-start")
|
| 752 | 783 |
if err != nil {
|