Merge pull request #1880 from AkihiroSuda/refactor-importer

importer: refactor and fix GC
This commit is contained in:
Derek McGowan
2017-12-04 20:56:26 -08:00
committed by GitHub
11 changed files with 394 additions and 292 deletions

View File

@@ -5,6 +5,7 @@ import (
"os"
"github.com/containerd/containerd/cmd/ctr/commands"
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"
@@ -13,11 +14,14 @@ import (
)
var exportCommand = cli.Command{
Name: "export",
Usage: "export an image",
ArgsUsage: "[flags] <out> <image>",
Description: "export an image to a tar stream",
Name: "export",
Usage: "export an image",
ArgsUsage: "[flags] <out> <image>",
Description: `Export an image to a tar stream.
Currently, only OCI format is supported.
`,
Flags: []cli.Flag{
// TODO(AkihiroSuda): make this map[string]string as in moby/moby#33355?
cli.StringFlag{
Name: "oci-ref-name",
Value: "",
@@ -78,7 +82,7 @@ var exportCommand = cli.Command{
return nil
}
}
r, err := client.Export(ctx, desc)
r, err := client.Export(ctx, &oci.V1Exporter{}, desc)
if err != nil {
return err
}

View File

@@ -5,37 +5,66 @@ import (
"io"
"os"
"github.com/containerd/containerd"
"github.com/containerd/containerd/cmd/ctr/commands"
"github.com/containerd/containerd/images"
oci "github.com/containerd/containerd/images/oci"
"github.com/containerd/containerd/log"
"github.com/urfave/cli"
)
var importCommand = cli.Command{
Name: "import",
Usage: "import an image",
ArgsUsage: "[flags] <ref> <in>",
Description: "import an image from a tar stream",
Flags: []cli.Flag{
Name: "import",
Usage: "import images",
ArgsUsage: "[flags] <in>",
Description: `Import images from a tar stream.
Implemented formats:
- oci.v1 (default)
For oci.v1 format, you need to specify --oci-name because an OCI archive contains image refs (tags)
but does not contain the base image name.
e.g.
$ ctr images import --format oci.v1 --oci-name foo/bar foobar.tar
If foobar.tar contains an OCI ref named "latest" and anonymous ref "sha256:deadbeef", the command will create
"foo/bar:latest" and "foo/bar@sha256:deadbeef" images in the containerd store.
`,
Flags: append([]cli.Flag{
cli.StringFlag{
Name: "ref-object",
Value: "",
Usage: "reference object e.g. tag@digest (default: use the object specified in ref)",
Name: "format",
Value: "oci.v1",
Usage: "image format. See DESCRIPTION.",
},
commands.LabelFlag,
},
cli.StringFlag{
Name: "oci-name",
Value: "unknown/unknown",
Usage: "prefix added to either oci.v1 ref annotation or digest",
},
// TODO(AkihiroSuda): support commands.LabelFlag (for all children objects)
}, commands.SnapshotterFlags...),
Action: func(context *cli.Context) error {
var (
ref = context.Args().First()
in = context.Args().Get(1)
refObject = context.String("ref-object")
labels = commands.LabelArgs(context.StringSlice("label"))
in = context.Args().First()
imageImporter images.Importer
)
switch format := context.String("format"); format {
case "oci.v1":
imageImporter = &oci.V1Importer{
ImageName: context.String("oci-name"),
}
default:
return fmt.Errorf("unknown format %s", format)
}
client, ctx, cancel, err := commands.NewClient(context)
if err != nil {
return err
}
defer cancel()
var r io.ReadCloser
if in == "-" {
r = os.Stdin
@@ -45,12 +74,7 @@ var importCommand = cli.Command{
return err
}
}
img, err := client.Import(ctx,
ref,
r,
containerd.WithRefObject(refObject),
containerd.WithImportLabels(labels),
)
imgs, err := client.Import(ctx, imageImporter, r)
if err != nil {
return err
}
@@ -58,12 +82,17 @@ var importCommand = cli.Command{
return err
}
log.G(ctx).WithField("image", ref).Debug("unpacking")
log.G(ctx).Debugf("unpacking %d images", len(imgs))
// TODO: Show unpack status
fmt.Printf("unpacking %s...", img.Target().Digest)
err = img.Unpack(ctx, context.String("snapshotter"))
fmt.Println("done")
return err
for _, img := range imgs {
// TODO: Show unpack status
fmt.Printf("unpacking %s (%s)...", img.Name(), img.Target().Digest)
err = img.Unpack(ctx, context.String("snapshotter"))
if err != nil {
return err
}
fmt.Println("done")
}
return nil
},
}