Skip to content

Ability to duplicate a manifest to another location #95

@ijc

Description

@ijc

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions