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>
| ... | ... |
@@ -26,6 +26,7 @@ import ( |
| 26 | 26 |
"github.com/docker/docker/pkg/chrootarchive" |
| 27 | 27 |
"github.com/docker/docker/pkg/idtools" |
| 28 | 28 |
"github.com/docker/docker/pkg/ioutils" |
| 29 |
+ "github.com/docker/docker/pkg/longpath" |
|
| 29 | 30 |
"github.com/vbatts/tar-split/tar/storage" |
| 30 | 31 |
) |
| 31 | 32 |
|
| ... | ... |
@@ -319,10 +320,10 @@ func (d *Driver) Changes(id, parent string) ([]archive.Change, error) {
|
| 319 | 319 |
} |
| 320 | 320 |
name = filepath.ToSlash(name) |
| 321 | 321 |
if fileInfo == nil {
|
| 322 |
- changes = append(changes, archive.Change{name, archive.ChangeDelete})
|
|
| 322 |
+ changes = append(changes, archive.Change{Path: name, Kind: archive.ChangeDelete})
|
|
| 323 | 323 |
} else {
|
| 324 | 324 |
// Currently there is no way to tell between an add and a modify. |
| 325 |
- changes = append(changes, archive.Change{name, archive.ChangeModify})
|
|
| 325 |
+ changes = append(changes, archive.Change{Path: name, Kind: archive.ChangeModify})
|
|
| 326 | 326 |
} |
| 327 | 327 |
} |
| 328 | 328 |
return changes, nil |
| ... | ... |
@@ -332,45 +333,49 @@ func (d *Driver) Changes(id, parent string) ([]archive.Change, error) {
|
| 332 | 332 |
// layer with the specified id and parent, returning the size of the |
| 333 | 333 |
// new layer in bytes. |
| 334 | 334 |
// The layer should not be mounted when calling this function |
| 335 |
-func (d *Driver) ApplyDiff(id, parent string, diff archive.Reader) (size int64, err error) {
|
|
| 336 |
- rPId, err := d.resolveID(parent) |
|
| 337 |
- if err != nil {
|
|
| 338 |
- return |
|
| 339 |
- } |
|
| 340 |
- |
|
| 335 |
+func (d *Driver) ApplyDiff(id, parent string, diff archive.Reader) (int64, error) {
|
|
| 341 | 336 |
if d.info.Flavour == diffDriver {
|
| 342 | 337 |
start := time.Now().UTC() |
| 343 | 338 |
logrus.Debugf("WindowsGraphDriver ApplyDiff: Start untar layer")
|
| 344 | 339 |
destination := d.dir(id) |
| 345 | 340 |
destination = filepath.Dir(destination) |
| 346 |
- if size, err = chrootarchive.ApplyUncompressedLayer(destination, diff, nil); err != nil {
|
|
| 347 |
- return |
|
| 341 |
+ size, err := chrootarchive.ApplyUncompressedLayer(destination, diff, nil) |
|
| 342 |
+ if err != nil {
|
|
| 343 |
+ return 0, err |
|
| 348 | 344 |
} |
| 349 | 345 |
logrus.Debugf("WindowsGraphDriver ApplyDiff: Untar time: %vs", time.Now().UTC().Sub(start).Seconds())
|
| 350 | 346 |
|
| 351 |
- return |
|
| 347 |
+ return size, nil |
|
| 352 | 348 |
} |
| 353 | 349 |
|
| 354 |
- parentChain, err := d.getLayerChain(rPId) |
|
| 355 |
- if err != nil {
|
|
| 356 |
- return |
|
| 357 |
- } |
|
| 358 |
- parentPath, err := hcsshim.GetLayerMountPath(d.info, rPId) |
|
| 359 |
- if err != nil {
|
|
| 360 |
- return |
|
| 350 |
+ var layerChain []string |
|
| 351 |
+ if parent != "" {
|
|
| 352 |
+ rPId, err := d.resolveID(parent) |
|
| 353 |
+ if err != nil {
|
|
| 354 |
+ return 0, err |
|
| 355 |
+ } |
|
| 356 |
+ parentChain, err := d.getLayerChain(rPId) |
|
| 357 |
+ if err != nil {
|
|
| 358 |
+ return 0, err |
|
| 359 |
+ } |
|
| 360 |
+ parentPath, err := hcsshim.GetLayerMountPath(d.info, rPId) |
|
| 361 |
+ if err != nil {
|
|
| 362 |
+ return 0, err |
|
| 363 |
+ } |
|
| 364 |
+ layerChain = append(layerChain, parentPath) |
|
| 365 |
+ layerChain = append(layerChain, parentChain...) |
|
| 361 | 366 |
} |
| 362 |
- layerChain := []string{parentPath}
|
|
| 363 |
- layerChain = append(layerChain, parentChain...) |
|
| 364 | 367 |
|
| 365 |
- if size, err = d.importLayer(id, diff, layerChain); err != nil {
|
|
| 366 |
- return |
|
| 368 |
+ size, err := d.importLayer(id, diff, layerChain) |
|
| 369 |
+ if err != nil {
|
|
| 370 |
+ return 0, err |
|
| 367 | 371 |
} |
| 368 | 372 |
|
| 369 | 373 |
if err = d.setLayerChain(id, layerChain); err != nil {
|
| 370 |
- return |
|
| 374 |
+ return 0, err |
|
| 371 | 375 |
} |
| 372 | 376 |
|
| 373 |
- return |
|
| 377 |
+ return size, nil |
|
| 374 | 378 |
} |
| 375 | 379 |
|
| 376 | 380 |
// DiffSize calculates the changes between the specified layer |
| ... | ... |
@@ -539,6 +544,12 @@ func writeLayerFromTar(r archive.Reader, w hcsshim.LayerWriter) (int64, error) {
|
| 539 | 539 |
return 0, err |
| 540 | 540 |
} |
| 541 | 541 |
hdr, err = t.Next() |
| 542 |
+ } else if hdr.Typeflag == tar.TypeLink {
|
|
| 543 |
+ err = w.AddLink(filepath.FromSlash(hdr.Name), filepath.FromSlash(hdr.Linkname)) |
|
| 544 |
+ if err != nil {
|
|
| 545 |
+ return 0, err |
|
| 546 |
+ } |
|
| 547 |
+ hdr, err = t.Next() |
|
| 542 | 548 |
} else {
|
| 543 | 549 |
var ( |
| 544 | 550 |
name string |
| ... | ... |
@@ -575,7 +586,6 @@ func (d *Driver) importLayer(id string, layerData archive.Reader, parentLayerPat |
| 575 | 575 |
if err != nil {
|
| 576 | 576 |
return |
| 577 | 577 |
} |
| 578 |
- |
|
| 579 | 578 |
size, err = writeLayerFromTar(layerData, w) |
| 580 | 579 |
if err != nil {
|
| 581 | 580 |
w.Close() |
| ... | ... |
@@ -653,7 +663,7 @@ func (fg *fileGetCloserWithBackupPrivileges) Get(filename string) (io.ReadCloser |
| 653 | 653 |
// file can be opened even if the caller does not actually have access to it according |
| 654 | 654 |
// to the security descriptor. |
| 655 | 655 |
err := winio.RunWithPrivilege(winio.SeBackupPrivilege, func() error {
|
| 656 |
- path := filepath.Join(fg.path, filename) |
|
| 656 |
+ path := longpath.AddPrefix(filepath.Join(fg.path, filename)) |
|
| 657 | 657 |
p, err := syscall.UTF16FromString(path) |
| 658 | 658 |
if err != nil {
|
| 659 | 659 |
return err |