-
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.