|
|
|
|
@@ -19,6 +19,7 @@ import (
|
|
|
|
|
"golang.org/x/net/context"
|
|
|
|
|
"google.golang.org/grpc"
|
|
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
|
"google.golang.org/grpc/status"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type service struct {
|
|
|
|
|
@@ -68,7 +69,7 @@ func (s *service) Register(server *grpc.Server) error {
|
|
|
|
|
|
|
|
|
|
func (s *service) Info(ctx context.Context, req *api.InfoRequest) (*api.InfoResponse, error) {
|
|
|
|
|
if err := req.Digest.Validate(); err != nil {
|
|
|
|
|
return nil, grpc.Errorf(codes.InvalidArgument, "%q failed validation", req.Digest)
|
|
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "%q failed validation", req.Digest)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bi, err := s.store.Info(ctx, req.Digest)
|
|
|
|
|
@@ -83,7 +84,7 @@ func (s *service) Info(ctx context.Context, req *api.InfoRequest) (*api.InfoResp
|
|
|
|
|
|
|
|
|
|
func (s *service) Update(ctx context.Context, req *api.UpdateRequest) (*api.UpdateResponse, error) {
|
|
|
|
|
if err := req.Info.Digest.Validate(); err != nil {
|
|
|
|
|
return nil, grpc.Errorf(codes.InvalidArgument, "%q failed validation", req.Info.Digest)
|
|
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "%q failed validation", req.Info.Digest)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
info, err := s.store.Update(ctx, infoFromGRPC(req.Info), req.UpdateMask.GetPaths()...)
|
|
|
|
|
@@ -140,7 +141,7 @@ func (s *service) List(req *api.ListContentRequest, session api.Content_ListServ
|
|
|
|
|
|
|
|
|
|
func (s *service) Delete(ctx context.Context, req *api.DeleteContentRequest) (*ptypes.Empty, error) {
|
|
|
|
|
if err := req.Digest.Validate(); err != nil {
|
|
|
|
|
return nil, grpc.Errorf(codes.InvalidArgument, err.Error())
|
|
|
|
|
return nil, status.Errorf(codes.InvalidArgument, err.Error())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := s.store.Delete(ctx, req.Digest); err != nil {
|
|
|
|
|
@@ -158,7 +159,7 @@ func (s *service) Delete(ctx context.Context, req *api.DeleteContentRequest) (*p
|
|
|
|
|
|
|
|
|
|
func (s *service) Read(req *api.ReadContentRequest, session api.Content_ReadServer) error {
|
|
|
|
|
if err := req.Digest.Validate(); err != nil {
|
|
|
|
|
return grpc.Errorf(codes.InvalidArgument, "%v: %v", req.Digest, err)
|
|
|
|
|
return status.Errorf(codes.InvalidArgument, "%v: %v", req.Digest, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
oi, err := s.store.Info(session.Context(), req.Digest)
|
|
|
|
|
@@ -191,7 +192,7 @@ func (s *service) Read(req *api.ReadContentRequest, session api.Content_ReadServ
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if offset+size > oi.Size {
|
|
|
|
|
return grpc.Errorf(codes.OutOfRange, "read past object length %v bytes", oi.Size)
|
|
|
|
|
return status.Errorf(codes.OutOfRange, "read past object length %v bytes", oi.Size)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if _, err := io.CopyBuffer(
|
|
|
|
|
@@ -277,7 +278,7 @@ func (s *service) Write(session api.Content_WriteServer) (err error) {
|
|
|
|
|
defer func(msg *api.WriteContentResponse) {
|
|
|
|
|
// pump through the last message if no error was encountered
|
|
|
|
|
if err != nil {
|
|
|
|
|
if grpc.Code(err) != codes.AlreadyExists {
|
|
|
|
|
if s, ok := status.FromError(err); ok && s.Code() != codes.AlreadyExists {
|
|
|
|
|
// TODO(stevvooe): Really need a log line here to track which
|
|
|
|
|
// errors are actually causing failure on the server side. May want
|
|
|
|
|
// to configure the service with an interceptor to make this work
|
|
|
|
|
@@ -302,7 +303,7 @@ func (s *service) Write(session api.Content_WriteServer) (err error) {
|
|
|
|
|
ref = req.Ref
|
|
|
|
|
|
|
|
|
|
if ref == "" {
|
|
|
|
|
return grpc.Errorf(codes.InvalidArgument, "first message must have a reference")
|
|
|
|
|
return status.Errorf(codes.InvalidArgument, "first message must have a reference")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fields := logrus.Fields{
|
|
|
|
|
@@ -356,7 +357,7 @@ func (s *service) Write(session api.Content_WriteServer) (err error) {
|
|
|
|
|
// users use the same writer style for each with a minimum of overhead.
|
|
|
|
|
if req.Expected != "" {
|
|
|
|
|
if expected != "" && expected != req.Expected {
|
|
|
|
|
return grpc.Errorf(codes.InvalidArgument, "inconsistent digest provided: %v != %v", req.Expected, expected)
|
|
|
|
|
return status.Errorf(codes.InvalidArgument, "inconsistent digest provided: %v != %v", req.Expected, expected)
|
|
|
|
|
}
|
|
|
|
|
expected = req.Expected
|
|
|
|
|
|
|
|
|
|
@@ -365,7 +366,7 @@ func (s *service) Write(session api.Content_WriteServer) (err error) {
|
|
|
|
|
log.G(ctx).WithError(err).Error("failed to abort write")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return grpc.Errorf(codes.AlreadyExists, "blob with expected digest %v exists", req.Expected)
|
|
|
|
|
return status.Errorf(codes.AlreadyExists, "blob with expected digest %v exists", req.Expected)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -373,7 +374,7 @@ func (s *service) Write(session api.Content_WriteServer) (err error) {
|
|
|
|
|
// Update the expected total. Typically, this could be seen at
|
|
|
|
|
// negotiation time or on a commit message.
|
|
|
|
|
if total > 0 && req.Total != total {
|
|
|
|
|
return grpc.Errorf(codes.InvalidArgument, "inconsistent total provided: %v != %v", req.Total, total)
|
|
|
|
|
return status.Errorf(codes.InvalidArgument, "inconsistent total provided: %v != %v", req.Total, total)
|
|
|
|
|
}
|
|
|
|
|
total = req.Total
|
|
|
|
|
}
|
|
|
|
|
@@ -388,7 +389,7 @@ func (s *service) Write(session api.Content_WriteServer) (err error) {
|
|
|
|
|
if req.Offset > 0 {
|
|
|
|
|
// validate the offset if provided
|
|
|
|
|
if req.Offset != ws.Offset {
|
|
|
|
|
return grpc.Errorf(codes.OutOfRange, "write @%v must occur at current offset %v", req.Offset, ws.Offset)
|
|
|
|
|
return status.Errorf(codes.OutOfRange, "write @%v must occur at current offset %v", req.Offset, ws.Offset)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -411,7 +412,7 @@ func (s *service) Write(session api.Content_WriteServer) (err error) {
|
|
|
|
|
if n != len(req.Data) {
|
|
|
|
|
// TODO(stevvooe): Perhaps, we can recover this by including it
|
|
|
|
|
// in the offset on the write return.
|
|
|
|
|
return grpc.Errorf(codes.DataLoss, "wrote %v of %v bytes", n, len(req.Data))
|
|
|
|
|
return status.Errorf(codes.DataLoss, "wrote %v of %v bytes", n, len(req.Data))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
msg.Offset += int64(n)
|
|
|
|
|
|