github.com/containerd/containerd@v22.0.0-20200918172823-438c87b8e050+incompatible/image_store.go (about)

     1  /*
     2     Copyright The containerd Authors.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  package containerd
    18  
    19  import (
    20  	"context"
    21  
    22  	imagesapi "github.com/containerd/containerd/api/services/images/v1"
    23  	"github.com/containerd/containerd/api/types"
    24  	"github.com/containerd/containerd/errdefs"
    25  	"github.com/containerd/containerd/images"
    26  	ptypes "github.com/gogo/protobuf/types"
    27  	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
    28  )
    29  
    30  type remoteImages struct {
    31  	client imagesapi.ImagesClient
    32  }
    33  
    34  // NewImageStoreFromClient returns a new image store client
    35  func NewImageStoreFromClient(client imagesapi.ImagesClient) images.Store {
    36  	return &remoteImages{
    37  		client: client,
    38  	}
    39  }
    40  
    41  func (s *remoteImages) Get(ctx context.Context, name string) (images.Image, error) {
    42  	resp, err := s.client.Get(ctx, &imagesapi.GetImageRequest{
    43  		Name: name,
    44  	})
    45  	if err != nil {
    46  		return images.Image{}, errdefs.FromGRPC(err)
    47  	}
    48  
    49  	return imageFromProto(resp.Image), nil
    50  }
    51  
    52  func (s *remoteImages) List(ctx context.Context, filters ...string) ([]images.Image, error) {
    53  	resp, err := s.client.List(ctx, &imagesapi.ListImagesRequest{
    54  		Filters: filters,
    55  	})
    56  	if err != nil {
    57  		return nil, errdefs.FromGRPC(err)
    58  	}
    59  
    60  	return imagesFromProto(resp.Images), nil
    61  }
    62  
    63  func (s *remoteImages) Create(ctx context.Context, image images.Image) (images.Image, error) {
    64  	created, err := s.client.Create(ctx, &imagesapi.CreateImageRequest{
    65  		Image: imageToProto(&image),
    66  	})
    67  	if err != nil {
    68  		return images.Image{}, errdefs.FromGRPC(err)
    69  	}
    70  
    71  	return imageFromProto(&created.Image), nil
    72  }
    73  
    74  func (s *remoteImages) Update(ctx context.Context, image images.Image, fieldpaths ...string) (images.Image, error) {
    75  	var updateMask *ptypes.FieldMask
    76  	if len(fieldpaths) > 0 {
    77  		updateMask = &ptypes.FieldMask{
    78  			Paths: fieldpaths,
    79  		}
    80  	}
    81  
    82  	updated, err := s.client.Update(ctx, &imagesapi.UpdateImageRequest{
    83  		Image:      imageToProto(&image),
    84  		UpdateMask: updateMask,
    85  	})
    86  	if err != nil {
    87  		return images.Image{}, errdefs.FromGRPC(err)
    88  	}
    89  
    90  	return imageFromProto(&updated.Image), nil
    91  }
    92  
    93  func (s *remoteImages) Delete(ctx context.Context, name string, opts ...images.DeleteOpt) error {
    94  	var do images.DeleteOptions
    95  	for _, opt := range opts {
    96  		if err := opt(ctx, &do); err != nil {
    97  			return err
    98  		}
    99  	}
   100  	_, err := s.client.Delete(ctx, &imagesapi.DeleteImageRequest{
   101  		Name: name,
   102  		Sync: do.Synchronous,
   103  	})
   104  
   105  	return errdefs.FromGRPC(err)
   106  }
   107  
   108  func imageToProto(image *images.Image) imagesapi.Image {
   109  	return imagesapi.Image{
   110  		Name:      image.Name,
   111  		Labels:    image.Labels,
   112  		Target:    descToProto(&image.Target),
   113  		CreatedAt: image.CreatedAt,
   114  		UpdatedAt: image.UpdatedAt,
   115  	}
   116  }
   117  
   118  func imageFromProto(imagepb *imagesapi.Image) images.Image {
   119  	return images.Image{
   120  		Name:      imagepb.Name,
   121  		Labels:    imagepb.Labels,
   122  		Target:    descFromProto(&imagepb.Target),
   123  		CreatedAt: imagepb.CreatedAt,
   124  		UpdatedAt: imagepb.UpdatedAt,
   125  	}
   126  }
   127  
   128  func imagesFromProto(imagespb []imagesapi.Image) []images.Image {
   129  	var images []images.Image
   130  
   131  	for _, image := range imagespb {
   132  		images = append(images, imageFromProto(&image))
   133  	}
   134  
   135  	return images
   136  }
   137  
   138  func descFromProto(desc *types.Descriptor) ocispec.Descriptor {
   139  	return ocispec.Descriptor{
   140  		MediaType:   desc.MediaType,
   141  		Size:        desc.Size_,
   142  		Digest:      desc.Digest,
   143  		Annotations: desc.Annotations,
   144  	}
   145  }
   146  
   147  func descToProto(desc *ocispec.Descriptor) types.Descriptor {
   148  	return types.Descriptor{
   149  		MediaType:   desc.MediaType,
   150  		Size_:       desc.Size,
   151  		Digest:      desc.Digest,
   152  		Annotations: desc.Annotations,
   153  	}
   154  }