diff options
Diffstat (limited to 'pkg/api/handlers/libpod')
-rw-r--r-- | pkg/api/handlers/libpod/manifests.go | 166 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/swagger.go | 9 |
2 files changed, 175 insertions, 0 deletions
diff --git a/pkg/api/handlers/libpod/manifests.go b/pkg/api/handlers/libpod/manifests.go new file mode 100644 index 000000000..a3d2caba6 --- /dev/null +++ b/pkg/api/handlers/libpod/manifests.go @@ -0,0 +1,166 @@ +package libpod + +import ( + "encoding/json" + "net/http" + + "github.com/containers/buildah/manifests" + copy2 "github.com/containers/image/v5/copy" + "github.com/containers/image/v5/transports/alltransports" + "github.com/containers/libpod/libpod" + "github.com/containers/libpod/libpod/image" + "github.com/containers/libpod/pkg/api/handlers" + "github.com/containers/libpod/pkg/api/handlers/utils" + "github.com/gorilla/schema" + "github.com/opencontainers/go-digest" + "github.com/pkg/errors" +) + +func ManifestCreate(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + Name []string `schema:"name"` + Image []string `schema:"image"` + All bool `schema:"all"` + }{ + // Add defaults here once needed. + } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) + return + } + rtc, err := runtime.GetConfig() + if err != nil { + utils.InternalServerError(w, err) + return + } + sc := image.GetSystemContext(rtc.SignaturePolicyPath, "", false) + manID, err := image.CreateManifestList(runtime.ImageRuntime(), *sc, query.Name, query.Image, query.All) + if err != nil { + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: manID}) +} + +func ManifestInspect(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + name := utils.GetName(r) + newImage, err := runtime.ImageRuntime().NewFromLocal(name) + if err != nil { + utils.ImageNotFound(w, name, err) + return + } + data, err := newImage.InspectManifest() + if err != nil { + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusOK, data) +} + +func ManifestAdd(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + var manifestInput image.ManifestAddOpts + if err := json.NewDecoder(r.Body).Decode(&manifestInput); err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) + return + } + name := utils.GetName(r) + newImage, err := runtime.ImageRuntime().NewFromLocal(name) + if err != nil { + utils.ImageNotFound(w, name, err) + return + } + rtc, err := runtime.GetConfig() + if err != nil { + utils.InternalServerError(w, err) + return + } + sc := image.GetSystemContext(rtc.SignaturePolicyPath, "", false) + newID, err := newImage.AddManifest(*sc, manifestInput) + if err != nil { + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID}) +} + +func ManifestRemove(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + Digest string `schema:"digest"` + }{ + // Add defaults here once needed. + } + name := utils.GetName(r) + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) + return + } + newImage, err := runtime.ImageRuntime().NewFromLocal(name) + if err != nil { + utils.ImageNotFound(w, name, err) + return + } + d, err := digest.Parse(query.Digest) + if err != nil { + utils.Error(w, "invalid digest", http.StatusBadRequest, err) + return + } + newID, err := newImage.RemoveManifest(d) + if err != nil { + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusOK, handlers.IDResponse{ID: newID}) +} +func ManifestPush(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + All bool `schema:"all"` + Destination string `schema:"destination"` + }{ + // Add defaults here once needed. + } + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, + errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String())) + return + } + name := utils.GetName(r) + newImage, err := runtime.ImageRuntime().NewFromLocal(name) + if err != nil { + utils.ImageNotFound(w, name, err) + return + } + dest, err := alltransports.ParseImageName(query.Destination) + if err != nil { + utils.Error(w, "invalid destination parameter", http.StatusBadRequest, errors.Errorf("invalid destination parameter %q", query.Destination)) + return + } + rtc, err := runtime.GetConfig() + if err != nil { + utils.InternalServerError(w, err) + return + } + sc := image.GetSystemContext(rtc.SignaturePolicyPath, "", false) + opts := manifests.PushOptions{ + ImageListSelection: copy2.CopySpecificImages, + SystemContext: sc, + } + if query.All { + opts.ImageListSelection = copy2.CopyAllImages + } + newD, err := newImage.PushManifest(dest, opts) + if err != nil { + utils.InternalServerError(w, err) + return + } + utils.WriteResponse(w, http.StatusOK, newD.String()) +} diff --git a/pkg/api/handlers/libpod/swagger.go b/pkg/api/handlers/libpod/swagger.go index aec30ef56..f6a26134b 100644 --- a/pkg/api/handlers/libpod/swagger.go +++ b/pkg/api/handlers/libpod/swagger.go @@ -1,8 +1,17 @@ package libpod +import "github.com/containers/image/v5/manifest" + // List Containers // swagger:response ListContainers type swagInspectPodResponse struct { // in:body Body []ListContainer } + +// Inspect Manifest +// swagger:response InspectManifest +type swagInspectManifestResponse struct { + // in:body + Body manifest.List +} |