mirror of
				https://github.com/moby/moby.git
				synced 2022-11-09 12:21:53 -05:00 
			
		
		
		
	graphdriver: Replace DiffPath with DiffGetter
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>
This commit is contained in:
		
							parent
							
								
									2d0c3d1328
								
							
						
					
					
						commit
						58bec40d16
					
				
					 4 changed files with 69 additions and 26 deletions
				
			
		| 
						 | 
				
			
			@ -34,6 +34,7 @@ import (
 | 
			
		|||
	"syscall"
 | 
			
		||||
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
	"github.com/vbatts/tar-split/tar/storage"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/daemon/graphdriver"
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
| 
						 | 
				
			
			@ -367,10 +368,19 @@ func (a *Driver) Diff(id, parent string) (archive.Archive, error) {
 | 
			
		|||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DiffPath returns path to the directory that contains files for the layer
 | 
			
		||||
// differences. Used for direct access for tar-split.
 | 
			
		||||
func (a *Driver) DiffPath(id string) (string, func() error, error) {
 | 
			
		||||
	return path.Join(a.rootPath(), "diff", id), func() error { return nil }, nil
 | 
			
		||||
type fileGetNilCloser struct {
 | 
			
		||||
	storage.FileGetter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f fileGetNilCloser) Close() error {
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DiffGetter returns a FileGetCloser that can read files from the directory that
 | 
			
		||||
// contains files for the layer differences. Used for direct access for tar-split.
 | 
			
		||||
func (a *Driver) DiffGetter(id string) (graphdriver.FileGetCloser, error) {
 | 
			
		||||
	p := path.Join(a.rootPath(), "diff", id)
 | 
			
		||||
	return fileGetNilCloser{storage.NewPathFileGetter(p)}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (a *Driver) applyDiff(id string, diff archive.Reader) error {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import (
 | 
			
		|||
	"strings"
 | 
			
		||||
 | 
			
		||||
	"github.com/Sirupsen/logrus"
 | 
			
		||||
	"github.com/vbatts/tar-split/tar/storage"
 | 
			
		||||
 | 
			
		||||
	"github.com/docker/docker/pkg/archive"
 | 
			
		||||
	"github.com/docker/docker/pkg/idtools"
 | 
			
		||||
| 
						 | 
				
			
			@ -92,6 +93,23 @@ type Driver interface {
 | 
			
		|||
	DiffSize(id, parent string) (size int64, err error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DiffGetterDriver is the interface for layered file system drivers that
 | 
			
		||||
// provide a specialized function for getting file contents for tar-split.
 | 
			
		||||
type DiffGetterDriver interface {
 | 
			
		||||
	Driver
 | 
			
		||||
	// DiffGetter returns an interface to efficiently retrieve the contents
 | 
			
		||||
	// of files in a layer.
 | 
			
		||||
	DiffGetter(id string) (FileGetCloser, error)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FileGetCloser extends the storage.FileGetter interface with a Close method
 | 
			
		||||
// for cleaning up.
 | 
			
		||||
type FileGetCloser interface {
 | 
			
		||||
	storage.FileGetter
 | 
			
		||||
	// Close cleans up any resources associated with the FileGetCloser.
 | 
			
		||||
	Close() error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	drivers = make(map[string]InitFunc)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,6 +22,7 @@ import (
 | 
			
		|||
	"github.com/docker/docker/pkg/idtools"
 | 
			
		||||
	"github.com/docker/docker/pkg/ioutils"
 | 
			
		||||
	"github.com/docker/docker/pkg/random"
 | 
			
		||||
	"github.com/vbatts/tar-split/tar/storage"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// init registers the windows graph drivers to the register.
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +48,8 @@ type Driver struct {
 | 
			
		|||
	active map[string]int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ graphdriver.DiffGetterDriver = &Driver{}
 | 
			
		||||
 | 
			
		||||
// InitFilter returns a new Windows storage filter driver.
 | 
			
		||||
func InitFilter(home string, options []string, uidMaps, gidMaps []idtools.IDMap) (graphdriver.Driver, error) {
 | 
			
		||||
	logrus.Debugf("WindowsGraphDriver InitFilter at %s", home)
 | 
			
		||||
| 
						 | 
				
			
			@ -564,8 +567,20 @@ func (d *Driver) setLayerChain(id string, chain []string) error {
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DiffPath returns a directory that contains files needed to construct layer diff.
 | 
			
		||||
func (d *Driver) DiffPath(id string) (path string, release func() error, err error) {
 | 
			
		||||
type fileGetDestroyCloser struct {
 | 
			
		||||
	storage.FileGetter
 | 
			
		||||
	d          *Driver
 | 
			
		||||
	folderName string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (f *fileGetDestroyCloser) Close() error {
 | 
			
		||||
	// TODO: activate layers and release here?
 | 
			
		||||
	return hcsshim.DestroyLayer(f.d.info, f.folderName)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// DiffGetter returns a FileGetCloser that can read files from the directory that
 | 
			
		||||
// contains files for the layer differences. Used for direct access for tar-split.
 | 
			
		||||
func (d *Driver) DiffGetter(id string) (fg graphdriver.FileGetCloser, err error) {
 | 
			
		||||
	id, err = d.resolveID(id)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return
 | 
			
		||||
| 
						 | 
				
			
			@ -597,9 +612,6 @@ func (d *Driver) DiffPath(id string) (path string, release func() error, err err
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return tempFolder, func() error {
 | 
			
		||||
		// TODO: activate layers and release here?
 | 
			
		||||
		_, folderName := filepath.Split(tempFolder)
 | 
			
		||||
		return hcsshim.DestroyLayer(d.info, folderName)
 | 
			
		||||
	}, nil
 | 
			
		||||
	_, folderName := filepath.Split(tempFolder)
 | 
			
		||||
	return &fileGetDestroyCloser{storage.NewPathFileGetter(tempFolder), d, folderName}, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -577,11 +577,7 @@ func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc Mou
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
func (ls *layerStore) assembleTarTo(graphID string, metadata io.ReadCloser, size *int64, w io.Writer) error {
 | 
			
		||||
	type diffPathDriver interface {
 | 
			
		||||
		DiffPath(string) (string, func() error, error)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	diffDriver, ok := ls.driver.(diffPathDriver)
 | 
			
		||||
	diffDriver, ok := ls.driver.(graphdriver.DiffGetterDriver)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		diffDriver = &naiveDiffPathDriver{ls.driver}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -589,17 +585,16 @@ func (ls *layerStore) assembleTarTo(graphID string, metadata io.ReadCloser, size
 | 
			
		|||
	defer metadata.Close()
 | 
			
		||||
 | 
			
		||||
	// get our relative path to the container
 | 
			
		||||
	fsPath, releasePath, err := diffDriver.DiffPath(graphID)
 | 
			
		||||
	fileGetCloser, err := diffDriver.DiffGetter(graphID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	defer releasePath()
 | 
			
		||||
	defer fileGetCloser.Close()
 | 
			
		||||
 | 
			
		||||
	metaUnpacker := storage.NewJSONUnpacker(metadata)
 | 
			
		||||
	upackerCounter := &unpackSizeCounter{metaUnpacker, size}
 | 
			
		||||
	fileGetter := storage.NewPathFileGetter(fsPath)
 | 
			
		||||
	logrus.Debugf("Assembling tar data for %s from %s", graphID, fsPath)
 | 
			
		||||
	return asm.WriteOutputTarStream(fileGetter, upackerCounter, w)
 | 
			
		||||
	logrus.Debugf("Assembling tar data for %s", graphID)
 | 
			
		||||
	return asm.WriteOutputTarStream(fileGetCloser, upackerCounter, w)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (ls *layerStore) Cleanup() error {
 | 
			
		||||
| 
						 | 
				
			
			@ -618,12 +613,20 @@ type naiveDiffPathDriver struct {
 | 
			
		|||
	graphdriver.Driver
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *naiveDiffPathDriver) DiffPath(id string) (string, func() error, error) {
 | 
			
		||||
type fileGetPutter struct {
 | 
			
		||||
	storage.FileGetter
 | 
			
		||||
	driver graphdriver.Driver
 | 
			
		||||
	id     string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (w *fileGetPutter) Close() error {
 | 
			
		||||
	return w.driver.Put(w.id)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (n *naiveDiffPathDriver) DiffGetter(id string) (graphdriver.FileGetCloser, error) {
 | 
			
		||||
	p, err := n.Driver.Get(id, "")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", nil, err
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return p, func() error {
 | 
			
		||||
		return n.Driver.Put(id)
 | 
			
		||||
	}, nil
 | 
			
		||||
	return &fileGetPutter{storage.NewPathFileGetter(p), n.Driver, id}, nil
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue