mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
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/chrootarchive"
|
||||||
"github.com/docker/docker/pkg/idtools"
|
"github.com/docker/docker/pkg/idtools"
|
||||||
"github.com/docker/docker/pkg/ioutils"
|
"github.com/docker/docker/pkg/ioutils"
|
||||||
|
"github.com/docker/docker/pkg/longpath"
|
||||||
"github.com/vbatts/tar-split/tar/storage"
|
"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)
|
name = filepath.ToSlash(name)
|
||||||
if fileInfo == nil {
|
if fileInfo == nil {
|
||||||
changes = append(changes, archive.Change{name, archive.ChangeDelete})
|
changes = append(changes, archive.Change{Path: name, Kind: archive.ChangeDelete})
|
||||||
} else {
|
} else {
|
||||||
// Currently there is no way to tell between an add and a modify.
|
// 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
|
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
|
// layer with the specified id and parent, returning the size of the
|
||||||
// new layer in bytes.
|
// new layer in bytes.
|
||||||
// The layer should not be mounted when calling this function
|
// The layer should not be mounted when calling this function
|
||||||
func (d *Driver) ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error) {
|
func (d *Driver) ApplyDiff(id, parent string, diff archive.Reader) (int64, error) {
|
||||||
rPId, err := d.resolveID(parent)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.info.Flavour == diffDriver {
|
if d.info.Flavour == diffDriver {
|
||||||
start := time.Now().UTC()
|
start := time.Now().UTC()
|
||||||
logrus.Debugf("WindowsGraphDriver ApplyDiff: Start untar layer")
|
logrus.Debugf("WindowsGraphDriver ApplyDiff: Start untar layer")
|
||||||
destination := d.dir(id)
|
destination := d.dir(id)
|
||||||
destination = filepath.Dir(destination)
|
destination = filepath.Dir(destination)
|
||||||
if size, err = chrootarchive.ApplyUncompressedLayer(destination, diff, nil); err != nil {
|
size, err := chrootarchive.ApplyUncompressedLayer(destination, diff, nil)
|
||||||
return
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
logrus.Debugf("WindowsGraphDriver ApplyDiff: Untar time: %vs", time.Now().UTC().Sub(start).Seconds())
|
logrus.Debugf("WindowsGraphDriver ApplyDiff: Untar time: %vs", time.Now().UTC().Sub(start).Seconds())
|
||||||
|
|
||||||
return
|
return size, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
parentChain, err := d.getLayerChain(rPId)
|
var layerChain []string
|
||||||
if err != nil {
|
if parent != "" {
|
||||||
return
|
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 {
|
size, err := d.importLayer(id, diff, layerChain)
|
||||||
return
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = d.setLayerChain(id, layerChain); err != nil {
|
if err = d.setLayerChain(id, layerChain); err != nil {
|
||||||
return
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return size, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DiffSize calculates the changes between the specified layer
|
// 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
|
return 0, err
|
||||||
}
|
}
|
||||||
hdr, err = t.Next()
|
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 {
|
} else {
|
||||||
var (
|
var (
|
||||||
name string
|
name string
|
||||||
|
@ -575,7 +586,6 @@ func (d *Driver) importLayer(id string, layerData archive.Reader, parentLayerPat
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
size, err = writeLayerFromTar(layerData, w)
|
size, err = writeLayerFromTar(layerData, w)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
w.Close()
|
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
|
// file can be opened even if the caller does not actually have access to it according
|
||||||
// to the security descriptor.
|
// to the security descriptor.
|
||||||
err := winio.RunWithPrivilege(winio.SeBackupPrivilege, func() error {
|
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)
|
p, err := syscall.UTF16FromString(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Add table
Reference in a new issue