diff --git a/cmd/containerd/main.go b/cmd/containerd/main.go index 0c3907763..aebe9a3c2 100644 --- a/cmd/containerd/main.go +++ b/cmd/containerd/main.go @@ -25,8 +25,8 @@ import ( snapshotapi "github.com/containerd/containerd/api/services/snapshot" versionapi "github.com/containerd/containerd/api/services/version" "github.com/containerd/containerd/content" - "github.com/containerd/containerd/images" "github.com/containerd/containerd/log" + "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/plugin" "github.com/containerd/containerd/snapshot" "github.com/containerd/containerd/sys" @@ -258,8 +258,7 @@ func resolveMetaDB(ctx *cli.Context) (*bolt.DB, error) { return nil, err } - // TODO(stevvooe): Break these down into components to be initialized. - if err := images.InitDB(db); err != nil { + if err := metadata.InitDB(db); err != nil { return nil, err } diff --git a/images/image.go b/images/image.go index c1ff32cb2..3a445a3b8 100644 --- a/images/image.go +++ b/images/image.go @@ -17,6 +17,13 @@ type Image struct { Target ocispec.Descriptor } +type Store interface { + Put(ctx context.Context, name string, desc ocispec.Descriptor) error + Get(ctx context.Context, name string) (Image, error) + List(ctx context.Context) ([]Image, error) + Delete(ctx context.Context, name string) error +} + // TODO(stevvooe): Many of these functions make strong platform assumptions, // which are untrue in a lot of cases. More refactoring must be done here to // make this work in all cases. diff --git a/images/storage.go b/images/storage.go deleted file mode 100644 index 66b4e115a..000000000 --- a/images/storage.go +++ /dev/null @@ -1,219 +0,0 @@ -package images - -import ( - "context" - "encoding/binary" - "fmt" - - "github.com/boltdb/bolt" - "github.com/containerd/containerd/log" - digest "github.com/opencontainers/go-digest" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" -) - -var ( - ErrExists = errors.New("images: exists") - ErrNotFound = errors.New("images: not found") -) - -type Store interface { - Put(ctx context.Context, name string, desc ocispec.Descriptor) error - Get(ctx context.Context, name string) (Image, error) - List(ctx context.Context) ([]Image, error) - Delete(ctx context.Context, name string) error -} - -// IsNotFound returns true if the error is due to a missing image. -func IsNotFound(err error) bool { - return errors.Cause(err) == ErrNotFound -} - -func IsExists(err error) bool { - return errors.Cause(err) == ErrExists -} - -var ( - bucketKeyStorageVersion = []byte("v1") - bucketKeyImages = []byte("images") - bucketKeyDigest = []byte("digest") - bucketKeyMediaType = []byte("mediatype") - bucketKeySize = []byte("size") -) - -// TODO(stevvooe): This file comprises the data required to implement the -// "metadata" store. For now, it is bound tightly to the local machine and bolt -// but we can take this and use it to define a service interface. - -// InitDB will initialize the database for use. The database must be opened for -// write and the caller must not be holding an open transaction. -func InitDB(db *bolt.DB) error { - log.L.Debug("init db") - return db.Update(func(tx *bolt.Tx) error { - _, err := createBucketIfNotExists(tx, bucketKeyStorageVersion, bucketKeyImages) - return err - }) -} - -func NewStore(tx *bolt.Tx) Store { - return &storage{tx: tx} -} - -type storage struct { - tx *bolt.Tx -} - -func (s *storage) Get(ctx context.Context, name string) (Image, error) { - var image Image - if err := withImageBucket(s.tx, name, func(bkt *bolt.Bucket) error { - image.Name = name - return readImage(&image, bkt) - }); err != nil { - return Image{}, err - } - - return image, nil -} - -func (s *storage) Put(ctx context.Context, name string, desc ocispec.Descriptor) error { - return withImagesBucket(s.tx, func(bkt *bolt.Bucket) error { - ibkt, err := bkt.CreateBucketIfNotExists([]byte(name)) - if err != nil { - return err - } - - var ( - buf [binary.MaxVarintLen64]byte - sizeEncoded []byte = buf[:] - ) - sizeEncoded = sizeEncoded[:binary.PutVarint(sizeEncoded, desc.Size)] - - if len(sizeEncoded) == 0 { - return fmt.Errorf("failed encoding size = %v", desc.Size) - } - - for _, v := range [][2][]byte{ - {bucketKeyDigest, []byte(desc.Digest)}, - {bucketKeyMediaType, []byte(desc.MediaType)}, - {bucketKeySize, sizeEncoded}, - } { - if err := ibkt.Put(v[0], v[1]); err != nil { - return err - } - } - - return nil - }) -} - -func (s *storage) List(ctx context.Context) ([]Image, error) { - var images []Image - - if err := withImagesBucket(s.tx, func(bkt *bolt.Bucket) error { - return bkt.ForEach(func(k, v []byte) error { - var ( - image = Image{ - Name: string(k), - } - kbkt = bkt.Bucket(k) - ) - - if err := readImage(&image, kbkt); err != nil { - return err - } - - images = append(images, image) - return nil - }) - }); err != nil { - return nil, err - } - - return images, nil -} - -func (s *storage) Delete(ctx context.Context, name string) error { - return withImagesBucket(s.tx, func(bkt *bolt.Bucket) error { - err := bkt.DeleteBucket([]byte(name)) - if err == bolt.ErrBucketNotFound { - return ErrNotFound - } - return err - }) -} - -func readImage(image *Image, bkt *bolt.Bucket) error { - return bkt.ForEach(func(k, v []byte) error { - if v == nil { - return nil // skip it? a bkt maybe? - } - - // TODO(stevvooe): This is why we need to use byte values for - // keys, rather than full arrays. - switch string(k) { - case string(bucketKeyDigest): - image.Target.Digest = digest.Digest(v) - case string(bucketKeyMediaType): - image.Target.MediaType = string(v) - case string(bucketKeySize): - image.Target.Size, _ = binary.Varint(v) - } - - return nil - }) -} - -func createBucketIfNotExists(tx *bolt.Tx, keys ...[]byte) (*bolt.Bucket, error) { - bkt, err := tx.CreateBucketIfNotExists(keys[0]) - if err != nil { - return nil, err - } - - for _, key := range keys[1:] { - bkt, err = bkt.CreateBucketIfNotExists(key) - if err != nil { - return nil, err - } - } - - return bkt, nil -} - -func withImagesBucket(tx *bolt.Tx, fn func(bkt *bolt.Bucket) error) error { - bkt := getImagesBucket(tx) - if bkt == nil { - return ErrNotFound - } - - return fn(bkt) -} - -func withImageBucket(tx *bolt.Tx, name string, fn func(bkt *bolt.Bucket) error) error { - bkt := getImageBucket(tx, name) - if bkt == nil { - return ErrNotFound - } - - return fn(bkt) -} - -func getImagesBucket(tx *bolt.Tx) *bolt.Bucket { - return getBucket(tx, bucketKeyStorageVersion, bucketKeyImages) -} - -func getImageBucket(tx *bolt.Tx, name string) *bolt.Bucket { - return getBucket(tx, bucketKeyStorageVersion, bucketKeyImages, []byte(name)) -} - -func getBucket(tx *bolt.Tx, keys ...[]byte) *bolt.Bucket { - bkt := tx.Bucket(keys[0]) - - for _, key := range keys[1:] { - if bkt == nil { - break - } - bkt = bkt.Bucket(key) - } - - return bkt -} diff --git a/metadata/buckets.go b/metadata/buckets.go new file mode 100644 index 000000000..d2db567b1 --- /dev/null +++ b/metadata/buckets.go @@ -0,0 +1,107 @@ +package metadata + +import ( + "github.com/boltdb/bolt" + "github.com/containerd/containerd/log" +) + +var ( + bucketKeyStorageVersion = []byte("v1") + bucketKeyImages = []byte("images") + bucketKeyContainers = []byte("containers") + + bucketKeyDigest = []byte("digest") + bucketKeyMediaType = []byte("mediatype") + bucketKeySize = []byte("size") + bucketKeyLabels = []byte("labels") + bucketKeyImage = []byte("image") + bucketKeyRuntime = []byte("runtime") + bucketKeySpec = []byte("spec") + bucketKeyRootFS = []byte("rootfs") +) + +// InitDB will initialize the database for use. The database must be opened for +// write and the caller must not be holding an open transaction. +func InitDB(db *bolt.DB) error { + log.L.Debug("init db") + return db.Update(func(tx *bolt.Tx) error { + if _, err := createBucketIfNotExists(tx, bucketKeyStorageVersion, bucketKeyImages); err != nil { + return err + } + if _, err := createBucketIfNotExists(tx, bucketKeyStorageVersion, bucketKeyContainers); err != nil { + return err + } + return nil + }) +} + +func getBucket(tx *bolt.Tx, keys ...[]byte) *bolt.Bucket { + bkt := tx.Bucket(keys[0]) + + for _, key := range keys[1:] { + if bkt == nil { + break + } + bkt = bkt.Bucket(key) + } + + return bkt +} + +func createBucketIfNotExists(tx *bolt.Tx, keys ...[]byte) (*bolt.Bucket, error) { + bkt, err := tx.CreateBucketIfNotExists(keys[0]) + if err != nil { + return nil, err + } + + for _, key := range keys[1:] { + bkt, err = bkt.CreateBucketIfNotExists(key) + if err != nil { + return nil, err + } + } + + return bkt, nil +} + +func withImagesBucket(tx *bolt.Tx, fn func(bkt *bolt.Bucket) error) error { + bkt := getImagesBucket(tx) + if bkt == nil { + return ErrNotFound + } + + return fn(bkt) +} + +func withImageBucket(tx *bolt.Tx, name string, fn func(bkt *bolt.Bucket) error) error { + bkt := getImageBucket(tx, name) + if bkt == nil { + return ErrNotFound + } + + return fn(bkt) +} + +func getImagesBucket(tx *bolt.Tx) *bolt.Bucket { + return getBucket(tx, bucketKeyStorageVersion, bucketKeyImages) +} + +func getImageBucket(tx *bolt.Tx, name string) *bolt.Bucket { + return getBucket(tx, bucketKeyStorageVersion, bucketKeyImages, []byte(name)) +} + +func createContainersBucket(tx *bolt.Tx) (*bolt.Bucket, error) { + bkt, err := tx.CreateBucketIfNotExists(bucketKeyStorageVersion) + if err != nil { + return nil, err + } + return bkt.CreateBucketIfNotExists(bucketKeyContainers) +} + +func getContainersBucket(tx *bolt.Tx) *bolt.Bucket { + return getBucket(tx, bucketKeyStorageVersion, bucketKeyContainers) +} + +func getContainerBucket(tx *bolt.Tx, id string) *bolt.Bucket { + return getBucket(tx, bucketKeyStorageVersion, bucketKeyContainers, []byte(id)) +} diff --git a/containers/storage.go b/metadata/containers.go similarity index 50% rename from containers/storage.go rename to metadata/containers.go index 3ec4952f7..bd22c0513 100644 --- a/containers/storage.go +++ b/metadata/containers.go @@ -1,90 +1,69 @@ -package containers +package metadata import ( "context" "github.com/boltdb/bolt" + "github.com/containerd/containerd/containers" "github.com/pkg/errors" ) -var ( - ErrExists = errors.New("images: exists") - ErrNotFound = errors.New("images: not found") -) - -// IsNotFound returns true if the error is due to a missing image. -func IsNotFound(err error) bool { - return errors.Cause(err) == ErrNotFound -} - -func IsExists(err error) bool { - return errors.Cause(err) == ErrExists -} - -var ( - bucketKeyStorageVersion = []byte("v1") - bucketKeyContainers = []byte("containers") - bucketKeyLabels = []byte("labels") - bucketKeyImage = []byte("image") - bucketKeyRuntime = []byte("runtime") - bucketKeySpec = []byte("spec") - bucketKeyRootFS = []byte("rootfs") -) - -type storage struct { +type containerStore struct { tx *bolt.Tx } -func NewStore(tx *bolt.Tx) Store { - return &storage{ +func NewContainerStore(tx *bolt.Tx) containers.Store { + return &containerStore{ tx: tx, } } -func (s *storage) Get(ctx context.Context, id string) (Container, error) { +func (s *containerStore) Get(ctx context.Context, id string) (containers.Container, error) { bkt := getContainerBucket(s.tx, id) if bkt == nil { - return Container{}, errors.Wrap(ErrNotFound, "bucket does not exist") + return containers.Container{}, errors.Wrap(ErrNotFound, "bucket does not exist") } - container := Container{ID: id} + container := containers.Container{ID: id} if err := readContainer(&container, bkt); err != nil { - return Container{}, errors.Wrap(err, "failed to read container") + return containers.Container{}, errors.Wrap(err, "failed to read container") } return container, nil } -func (s *storage) List(ctx context.Context, filter string) ([]Container, error) { - containers := []Container{} - bkt := getContainersBucket(s.tx) +func (s *containerStore) List(ctx context.Context, filter string) ([]containers.Container, error) { + var ( + m = []containers.Container{} + bkt = getContainersBucket(s.tx) + ) if bkt == nil { - return containers, nil + return m, nil } err := bkt.ForEach(func(k, v []byte) error { cbkt := bkt.Bucket(k) if cbkt == nil { return nil } - container := Container{ID: string(k)} + container := containers.Container{ID: string(k)} if err := readContainer(&container, cbkt); err != nil { return errors.Wrap(err, "failed to read container") } - containers = append(containers, container) + m = append(m, container) return nil }) if err != nil { return nil, err } - return containers, nil + return m, nil } -func (s *storage) Create(ctx context.Context, container Container) (Container, error) { +func (s *containerStore) Create(ctx context.Context, container containers.Container) (containers.Container, error) { bkt, err := createContainersBucket(s.tx) if err != nil { - return Container{}, err + return containers.Container{}, err } cbkt, err := bkt.CreateBucket([]byte(container.ID)) @@ -92,35 +71,35 @@ func (s *storage) Create(ctx context.Context, container Container) (Container, e if err == bolt.ErrBucketExists { err = errors.Wrap(ErrExists, "content for id already exists") } - return Container{}, err + return containers.Container{}, err } if err := writeContainer(&container, cbkt); err != nil { - return Container{}, errors.Wrap(err, "failed to write container") + return containers.Container{}, errors.Wrap(err, "failed to write container") } return container, nil } -func (s *storage) Update(ctx context.Context, container Container) (Container, error) { +func (s *containerStore) Update(ctx context.Context, container containers.Container) (containers.Container, error) { bkt := getContainersBucket(s.tx) if bkt == nil { - return Container{}, errors.Wrap(ErrNotFound, "no containers") + return containers.Container{}, errors.Wrap(ErrNotFound, "no containers") } cbkt := bkt.Bucket([]byte(container.ID)) if cbkt == nil { - return Container{}, errors.Wrap(ErrNotFound, "no content for id") + return containers.Container{}, errors.Wrap(ErrNotFound, "no content for id") } if err := writeContainer(&container, cbkt); err != nil { - return Container{}, errors.Wrap(err, "failed to write container") + return containers.Container{}, errors.Wrap(err, "failed to write container") } return container, nil } -func (s *storage) Delete(ctx context.Context, id string) error { +func (s *containerStore) Delete(ctx context.Context, id string) error { bkt := getContainersBucket(s.tx) if bkt == nil { return errors.Wrap(ErrNotFound, "no containers") @@ -133,7 +112,7 @@ func (s *storage) Delete(ctx context.Context, id string) error { return err } -func readContainer(container *Container, bkt *bolt.Bucket) error { +func readContainer(container *containers.Container, bkt *bolt.Bucket) error { return bkt.ForEach(func(k, v []byte) error { switch string(k) { case string(bucketKeyImage): @@ -162,7 +141,7 @@ func readContainer(container *Container, bkt *bolt.Bucket) error { }) } -func writeContainer(container *Container, bkt *bolt.Bucket) error { +func writeContainer(container *containers.Container, bkt *bolt.Bucket) error { for _, v := range [][2][]byte{ {bucketKeyImage, []byte(container.Image)}, {bucketKeyRuntime, []byte(container.Runtime)}, @@ -190,32 +169,3 @@ func writeContainer(container *Container, bkt *bolt.Bucket) error { } return nil } - -func createContainersBucket(tx *bolt.Tx) (*bolt.Bucket, error) { - bkt, err := tx.CreateBucketIfNotExists(bucketKeyStorageVersion) - if err != nil { - return nil, err - } - return bkt.CreateBucketIfNotExists(bucketKeyContainers) -} - -func getContainersBucket(tx *bolt.Tx) *bolt.Bucket { - return getBucket(tx, bucketKeyStorageVersion, bucketKeyContainers) -} - -func getContainerBucket(tx *bolt.Tx, id string) *bolt.Bucket { - return getBucket(tx, bucketKeyStorageVersion, bucketKeyContainers, []byte(id)) -} - -func getBucket(tx *bolt.Tx, keys ...[]byte) *bolt.Bucket { - bkt := tx.Bucket(keys[0]) - - for _, key := range keys[1:] { - if bkt == nil { - break - } - bkt = bkt.Bucket(key) - } - - return bkt -} diff --git a/metadata/errors.go b/metadata/errors.go new file mode 100644 index 000000000..ab370a5dd --- /dev/null +++ b/metadata/errors.go @@ -0,0 +1,17 @@ +package metadata + +import "github.com/pkg/errors" + +var ( + ErrExists = errors.New("metadata: exists") + ErrNotFound = errors.New("metadata: not found") +) + +// IsNotFound returns true if the error is due to a missing image. +func IsNotFound(err error) bool { + return errors.Cause(err) == ErrNotFound +} + +func IsExists(err error) bool { + return errors.Cause(err) == ErrExists +} diff --git a/metadata/images.go b/metadata/images.go new file mode 100644 index 000000000..a922f7b66 --- /dev/null +++ b/metadata/images.go @@ -0,0 +1,120 @@ +package metadata + +import ( + "context" + "encoding/binary" + "fmt" + + "github.com/boltdb/bolt" + "github.com/containerd/containerd/images" + digest "github.com/opencontainers/go-digest" + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +type imageStore struct { + tx *bolt.Tx +} + +func NewImageStore(tx *bolt.Tx) images.Store { + return &imageStore{tx: tx} +} + +func (s *imageStore) Get(ctx context.Context, name string) (images.Image, error) { + var image images.Image + if err := withImageBucket(s.tx, name, func(bkt *bolt.Bucket) error { + image.Name = name + return readImage(&image, bkt) + }); err != nil { + return images.Image{}, err + } + + return image, nil +} + +func (s *imageStore) Put(ctx context.Context, name string, desc ocispec.Descriptor) error { + return withImagesBucket(s.tx, func(bkt *bolt.Bucket) error { + ibkt, err := bkt.CreateBucketIfNotExists([]byte(name)) + if err != nil { + return err + } + + var ( + buf [binary.MaxVarintLen64]byte + sizeEncoded []byte = buf[:] + ) + sizeEncoded = sizeEncoded[:binary.PutVarint(sizeEncoded, desc.Size)] + + if len(sizeEncoded) == 0 { + return fmt.Errorf("failed encoding size = %v", desc.Size) + } + + for _, v := range [][2][]byte{ + {bucketKeyDigest, []byte(desc.Digest)}, + {bucketKeyMediaType, []byte(desc.MediaType)}, + {bucketKeySize, sizeEncoded}, + } { + if err := ibkt.Put(v[0], v[1]); err != nil { + return err + } + } + + return nil + }) +} + +func (s *imageStore) List(ctx context.Context) ([]images.Image, error) { + var m []images.Image + + if err := withImagesBucket(s.tx, func(bkt *bolt.Bucket) error { + return bkt.ForEach(func(k, v []byte) error { + var ( + image = images.Image{ + Name: string(k), + } + kbkt = bkt.Bucket(k) + ) + + if err := readImage(&image, kbkt); err != nil { + return err + } + + m = append(m, image) + return nil + }) + }); err != nil { + return nil, err + } + + return m, nil +} + +func (s *imageStore) Delete(ctx context.Context, name string) error { + return withImagesBucket(s.tx, func(bkt *bolt.Bucket) error { + err := bkt.DeleteBucket([]byte(name)) + if err == bolt.ErrBucketNotFound { + return ErrNotFound + } + return err + }) +} + +func readImage(image *images.Image, bkt *bolt.Bucket) error { + return bkt.ForEach(func(k, v []byte) error { + if v == nil { + return nil // skip it? a bkt maybe? + } + + // TODO(stevvooe): This is why we need to use byte values for + // keys, rather than full arrays. + switch string(k) { + case string(bucketKeyDigest): + image.Target.Digest = digest.Digest(v) + case string(bucketKeyMediaType): + image.Target.MediaType = string(v) + case string(bucketKeySize): + image.Target.Size, _ = binary.Varint(v) + } + + return nil + }) +} diff --git a/services/containers/helpers.go b/services/containers/helpers.go index 42321e2f0..525878ac5 100644 --- a/services/containers/helpers.go +++ b/services/containers/helpers.go @@ -3,6 +3,7 @@ package containers import ( api "github.com/containerd/containerd/api/services/containers" "github.com/containerd/containerd/containers" + "github.com/containerd/containerd/metadata" "github.com/gogo/protobuf/types" specs "github.com/opencontainers/runtime-spec/specs-go" "google.golang.org/grpc" @@ -46,9 +47,9 @@ func containerFromProto(containerpb *api.Container) containers.Container { func mapGRPCError(err error, id string) error { switch { - case containers.IsNotFound(err): + case metadata.IsNotFound(err): return grpc.Errorf(codes.NotFound, "container %v not found", id) - case containers.IsExists(err): + case metadata.IsExists(err): return grpc.Errorf(codes.AlreadyExists, "container %v already exists", id) } diff --git a/services/containers/service.go b/services/containers/service.go index b6b82a86b..7de0bbc18 100644 --- a/services/containers/service.go +++ b/services/containers/service.go @@ -4,6 +4,7 @@ import ( "github.com/boltdb/bolt" api "github.com/containerd/containerd/api/services/containers" "github.com/containerd/containerd/containers" + "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/plugin" "github.com/golang/protobuf/ptypes/empty" "golang.org/x/net/context" @@ -136,7 +137,7 @@ func (s *Service) Delete(ctx context.Context, req *api.DeleteContainerRequest) ( } func (s *Service) withStore(ctx context.Context, fn func(ctx context.Context, store containers.Store) error) func(tx *bolt.Tx) error { - return func(tx *bolt.Tx) error { return fn(ctx, containers.NewStore(tx)) } + return func(tx *bolt.Tx) error { return fn(ctx, metadata.NewContainerStore(tx)) } } func (s *Service) withStoreView(ctx context.Context, fn func(ctx context.Context, store containers.Store) error) error { diff --git a/services/execution/service.go b/services/execution/service.go index c4db8efee..e944dd412 100644 --- a/services/execution/service.go +++ b/services/execution/service.go @@ -18,6 +18,7 @@ import ( "github.com/containerd/containerd/content" "github.com/containerd/containerd/images" "github.com/containerd/containerd/log" + "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/mount" "github.com/containerd/containerd/plugin" protobuf "github.com/gogo/protobuf/types" @@ -105,15 +106,15 @@ func (s *Service) Create(ctx context.Context, r *api.CreateRequest) (*api.Create var container containers.Container if err := s.db.View(func(tx *bolt.Tx) error { - store := containers.NewStore(tx) + store := metadata.NewContainerStore(tx) var err error container, err = store.Get(ctx, r.ContainerID) return err }); err != nil { switch { - case containers.IsNotFound(err): + case metadata.IsNotFound(err): return nil, grpc.Errorf(codes.NotFound, "container %v not found", r.ContainerID) - case containers.IsExists(err): + case metadata.IsExists(err): return nil, grpc.Errorf(codes.AlreadyExists, "container %v already exists", r.ContainerID) } diff --git a/services/images/helpers.go b/services/images/helpers.go index 539a918d3..52be324d9 100644 --- a/services/images/helpers.go +++ b/services/images/helpers.go @@ -4,6 +4,7 @@ import ( imagesapi "github.com/containerd/containerd/api/services/images" "github.com/containerd/containerd/api/types/descriptor" "github.com/containerd/containerd/images" + "github.com/containerd/containerd/metadata" ocispec "github.com/opencontainers/image-spec/specs-go/v1" "github.com/pkg/errors" "google.golang.org/grpc" @@ -67,9 +68,9 @@ func rewriteGRPCError(err error) error { switch grpc.Code(errors.Cause(err)) { case codes.AlreadyExists: - return images.ErrExists + return metadata.ErrExists case codes.NotFound: - return images.ErrNotFound + return metadata.ErrNotFound } return err @@ -77,9 +78,9 @@ func rewriteGRPCError(err error) error { func mapGRPCError(err error, id string) error { switch { - case images.IsNotFound(err): + case metadata.IsNotFound(err): return grpc.Errorf(codes.NotFound, "image %v not found", id) - case images.IsExists(err): + case metadata.IsExists(err): return grpc.Errorf(codes.AlreadyExists, "image %v already exists", id) } diff --git a/services/images/service.go b/services/images/service.go index 2310db4e3..f6643637e 100644 --- a/services/images/service.go +++ b/services/images/service.go @@ -4,6 +4,7 @@ import ( "github.com/boltdb/bolt" imagesapi "github.com/containerd/containerd/api/services/images" "github.com/containerd/containerd/images" + "github.com/containerd/containerd/metadata" "github.com/containerd/containerd/plugin" "github.com/golang/protobuf/ptypes/empty" "golang.org/x/net/context" @@ -73,7 +74,7 @@ func (s *Service) Delete(ctx context.Context, req *imagesapi.DeleteRequest) (*em } func (s *Service) withStore(ctx context.Context, fn func(ctx context.Context, store images.Store) error) func(tx *bolt.Tx) error { - return func(tx *bolt.Tx) error { return fn(ctx, images.NewStore(tx)) } + return func(tx *bolt.Tx) error { return fn(ctx, metadata.NewImageStore(tx)) } } func (s *Service) withStoreView(ctx context.Context, fn func(ctx context.Context, store images.Store) error) error {