diff options
author | Valentin Rothberg <rothberg@redhat.com> | 2020-05-04 14:01:39 +0200 |
---|---|---|
committer | Valentin Rothberg <rothberg@redhat.com> | 2020-05-04 16:01:45 +0200 |
commit | 7f97896c59d23d9dda704b19203a9ceb49b57237 (patch) | |
tree | 6f4785d283eb84b103592d159f795987ebaf7ae9 /pkg/api/handlers | |
parent | 51d0be42046f691e81cddfe2712baa14cecbdfbe (diff) | |
download | podman-7f97896c59d23d9dda704b19203a9ceb49b57237.tar.gz podman-7f97896c59d23d9dda704b19203a9ceb49b57237.tar.bz2 podman-7f97896c59d23d9dda704b19203a9ceb49b57237.zip |
image removal: refactor part 2
Continue the refactoring of image removal. I didn't manage to break all
the following changes into smaller and easier to digest commits due to
time constraints:
* Return an error slice instead of a single error. Use multierror only
in the client/frontend. Reflect that in the types.
* Use the batch image removal in the client while preserving the more
rest-idiomatic single-image removal endpoint.
* Add a new handler for the single-image removal endpoint to make it
share the same code as the batch endpoint.
* Expose bindings for the single and batch endpoints, so we can
properly test them.
* Add several convenience functions for error handling to
pkg/errorhandling.
* Set the correct error type in libpod to set the exit code to 2 when
one or more containers are using an image.
* Massage the bindings tests a bit and tackle compilation errors.
Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'pkg/api/handlers')
-rw-r--r-- | pkg/api/handlers/libpod/images.go | 51 | ||||
-rw-r--r-- | pkg/api/handlers/types.go | 2 |
2 files changed, 48 insertions, 5 deletions
diff --git a/pkg/api/handlers/libpod/images.go b/pkg/api/handlers/libpod/images.go index f7be5ce9a..93b4564a1 100644 --- a/pkg/api/handlers/libpod/images.go +++ b/pkg/api/handlers/libpod/images.go @@ -23,6 +23,7 @@ import ( "github.com/containers/libpod/pkg/api/handlers/utils" "github.com/containers/libpod/pkg/domain/entities" "github.com/containers/libpod/pkg/domain/infra/abi" + "github.com/containers/libpod/pkg/errorhandling" "github.com/containers/libpod/pkg/util" utils2 "github.com/containers/libpod/utils" "github.com/gorilla/schema" @@ -700,8 +701,8 @@ func SearchImages(w http.ResponseWriter, r *http.Request) { utils.WriteResponse(w, http.StatusOK, reports) } -// ImagesRemove is the endpoint for image removal. -func ImagesRemove(w http.ResponseWriter, r *http.Request) { +// ImagesBatchRemove is the endpoint for batch image removal. +func ImagesBatchRemove(w http.ResponseWriter, r *http.Request) { runtime := r.Context().Value("runtime").(*libpod.Runtime) decoder := r.Context().Value("decoder").(*schema.Decoder) query := struct { @@ -722,7 +723,49 @@ func ImagesRemove(w http.ResponseWriter, r *http.Request) { opts := entities.ImageRemoveOptions{All: query.All, Force: query.Force} imageEngine := abi.ImageEngine{Libpod: runtime} - rmReport, rmError := imageEngine.Remove(r.Context(), query.Images, opts) - report := handlers.LibpodImagesRemoveReport{ImageRemoveReport: *rmReport, Error: rmError.Error()} + rmReport, rmErrors := imageEngine.Remove(r.Context(), query.Images, opts) + + strErrs := errorhandling.ErrorsToStrings(rmErrors) + report := handlers.LibpodImagesRemoveReport{ImageRemoveReport: *rmReport, Errors: strErrs} utils.WriteResponse(w, http.StatusOK, report) } + +// ImagesRemove is the endpoint for removing one image. +func ImagesRemove(w http.ResponseWriter, r *http.Request) { + runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + Force bool `schema:"force"` + }{ + Force: false, + } + + 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 + } + + opts := entities.ImageRemoveOptions{Force: query.Force} + imageEngine := abi.ImageEngine{Libpod: runtime} + rmReport, rmErrors := imageEngine.Remove(r.Context(), []string{utils.GetName(r)}, opts) + + // In contrast to batch-removal, where we're only setting the exit + // code, we need to have another closer look at the errors here and set + // the appropriate http status code. + + switch rmReport.ExitCode { + case 0: + report := handlers.LibpodImagesRemoveReport{ImageRemoveReport: *rmReport, Errors: []string{}} + utils.WriteResponse(w, http.StatusOK, report) + case 1: + // 404 - no such image + utils.Error(w, "error removing image", http.StatusNotFound, errorhandling.JoinErrors(rmErrors)) + case 2: + // 409 - conflict error (in use by containers) + utils.Error(w, "error removing image", http.StatusConflict, errorhandling.JoinErrors(rmErrors)) + default: + // 500 - internal error + utils.Error(w, "failed to remove image", http.StatusInternalServerError, errorhandling.JoinErrors(rmErrors)) + } +} diff --git a/pkg/api/handlers/types.go b/pkg/api/handlers/types.go index 58a12ea6a..a7abf59c0 100644 --- a/pkg/api/handlers/types.go +++ b/pkg/api/handlers/types.go @@ -41,7 +41,7 @@ type LibpodImagesPullReport struct { type LibpodImagesRemoveReport struct { entities.ImageRemoveReport // Image removal requires is to return data and an error. - Error string + Errors []string } type ContainersPruneReport struct { |