Windows: Support ApplyDiff on a base layer
This adds support to the Windows graph driver for ApplyDiff on a base layer. It also adds support for hard links, which are needed because the Windows base layers double in size without hard link support. Signed-off-by: John Starks <jostarks@microsoft.com>
This commit is contained in:
parent
9b486999f2
commit
cf7944bf6f
1 changed files with 36 additions and 26 deletions
|
@ -26,6 +26,7 @@ import (
|
|||
"github.com/docker/docker/pkg/chrootarchive"
|
||||
"github.com/docker/docker/pkg/idtools"
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
"github.com/docker/docker/pkg/longpath"
|
||||
"github.com/vbatts/tar-split/tar/storage"
|
||||
)
|
||||
|
||||
|
@ -319,10 +320,10 @@ func (d *Driver) Changes(id, parent string) ([]archive.Change, error) {
|
|||
}
|
||||
name = filepath.ToSlash(name)
|
||||
if fileInfo == nil {
|
||||
changes = append(changes, archive.Change{name, archive.ChangeDelete})
|
||||
changes = append(changes, archive.Change{Path: name, Kind: archive.ChangeDelete})
|
||||
} else {
|
||||
// Currently there is no way to tell between an add and a modify.
|
||||
changes = append(changes, archive.Change{name, archive.ChangeModify})
|
||||
changes = append(changes, archive.Change{Path: name, Kind: archive.ChangeModify})
|
||||
}
|
||||
}
|
||||
return changes, nil
|
||||
|
@ -332,45 +333,49 @@ func (d *Driver) Changes(id, parent string) ([]archive.Change, error) {
|
|||
// layer with the specified id and parent, returning the size of the
|
||||
// new layer in bytes.
|
||||
// The layer should not be mounted when calling this function
|
||||
func (d *Driver) ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error) {
|
||||
rPId, err := d.resolveID(parent)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
func (d *Driver) ApplyDiff(id, parent string, diff archive.Reader) (int64, error) {
|
||||
if d.info.Flavour == diffDriver {
|
||||
start := time.Now().UTC()
|
||||
logrus.Debugf("WindowsGraphDriver ApplyDiff: Start untar layer")
|
||||
destination := d.dir(id)
|
||||
destination = filepath.Dir(destination)
|
||||
if size, err = chrootarchive.ApplyUncompressedLayer(destination, diff, nil); err != nil {
|
||||
return
|
||||
size, err := chrootarchive.ApplyUncompressedLayer(destination, diff, nil)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
logrus.Debugf("WindowsGraphDriver ApplyDiff: Untar time: %vs", time.Now().UTC().Sub(start).Seconds())
|
||||
|
||||
return
|
||||
return size, nil
|
||||
}
|
||||
|
||||
parentChain, err := d.getLayerChain(rPId)
|
||||
if err != nil {
|
||||
return
|
||||
var layerChain []string
|
||||
if parent != "" {
|
||||
rPId, err := d.resolveID(parent)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
parentChain, err := d.getLayerChain(rPId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
parentPath, err := hcsshim.GetLayerMountPath(d.info, rPId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
layerChain = append(layerChain, parentPath)
|
||||
layerChain = append(layerChain, parentChain...)
|
||||
}
|
||||
parentPath, err := hcsshim.GetLayerMountPath(d.info, rPId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
layerChain := []string{parentPath}
|
||||
layerChain = append(layerChain, parentChain...)
|
||||
|
||||
if size, err = d.importLayer(id, diff, layerChain); err != nil {
|
||||
return
|
||||
size, err := d.importLayer(id, diff, layerChain)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if err = d.setLayerChain(id, layerChain); err != nil {
|
||||
return
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return
|
||||
return size, nil
|
||||
}
|
||||
|
||||
// DiffSize calculates the changes between the specified layer
|
||||
|
@ -539,6 +544,12 @@ func writeLayerFromTar(r archive.Reader, w hcsshim.LayerWriter) (int64, error) {
|
|||
return 0, err
|
||||
}
|
||||
hdr, err = t.Next()
|
||||
} else if hdr.Typeflag == tar.TypeLink {
|
||||
err = w.AddLink(filepath.FromSlash(hdr.Name), filepath.FromSlash(hdr.Linkname))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
hdr, err = t.Next()
|
||||
} else {
|
||||
var (
|
||||
name string
|
||||
|
@ -575,7 +586,6 @@ func (d *Driver) importLayer(id string, layerData archive.Reader, parentLayerPat
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
size, err = writeLayerFromTar(layerData, w)
|
||||
if err != nil {
|
||||
w.Close()
|
||||
|
@ -653,7 +663,7 @@ func (fg *fileGetCloserWithBackupPrivileges) Get(filename string) (io.ReadCloser
|
|||
// file can be opened even if the caller does not actually have access to it according
|
||||
// to the security descriptor.
|
||||
err := winio.RunWithPrivilege(winio.SeBackupPrivilege, func() error {
|
||||
path := filepath.Join(fg.path, filename)
|
||||
path := longpath.AddPrefix(filepath.Join(fg.path, filename))
|
||||
p, err := syscall.UTF16FromString(path)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Reference in a new issue