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