This allows a graph driver to provide a custom FileGetter for tar-split
to use. Windows will use this to provide a more efficient implementation
in a follow-up change.
Signed-off-by: John Starks <jostarks@microsoft.com>
| ... | ... |
@@ -34,6 +34,7 @@ import ( |
| 34 | 34 |
"syscall" |
| 35 | 35 |
|
| 36 | 36 |
"github.com/Sirupsen/logrus" |
| 37 |
+ "github.com/vbatts/tar-split/tar/storage" |
|
| 37 | 38 |
|
| 38 | 39 |
"github.com/docker/docker/daemon/graphdriver" |
| 39 | 40 |
"github.com/docker/docker/pkg/archive" |
| ... | ... |
@@ -367,10 +368,19 @@ func (a *Driver) Diff(id, parent string) (archive.Archive, error) {
|
| 367 | 367 |
}) |
| 368 | 368 |
} |
| 369 | 369 |
|
| 370 |
-// DiffPath returns path to the directory that contains files for the layer |
|
| 371 |
-// differences. Used for direct access for tar-split. |
|
| 372 |
-func (a *Driver) DiffPath(id string) (string, func() error, error) {
|
|
| 373 |
- return path.Join(a.rootPath(), "diff", id), func() error { return nil }, nil
|
|
| 370 |
+type fileGetNilCloser struct {
|
|
| 371 |
+ storage.FileGetter |
|
| 372 |
+} |
|
| 373 |
+ |
|
| 374 |
+func (f fileGetNilCloser) Close() error {
|
|
| 375 |
+ return nil |
|
| 376 |
+} |
|
| 377 |
+ |
|
| 378 |
+// DiffGetter returns a FileGetCloser that can read files from the directory that |
|
| 379 |
+// contains files for the layer differences. Used for direct access for tar-split. |
|
| 380 |
+func (a *Driver) DiffGetter(id string) (graphdriver.FileGetCloser, error) {
|
|
| 381 |
+ p := path.Join(a.rootPath(), "diff", id) |
|
| 382 |
+ return fileGetNilCloser{storage.NewPathFileGetter(p)}, nil
|
|
| 374 | 383 |
} |
| 375 | 384 |
|
| 376 | 385 |
func (a *Driver) applyDiff(id string, diff archive.Reader) error {
|
| ... | ... |
@@ -8,6 +8,7 @@ import ( |
| 8 | 8 |
"strings" |
| 9 | 9 |
|
| 10 | 10 |
"github.com/Sirupsen/logrus" |
| 11 |
+ "github.com/vbatts/tar-split/tar/storage" |
|
| 11 | 12 |
|
| 12 | 13 |
"github.com/docker/docker/pkg/archive" |
| 13 | 14 |
"github.com/docker/docker/pkg/idtools" |
| ... | ... |
@@ -92,6 +93,23 @@ type Driver interface {
|
| 92 | 92 |
DiffSize(id, parent string) (size int64, err error) |
| 93 | 93 |
} |
| 94 | 94 |
|
| 95 |
+// DiffGetterDriver is the interface for layered file system drivers that |
|
| 96 |
+// provide a specialized function for getting file contents for tar-split. |
|
| 97 |
+type DiffGetterDriver interface {
|
|
| 98 |
+ Driver |
|
| 99 |
+ // DiffGetter returns an interface to efficiently retrieve the contents |
|
| 100 |
+ // of files in a layer. |
|
| 101 |
+ DiffGetter(id string) (FileGetCloser, error) |
|
| 102 |
+} |
|
| 103 |
+ |
|
| 104 |
+// FileGetCloser extends the storage.FileGetter interface with a Close method |
|
| 105 |
+// for cleaning up. |
|
| 106 |
+type FileGetCloser interface {
|
|
| 107 |
+ storage.FileGetter |
|
| 108 |
+ // Close cleans up any resources associated with the FileGetCloser. |
|
| 109 |
+ Close() error |
|
| 110 |
+} |
|
| 111 |
+ |
|
| 95 | 112 |
func init() {
|
| 96 | 113 |
drivers = make(map[string]InitFunc) |
| 97 | 114 |
} |
| ... | ... |
@@ -22,6 +22,7 @@ import ( |
| 22 | 22 |
"github.com/docker/docker/pkg/idtools" |
| 23 | 23 |
"github.com/docker/docker/pkg/ioutils" |
| 24 | 24 |
"github.com/docker/docker/pkg/random" |
| 25 |
+ "github.com/vbatts/tar-split/tar/storage" |
|
| 25 | 26 |
) |
| 26 | 27 |
|
| 27 | 28 |
// init registers the windows graph drivers to the register. |
| ... | ... |
@@ -47,6 +48,8 @@ type Driver struct {
|
| 47 | 47 |
active map[string]int |
| 48 | 48 |
} |
| 49 | 49 |
|
| 50 |
+var _ graphdriver.DiffGetterDriver = &Driver{}
|
|
| 51 |
+ |
|
| 50 | 52 |
// InitFilter returns a new Windows storage filter driver. |
| 51 | 53 |
func InitFilter(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
|
| 52 | 54 |
logrus.Debugf("WindowsGraphDriver InitFilter at %s", home)
|
| ... | ... |
@@ -564,8 +567,20 @@ func (d *Driver) setLayerChain(id string, chain []string) error {
|
| 564 | 564 |
return nil |
| 565 | 565 |
} |
| 566 | 566 |
|
| 567 |
-// DiffPath returns a directory that contains files needed to construct layer diff. |
|
| 568 |
-func (d *Driver) DiffPath(id string) (path string, release func() error, err error) {
|
|
| 567 |
+type fileGetDestroyCloser struct {
|
|
| 568 |
+ storage.FileGetter |
|
| 569 |
+ d *Driver |
|
| 570 |
+ folderName string |
|
| 571 |
+} |
|
| 572 |
+ |
|
| 573 |
+func (f *fileGetDestroyCloser) Close() error {
|
|
| 574 |
+ // TODO: activate layers and release here? |
|
| 575 |
+ return hcsshim.DestroyLayer(f.d.info, f.folderName) |
|
| 576 |
+} |
|
| 577 |
+ |
|
| 578 |
+// DiffGetter returns a FileGetCloser that can read files from the directory that |
|
| 579 |
+// contains files for the layer differences. Used for direct access for tar-split. |
|
| 580 |
+func (d *Driver) DiffGetter(id string) (fg graphdriver.FileGetCloser, err error) {
|
|
| 569 | 581 |
id, err = d.resolveID(id) |
| 570 | 582 |
if err != nil {
|
| 571 | 583 |
return |
| ... | ... |
@@ -597,9 +612,6 @@ func (d *Driver) DiffPath(id string) (path string, release func() error, err err |
| 597 | 597 |
return |
| 598 | 598 |
} |
| 599 | 599 |
|
| 600 |
- return tempFolder, func() error {
|
|
| 601 |
- // TODO: activate layers and release here? |
|
| 602 |
- _, folderName := filepath.Split(tempFolder) |
|
| 603 |
- return hcsshim.DestroyLayer(d.info, folderName) |
|
| 604 |
- }, nil |
|
| 600 |
+ _, folderName := filepath.Split(tempFolder) |
|
| 601 |
+ return &fileGetDestroyCloser{storage.NewPathFileGetter(tempFolder), d, folderName}, nil
|
|
| 605 | 602 |
} |
| ... | ... |
@@ -577,11 +577,7 @@ func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc Mou |
| 577 | 577 |
} |
| 578 | 578 |
|
| 579 | 579 |
func (ls *layerStore) assembleTarTo(graphID string, metadata io.ReadCloser, size *int64, w io.Writer) error {
|
| 580 |
- type diffPathDriver interface {
|
|
| 581 |
- DiffPath(string) (string, func() error, error) |
|
| 582 |
- } |
|
| 583 |
- |
|
| 584 |
- diffDriver, ok := ls.driver.(diffPathDriver) |
|
| 580 |
+ diffDriver, ok := ls.driver.(graphdriver.DiffGetterDriver) |
|
| 585 | 581 |
if !ok {
|
| 586 | 582 |
diffDriver = &naiveDiffPathDriver{ls.driver}
|
| 587 | 583 |
} |
| ... | ... |
@@ -589,17 +585,16 @@ func (ls *layerStore) assembleTarTo(graphID string, metadata io.ReadCloser, size |
| 589 | 589 |
defer metadata.Close() |
| 590 | 590 |
|
| 591 | 591 |
// get our relative path to the container |
| 592 |
- fsPath, releasePath, err := diffDriver.DiffPath(graphID) |
|
| 592 |
+ fileGetCloser, err := diffDriver.DiffGetter(graphID) |
|
| 593 | 593 |
if err != nil {
|
| 594 | 594 |
return err |
| 595 | 595 |
} |
| 596 |
- defer releasePath() |
|
| 596 |
+ defer fileGetCloser.Close() |
|
| 597 | 597 |
|
| 598 | 598 |
metaUnpacker := storage.NewJSONUnpacker(metadata) |
| 599 | 599 |
upackerCounter := &unpackSizeCounter{metaUnpacker, size}
|
| 600 |
- fileGetter := storage.NewPathFileGetter(fsPath) |
|
| 601 |
- logrus.Debugf("Assembling tar data for %s from %s", graphID, fsPath)
|
|
| 602 |
- return asm.WriteOutputTarStream(fileGetter, upackerCounter, w) |
|
| 600 |
+ logrus.Debugf("Assembling tar data for %s", graphID)
|
|
| 601 |
+ return asm.WriteOutputTarStream(fileGetCloser, upackerCounter, w) |
|
| 603 | 602 |
} |
| 604 | 603 |
|
| 605 | 604 |
func (ls *layerStore) Cleanup() error {
|
| ... | ... |
@@ -618,12 +613,20 @@ type naiveDiffPathDriver struct {
|
| 618 | 618 |
graphdriver.Driver |
| 619 | 619 |
} |
| 620 | 620 |
|
| 621 |
-func (n *naiveDiffPathDriver) DiffPath(id string) (string, func() error, error) {
|
|
| 621 |
+type fileGetPutter struct {
|
|
| 622 |
+ storage.FileGetter |
|
| 623 |
+ driver graphdriver.Driver |
|
| 624 |
+ id string |
|
| 625 |
+} |
|
| 626 |
+ |
|
| 627 |
+func (w *fileGetPutter) Close() error {
|
|
| 628 |
+ return w.driver.Put(w.id) |
|
| 629 |
+} |
|
| 630 |
+ |
|
| 631 |
+func (n *naiveDiffPathDriver) DiffGetter(id string) (graphdriver.FileGetCloser, error) {
|
|
| 622 | 632 |
p, err := n.Driver.Get(id, "") |
| 623 | 633 |
if err != nil {
|
| 624 |
- return "", nil, err |
|
| 634 |
+ return nil, err |
|
| 625 | 635 |
} |
| 626 |
- return p, func() error {
|
|
| 627 |
- return n.Driver.Put(id) |
|
| 628 |
- }, nil |
|
| 636 |
+ return &fileGetPutter{storage.NewPathFileGetter(p), n.Driver, id}, nil
|
|
| 629 | 637 |
} |