fix ctr image export not found error

Signed-off-by: Jie Zhang <iamkadisi@163.com>
This commit is contained in:
kadisi 2018-09-08 18:43:23 +08:00 committed by Jie Zhang
parent 1a9b010de0
commit 40267382c5
5 changed files with 64 additions and 27 deletions

View File

@ -21,7 +21,7 @@ import (
"os"
"github.com/containerd/containerd/cmd/ctr/commands"
oci "github.com/containerd/containerd/images/oci"
"github.com/containerd/containerd/images/oci"
"github.com/containerd/containerd/reference"
digest "github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@ -52,6 +52,10 @@ Currently, only OCI format is supported.
Usage: "media type of manifest digest",
Value: ocispec.MediaTypeImageManifest,
},
cli.BoolFlag{
Name: "all-platforms",
Usage: "exports content from all platforms",
},
},
Action: func(context *cli.Context) error {
var (
@ -101,7 +105,14 @@ Currently, only OCI format is supported.
return nil
}
}
r, err := client.Export(ctx, &oci.V1Exporter{}, desc)
var (
exportOpts []oci.V1ExporterOpt
)
exportOpts = append(exportOpts, oci.WithAllPlatforms(context.Bool("all-platforms")))
r, err := client.Export(ctx, desc, exportOpts...)
if err != nil {
return err
}

View File

@ -20,36 +20,23 @@ import (
"context"
"io"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/images/oci"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
)
type exportOpts struct {
}
// ExportOpt allows the caller to specify export-specific options
type ExportOpt func(c *exportOpts) error
func resolveExportOpt(opts ...ExportOpt) (exportOpts, error) {
var eopts exportOpts
for _, o := range opts {
if err := o(&eopts); err != nil {
return eopts, err
}
}
return eopts, nil
}
// Export exports an image to a Tar stream.
// OCI format is used by default.
// It is up to caller to put "org.opencontainers.image.ref.name" annotation to desc.
// TODO(AkihiroSuda): support exporting multiple descriptors at once to a single archive stream.
func (c *Client) Export(ctx context.Context, exporter images.Exporter, desc ocispec.Descriptor, opts ...ExportOpt) (io.ReadCloser, error) {
_, err := resolveExportOpt(opts...) // unused now
func (c *Client) Export(ctx context.Context, desc ocispec.Descriptor, opts ...oci.V1ExporterOpt) (io.ReadCloser, error) {
exporter, err := oci.ResolveV1ExportOpt(opts...)
if err != nil {
return nil, err
}
pr, pw := io.Pipe()
go func() {
pw.CloseWithError(errors.Wrap(exporter.Export(ctx, c.ContentStore(), desc, pw), "export failed"))

View File

@ -21,8 +21,6 @@ import (
"io"
"runtime"
"testing"
"github.com/containerd/containerd/images/oci"
)
// TestOCIExport exports testImage as a tar stream
@ -44,7 +42,7 @@ func TestOCIExport(t *testing.T) {
if err != nil {
t.Fatal(err)
}
exportedStream, err := client.Export(ctx, &oci.V1Exporter{}, pulled.Target)
exportedStream, err := client.Export(ctx, pulled.Target)
if err != nil {
t.Fatal(err)
}

View File

@ -25,6 +25,7 @@ import (
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/platforms"
ocispecs "github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
@ -37,6 +38,36 @@ import (
// e.g. application/vnd.docker.image.rootfs.diff.tar.gzip
// -> application/vnd.oci.image.layer.v1.tar+gzip
type V1Exporter struct {
AllPlatforms bool
}
// V1ExporterOpt allows to set additional options to a newly V1Exporter
type V1ExporterOpt func(c *V1Exporter) error
// DefaultV1Exporter return a default V1Exporter pointer
func DefaultV1Exporter() *V1Exporter {
return &V1Exporter{
AllPlatforms: false,
}
}
// ResolveV1ExportOpt return a new V1Exporter with V1ExporterOpt
func ResolveV1ExportOpt(opts ...V1ExporterOpt) (*V1Exporter, error) {
exporter := DefaultV1Exporter()
for _, o := range opts {
if err := o(exporter); err != nil {
return exporter, err
}
}
return exporter, nil
}
// WithAllPlatforms set V1Exporter`s AllPlatforms option
func WithAllPlatforms(allPlatforms bool) V1ExporterOpt {
return func(c *V1Exporter) error {
c.AllPlatforms = allPlatforms
return nil
}
}
// Export implements Exporter.
@ -56,8 +87,19 @@ func (oe *V1Exporter) Export(ctx context.Context, store content.Provider, desc o
return nil, nil
}
childrenHandler := images.ChildrenHandler(store)
if !oe.AllPlatforms {
// get local default platform to fetch image manifest
p, err := platforms.Parse(platforms.DefaultString())
if err != nil {
return errors.Wrapf(err, "invalid platform %s", platforms.DefaultString())
}
childrenHandler = images.FilterPlatforms(childrenHandler, platforms.Any(p))
}
handlers := images.Handlers(
images.ChildrenHandler(store),
childrenHandler,
images.HandlerFunc(exportHandler),
)

View File

@ -29,7 +29,6 @@ import (
"github.com/containerd/containerd/archive/tartest"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/images/archive"
"github.com/containerd/containerd/images/oci"
digest "github.com/opencontainers/go-digest"
specs "github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
@ -56,7 +55,7 @@ func TestOCIExportAndImport(t *testing.T) {
t.Fatal(err)
}
exported, err := client.Export(ctx, &oci.V1Exporter{}, pulled.Target)
exported, err := client.Export(ctx, pulled.Target)
if err != nil {
t.Fatal(err)
}