Merge pull request #1115 from stevvooe/consolidate-errors

errdefs: centralize error handling
This commit is contained in:
Derek McGowan
2017-06-29 15:18:24 -07:00
committed by GitHub
42 changed files with 331 additions and 555 deletions

View File

@@ -3,13 +3,8 @@ package containers
import (
api "github.com/containerd/containerd/api/services/containers/v1"
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/identifiers"
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/namespaces"
"github.com/gogo/protobuf/types"
specs "github.com/opencontainers/runtime-spec/specs-go"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
)
func containersToProto(containers []containers.Container) []api.Container {
@@ -52,18 +47,3 @@ func containerFromProto(containerpb *api.Container) containers.Container {
RootFS: containerpb.RootFS,
}
}
func mapGRPCError(err error, id string) error {
switch {
case metadata.IsNotFound(err):
return grpc.Errorf(codes.NotFound, "container %v not found", id)
case metadata.IsExists(err):
return grpc.Errorf(codes.AlreadyExists, "container %v already exists", id)
case namespaces.IsNamespaceRequired(err):
return grpc.Errorf(codes.InvalidArgument, "namespace required, please set %q header", namespaces.GRPCHeader)
case identifiers.IsInvalid(err):
return grpc.Errorf(codes.InvalidArgument, err.Error())
}
return err
}

View File

@@ -5,6 +5,7 @@ import (
api "github.com/containerd/containerd/api/services/containers/v1"
eventsapi "github.com/containerd/containerd/api/services/events/v1"
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/plugin"
@@ -49,31 +50,30 @@ func (s *Service) Register(server *grpc.Server) error {
func (s *Service) Get(ctx context.Context, req *api.GetContainerRequest) (*api.GetContainerResponse, error) {
var resp api.GetContainerResponse
return &resp, s.withStoreView(ctx, func(ctx context.Context, store containers.Store) error {
return &resp, errdefs.ToGRPC(s.withStoreView(ctx, func(ctx context.Context, store containers.Store) error {
container, err := store.Get(ctx, req.ID)
if err != nil {
return mapGRPCError(err, req.ID)
return err
}
containerpb := containerToProto(&container)
resp.Container = containerpb
return nil
})
}))
}
func (s *Service) List(ctx context.Context, req *api.ListContainersRequest) (*api.ListContainersResponse, error) {
var resp api.ListContainersResponse
return &resp, s.withStoreView(ctx, func(ctx context.Context, store containers.Store) error {
return &resp, errdefs.ToGRPC(s.withStoreView(ctx, func(ctx context.Context, store containers.Store) error {
containers, err := store.List(ctx, req.Filter)
if err != nil {
return mapGRPCError(err, "")
return err
}
resp.Containers = containersToProto(containers)
return nil
})
}))
}
func (s *Service) Create(ctx context.Context, req *api.CreateContainerRequest) (*api.CreateContainerResponse, error) {
@@ -84,14 +84,14 @@ func (s *Service) Create(ctx context.Context, req *api.CreateContainerRequest) (
created, err := store.Create(ctx, container)
if err != nil {
return mapGRPCError(err, req.Container.ID)
return err
}
resp.Container = containerToProto(&created)
return nil
}); err != nil {
return &resp, err
return &resp, errdefs.ToGRPC(err)
}
if err := s.emit(ctx, "/containers/create", &eventsapi.ContainerCreate{
ContainerID: resp.Container.ID,
@@ -115,7 +115,7 @@ func (s *Service) Update(ctx context.Context, req *api.UpdateContainerRequest) (
current, err := store.Get(ctx, container.ID)
if err != nil {
return mapGRPCError(err, container.ID)
return err
}
if current.ID != container.ID {
@@ -150,14 +150,14 @@ func (s *Service) Update(ctx context.Context, req *api.UpdateContainerRequest) (
created, err := store.Update(ctx, container)
if err != nil {
return mapGRPCError(err, req.Container.ID)
return err
}
resp.Container = containerToProto(&created)
return nil
}); err != nil {
return &resp, err
return &resp, errdefs.ToGRPC(err)
}
if err := s.emit(ctx, "/containers/update", &eventsapi.ContainerUpdate{
@@ -174,9 +174,9 @@ func (s *Service) Update(ctx context.Context, req *api.UpdateContainerRequest) (
func (s *Service) Delete(ctx context.Context, req *api.DeleteContainerRequest) (*empty.Empty, error) {
if err := s.withStoreUpdate(ctx, func(ctx context.Context, store containers.Store) error {
return mapGRPCError(store.Delete(ctx, req.ID), req.ID)
return store.Delete(ctx, req.ID)
}); err != nil {
return &empty.Empty{}, mapGRPCError(err, req.ID)
return &empty.Empty{}, errdefs.ToGRPC(err)
}
if err := s.emit(ctx, "/containers/delete", &eventsapi.ContainerDelete{

View File

@@ -1,33 +0,0 @@
package content
import (
"github.com/containerd/containerd/content"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
)
func rewriteGRPCError(err error) error {
switch grpc.Code(errors.Cause(err)) {
case codes.AlreadyExists:
return content.ErrExists(grpc.ErrorDesc(err))
case codes.NotFound:
return content.ErrNotFound(grpc.ErrorDesc(err))
case codes.Unavailable:
return content.ErrLocked(grpc.ErrorDesc(err))
}
return err
}
func serverErrorToGRPC(err error, id string) error {
switch {
case content.IsNotFound(err):
return grpc.Errorf(codes.NotFound, "%v: not found", id)
case content.IsExists(err):
return grpc.Errorf(codes.AlreadyExists, "%v: exists", id)
case content.IsLocked(err):
return grpc.Errorf(codes.Unavailable, "%v: locked", id)
}
return err
}

View File

@@ -8,6 +8,7 @@ import (
api "github.com/containerd/containerd/api/services/content/v1"
eventsapi "github.com/containerd/containerd/api/services/events/v1"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/plugin"
@@ -66,7 +67,7 @@ func (s *Service) Info(ctx context.Context, req *api.InfoRequest) (*api.InfoResp
bi, err := s.store.Info(ctx, req.Digest)
if err != nil {
return nil, serverErrorToGRPC(err, req.Digest.String())
return nil, errdefs.ToGRPC(err)
}
return &api.InfoResponse{
@@ -125,7 +126,7 @@ func (s *Service) Delete(ctx context.Context, req *api.DeleteContentRequest) (*e
}
if err := s.store.Delete(ctx, req.Digest); err != nil {
return nil, serverErrorToGRPC(err, req.Digest.String())
return nil, errdefs.ToGRPC(err)
}
if err := s.emit(ctx, "/content/delete", &eventsapi.ContentDelete{
@@ -144,12 +145,12 @@ func (s *Service) Read(req *api.ReadContentRequest, session api.Content_ReadServ
oi, err := s.store.Info(session.Context(), req.Digest)
if err != nil {
return serverErrorToGRPC(err, req.Digest.String())
return errdefs.ToGRPC(err)
}
rc, err := s.store.Reader(session.Context(), req.Digest)
if err != nil {
return serverErrorToGRPC(err, req.Digest.String())
return errdefs.ToGRPC(err)
}
defer rc.Close() // TODO(stevvooe): Cache these file descriptors for performance.
@@ -217,7 +218,7 @@ func (rw *readResponseWriter) Write(p []byte) (n int, err error) {
func (s *Service) Status(ctx context.Context, req *api.StatusRequest) (*api.StatusResponse, error) {
statuses, err := s.store.Status(ctx, req.Filter)
if err != nil {
return nil, serverErrorToGRPC(err, req.Filter)
return nil, errdefs.ToGRPCf(err, "could not get status for filter %q", req.Filter)
}
var resp api.StatusResponse
@@ -295,7 +296,7 @@ func (s *Service) Write(session api.Content_WriteServer) (err error) {
// this action locks the writer for the session.
wr, err := s.store.Writer(ctx, ref, total, expected)
if err != nil {
return serverErrorToGRPC(err, ref)
return errdefs.ToGRPC(err)
}
defer wr.Close()
@@ -303,7 +304,7 @@ func (s *Service) Write(session api.Content_WriteServer) (err error) {
msg.Action = req.Action
ws, err := wr.Status()
if err != nil {
return serverErrorToGRPC(err, ref)
return errdefs.ToGRPC(err)
}
msg.Offset = ws.Offset // always set the offset.
@@ -414,7 +415,7 @@ func (s *Service) Write(session api.Content_WriteServer) (err error) {
func (s *Service) Abort(ctx context.Context, req *api.AbortRequest) (*empty.Empty, error) {
if err := s.store.Abort(ctx, req.Ref); err != nil {
return nil, serverErrorToGRPC(err, req.Ref)
return nil, errdefs.ToGRPC(err)
}
return &empty.Empty{}, nil

View File

@@ -6,6 +6,7 @@ import (
contentapi "github.com/containerd/containerd/api/services/content/v1"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
digest "github.com/opencontainers/go-digest"
)
@@ -24,7 +25,7 @@ func (rs *remoteStore) Info(ctx context.Context, dgst digest.Digest) (content.In
Digest: dgst,
})
if err != nil {
return content.Info{}, rewriteGRPCError(err)
return content.Info{}, errdefs.FromGRPC(err)
}
return content.Info{
@@ -37,14 +38,14 @@ func (rs *remoteStore) Info(ctx context.Context, dgst digest.Digest) (content.In
func (rs *remoteStore) Walk(ctx context.Context, fn content.WalkFunc) error {
session, err := rs.client.List(ctx, &contentapi.ListContentRequest{})
if err != nil {
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
for {
msg, err := session.Recv()
if err != nil {
if err != io.EOF {
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
break
@@ -68,7 +69,7 @@ func (rs *remoteStore) Delete(ctx context.Context, dgst digest.Digest) error {
if _, err := rs.client.Delete(ctx, &contentapi.DeleteContentRequest{
Digest: dgst,
}); err != nil {
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
return nil
@@ -98,7 +99,7 @@ func (rs *remoteStore) Status(ctx context.Context, filter string) ([]content.Sta
Filter: filter,
})
if err != nil {
return nil, rewriteGRPCError(err)
return nil, errdefs.FromGRPC(err)
}
var statuses []content.Status
@@ -119,7 +120,7 @@ func (rs *remoteStore) Status(ctx context.Context, filter string) ([]content.Sta
func (rs *remoteStore) Writer(ctx context.Context, ref string, size int64, expected digest.Digest) (content.Writer, error) {
wrclient, offset, err := rs.negotiate(ctx, ref, size, expected)
if err != nil {
return nil, rewriteGRPCError(err)
return nil, errdefs.FromGRPC(err)
}
return &remoteWriter{
@@ -134,7 +135,7 @@ func (rs *remoteStore) Abort(ctx context.Context, ref string) error {
if _, err := rs.client.Abort(ctx, &contentapi.AbortRequest{
Ref: ref,
}); err != nil {
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
return nil

View File

@@ -5,6 +5,7 @@ import (
contentapi "github.com/containerd/containerd/api/services/content/v1"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
digest "github.com/opencontainers/go-digest"
"github.com/pkg/errors"
)
@@ -86,7 +87,7 @@ func (rw *remoteWriter) Commit(size int64, expected digest.Digest) error {
Expected: expected,
})
if err != nil {
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
if size != 0 && resp.Offset != size {

View File

@@ -4,6 +4,7 @@ import (
"context"
imagesapi "github.com/containerd/containerd/api/services/images/v1"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/images"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)
@@ -28,7 +29,7 @@ func (s *remoteStore) Update(ctx context.Context, name string, desc ocispec.Desc
},
})
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
func (s *remoteStore) Get(ctx context.Context, name string) (images.Image, error) {
@@ -36,7 +37,7 @@ func (s *remoteStore) Get(ctx context.Context, name string) (images.Image, error
Name: name,
})
if err != nil {
return images.Image{}, rewriteGRPCError(err)
return images.Image{}, errdefs.FromGRPC(err)
}
return imageFromProto(resp.Image), nil
@@ -45,7 +46,7 @@ func (s *remoteStore) Get(ctx context.Context, name string) (images.Image, error
func (s *remoteStore) List(ctx context.Context) ([]images.Image, error) {
resp, err := s.client.List(ctx, &imagesapi.ListImagesRequest{})
if err != nil {
return nil, rewriteGRPCError(err)
return nil, errdefs.FromGRPC(err)
}
return imagesFromProto(resp.Images), nil
@@ -56,5 +57,5 @@ func (s *remoteStore) Delete(ctx context.Context, name string) error {
Name: name,
})
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}

View File

@@ -3,14 +3,8 @@ package images
import (
imagesapi "github.com/containerd/containerd/api/services/images/v1"
"github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/identifiers"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/namespaces"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
)
func imagesToProto(images []images.Image) []imagesapi.Image {
@@ -62,33 +56,3 @@ func descToProto(desc *ocispec.Descriptor) types.Descriptor {
Digest: desc.Digest,
}
}
func rewriteGRPCError(err error) error {
if err == nil {
return err
}
switch grpc.Code(errors.Cause(err)) {
case codes.AlreadyExists:
return metadata.ErrExists(grpc.ErrorDesc(err))
case codes.NotFound:
return metadata.ErrNotFound(grpc.ErrorDesc(err))
}
return err
}
func mapGRPCError(err error, id string) error {
switch {
case metadata.IsNotFound(err):
return grpc.Errorf(codes.NotFound, "image %v not found", id)
case metadata.IsExists(err):
return grpc.Errorf(codes.AlreadyExists, "image %v already exists", id)
case namespaces.IsNamespaceRequired(err):
return grpc.Errorf(codes.InvalidArgument, "namespace required, please set %q header", namespaces.GRPCHeader)
case identifiers.IsInvalid(err):
return grpc.Errorf(codes.InvalidArgument, err.Error())
}
return err
}

View File

@@ -4,6 +4,7 @@ import (
"github.com/boltdb/bolt"
eventsapi "github.com/containerd/containerd/api/services/events/v1"
imagesapi "github.com/containerd/containerd/api/services/images/v1"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/metadata"
@@ -51,22 +52,22 @@ func (s *Service) Register(server *grpc.Server) error {
func (s *Service) Get(ctx context.Context, req *imagesapi.GetImageRequest) (*imagesapi.GetImageResponse, error) {
var resp imagesapi.GetImageResponse
return &resp, s.withStoreView(ctx, func(ctx context.Context, store images.Store) error {
return &resp, errdefs.ToGRPC(s.withStoreView(ctx, func(ctx context.Context, store images.Store) error {
image, err := store.Get(ctx, req.Name)
if err != nil {
return mapGRPCError(err, req.Name)
return err
}
imagepb := imageToProto(&image)
resp.Image = &imagepb
return nil
})
}))
}
func (s *Service) Update(ctx context.Context, req *imagesapi.UpdateImageRequest) (*imagesapi.UpdateImageResponse, error) {
if err := s.withStoreUpdate(ctx, func(ctx context.Context, store images.Store) error {
return mapGRPCError(store.Update(ctx, req.Image.Name, descFromProto(&req.Image.Target)), req.Image.Name)
return store.Update(ctx, req.Image.Name, descFromProto(&req.Image.Target))
}); err != nil {
return nil, err
return nil, errdefs.ToGRPC(err)
}
if err := s.emit(ctx, "/images/update", &eventsapi.ImageUpdate{
@@ -88,7 +89,7 @@ func (s *Service) List(ctx context.Context, _ *imagesapi.ListImagesRequest) (*im
return &resp, s.withStoreView(ctx, func(ctx context.Context, store images.Store) error {
images, err := store.List(ctx)
if err != nil {
return mapGRPCError(err, "")
return errdefs.ToGRPC(err)
}
resp.Images = imagesToProto(images)
@@ -98,7 +99,7 @@ func (s *Service) List(ctx context.Context, _ *imagesapi.ListImagesRequest) (*im
func (s *Service) Delete(ctx context.Context, req *imagesapi.DeleteImageRequest) (*empty.Empty, error) {
if err := s.withStoreUpdate(ctx, func(ctx context.Context, store images.Store) error {
return mapGRPCError(store.Delete(ctx, req.Name), req.Name)
return errdefs.ToGRPC(store.Delete(ctx, req.Name))
}); err != nil {
return nil, err
}

View File

@@ -5,6 +5,7 @@ import (
"strings"
api "github.com/containerd/containerd/api/services/namespaces/v1"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/namespaces"
"github.com/gogo/protobuf/types"
)
@@ -27,7 +28,7 @@ func (r *remote) Create(ctx context.Context, namespace string, labels map[string
_, err := r.client.Create(ctx, &req)
if err != nil {
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
return nil
@@ -39,7 +40,7 @@ func (r *remote) Labels(ctx context.Context, namespace string) (map[string]strin
resp, err := r.client.Get(ctx, &req)
if err != nil {
return nil, rewriteGRPCError(err)
return nil, errdefs.FromGRPC(err)
}
return resp.Namespace.Labels, nil
@@ -59,7 +60,7 @@ func (r *remote) SetLabel(ctx context.Context, namespace, key, value string) err
_, err := r.client.Update(ctx, &req)
if err != nil {
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
return nil
@@ -70,7 +71,7 @@ func (r *remote) List(ctx context.Context) ([]string, error) {
resp, err := r.client.List(ctx, &req)
if err != nil {
return nil, rewriteGRPCError(err)
return nil, errdefs.FromGRPC(err)
}
var namespaces []string
@@ -88,7 +89,7 @@ func (r *remote) Delete(ctx context.Context, namespace string) error {
req.Name = namespace
_, err := r.client.Delete(ctx, &req)
if err != nil {
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
return nil

View File

@@ -1,36 +0,0 @@
package namespaces
import (
"github.com/containerd/containerd/metadata"
"github.com/pkg/errors"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
)
func mapGRPCError(err error, id string) error {
switch {
case metadata.IsNotFound(err):
return grpc.Errorf(codes.NotFound, "namespace %v not found", id)
case metadata.IsExists(err):
return grpc.Errorf(codes.AlreadyExists, "namespace %v already exists", id)
case metadata.IsNotEmpty(err):
return grpc.Errorf(codes.FailedPrecondition, "namespace %v must be empty", id)
}
return err
}
func rewriteGRPCError(err error) error {
if err == nil {
return err
}
switch grpc.Code(errors.Cause(err)) {
case codes.AlreadyExists:
return metadata.ErrExists(grpc.ErrorDesc(err))
case codes.NotFound:
return metadata.ErrNotFound(grpc.ErrorDesc(err))
}
return err
}

View File

@@ -6,6 +6,7 @@ import (
"github.com/boltdb/bolt"
eventsapi "github.com/containerd/containerd/api/services/events/v1"
api "github.com/containerd/containerd/api/services/namespaces/v1"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/metadata"
"github.com/containerd/containerd/namespaces"
@@ -59,7 +60,7 @@ func (s *Service) Get(ctx context.Context, req *api.GetNamespaceRequest) (*api.G
return &resp, s.withStoreView(ctx, func(ctx context.Context, store namespaces.Store) error {
labels, err := store.Labels(ctx, req.Name)
if err != nil {
return mapGRPCError(err, req.Name)
return errdefs.ToGRPC(err)
}
resp.Namespace = api.Namespace{
@@ -85,7 +86,7 @@ func (s *Service) List(ctx context.Context, req *api.ListNamespacesRequest) (*ap
if err != nil {
// In general, this should be unlikely, since we are holding a
// transaction to service this request.
return mapGRPCError(err, namespace)
return errdefs.ToGRPC(err)
}
resp.Namespaces = append(resp.Namespaces, api.Namespace{
@@ -103,7 +104,7 @@ func (s *Service) Create(ctx context.Context, req *api.CreateNamespaceRequest) (
if err := s.withStoreUpdate(ctx, func(ctx context.Context, store namespaces.Store) error {
if err := store.Create(ctx, req.Namespace.Name, req.Namespace.Labels); err != nil {
return mapGRPCError(err, req.Namespace.Name)
return errdefs.ToGRPC(err)
}
for k, v := range req.Namespace.Labels {
@@ -149,7 +150,7 @@ func (s *Service) Update(ctx context.Context, req *api.UpdateNamespaceRequest) (
// get current set of labels
labels, err := store.Labels(ctx, req.Namespace.Name)
if err != nil {
return mapGRPCError(err, req.Namespace.Name)
return errdefs.ToGRPC(err)
}
for k := range labels {
@@ -183,7 +184,7 @@ func (s *Service) Update(ctx context.Context, req *api.UpdateNamespaceRequest) (
func (s *Service) Delete(ctx context.Context, req *api.DeleteNamespaceRequest) (*empty.Empty, error) {
if err := s.withStoreUpdate(ctx, func(ctx context.Context, store namespaces.Store) error {
return mapGRPCError(store.Delete(ctx, req.Name), req.Name)
return errdefs.ToGRPC(store.Delete(ctx, req.Name))
}); err != nil {
return &empty.Empty{}, err
}

View File

@@ -3,16 +3,12 @@ package snapshot
import (
"context"
"io"
"strings"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
snapshotapi "github.com/containerd/containerd/api/services/snapshot/v1"
"github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/mount"
"github.com/containerd/containerd/snapshot"
"github.com/pkg/errors"
)
// NewSnapshotterFromClient returns a new Snapshotter which communicates
@@ -30,7 +26,7 @@ type remoteSnapshotter struct {
func (r *remoteSnapshotter) Stat(ctx context.Context, key string) (snapshot.Info, error) {
resp, err := r.client.Stat(ctx, &snapshotapi.StatSnapshotRequest{Key: key})
if err != nil {
return snapshot.Info{}, rewriteGRPCError(err)
return snapshot.Info{}, errdefs.FromGRPC(err)
}
return toInfo(resp.Info), nil
}
@@ -38,7 +34,7 @@ func (r *remoteSnapshotter) Stat(ctx context.Context, key string) (snapshot.Info
func (r *remoteSnapshotter) Usage(ctx context.Context, key string) (snapshot.Usage, error) {
resp, err := r.client.Usage(ctx, &snapshotapi.UsageRequest{Key: key})
if err != nil {
return snapshot.Usage{}, rewriteGRPCError(err)
return snapshot.Usage{}, errdefs.FromGRPC(err)
}
return toUsage(resp), nil
}
@@ -46,7 +42,7 @@ func (r *remoteSnapshotter) Usage(ctx context.Context, key string) (snapshot.Usa
func (r *remoteSnapshotter) Mounts(ctx context.Context, key string) ([]mount.Mount, error) {
resp, err := r.client.Mounts(ctx, &snapshotapi.MountsRequest{Key: key})
if err != nil {
return nil, rewriteGRPCError(err)
return nil, errdefs.FromGRPC(err)
}
return toMounts(resp.Mounts), nil
}
@@ -54,7 +50,7 @@ func (r *remoteSnapshotter) Mounts(ctx context.Context, key string) ([]mount.Mou
func (r *remoteSnapshotter) Prepare(ctx context.Context, key, parent string) ([]mount.Mount, error) {
resp, err := r.client.Prepare(ctx, &snapshotapi.PrepareSnapshotRequest{Key: key, Parent: parent})
if err != nil {
return nil, rewriteGRPCError(err)
return nil, errdefs.FromGRPC(err)
}
return toMounts(resp.Mounts), nil
}
@@ -62,7 +58,7 @@ func (r *remoteSnapshotter) Prepare(ctx context.Context, key, parent string) ([]
func (r *remoteSnapshotter) View(ctx context.Context, key, parent string) ([]mount.Mount, error) {
resp, err := r.client.View(ctx, &snapshotapi.ViewSnapshotRequest{Key: key, Parent: parent})
if err != nil {
return nil, rewriteGRPCError(err)
return nil, errdefs.FromGRPC(err)
}
return toMounts(resp.Mounts), nil
}
@@ -72,18 +68,18 @@ func (r *remoteSnapshotter) Commit(ctx context.Context, name, key string) error
Name: name,
Key: key,
})
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
func (r *remoteSnapshotter) Remove(ctx context.Context, key string) error {
_, err := r.client.Remove(ctx, &snapshotapi.RemoveSnapshotRequest{Key: key})
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
func (r *remoteSnapshotter) Walk(ctx context.Context, fn func(context.Context, snapshot.Info) error) error {
sc, err := r.client.List(ctx, &snapshotapi.ListSnapshotsRequest{})
if err != nil {
rewriteGRPCError(err)
errdefs.FromGRPC(err)
}
for {
resp, err := sc.Recv()
@@ -91,7 +87,7 @@ func (r *remoteSnapshotter) Walk(ctx context.Context, fn func(context.Context, s
if err == io.EOF {
return nil
}
return rewriteGRPCError(err)
return errdefs.FromGRPC(err)
}
if resp == nil {
return nil
@@ -104,25 +100,6 @@ func (r *remoteSnapshotter) Walk(ctx context.Context, fn func(context.Context, s
}
}
func rewriteGRPCError(err error) error {
switch grpc.Code(errors.Cause(err)) {
case codes.AlreadyExists:
return snapshot.ErrSnapshotExist
case codes.NotFound:
return snapshot.ErrSnapshotNotExist
case codes.FailedPrecondition:
desc := grpc.ErrorDesc(errors.Cause(err))
if strings.Contains(desc, snapshot.ErrSnapshotNotActive.Error()) {
return snapshot.ErrSnapshotNotActive
}
if strings.Contains(desc, snapshot.ErrSnapshotNotCommitted.Error()) {
return snapshot.ErrSnapshotNotCommitted
}
}
return err
}
func toKind(kind snapshotapi.Kind) snapshot.Kind {
if kind == snapshotapi.KindActive {
return snapshot.KindActive

View File

@@ -6,6 +6,7 @@ import (
eventsapi "github.com/containerd/containerd/api/services/events/v1"
snapshotapi "github.com/containerd/containerd/api/services/snapshot/v1"
"github.com/containerd/containerd/api/types"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/log"
"github.com/containerd/containerd/mount"
@@ -14,7 +15,6 @@ import (
protoempty "github.com/golang/protobuf/ptypes/empty"
"golang.org/x/net/context"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
)
func init() {
@@ -60,7 +60,7 @@ func (s *service) Prepare(ctx context.Context, pr *snapshotapi.PrepareSnapshotRe
// TODO: Lookup snapshot id from metadata store
mounts, err := s.snapshotter.Prepare(ctx, pr.Key, pr.Parent)
if err != nil {
return nil, grpcError(err)
return nil, errdefs.ToGRPC(err)
}
if err := s.emit(ctx, "/snapshot/prepare", &eventsapi.SnapshotPrepare{
@@ -80,7 +80,7 @@ func (s *service) View(ctx context.Context, pr *snapshotapi.ViewSnapshotRequest)
// TODO: Lookup snapshot id from metadata store
mounts, err := s.snapshotter.View(ctx, pr.Key, pr.Parent)
if err != nil {
return nil, grpcError(err)
return nil, errdefs.ToGRPC(err)
}
return &snapshotapi.ViewSnapshotResponse{
Mounts: fromMounts(mounts),
@@ -93,7 +93,7 @@ func (s *service) Mounts(ctx context.Context, mr *snapshotapi.MountsRequest) (*s
// TODO: Lookup snapshot id from metadata store
mounts, err := s.snapshotter.Mounts(ctx, mr.Key)
if err != nil {
return nil, grpcError(err)
return nil, errdefs.ToGRPC(err)
}
return &snapshotapi.MountsResponse{
Mounts: fromMounts(mounts),
@@ -105,7 +105,7 @@ func (s *service) Commit(ctx context.Context, cr *snapshotapi.CommitSnapshotRequ
// TODO: Apply namespace
// TODO: Lookup snapshot id from metadata store
if err := s.snapshotter.Commit(ctx, cr.Name, cr.Key); err != nil {
return nil, grpcError(err)
return nil, errdefs.ToGRPC(err)
}
if err := s.emit(ctx, "/snapshot/commit", &eventsapi.SnapshotCommit{
@@ -122,7 +122,7 @@ func (s *service) Remove(ctx context.Context, rr *snapshotapi.RemoveSnapshotRequ
// TODO: Apply namespace
// TODO: Lookup snapshot id from metadata store
if err := s.snapshotter.Remove(ctx, rr.Key); err != nil {
return nil, grpcError(err)
return nil, errdefs.ToGRPC(err)
}
if err := s.emit(ctx, "/snapshot/remove", &eventsapi.SnapshotRemove{
@@ -138,7 +138,7 @@ func (s *service) Stat(ctx context.Context, sr *snapshotapi.StatSnapshotRequest)
// TODO: Apply namespace
info, err := s.snapshotter.Stat(ctx, sr.Key)
if err != nil {
return nil, grpcError(err)
return nil, errdefs.ToGRPC(err)
}
return &snapshotapi.StatSnapshotResponse{Info: fromInfo(info)}, nil
@@ -184,26 +184,12 @@ func (s *service) Usage(ctx context.Context, ur *snapshotapi.UsageRequest) (*sna
// TODO: Apply namespace
usage, err := s.snapshotter.Usage(ctx, ur.Key)
if err != nil {
return nil, grpcError(err)
return nil, errdefs.ToGRPC(err)
}
return fromUsage(usage), nil
}
func grpcError(err error) error {
if snapshot.IsNotExist(err) {
return grpc.Errorf(codes.NotFound, err.Error())
}
if snapshot.IsExist(err) {
return grpc.Errorf(codes.AlreadyExists, err.Error())
}
if snapshot.IsNotActive(err) || snapshot.IsNotCommitted(err) {
return grpc.Errorf(codes.FailedPrecondition, err.Error())
}
return err
}
func fromKind(kind snapshot.Kind) snapshotapi.Kind {
if kind == snapshot.KindActive {
return snapshotapi.KindActive

View File

@@ -16,6 +16,7 @@ import (
"github.com/containerd/containerd/archive"
"github.com/containerd/containerd/containers"
"github.com/containerd/containerd/content"
"github.com/containerd/containerd/errdefs"
"github.com/containerd/containerd/events"
"github.com/containerd/containerd/images"
"github.com/containerd/containerd/log"
@@ -37,6 +38,9 @@ var (
empty = &google_protobuf.Empty{}
)
// TODO(stevvooe): Clean up error mapping to avoid double mapping certain
// errors within helper methods.
func init() {
plugin.Register(&plugin.Registration{
Type: plugin.GRPCPlugin,
@@ -115,14 +119,7 @@ func (s *Service) Create(ctx context.Context, r *api.CreateTaskRequest) (*api.Cr
container, err := s.getContainer(ctx, r.ContainerID)
if err != nil {
switch {
case metadata.IsNotFound(err):
return nil, grpc.Errorf(codes.NotFound, "container %v not found", r.ContainerID)
case metadata.IsExists(err):
return nil, grpc.Errorf(codes.AlreadyExists, "container %v already exists", r.ContainerID)
}
return nil, err
return nil, errdefs.ToGRPC(err)
}
opts := runtime.CreateOpts{
@@ -484,7 +481,7 @@ func (s *Service) getContainer(ctx context.Context, id string) (containers.Conta
container, err = store.Get(ctx, id)
return err
}); err != nil {
return containers.Container{}, err
return containers.Container{}, errdefs.ToGRPC(err)
}
return container, nil
@@ -493,12 +490,12 @@ func (s *Service) getContainer(ctx context.Context, id string) (containers.Conta
func (s *Service) getTask(ctx context.Context, id string) (runtime.Task, error) {
container, err := s.getContainer(ctx, id)
if err != nil {
return nil, grpc.Errorf(codes.InvalidArgument, "task %v not found: %s", id, err.Error())
return nil, err
}
runtime, err := s.getRuntime(container.Runtime.Name)
if err != nil {
return nil, grpc.Errorf(codes.NotFound, "task %v not found: %s", id, err.Error())
return nil, errdefs.ToGRPCf(err, "runtime for task %v", id)
}
t, err := runtime.Get(ctx, id)
@@ -512,7 +509,7 @@ func (s *Service) getTask(ctx context.Context, id string) (runtime.Task, error)
func (s *Service) getRuntime(name string) (runtime.Runtime, error) {
runtime, ok := s.runtimes[name]
if !ok {
return nil, fmt.Errorf("unknown runtime %q", name)
return nil, grpc.Errorf(codes.NotFound, "unknown runtime %q", name)
}
return runtime, nil
}