Skip to content

Commit

Permalink
graphdriver: Replace DiffPath with DiffGetter
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
jstarks committed Mar 1, 2016
1 parent 2d0c3d1 commit 58bec40
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 26 deletions.
18 changes: 14 additions & 4 deletions daemon/graphdriver/aufs/aufs.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
Expand Down
18 changes: 18 additions & 0 deletions daemon/graphdriver/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
}
Expand Down
26 changes: 19 additions & 7 deletions daemon/graphdriver/windows/windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
}
33 changes: 18 additions & 15 deletions layer/layer_store.go
Original file line number Diff line number Diff line change
Expand Up @@ -577,29 +577,24 @@ 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}
}

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 {
Expand All @@ -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
}

0 comments on commit 58bec40

Please sign in to comment.