summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Guzik <jakubmguzik@gmail.com>2021-03-20 22:56:01 +0100
committerMatthew Heon <mheon@redhat.com>2021-03-29 13:48:59 -0400
commit96ffce2198785c9d5717e3104f0afd8a0c38b6af (patch)
tree7f141964ca81f132eb6f470204c1ad552607ede3
parente772719bfd5f06442ed682d32e85cbe9e47ec558 (diff)
downloadpodman-96ffce2198785c9d5717e3104f0afd8a0c38b6af.tar.gz
podman-96ffce2198785c9d5717e3104f0afd8a0c38b6af.tar.bz2
podman-96ffce2198785c9d5717e3104f0afd8a0c38b6af.zip
Fix containers list/prune http api filter behaviour
The problem described in #9711 and followed by #9758 affects containers as well. When user provides wrong filter input, error message should occur, not fallback to full list/prune command. This change fixes the issue. Additionally, there are error message fixes for docker http api compat. Signed-off-by: Jakub Guzik <jakubmguzik@gmail.com>
-rw-r--r--pkg/api/handlers/compat/containers.go22
-rw-r--r--pkg/api/handlers/compat/containers_prune.go17
-rw-r--r--pkg/api/handlers/libpod/containers.go24
-rw-r--r--test/apiv2/20-containers.at26
4 files changed, 58 insertions, 31 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index d3277b815..e7146a5d8 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -19,6 +19,7 @@ import (
"github.com/containers/podman/v3/pkg/domain/infra/abi"
"github.com/containers/podman/v3/pkg/ps"
"github.com/containers/podman/v3/pkg/signal"
+ "github.com/containers/podman/v3/pkg/util"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
@@ -92,23 +93,24 @@ func ListContainers(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"`
- Limit int `schema:"limit"`
- Size bool `schema:"size"`
- Filters map[string][]string `schema:"filters"`
+ All bool `schema:"all"`
+ Limit int `schema:"limit"`
+ Size bool `schema:"size"`
}{
// override any golang type defaults
}
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ filterMap, err := util.PrepareFilters(r)
+
+ if dErr := decoder.Decode(&query, r.URL.Query()); dErr != nil || err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
- filterFuncs := make([]libpod.ContainerFilter, 0, len(query.Filters))
+ filterFuncs := make([]libpod.ContainerFilter, 0, len(*filterMap))
all := query.All || query.Limit > 0
- if len(query.Filters) > 0 {
- for k, v := range query.Filters {
+ if len((*filterMap)) > 0 {
+ for k, v := range *filterMap {
generatedFunc, err := filters.GenerateContainerFilterFuncs(k, v, runtime)
if err != nil {
utils.InternalServerError(w, err)
@@ -120,7 +122,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
// Docker thinks that if status is given as an input, then we should override
// the all setting and always deal with all containers.
- if len(query.Filters["status"]) > 0 {
+ if len((*filterMap)["status"]) > 0 {
all = true
}
if !all {
diff --git a/pkg/api/handlers/compat/containers_prune.go b/pkg/api/handlers/compat/containers_prune.go
index dc4d53af6..e37929d27 100644
--- a/pkg/api/handlers/compat/containers_prune.go
+++ b/pkg/api/handlers/compat/containers_prune.go
@@ -9,23 +9,20 @@ import (
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/domain/entities/reports"
"github.com/containers/podman/v3/pkg/domain/filters"
- "github.com/gorilla/schema"
+ "github.com/containers/podman/v3/pkg/util"
"github.com/pkg/errors"
)
func PruneContainers(w http.ResponseWriter, r *http.Request) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
- decoder := r.Context().Value("decoder").(*schema.Decoder)
-
- query := struct {
- Filters map[string][]string `schema:"filters"`
- }{}
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
+ filtersMap, err := util.PrepareFilters(r)
+ if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
- filterFuncs := make([]libpod.ContainerFilter, 0, len(query.Filters))
- for k, v := range query.Filters {
+
+ filterFuncs := make([]libpod.ContainerFilter, 0, len(*filtersMap))
+ for k, v := range *filtersMap {
generatedFunc, err := filters.GenerateContainerFilterFuncs(k, v, runtime)
if err != nil {
utils.InternalServerError(w, err)
diff --git a/pkg/api/handlers/libpod/containers.go b/pkg/api/handlers/libpod/containers.go
index 01b9ec101..77269db8b 100644
--- a/pkg/api/handlers/libpod/containers.go
+++ b/pkg/api/handlers/libpod/containers.go
@@ -11,6 +11,7 @@ import (
"github.com/containers/podman/v3/pkg/api/handlers/utils"
"github.com/containers/podman/v3/pkg/domain/entities"
"github.com/containers/podman/v3/pkg/domain/infra/abi"
+ "github.com/containers/podman/v3/pkg/util"
"github.com/gorilla/schema"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -59,20 +60,21 @@ func ContainerExists(w http.ResponseWriter, r *http.Request) {
func ListContainers(w http.ResponseWriter, r *http.Request) {
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
- All bool `schema:"all"`
- External bool `schema:"external"`
- Filters map[string][]string `schema:"filters"`
- Last int `schema:"last"` // alias for limit
- Limit int `schema:"limit"`
- Namespace bool `schema:"namespace"`
- Size bool `schema:"size"`
- Sync bool `schema:"sync"`
+ All bool `schema:"all"`
+ External bool `schema:"external"`
+ Last int `schema:"last"` // alias for limit
+ Limit int `schema:"limit"`
+ Namespace bool `schema:"namespace"`
+ Size bool `schema:"size"`
+ Sync bool `schema:"sync"`
}{
// override any golang type defaults
}
- if err := decoder.Decode(&query, r.URL.Query()); err != nil {
- utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest,
+ filterMap, err := util.PrepareFilters(r)
+
+ if dErr := decoder.Decode(&query, r.URL.Query()); dErr != nil || err != nil {
+ utils.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError,
errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
@@ -94,7 +96,7 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
opts := entities.ContainerListOptions{
All: query.All,
External: query.External,
- Filters: query.Filters,
+ Filters: *filterMap,
Last: limit,
Namespace: query.Namespace,
// Always return Pod, should not be part of the API.
diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at
index 478717700..9030f0095 100644
--- a/test/apiv2/20-containers.at
+++ b/test/apiv2/20-containers.at
@@ -280,6 +280,32 @@ t GET containers/json 200 \
podman stop bar
+#compat api list containers sanity checks
+t GET containers/json?filters='garb1age}' 500 \
+ .cause="invalid character 'g' looking for beginning of value"
+t GET containers/json?filters='{"label":["testl' 500 \
+ .cause="unexpected end of JSON input"
+
+#libpod api list containers sanity checks
+t GET libpod/containers/json?filters='garb1age}' 500 \
+ .cause="invalid character 'g' looking for beginning of value"
+t GET libpod/containers/json?filters='{"label":["testl' 500 \
+ .cause="unexpected end of JSON input"
+
+# Prune containers - bad filter input
+t POST containers/prune?filters='garb1age}' 500 \
+ .cause="invalid character 'g' looking for beginning of value"
+t POST libpod/containers/prune?filters='garb1age}' 500 \
+ .cause="invalid character 'g' looking for beginning of value"
+
+## Prune containers with illformed label
+t POST containers/prune?filters='{"label":["tes' 500 \
+ .cause="unexpected end of JSON input"
+t POST libpod/containers/prune?filters='{"label":["tes' 500 \
+ .cause="unexpected end of JSON input"
+
+t GET libpod/containers/json?filters='{"label":["testlabel"]}' 200 length=0
+
# Test CPU limit (NanoCPUs)
t POST containers/create Image=$IMAGE HostConfig='{"NanoCpus":500000}' 201 \
.Id~[0-9a-f]\\{64\\}