-
Notifications
You must be signed in to change notification settings - Fork 68
Description
Background
Following on from containerd/containerd#1482 (comment)
Docker style volumes (those declared with VOLUME /path in a Dockerfile) have the property that they are initialised using the contents /path in underlying image. In order to produce a helper which can allow containerd clients to support such functionality a safe mechanism to duplicate a filesystem trees is required.
Safe here means at least:
- Must never dereference symbolic links (must recreate them as is, even if they dangle) including never traversing a directory symlink (since this could lead outside the root).
- Must not pull entire filesystem objects into RAM.
- Safe against directory hardlink loops.
Since continuity can safely and fully represent a filesystem tree extending it to allow duplicating that tree seems reasonable.
Proposal
I propose adding a single method to the existing Resource interface:
Copy(srcroot, dstroot string) error
This method will (given p := resource.Path()) duplicate srcroot/p to dstroot/p, preserving permissions and ownership. If the Resource implements the Xattrer interface then xattrs will also be preserved. Likewise if the Resource implements Hardlinkable then all hardlinks will be created. (similarly for any other interfaces I've missed or which are added in the future)
In normal expected usage srcroot would be the root of a Context. Therefore a new method will also be added to the Context interfaces:
Copy(dstroot string) error
This will BuildManifest(self), sort the result using ByPath and then iterate calling resource.Copy(self.path, dstroot) for each resource.
Variations
Copying Xattrer and Hardlinkable as responsiblity of caller
The support for Xattrer and Hardlinkable in each implementation of Resource seems likely to be quite similar, which likely implies the addition of a helper for each.
We could therefore consider excluding handling of those from the Resource.Copy method and instead push the responsibility back to the callers (so, Context.Copy here) using those same helpers.
Perhaps:
ApplyXattrs(xattrer Xattrer, dstroot, path string) error
ApplyHardlinks(hlable Hardlinkable, dstroot, path string) error
I lean towards requiring Resource.Copy to completely copy all known properties since this seems simpler. The downside is that callers cannot then opt out of copying certain properties.
Copyable interface
Rather than adding a new method to Resource we could add a new interface:
type Copyable interface {
Copy(dstroot string) error
}
However since all Resources would have to support the method in order for the overall functionality to be reliably usable there doesn't seem much point.