package containerd import ( "context" imagesapi "github.com/containerd/containerd/api/services/images/v1" "github.com/containerd/containerd/api/types" "github.com/containerd/containerd/errdefs" "github.com/containerd/containerd/images" ptypes "github.com/gogo/protobuf/types" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) type remoteImages struct { client imagesapi.ImagesClient } // NewImageStoreFromClient returns a new image store client func NewImageStoreFromClient(client imagesapi.ImagesClient) images.Store { return &remoteImages{ client: client, } } func (s *remoteImages) Get(ctx context.Context, name string) (images.Image, error) { resp, err := s.client.Get(ctx, &imagesapi.GetImageRequest{ Name: name, }) if err != nil { return images.Image{}, errdefs.FromGRPC(err) } return imageFromProto(resp.Image), nil } func (s *remoteImages) List(ctx context.Context, filters ...string) ([]images.Image, error) { resp, err := s.client.List(ctx, &imagesapi.ListImagesRequest{ Filters: filters, }) if err != nil { return nil, errdefs.FromGRPC(err) } return imagesFromProto(resp.Images), nil } func (s *remoteImages) Create(ctx context.Context, image images.Image) (images.Image, error) { created, err := s.client.Create(ctx, &imagesapi.CreateImageRequest{ Image: imageToProto(&image), }) if err != nil { return images.Image{}, errdefs.FromGRPC(err) } return imageFromProto(&created.Image), nil } func (s *remoteImages) Update(ctx context.Context, image images.Image, fieldpaths ...string) (images.Image, error) { var updateMask *ptypes.FieldMask if len(fieldpaths) > 0 { updateMask = &ptypes.FieldMask{ Paths: fieldpaths, } } updated, err := s.client.Update(ctx, &imagesapi.UpdateImageRequest{ Image: imageToProto(&image), UpdateMask: updateMask, }) if err != nil { return images.Image{}, errdefs.FromGRPC(err) } return imageFromProto(&updated.Image), nil } func (s *remoteImages) Delete(ctx context.Context, name string) error { _, err := s.client.Delete(ctx, &imagesapi.DeleteImageRequest{ Name: name, }) return errdefs.FromGRPC(err) } func imageToProto(image *images.Image) imagesapi.Image { return imagesapi.Image{ Name: image.Name, Labels: image.Labels, Target: descToProto(&image.Target), CreatedAt: image.CreatedAt, UpdatedAt: image.UpdatedAt, } } func imageFromProto(imagepb *imagesapi.Image) images.Image { return images.Image{ Name: imagepb.Name, Labels: imagepb.Labels, Target: descFromProto(&imagepb.Target), CreatedAt: imagepb.CreatedAt, UpdatedAt: imagepb.UpdatedAt, } } func imagesFromProto(imagespb []imagesapi.Image) []images.Image { var images []images.Image for _, image := range imagespb { images = append(images, imageFromProto(&image)) } return images } func descFromProto(desc *types.Descriptor) ocispec.Descriptor { return ocispec.Descriptor{ MediaType: desc.MediaType, Size: desc.Size_, Digest: desc.Digest, } } func descToProto(desc *ocispec.Descriptor) types.Descriptor { return types.Descriptor{ MediaType: desc.MediaType, Size_: desc.Size, Digest: desc.Digest, } }