github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/pkg/api/handlers/libpod/manifests.go (about) 1 package libpod 2 3 import ( 4 "encoding/json" 5 "net/http" 6 7 "github.com/containers/buildah/manifests" 8 copy2 "github.com/containers/image/v5/copy" 9 "github.com/containers/image/v5/transports/alltransports" 10 "github.com/containers/libpod/libpod" 11 "github.com/containers/libpod/libpod/image" 12 "github.com/containers/libpod/pkg/api/handlers" 13 "github.com/containers/libpod/pkg/api/handlers/utils" 14 "github.com/gorilla/schema" 15 "github.com/opencontainers/go-digest" 16 "github.com/pkg/errors" 17 ) 18 19 func ManifestCreate(w http.ResponseWriter, r *http.Request) { 20 runtime := r.Context().Value("runtime").(*libpod.Runtime) 21 decoder := r.Context().Value("decoder").(*schema.Decoder) 22 query := struct { 23 Name []string `schema:"name"` 24 Image []string `schema:"image"` 25 All bool `schema:"all"` 26 }{ 27 // Add defaults here once needed. 28 } 29 if err := decoder.Decode(&query, r.URL.Query()); err != nil { 30 utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, 31 errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) 32 return 33 } 34 rtc, err := runtime.GetConfig() 35 if err != nil { 36 utils.InternalServerError(w, err) 37 return 38 } 39 sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false) 40 manID, err := image.CreateManifestList(runtime.ImageRuntime(), *sc, query.Name, query.Image, query.All) 41 if err != nil { 42 utils.InternalServerError(w, err) 43 return 44 } 45 utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: manID}) 46 } 47 48 func ManifestInspect(w http.ResponseWriter, r *http.Request) { 49 runtime := r.Context().Value("runtime").(*libpod.Runtime) 50 name := utils.GetName(r) 51 newImage, err := runtime.ImageRuntime().NewFromLocal(name) 52 if err != nil { 53 utils.ImageNotFound(w, name, err) 54 return 55 } 56 data, err := newImage.InspectManifest() 57 if err != nil { 58 utils.InternalServerError(w, err) 59 return 60 } 61 utils.WriteResponse(w, http.StatusOK, data) 62 } 63 64 func ManifestAdd(w http.ResponseWriter, r *http.Request) { 65 runtime := r.Context().Value("runtime").(*libpod.Runtime) 66 var manifestInput image.ManifestAddOpts 67 if err := json.NewDecoder(r.Body).Decode(&manifestInput); err != nil { 68 utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) 69 return 70 } 71 name := utils.GetName(r) 72 newImage, err := runtime.ImageRuntime().NewFromLocal(name) 73 if err != nil { 74 utils.ImageNotFound(w, name, err) 75 return 76 } 77 rtc, err := runtime.GetConfig() 78 if err != nil { 79 utils.InternalServerError(w, err) 80 return 81 } 82 sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false) 83 newID, err := newImage.AddManifest(*sc, manifestInput) 84 if err != nil { 85 utils.InternalServerError(w, err) 86 return 87 } 88 utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID}) 89 } 90 91 func ManifestRemove(w http.ResponseWriter, r *http.Request) { 92 runtime := r.Context().Value("runtime").(*libpod.Runtime) 93 decoder := r.Context().Value("decoder").(*schema.Decoder) 94 query := struct { 95 Digest string `schema:"digest"` 96 }{ 97 // Add defaults here once needed. 98 } 99 name := utils.GetName(r) 100 if err := decoder.Decode(&query, r.URL.Query()); err != nil { 101 utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, 102 errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) 103 return 104 } 105 newImage, err := runtime.ImageRuntime().NewFromLocal(name) 106 if err != nil { 107 utils.ImageNotFound(w, name, err) 108 return 109 } 110 d, err := digest.Parse(query.Digest) 111 if err != nil { 112 utils.Error(w, "invalid digest", http.StatusBadRequest, err) 113 return 114 } 115 newID, err := newImage.RemoveManifest(d) 116 if err != nil { 117 utils.InternalServerError(w, err) 118 return 119 } 120 utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID}) 121 } 122 func ManifestPush(w http.ResponseWriter, r *http.Request) { 123 runtime := r.Context().Value("runtime").(*libpod.Runtime) 124 decoder := r.Context().Value("decoder").(*schema.Decoder) 125 query := struct { 126 All bool `schema:"all"` 127 Destination string `schema:"destination"` 128 }{ 129 // Add defaults here once needed. 130 } 131 if err := decoder.Decode(&query, r.URL.Query()); err != nil { 132 utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, 133 errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) 134 return 135 } 136 name := utils.GetName(r) 137 newImage, err := runtime.ImageRuntime().NewFromLocal(name) 138 if err != nil { 139 utils.ImageNotFound(w, name, err) 140 return 141 } 142 dest, err := alltransports.ParseImageName(query.Destination) 143 if err != nil { 144 utils.Error(w, "invalid destination parameter", http.StatusBadRequest, errors.Errorf("invalid destination parameter %q", query.Destination)) 145 return 146 } 147 rtc, err := runtime.GetConfig() 148 if err != nil { 149 utils.InternalServerError(w, err) 150 return 151 } 152 sc := image.GetSystemContext(rtc.Engine.SignaturePolicyPath, "", false) 153 opts := manifests.PushOptions{ 154 ImageListSelection: copy2.CopySpecificImages, 155 SystemContext: sc, 156 } 157 if query.All { 158 opts.ImageListSelection = copy2.CopyAllImages 159 } 160 newD, err := newImage.PushManifest(dest, opts) 161 if err != nil { 162 utils.InternalServerError(w, err) 163 return 164 } 165 utils.WriteResponse(w, http.StatusOK, newD.String()) 166 }