github.com/containers/podman/v2@v2.2.2-0.20210501105131-c1e07d070c4c/libpod/image/manifests.go (about) 1 package image 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/containers/buildah/manifests" 8 "github.com/containers/image/v5/docker" 9 "github.com/containers/image/v5/manifest" 10 "github.com/containers/image/v5/transports/alltransports" 11 "github.com/containers/image/v5/types" 12 "github.com/opencontainers/go-digest" 13 ) 14 15 // Options for adding a manifest 16 // swagger:model ManifestAddOpts 17 type ManifestAddOpts struct { 18 All bool `json:"all"` 19 Annotation map[string]string `json:"annotation"` 20 Arch string `json:"arch"` 21 Features []string `json:"features"` 22 Images []string `json:"images"` 23 OS string `json:"os"` 24 OSVersion string `json:"os_version"` 25 Variant string `json:"variant"` 26 } 27 28 // ManifestAnnotateOptions defines the options for 29 // manifest annotate 30 type ManifestAnnotateOpts struct { 31 Annotation map[string]string `json:"annotation"` 32 Arch string `json:"arch"` 33 Features []string `json:"features"` 34 OS string `json:"os"` 35 OSFeatures []string `json:"os_feature"` 36 OSVersion string `json:"os_version"` 37 Variant string `json:"variant"` 38 } 39 40 // InspectManifest returns a dockerized version of the manifest list 41 func (i *Image) InspectManifest() (*manifest.Schema2List, error) { 42 list, err := i.getManifestList() 43 if err != nil { 44 return nil, err 45 } 46 return list.Docker(), nil 47 } 48 49 // RemoveManifest removes the given digest from the manifest list. 50 func (i *Image) RemoveManifest(d digest.Digest) (string, error) { 51 list, err := i.getManifestList() 52 if err != nil { 53 return "", err 54 } 55 if err := list.Remove(d); err != nil { 56 return "", err 57 } 58 return list.SaveToImage(i.imageruntime.store, i.ID(), nil, "") 59 } 60 61 // getManifestList is a helper to obtain a manifest list 62 func (i *Image) getManifestList() (manifests.List, error) { 63 _, list, err := manifests.LoadFromImage(i.imageruntime.store, i.ID()) 64 return list, err 65 } 66 67 // CreateManifestList creates a new manifest list and can optionally add given images 68 // to the list 69 func CreateManifestList(rt *Runtime, systemContext types.SystemContext, names []string, imgs []string, all bool) (string, error) { 70 list := manifests.Create() 71 opts := ManifestAddOpts{Images: names, All: all} 72 for _, img := range imgs { 73 ref, err := alltransports.ParseImageName(img) 74 if err != nil { 75 dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name()) 76 ref, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, img)) 77 if err != nil { 78 return "", err 79 } 80 } 81 list, err = addManifestToList(ref, list, systemContext, opts) 82 if err != nil { 83 return "", err 84 } 85 } 86 return list.SaveToImage(rt.store, "", names, manifest.DockerV2ListMediaType) 87 } 88 89 func addManifestToList(ref types.ImageReference, list manifests.List, systemContext types.SystemContext, opts ManifestAddOpts) (manifests.List, error) { 90 d, err := list.Add(context.Background(), &systemContext, ref, opts.All) 91 if err != nil { 92 return nil, err 93 } 94 if opts.OS != "" { 95 if err := list.SetOS(d, opts.OS); err != nil { 96 return nil, err 97 } 98 } 99 if len(opts.OSVersion) > 0 { 100 if err := list.SetOSVersion(d, opts.OSVersion); err != nil { 101 return nil, err 102 } 103 } 104 if len(opts.Features) > 0 { 105 if err := list.SetFeatures(d, opts.Features); err != nil { 106 return nil, err 107 } 108 } 109 if len(opts.Arch) > 0 { 110 if err := list.SetArchitecture(d, opts.Arch); err != nil { 111 return nil, err 112 } 113 } 114 if len(opts.Variant) > 0 { 115 if err := list.SetVariant(d, opts.Variant); err != nil { 116 return nil, err 117 } 118 } 119 if len(opts.Annotation) > 0 { 120 if err := list.SetAnnotations(&d, opts.Annotation); err != nil { 121 return nil, err 122 } 123 } 124 return list, err 125 } 126 127 // AddManifest adds a manifest to a given manifest list. 128 func (i *Image) AddManifest(systemContext types.SystemContext, opts ManifestAddOpts) (string, error) { 129 ref, err := alltransports.ParseImageName(opts.Images[0]) 130 if err != nil { 131 dockerPrefix := fmt.Sprintf("%s://", docker.Transport.Name()) 132 ref, err = alltransports.ParseImageName(fmt.Sprintf("%s%s", dockerPrefix, opts.Images[0])) 133 if err != nil { 134 return "", err 135 } 136 } 137 list, err := i.getManifestList() 138 if err != nil { 139 return "", err 140 } 141 list, err = addManifestToList(ref, list, systemContext, opts) 142 if err != nil { 143 return "", err 144 } 145 return list.SaveToImage(i.imageruntime.store, i.ID(), nil, "") 146 } 147 148 // PushManifest pushes a manifest to a destination 149 func (i *Image) PushManifest(dest types.ImageReference, opts manifests.PushOptions) (digest.Digest, error) { 150 list, err := i.getManifestList() 151 if err != nil { 152 return "", err 153 } 154 _, d, err := list.Push(context.Background(), dest, opts) 155 return d, err 156 } 157 158 // AnnotateManifest updates an image configuration of a manifest list. 159 func (i *Image) AnnotateManifest(systemContext types.SystemContext, d digest.Digest, opts ManifestAnnotateOpts) (string, error) { 160 list, err := i.getManifestList() 161 if err != nil { 162 return "", err 163 } 164 if len(opts.OS) > 0 { 165 if err := list.SetOS(d, opts.OS); err != nil { 166 return "", err 167 } 168 } 169 if len(opts.OSVersion) > 0 { 170 if err := list.SetOSVersion(d, opts.OSVersion); err != nil { 171 return "", err 172 } 173 } 174 if len(opts.Features) > 0 { 175 if err := list.SetFeatures(d, opts.Features); err != nil { 176 return "", err 177 } 178 } 179 if len(opts.OSFeatures) > 0 { 180 if err := list.SetOSFeatures(d, opts.OSFeatures); err != nil { 181 return "", err 182 } 183 } 184 if len(opts.Arch) > 0 { 185 if err := list.SetArchitecture(d, opts.Arch); err != nil { 186 return "", err 187 } 188 } 189 if len(opts.Variant) > 0 { 190 if err := list.SetVariant(d, opts.Variant); err != nil { 191 return "", err 192 } 193 } 194 if len(opts.Annotation) > 0 { 195 if err := list.SetAnnotations(&d, opts.Annotation); err != nil { 196 return "", err 197 } 198 } 199 return list.SaveToImage(i.imageruntime.store, i.ID(), nil, "") 200 }