github.com/alibaba/sealer@v0.8.6-0.20220430115802-37a2bdaa8173/pkg/image/default_image_metadata.go (about) 1 // Copyright © 2021 Alibaba Group Holding Ltd. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package image 16 17 import ( 18 "context" 19 "encoding/json" 20 "fmt" 21 22 "github.com/distribution/distribution/v3" 23 "github.com/distribution/distribution/v3/manifest/schema2" 24 25 "github.com/alibaba/sealer/pkg/image/distributionutil" 26 "github.com/alibaba/sealer/pkg/image/reference" 27 "github.com/alibaba/sealer/pkg/image/store" 28 v1 "github.com/alibaba/sealer/types/api/v1" 29 ) 30 31 //DefaultImageMetadataService provide service for image metadata operations 32 type DefaultImageMetadataService struct { 33 imageStore store.ImageStore 34 } 35 36 // Tag is used to give a name for imageName 37 func (d DefaultImageMetadataService) Tag(imageName, tarImageName string) error { 38 tarNamed, err := reference.ParseToNamed(tarImageName) 39 if err != nil { 40 return err 41 } 42 43 manifestList, err := d.imageStore.GetImageManifestList(imageName) 44 if err != nil { 45 return err 46 } 47 48 for _, m := range manifestList { 49 image, err := d.imageStore.GetByID(m.ID) 50 if err != nil { 51 return err 52 } 53 54 image.Name = tarNamed.CompleteName() 55 err = setClusterFile(tarNamed.CompleteName(), image) 56 if err != nil { 57 return err 58 } 59 60 imageID, err := GenerateImageID(*image) 61 if err != nil { 62 return err 63 } 64 image.Spec.ID = imageID 65 err = d.imageStore.Save(*image) 66 if err != nil { 67 return err 68 } 69 } 70 return nil 71 } 72 73 //List will list all cloud image locally 74 func (d DefaultImageMetadataService) List() (store.ImageMetadataMap, error) { 75 return d.imageStore.GetImageMetadataMap() 76 } 77 78 // GetImage will return the v1.Image locally 79 func (d DefaultImageMetadataService) GetImage(imageName string, platform *v1.Platform) (*v1.Image, error) { 80 image, err := d.imageStore.GetByName(imageName, platform) 81 if err != nil { 82 return nil, err 83 } 84 return image, nil 85 } 86 87 // GetRemoteImage will return the v1.Image from remote registry 88 func (d DefaultImageMetadataService) GetRemoteImage(imageName string, platform *v1.Platform) (v1.Image, error) { 89 var ( 90 image v1.Image 91 err error 92 named reference.Named 93 ctx = context.Background() 94 ) 95 96 named, err = reference.ParseToNamed(imageName) 97 if err != nil { 98 return image, err 99 } 100 101 repo, err := distributionutil.NewV2Repository(named, "pull") 102 if err != nil { 103 return v1.Image{}, err 104 } 105 106 ms, err := repo.Manifests(ctx) 107 if err != nil { 108 return v1.Image{}, err 109 } 110 111 manifest, err := ms.Get(ctx, "", distribution.WithTagOption{Tag: named.Tag()}) 112 if err != nil { 113 return v1.Image{}, err 114 } 115 116 // just transform it to schema2.DeserializedManifest 117 // because we only upload this kind manifest. 118 scheme2Manifest, ok := manifest.(*schema2.DeserializedManifest) 119 if !ok { 120 return v1.Image{}, fmt.Errorf("failed to parse manifest %s to DeserializedManifest", named.RepoTag()) 121 } 122 123 bs := repo.Blobs(ctx) 124 configJSONReader, err := bs.Open(ctx, scheme2Manifest.Config.Digest) 125 if err != nil { 126 return v1.Image{}, err 127 } 128 defer configJSONReader.Close() 129 130 decoder := json.NewDecoder(configJSONReader) 131 return image, decoder.Decode(&image) 132 } 133 134 func (d DefaultImageMetadataService) DeleteImage(imageName string, platform *v1.Platform) error { 135 return d.imageStore.DeleteByName(imageName, platform) 136 }