Matching support is now implemented in the platforms package. The `Parse` function now returns a matcher object that can be used to match OCI platform specifications. We define this as an interface to allow the creation of helpers oriented around platform selection. Signed-off-by: Stephen J Day <stephen.day@docker.com>
		
			
				
	
	
		
			109 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package errdefs
 | 
						|
 | 
						|
import (
 | 
						|
	"strings"
 | 
						|
 | 
						|
	"github.com/pkg/errors"
 | 
						|
	"google.golang.org/grpc"
 | 
						|
	"google.golang.org/grpc/codes"
 | 
						|
	"google.golang.org/grpc/status"
 | 
						|
)
 | 
						|
 | 
						|
// ToGRPC will attempt to map the backend containerd error into a grpc error,
 | 
						|
// using the original error message as a description.
 | 
						|
//
 | 
						|
// Further information may be extracted from certain errors depending on their
 | 
						|
// type.
 | 
						|
//
 | 
						|
// If the error is unmapped, the original error will be returned to be handled
 | 
						|
// by the regular grpc error handling stack.
 | 
						|
func ToGRPC(err error) error {
 | 
						|
	if err == nil {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	if isGRPCError(err) {
 | 
						|
		// error has already been mapped to grpc
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	switch {
 | 
						|
	case IsInvalidArgument(err):
 | 
						|
		return grpc.Errorf(codes.InvalidArgument, err.Error())
 | 
						|
	case IsNotFound(err):
 | 
						|
		return grpc.Errorf(codes.NotFound, err.Error())
 | 
						|
	case IsAlreadyExists(err):
 | 
						|
		return grpc.Errorf(codes.AlreadyExists, err.Error())
 | 
						|
	case IsFailedPrecondition(err):
 | 
						|
		return grpc.Errorf(codes.FailedPrecondition, err.Error())
 | 
						|
	case IsUnavailable(err):
 | 
						|
		return grpc.Errorf(codes.Unavailable, err.Error())
 | 
						|
	case IsNotImplemented(err):
 | 
						|
		return grpc.Errorf(codes.Unimplemented, err.Error())
 | 
						|
	}
 | 
						|
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
// ToGRPCf maps the error to grpc error codes, assembling the formatting string
 | 
						|
// and combining it with the target error string.
 | 
						|
//
 | 
						|
// This is equivalent to errors.ToGRPC(errors.Wrapf(err, format, args...))
 | 
						|
func ToGRPCf(err error, format string, args ...interface{}) error {
 | 
						|
	return ToGRPC(errors.Wrapf(err, format, args...))
 | 
						|
}
 | 
						|
 | 
						|
func FromGRPC(err error) error {
 | 
						|
	if err == nil {
 | 
						|
		return nil
 | 
						|
	}
 | 
						|
 | 
						|
	var cls error // divide these into error classes, becomes the cause
 | 
						|
 | 
						|
	switch grpc.Code(err) {
 | 
						|
	case codes.InvalidArgument:
 | 
						|
		cls = ErrInvalidArgument
 | 
						|
	case codes.AlreadyExists:
 | 
						|
		cls = ErrAlreadyExists
 | 
						|
	case codes.NotFound:
 | 
						|
		cls = ErrNotFound
 | 
						|
	case codes.Unavailable:
 | 
						|
		cls = ErrUnavailable
 | 
						|
	case codes.FailedPrecondition:
 | 
						|
		cls = ErrFailedPrecondition
 | 
						|
	case codes.Unimplemented:
 | 
						|
		cls = ErrNotImplemented
 | 
						|
	default:
 | 
						|
		cls = ErrUnknown
 | 
						|
	}
 | 
						|
 | 
						|
	msg := rebaseMessage(cls, err)
 | 
						|
	if msg != "" {
 | 
						|
		err = errors.Wrapf(cls, msg)
 | 
						|
	} else {
 | 
						|
		err = errors.WithStack(cls)
 | 
						|
	}
 | 
						|
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
// rebaseMessage removes the repeats for an error at the end of an error
 | 
						|
// string. This will happen when taking an error over grpc then remapping it.
 | 
						|
//
 | 
						|
// Effectively, we just remove the string of cls from the end of err if it
 | 
						|
// appears there.
 | 
						|
func rebaseMessage(cls error, err error) string {
 | 
						|
	desc := grpc.ErrorDesc(err)
 | 
						|
	clss := cls.Error()
 | 
						|
	if desc == clss {
 | 
						|
		return ""
 | 
						|
	}
 | 
						|
 | 
						|
	return strings.TrimSuffix(desc, ": "+clss)
 | 
						|
}
 | 
						|
 | 
						|
func isGRPCError(err error) bool {
 | 
						|
	_, ok := status.FromError(err)
 | 
						|
	return ok
 | 
						|
}
 |