-
Notifications
You must be signed in to change notification settings - Fork 38
WIP: Staged layer creation #378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
e6b50cf
a9ab042
ffaf5cf
9433c52
ba6d7ad
fd2cc61
633d40c
e98f783
ea94927
39cde30
639f0f5
651c8f5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2369,31 +2369,94 @@ func (d *Driver) DifferTarget(id string) (string, error) { | |
| return d.getDiffPath(id) | ||
| } | ||
|
|
||
| // ApplyDiff applies the new layer into a root | ||
| func (d *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts) (size int64, err error) { | ||
| if !d.isParent(id, parent) { | ||
| if d.options.ignoreChownErrors { | ||
| options.IgnoreChownErrors = d.options.ignoreChownErrors | ||
| // StartStagingDiffToApply applies the new layer into a temporary directory. | ||
| // It returns a CleanupTempDirFunc which can nil or set regardless if the function return an error or not. | ||
| // StagedAddition is only set when there is no error returned and the int64 value returns the size of the layer. | ||
| // This can be done without holding the storage lock. | ||
| // | ||
| // This API is experimental and can be changed without bumping the major version number. | ||
| func (d *Driver) StartStagingDiffToApply(options graphdriver.ApplyDiffOpts) (tempdir.CleanupTempDirFunc, *tempdir.StagedAddition, int64, error) { | ||
| // FIXME: how to consolidate with d.getTempDirRoot(id) if we don't have the id? | ||
| tempDirRoot := filepath.Join(d.homeDirForImageStore(), tempDirName) | ||
| t, err := tempdir.NewTempDir(tempDirRoot) | ||
| if err != nil { | ||
| return nil, nil, -1, err | ||
| } | ||
|
|
||
| sa, err := t.StageAddition() | ||
| if err != nil { | ||
| return t.Cleanup, nil, -1, err | ||
| } | ||
|
|
||
| size, err := d.applyDiff(sa.Path, options) | ||
| if err != nil { | ||
| return t.Cleanup, nil, -1, err | ||
| } | ||
|
|
||
| return t.Cleanup, sa, size, nil | ||
| } | ||
|
|
||
| // CommitStagedLayer that was created with StartStagingDiffToApply(). | ||
| // | ||
| // This API is experimental and can be changed without bumping the major version number. | ||
| func (d *Driver) CommitStagedLayer(id string, sa *tempdir.StagedAddition) error { | ||
| applyDir, err := d.getDiffPath(id) | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // FIXME: Is there a better way to do this? | ||
| stat, err := system.Stat(applyDir) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| if err := os.Chmod(sa.Path, os.FileMode(stat.Mode())); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| if err := os.Chown(sa.Path, int(stat.UID()), int(stat.GID())); err != nil { | ||
| return err | ||
| } | ||
| if d.options.forceMask != nil { | ||
| st, err := idtools.GetContainersOverrideXattr(applyDir) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| if d.options.forceMask != nil { | ||
| options.ForceMask = d.options.forceMask | ||
| if err := idtools.SetContainersOverrideXattr(sa.Path, st); err != nil { | ||
| return err | ||
| } | ||
| return d.naiveDiff.ApplyDiff(id, parent, options) | ||
| } | ||
|
|
||
| idMappings := options.Mappings | ||
| if idMappings == nil { | ||
| idMappings = &idtools.IDMappings{} | ||
| // The os.Rename() function used by CommitFunc errors when the target directory already | ||
| // exists, as such delete the dir. | ||
| if err := os.Remove(applyDir); err != nil { | ||
| return err | ||
| } | ||
|
|
||
| return sa.Commit(applyDir) | ||
| } | ||
|
|
||
| // ApplyDiff applies the new layer into a root | ||
| func (d *Driver) ApplyDiff(id string, options graphdriver.ApplyDiffOpts) (size int64, err error) { | ||
| applyDir, err := d.getDiffPath(id) | ||
| if err != nil { | ||
| return 0, err | ||
| } | ||
| return d.applyDiff(applyDir, options) | ||
| } | ||
|
|
||
| // ApplyDiff applies the new layer into a root. | ||
| // This can run concurrently with any other driver operations, as such it is the | ||
| // callers responsibility to ensure the target path passed is safe to use if that is the case. | ||
| func (d *Driver) applyDiff(target string, options graphdriver.ApplyDiffOpts) (size int64, err error) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A warning that this can run concurrently with any other operations on the driver would be nice. … and that might motivate auditing and documenting which fields of |
||
| idMappings := options.Mappings | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Non-blocking: So far, all callers were setting |
||
| if idMappings == nil { | ||
| idMappings = &idtools.IDMappings{} | ||
| } | ||
|
|
||
| logrus.Debugf("Applying tar in %s", applyDir) | ||
| logrus.Debugf("Applying tar in %s", target) | ||
| // Overlay doesn't need the parent id to apply the diff | ||
| if err := untar(options.Diff, applyDir, &archive.TarOptions{ | ||
| if err := untar(options.Diff, target, &archive.TarOptions{ | ||
| UIDMaps: idMappings.UIDs(), | ||
| GIDMaps: idMappings.GIDs(), | ||
| IgnoreChownErrors: d.options.ignoreChownErrors, | ||
|
|
@@ -2404,7 +2467,7 @@ func (d *Driver) ApplyDiff(id, parent string, options graphdriver.ApplyDiffOpts) | |
| return 0, err | ||
| } | ||
|
|
||
| return directory.Size(applyDir) | ||
| return directory.Size(target) | ||
| } | ||
|
|
||
| func (d *Driver) getComposefsData(id string) string { | ||
|
|
||
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I agree, this suggests a refactoring might be possible and beneficial.)