github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/libpod/image/manifests.go (about) 1 package image 2 3 import ( 4 "context" 5 6 "github.com/containers/buildah/manifests" 7 "github.com/containers/image/v5/manifest" 8 "github.com/containers/image/v5/transports/alltransports" 9 "github.com/containers/image/v5/types" 10 "github.com/opencontainers/go-digest" 11 "github.com/pkg/errors" 12 ) 13 14 // Options for adding a manifest 15 // swagger:model ManifestAddOpts 16 type ManifestAddOpts struct { 17 All bool `json:"all"` 18 Annotation map[string]string `json:"annotation"` 19 Arch string `json:"arch"` 20 Features []string `json:"features"` 21 Images []string `json:"images"` 22 OSVersion string `json:"os_version"` 23 Variant string `json:"variant"` 24 } 25 26 // InspectManifest returns a dockerized version of the manifest list 27 func (i *Image) InspectManifest() (*manifest.Schema2List, error) { 28 list, err := i.getManifestList() 29 if err != nil { 30 return nil, err 31 } 32 return list.Docker(), nil 33 } 34 35 // RemoveManifest removes the given digest from the manifest list. 36 func (i *Image) RemoveManifest(d digest.Digest) (string, error) { 37 list, err := i.getManifestList() 38 if err != nil { 39 return "", err 40 } 41 if err := list.Remove(d); err != nil { 42 return "", err 43 } 44 return list.SaveToImage(i.imageruntime.store, i.ID(), nil, "") 45 } 46 47 // getManifestList is a helper to obtain a manifest list 48 func (i *Image) getManifestList() (manifests.List, error) { 49 _, list, err := manifests.LoadFromImage(i.imageruntime.store, i.ID()) 50 return list, err 51 } 52 53 // CreateManifestList creates a new manifest list and can optionally add given images 54 // to the list 55 func CreateManifestList(rt *Runtime, systemContext types.SystemContext, names []string, imgs []string, all bool) (string, error) { 56 list := manifests.Create() 57 opts := ManifestAddOpts{Images: names, All: all} 58 for _, img := range imgs { 59 var ref types.ImageReference 60 newImage, err := rt.NewFromLocal(img) 61 if err == nil { 62 ir, err := newImage.toImageRef(context.Background()) 63 if err != nil { 64 return "", err 65 } 66 if ir == nil { 67 return "", errors.New("unable to convert image to ImageReference") 68 } 69 ref = ir.Reference() 70 } else { 71 ref, err = alltransports.ParseImageName(img) 72 if err != nil { 73 return "", err 74 } 75 } 76 list, err = addManifestToList(ref, list, systemContext, opts) 77 if err != nil { 78 return "", err 79 } 80 } 81 return list.SaveToImage(rt.store, "", names, manifest.DockerV2ListMediaType) 82 } 83 84 func addManifestToList(ref types.ImageReference, list manifests.List, systemContext types.SystemContext, opts ManifestAddOpts) (manifests.List, error) { 85 d, err := list.Add(context.Background(), &systemContext, ref, opts.All) 86 if err != nil { 87 return nil, err 88 } 89 if len(opts.OSVersion) > 0 { 90 if err := list.SetOSVersion(d, opts.OSVersion); err != nil { 91 return nil, err 92 } 93 } 94 if len(opts.Features) > 0 { 95 if err := list.SetFeatures(d, opts.Features); err != nil { 96 return nil, err 97 } 98 } 99 if len(opts.Arch) > 0 { 100 if err := list.SetArchitecture(d, opts.Arch); err != nil { 101 return nil, err 102 } 103 } 104 if len(opts.Variant) > 0 { 105 if err := list.SetVariant(d, opts.Variant); err != nil { 106 return nil, err 107 } 108 } 109 if len(opts.Annotation) > 0 { 110 if err := list.SetAnnotations(&d, opts.Annotation); err != nil { 111 return nil, err 112 } 113 } 114 return list, err 115 } 116 117 // AddManifest adds a manifest to a given manifest list. 118 func (i *Image) AddManifest(systemContext types.SystemContext, opts ManifestAddOpts) (string, error) { 119 var ( 120 ref types.ImageReference 121 ) 122 newImage, err := i.imageruntime.NewFromLocal(opts.Images[0]) 123 if err == nil { 124 ir, err := newImage.toImageRef(context.Background()) 125 if err != nil { 126 return "", err 127 } 128 ref = ir.Reference() 129 } else { 130 ref, err = alltransports.ParseImageName(opts.Images[0]) 131 if err != nil { 132 return "", err 133 } 134 } 135 list, err := i.getManifestList() 136 if err != nil { 137 return "", err 138 } 139 list, err = addManifestToList(ref, list, systemContext, opts) 140 if err != nil { 141 return "", err 142 } 143 return list.SaveToImage(i.imageruntime.store, i.ID(), nil, "") 144 } 145 146 // PushManifest pushes a manifest to a destination 147 func (i *Image) PushManifest(dest types.ImageReference, opts manifests.PushOptions) (digest.Digest, error) { 148 list, err := i.getManifestList() 149 if err != nil { 150 return "", err 151 } 152 _, d, err := list.Push(context.Background(), dest, opts) 153 return d, err 154 }