client: add Import() and Export() for importing/exporting image in OCI format

Export as a tar (Note: "-" can be used for stdout):

    $ ctr images export /tmp/oci-busybox.tar docker.io/library/busybox:latest

Import a tar (Note: "-" can be used for stdin):

    $ ctr images import foo/new:latest /tmp/oci-busybox.tar

Note: media types are not converted at the moment: e.g.
  application/vnd.docker.image.rootfs.diff.tar.gzip
  -> application/vnd.oci.image.layer.v1.tar+gzip

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
This commit is contained in:
Akihiro Suda
2017-06-15 08:50:20 +00:00
parent 856b038437
commit b518f11dba
13 changed files with 904 additions and 284 deletions

View File

@@ -5,6 +5,7 @@ import (
"io"
"time"
"github.com/containerd/containerd/oci"
"github.com/opencontainers/go-digest"
)
@@ -77,10 +78,8 @@ type IngestManager interface {
}
type Writer interface {
io.WriteCloser
oci.BlobWriter
Status() (Status, error)
Digest() digest.Digest
Commit(size int64, expected digest.Digest) error
Truncate(size int64) error
}

View File

@@ -8,6 +8,7 @@ import (
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/oci"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
)
@@ -78,7 +79,7 @@ func (w *writer) Commit(size int64, expected digest.Digest) error {
}
if size > 0 && size != fi.Size() {
return errors.Errorf("%q failed size validation: %v != %v", w.ref, fi.Size(), size)
return oci.ErrUnexpectedSize{Expected: size, Actual: fi.Size()}
}
if err := w.fp.Close(); err != nil {
@@ -87,7 +88,7 @@ func (w *writer) Commit(size int64, expected digest.Digest) error {
dgst := w.digester.Digest()
if expected != "" && expected != dgst {
return errors.Errorf("unexpected digest: %v != %v", dgst, expected)
return oci.ErrUnexpectedDigest{Expected: expected, Actual: dgst}
}
var (