
These interfaces allow us to preserve both the checking of error "cause" as well as messages returned from the gRPC API so that the client gets full error reason instead of a default "metadata: not found" in the case of a missing image. Signed-off-by: Phil Estes <estesp@linux.vnet.ibm.com>
92 lines
2.2 KiB
Go
92 lines
2.2 KiB
Go
package images
|
|
|
|
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"
|
|
"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 {
|
|
var imagespb []imagesapi.Image
|
|
|
|
for _, image := range images {
|
|
imagespb = append(imagespb, imageToProto(&image))
|
|
}
|
|
|
|
return imagespb
|
|
}
|
|
|
|
func imagesFromProto(imagespb []imagesapi.Image) []images.Image {
|
|
var images []images.Image
|
|
|
|
for _, image := range imagespb {
|
|
images = append(images, imageFromProto(&image))
|
|
}
|
|
|
|
return images
|
|
}
|
|
|
|
func imageToProto(image *images.Image) imagesapi.Image {
|
|
return imagesapi.Image{
|
|
Name: image.Name,
|
|
Target: descToProto(&image.Target),
|
|
}
|
|
}
|
|
|
|
func imageFromProto(imagepb *imagesapi.Image) images.Image {
|
|
return images.Image{
|
|
Name: imagepb.Name,
|
|
Target: descFromProto(&imagepb.Target),
|
|
}
|
|
}
|
|
|
|
func descFromProto(desc *descriptor.Descriptor) ocispec.Descriptor {
|
|
return ocispec.Descriptor{
|
|
MediaType: desc.MediaType,
|
|
Size: desc.Size_,
|
|
Digest: desc.Digest,
|
|
}
|
|
}
|
|
|
|
func descToProto(desc *ocispec.Descriptor) descriptor.Descriptor {
|
|
return descriptor.Descriptor{
|
|
MediaType: desc.MediaType,
|
|
Size_: desc.Size,
|
|
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)
|
|
}
|
|
|
|
return err
|
|
}
|