@@ -2369,21 +2369,67 @@ func (d *Driver) DifferTarget(id string) (string, error) {
23692369 return d .getDiffPath (id )
23702370}
23712371
2372- // ApplyDiff applies the new layer into a root
2373- func (d * Driver ) ApplyDiff (id , parent string , options graphdriver.ApplyDiffOpts ) (size int64 , err error ) {
2374- idMappings := options .Mappings
2375- if idMappings == nil {
2376- idMappings = & idtools.IDMappings {}
2372+ // StartStagingDiffToApply applies the new layer into a temporary directory.
2373+ // It returns a CleanupTempDirFunc which can nil or set regardless if the function return an error or not.
2374+ // CommitFunc is only set when there is no error returned and the int64 value returns the size of the layer.
2375+ //
2376+ // This API is experimental and can be changed without bumping the major version number.
2377+ func (d * Driver ) StartStagingDiffToApply (id , parent string , options graphdriver.ApplyDiffOpts ) (tempdir.CleanupTempDirFunc , tempdir.CommitFunc , int64 , error ) {
2378+ tempDirRoot := d .getTempDirRoot (id )
2379+ t , err := tempdir .NewTempDir (tempDirRoot )
2380+ if err != nil {
2381+ return nil , nil , - 1 , err
2382+ }
2383+
2384+ var size int64
2385+ sa , err := t .StageDirectoryAddition (func (path string ) error {
2386+ size , err = d .applyDiff (id , path , options )
2387+ return err
2388+ })
2389+ if err != nil {
2390+ return t .Cleanup , nil , - 1 , err
2391+ }
2392+
2393+ return t .Cleanup , sa .Commit , size , nil
2394+ }
2395+
2396+ // CommitStagedLayer that was created with StartStagingDiffToApply().
2397+ //
2398+ // This API is experimental and can be changed without bumping the major version number.
2399+ func (d * Driver ) CommitStagedLayer (id string , commit tempdir.CommitFunc ) error {
2400+ applyDir , err := d .getDiffPath (id )
2401+ if err != nil {
2402+ return err
23772403 }
23782404
2405+ // The os.Rename() function used by CommitFunc errors when the target directory already
2406+ // exists, as such delete the dir if it already exists.
2407+ if err := os .Remove (applyDir ); err != nil && ! errors .Is (err , fs .ErrNotExist ) {
2408+ return err
2409+ }
2410+
2411+ return commit (applyDir )
2412+ }
2413+
2414+ // ApplyDiff applies the new layer into a root
2415+ func (d * Driver ) ApplyDiff (id , parent string , options graphdriver.ApplyDiffOpts ) (size int64 , err error ) {
23792416 applyDir , err := d .getDiffPath (id )
23802417 if err != nil {
23812418 return 0 , err
23822419 }
2420+ return d .applyDiff (id , applyDir , options )
2421+ }
2422+
2423+ // ApplyDiff applies the new layer into a root
2424+ func (d * Driver ) applyDiff (id , target string , options graphdriver.ApplyDiffOpts ) (size int64 , err error ) {
2425+ idMappings := options .Mappings
2426+ if idMappings == nil {
2427+ idMappings = & idtools.IDMappings {}
2428+ }
23832429
2384- logrus .Debugf ("Applying tar in %s" , applyDir )
2430+ logrus .Debugf ("Applying tar in %s" , target )
23852431 // Overlay doesn't need the parent id to apply the diff
2386- if err := untar (options .Diff , applyDir , & archive.TarOptions {
2432+ if err := untar (options .Diff , target , & archive.TarOptions {
23872433 UIDMaps : idMappings .UIDs (),
23882434 GIDMaps : idMappings .GIDs (),
23892435 IgnoreChownErrors : d .options .ignoreChownErrors ,
@@ -2394,7 +2440,7 @@ func (d *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts)
23942440 return 0 , err
23952441 }
23962442
2397- return directory .Size (applyDir )
2443+ return directory .Size (target )
23982444}
23992445
24002446func (d * Driver ) getComposefsData (id string ) string {
0 commit comments