cmd/dist, cmd/ctr: move image store access to GRPC

With this changeset, image store access is now moved to completely
accessible over GRPC. No clients manipulate the image store database
directly and the GRPC client is fully featured. The metadata database is
now managed by the daemon and access coordinated via services.

Signed-off-by: Stephen J Day <stephen.day@docker.com>
This commit is contained in:
Stephen J Day 2017-04-03 18:40:59 -07:00
parent 1ea809dc2a
commit 8c74da3983
No known key found for this signature in database
GPG key ID: 67B3DED84EDC823F
10 changed files with 69 additions and 98 deletions

32
cmd/dist/common.go vendored
View file

@ -6,11 +6,12 @@ import (
"path/filepath"
"time"
"github.com/boltdb/bolt"
imagesapi "github.com/containerd/containerd/api/services/images"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/remotes"
"github.com/containerd/containerd/remotes/docker"
imagesservice "github.com/containerd/containerd/services/images"
"github.com/urfave/cli"
"google.golang.org/grpc"
)
@ -27,6 +28,14 @@ func resolveContentStore(context *cli.Context) (*content.Store, error) {
return content.NewStore(root)
}
func resolveImageStore(clicontext *cli.Context) (images.Store, error) {
conn, err := connectGRPC(clicontext)
if err != nil {
return nil, err
}
return imagesservice.NewStoreFromClient(imagesapi.NewImagesClient(conn)), nil
}
func connectGRPC(context *cli.Context) (*grpc.ClientConn, error) {
socket := context.GlobalString("socket")
timeout := context.GlobalDuration("connect-timeout")
@ -40,27 +49,6 @@ func connectGRPC(context *cli.Context) (*grpc.ClientConn, error) {
)
}
func getDB(ctx *cli.Context, readonly bool) (*bolt.DB, error) {
// TODO(stevvooe): For now, we operate directly on the database. We will
// replace this with a GRPC service when the details are more concrete.
path := filepath.Join(ctx.GlobalString("root"), "meta.db")
db, err := bolt.Open(path, 0644, &bolt.Options{
ReadOnly: readonly,
})
if err != nil {
return nil, err
}
if !readonly {
if err := images.InitDB(db); err != nil {
return nil, err
}
}
return db, nil
}
// getResolver prepares the resolver from the environment and options.
func getResolver(ctx context.Context) (remotes.Resolver, error) {
return docker.NewResolver(), nil

27
cmd/dist/images.go vendored
View file

@ -6,7 +6,6 @@ import (
"text/tabwriter"
contentapi "github.com/containerd/containerd/api/services/content"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/progress"
contentservice "github.com/containerd/containerd/services/content"
@ -25,23 +24,19 @@ var imagesCommand = cli.Command{
ctx = background
)
db, err := getDB(clicontext, true)
imageStore, err := resolveImageStore(clicontext)
if err != nil {
return errors.Wrap(err, "failed to open database")
return err
}
tx, err := db.Begin(false)
if err != nil {
return errors.Wrap(err, "could not start transaction")
}
defer tx.Rollback()
conn, err := connectGRPC(clicontext)
if err != nil {
return err
}
provider := contentservice.NewProviderFromClient(contentapi.NewContentClient(conn))
images, err := images.List(tx)
images, err := imageStore.List(ctx)
if err != nil {
return errors.Wrap(err, "failed to list images")
}
@ -54,7 +49,7 @@ var imagesCommand = cli.Command{
log.G(ctx).WithError(err).Errorf("failed calculating size for image %s", image.Name)
}
fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t\n", image.Name, image.Descriptor.MediaType, image.Descriptor.Digest, progress.Bytes(size))
fmt.Fprintf(tw, "%v\t%v\t%v\t%v\t\n", image.Name, image.Target.MediaType, image.Target.Digest, progress.Bytes(size))
}
tw.Flush()
@ -74,19 +69,13 @@ var rmiCommand = cli.Command{
exitErr error
)
db, err := getDB(clicontext, false)
imageStore, err := resolveImageStore(clicontext)
if err != nil {
return errors.Wrap(err, "failed to open database")
return err
}
tx, err := db.Begin(true)
if err != nil {
return errors.Wrap(err, "could not start transaction")
}
defer tx.Rollback()
for _, target := range clicontext.Args() {
if err := images.Delete(tx, target); err != nil {
if err := imageStore.Delete(ctx, target); err != nil {
if exitErr == nil {
exitErr = errors.Wrapf(err, "unable to delete %v", target)
}

27
cmd/dist/pull.go vendored
View file

@ -47,17 +47,10 @@ command. As part of this process, we do the following:
return err
}
db, err := getDB(clicontext, false)
imageStore, err := resolveImageStore(clicontext)
if err != nil {
return err
}
defer db.Close()
tx, err := db.Begin(true)
if err != nil {
return err
}
defer tx.Rollback()
resolver, err := getResolver(ctx)
if err != nil {
@ -65,6 +58,7 @@ command. As part of this process, we do the following:
}
ongoing := newJobs()
// TODO(stevvooe): Must unify this type.
ingester := contentservice.NewIngesterFromClient(contentapi.NewContentClient(conn))
provider := contentservice.NewProviderFromClient(contentapi.NewContentClient(conn))
@ -88,13 +82,8 @@ command. As part of this process, we do the following:
close(resolved)
eg.Go(func() error {
return images.Register(tx, name, desc)
return imageStore.Put(ctx, name, desc)
})
defer func() {
if err := tx.Commit(); err != nil {
log.G(ctx).WithError(err).Error("commit failed")
}
}()
return images.Dispatch(ctx,
images.Handlers(images.HandlerFunc(func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) {
@ -114,24 +103,20 @@ command. As part of this process, we do the following:
}()
defer func() {
ctx := context.Background()
tx, err := db.Begin(false)
if err != nil {
log.G(ctx).Fatal(err)
}
ctx := background
// TODO(stevvooe): This section unpacks the layers and resolves the
// root filesystem chainid for the image. For now, we just print
// it, but we should keep track of this in the metadata storage.
image, err := images.Get(tx, resolvedImageName)
image, err := imageStore.Get(ctx, resolvedImageName)
if err != nil {
log.G(ctx).Fatal(err)
}
provider := contentservice.NewProviderFromClient(contentapi.NewContentClient(conn))
p, err := content.ReadBlob(ctx, provider, image.Descriptor.Digest)
p, err := content.ReadBlob(ctx, provider, image.Target.Digest)
if err != nil {
log.G(ctx).Fatal(err)
}