github.com/demonoid81/containerd@v1.3.4/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 }