summaryrefslogtreecommitdiff
path: root/pkg/api/handlers/compat
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/api/handlers/compat')
-rw-r--r--pkg/api/handlers/compat/containers.go49
-rw-r--r--pkg/api/handlers/compat/containers_archive.go97
-rw-r--r--pkg/api/handlers/compat/containers_create.go15
-rw-r--r--pkg/api/handlers/compat/containers_prune.go34
-rw-r--r--pkg/api/handlers/compat/events.go8
-rw-r--r--pkg/api/handlers/compat/images.go17
-rw-r--r--pkg/api/handlers/compat/images_search.go16
-rw-r--r--pkg/api/handlers/compat/info.go2
-rw-r--r--pkg/api/handlers/compat/networks.go6
-rw-r--r--pkg/api/handlers/compat/resize.go8
-rw-r--r--pkg/api/handlers/compat/volumes.go20
11 files changed, 147 insertions, 125 deletions
diff --git a/pkg/api/handlers/compat/containers.go b/pkg/api/handlers/compat/containers.go
index 7a3e5dd84..0f89c859e 100644
--- a/pkg/api/handlers/compat/containers.go
+++ b/pkg/api/handlers/compat/containers.go
@@ -4,6 +4,7 @@ import (
"encoding/json"
"fmt"
"net/http"
+ "sort"
"strconv"
"strings"
"syscall"
@@ -13,6 +14,8 @@ import (
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/api/handlers"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
+ "github.com/containers/podman/v2/pkg/domain/filters"
+ "github.com/containers/podman/v2/pkg/ps"
"github.com/containers/podman/v2/pkg/signal"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
@@ -78,10 +81,6 @@ func RemoveContainer(w http.ResponseWriter, r *http.Request) {
}
func ListContainers(w http.ResponseWriter, r *http.Request) {
- var (
- containers []*libpod.Container
- err error
- )
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
query := struct {
@@ -97,22 +96,48 @@ func ListContainers(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
- if query.All {
- containers, err = runtime.GetAllContainers()
- } else {
- containers, err = runtime.GetRunningContainers()
+
+ filterFuncs := make([]libpod.ContainerFilter, 0, len(query.Filters))
+ all := query.All || query.Limit > 0
+ if len(query.Filters) > 0 {
+ for k, v := range query.Filters {
+ generatedFunc, err := filters.GenerateContainerFilterFuncs(k, v, runtime)
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+ filterFuncs = append(filterFuncs, generatedFunc)
+ }
}
+
+ // 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 {
+ all = true
+ }
+ if !all {
+ runningOnly, err := filters.GenerateContainerFilterFuncs("status", []string{define.ContainerStateRunning.String()}, runtime)
+ if err != nil {
+ utils.InternalServerError(w, err)
+ return
+ }
+ filterFuncs = append(filterFuncs, runningOnly)
+ }
+
+ containers, err := runtime.GetContainers(filterFuncs...)
if err != nil {
utils.InternalServerError(w, err)
return
}
if _, found := r.URL.Query()["limit"]; found && query.Limit > 0 {
- last := query.Limit
- if len(containers) > last {
- containers = containers[len(containers)-last:]
+ // Sort the libpod containers
+ sort.Sort(ps.SortCreateTime{SortContainers: containers})
+ // we should perform the lopping before we start getting
+ // the expensive information on containers
+ if len(containers) > query.Limit {
+ containers = containers[:query.Limit]
}
}
- // TODO filters still need to be applied
var list = make([]*handlers.Container, len(containers))
for i, ctnr := range containers {
api, err := LibpodToContainer(ctnr, query.Size)
diff --git a/pkg/api/handlers/compat/containers_archive.go b/pkg/api/handlers/compat/containers_archive.go
index d8197415c..083c72ce8 100644
--- a/pkg/api/handlers/compat/containers_archive.go
+++ b/pkg/api/handlers/compat/containers_archive.go
@@ -3,11 +3,13 @@ package compat
import (
"fmt"
"net/http"
+ "os"
"github.com/containers/podman/v2/libpod"
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/copy"
+ "github.com/containers/podman/v2/pkg/domain/infra/abi"
"github.com/gorilla/schema"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@@ -44,58 +46,47 @@ func handleHeadAndGet(w http.ResponseWriter, r *http.Request, decoder *schema.De
}
containerName := utils.GetName(r)
-
- ctr, err := runtime.LookupContainer(containerName)
- if errors.Cause(err) == define.ErrNoSuchCtr {
- utils.Error(w, "Not found.", http.StatusNotFound, errors.Wrap(err, "the container doesn't exists"))
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
+ statReport, err := containerEngine.ContainerStat(r.Context(), containerName, query.Path)
+
+ // NOTE
+ // The statReport may actually be set even in case of an error. That's
+ // the case when we're looking at a symlink pointing to nirvana. In
+ // such cases, we really need the FileInfo but we also need the error.
+ if statReport != nil {
+ statHeader, err := copy.EncodeFileInfo(&statReport.FileInfo)
+ if err != nil {
+ utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
+ return
+ }
+ w.Header().Add(copy.XDockerContainerPathStatHeader, statHeader)
+ }
+
+ if errors.Cause(err) == define.ErrNoSuchCtr || errors.Cause(err) == copy.ENOENT {
+ // 404 is returned for an absent container and path. The
+ // clients must deal with it accordingly.
+ utils.Error(w, "Not found.", http.StatusNotFound, err)
return
} else if err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
}
- source, err := copy.CopyItemForContainer(ctr, query.Path, true, true)
- defer source.CleanUp()
- if err != nil {
- utils.Error(w, "Not found.", http.StatusNotFound, errors.Wrapf(err, "error stating container path %q", query.Path))
- return
- }
-
- // NOTE: Docker always sets the header.
- info, err := source.Stat()
- if err != nil {
- utils.Error(w, "Not found.", http.StatusNotFound, errors.Wrapf(err, "error stating container path %q", query.Path))
- return
- }
- statHeader, err := copy.EncodeFileInfo(info)
- if err != nil {
- utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
- return
- }
- w.Header().Add(copy.XDockerContainerPathStatHeader, statHeader)
-
// Our work is done when the user is interested in the header only.
if r.Method == http.MethodHead {
w.WriteHeader(http.StatusOK)
return
}
- // Alright, the users wants data from the container.
- destination, err := copy.CopyItemForWriter(w)
- if err != nil {
- utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
- return
- }
-
- copier, err := copy.GetCopier(&source, &destination, false)
+ copyFunc, err := containerEngine.ContainerCopyToArchive(r.Context(), containerName, query.Path, w)
if err != nil {
utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
return
}
+ w.Header().Set("Content-Type", "application/x-tar")
w.WriteHeader(http.StatusOK)
- if err := copier.Copy(); err != nil {
- logrus.Errorf("Error during copy: %v", err)
- return
+ if err := copyFunc(); err != nil {
+ logrus.Error(err.Error())
}
}
@@ -113,36 +104,22 @@ func handlePut(w http.ResponseWriter, r *http.Request, decoder *schema.Decoder,
return
}
- ctrName := utils.GetName(r)
-
- ctr, err := runtime.LookupContainer(ctrName)
- if err != nil {
- utils.Error(w, "Not found", http.StatusNotFound, errors.Wrapf(err, "the %s container doesn't exists", ctrName))
- return
- }
+ containerName := utils.GetName(r)
+ containerEngine := abi.ContainerEngine{Libpod: runtime}
- destination, err := copy.CopyItemForContainer(ctr, query.Path, true, false)
- defer destination.CleanUp()
- if err != nil {
- utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
+ copyFunc, err := containerEngine.ContainerCopyFromArchive(r.Context(), containerName, query.Path, r.Body)
+ if errors.Cause(err) == define.ErrNoSuchCtr || os.IsNotExist(err) {
+ // 404 is returned for an absent container and path. The
+ // clients must deal with it accordingly.
+ utils.Error(w, "Not found.", http.StatusNotFound, errors.Wrap(err, "the container doesn't exists"))
return
- }
-
- source, err := copy.CopyItemForReader(r.Body)
- defer source.CleanUp()
- if err != nil {
- utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
+ } else if err != nil {
+ utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err)
return
}
- copier, err := copy.GetCopier(&source, &destination, false)
- if err != nil {
- utils.Error(w, "Something went wrong", http.StatusInternalServerError, err)
- return
- }
w.WriteHeader(http.StatusOK)
- if err := copier.Copy(); err != nil {
- logrus.Errorf("Error during copy: %v", err)
- return
+ if err := copyFunc(); err != nil {
+ logrus.Error(err.Error())
}
}
diff --git a/pkg/api/handlers/compat/containers_create.go b/pkg/api/handlers/compat/containers_create.go
index 409a74de2..6e85872b2 100644
--- a/pkg/api/handlers/compat/containers_create.go
+++ b/pkg/api/handlers/compat/containers_create.go
@@ -66,7 +66,20 @@ func CreateContainer(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "make cli opts()"))
return
}
- sg := specgen.NewSpecGenerator(newImage.ID(), cliOpts.RootFS)
+
+ imgNameOrID := newImage.ID()
+ // if the img had multi names with the same sha256 ID, should use the InputName, not the ID
+ if len(newImage.Names()) > 1 {
+ imageRef, err := utils.ParseDockerReference(newImage.InputName)
+ if err != nil {
+ utils.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest, err)
+ return
+ }
+ // maybe the InputName has no tag, so use full name to display
+ imgNameOrID = imageRef.DockerReference().String()
+ }
+
+ sg := specgen.NewSpecGenerator(imgNameOrID, cliOpts.RootFS)
if err := common.FillOutSpecGen(sg, cliOpts, args); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "fill out specgen"))
return
diff --git a/pkg/api/handlers/compat/containers_prune.go b/pkg/api/handlers/compat/containers_prune.go
index 2cfeebcce..b3d26b8f4 100644
--- a/pkg/api/handlers/compat/containers_prune.go
+++ b/pkg/api/handlers/compat/containers_prune.go
@@ -4,19 +4,14 @@ import (
"net/http"
"github.com/containers/podman/v2/libpod"
- lpfilters "github.com/containers/podman/v2/libpod/filters"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
- "github.com/containers/podman/v2/pkg/domain/entities"
- "github.com/docker/docker/api/types"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
+ "github.com/containers/podman/v2/pkg/domain/filters"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
func PruneContainers(w http.ResponseWriter, r *http.Request) {
- var (
- delContainers []string
- space int64
- )
runtime := r.Context().Value("runtime").(*libpod.Runtime)
decoder := r.Context().Value("decoder").(*schema.Decoder)
@@ -29,7 +24,7 @@ func PruneContainers(w http.ResponseWriter, r *http.Request) {
}
filterFuncs := make([]libpod.ContainerFilter, 0, len(query.Filters))
for k, v := range query.Filters {
- generatedFunc, err := lpfilters.GenerateContainerFilterFuncs(k, v, runtime)
+ generatedFunc, err := filters.GenerateContainerFilterFuncs(k, v, runtime)
if err != nil {
utils.InternalServerError(w, err)
return
@@ -49,36 +44,21 @@ func PruneContainers(w http.ResponseWriter, r *http.Request) {
return
}
- prunedContainers, pruneErrors, err := runtime.PruneContainers(filterFuncs)
+ report, err := runtime.PruneContainers(filterFuncs)
if err != nil {
utils.InternalServerError(w, err)
return
}
- for ctrID, size := range prunedContainers {
- if pruneErrors[ctrID] == nil {
- space += size
- delContainers = append(delContainers, ctrID)
- }
- }
- report := types.ContainersPruneReport{
- ContainersDeleted: delContainers,
- SpaceReclaimed: uint64(space),
- }
utils.WriteResponse(w, http.StatusOK, report)
}
func PruneContainersHelper(w http.ResponseWriter, r *http.Request, filterFuncs []libpod.ContainerFilter) (
- *entities.ContainerPruneReport, error) {
+ []*reports.PruneReport, error) {
runtime := r.Context().Value("runtime").(*libpod.Runtime)
- prunedContainers, pruneErrors, err := runtime.PruneContainers(filterFuncs)
+ reports, err := runtime.PruneContainers(filterFuncs)
if err != nil {
utils.InternalServerError(w, err)
return nil, err
}
-
- report := &entities.ContainerPruneReport{
- Err: pruneErrors,
- ID: prunedContainers,
- }
- return report, nil
+ return reports, nil
}
diff --git a/pkg/api/handlers/compat/events.go b/pkg/api/handlers/compat/events.go
index f74491a8f..82a74e419 100644
--- a/pkg/api/handlers/compat/events.go
+++ b/pkg/api/handlers/compat/events.go
@@ -33,6 +33,8 @@ func filtersFromRequest(r *http.Request) ([]string, error) {
if _, found := r.URL.Query()["filters"]; found {
raw = []byte(r.Form.Get("filters"))
+ } else if _, found := r.URL.Query()["Filters"]; found {
+ raw = []byte(r.Form.Get("Filters"))
} else {
return []string{}, nil
}
@@ -73,7 +75,7 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
)
// NOTE: the "filters" parameter is extracted separately for backwards
- // compat via `fitlerFromRequest()`.
+ // compat via `filterFromRequest()`.
query := struct {
Since string `schema:"since"`
Until string `schema:"until"`
@@ -95,7 +97,6 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "failed to parse parameters", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
-
eventChannel := make(chan *events.Event)
errorChannel := make(chan error)
@@ -110,6 +111,7 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
Until: query.Until,
}
errorChannel <- runtime.Events(r.Context(), readOpts)
+
}()
var flush = func() {}
@@ -130,8 +132,8 @@ func GetEvents(w http.ResponseWriter, r *http.Request) {
if err != nil {
// FIXME StatusOK already sent above cannot send 500 here
utils.InternalServerError(w, err)
- return
}
+ return
case evt := <-eventChannel:
if evt == nil {
continue
diff --git a/pkg/api/handlers/compat/images.go b/pkg/api/handlers/compat/images.go
index a51dd8ed3..9d7503aba 100644
--- a/pkg/api/handlers/compat/images.go
+++ b/pkg/api/handlers/compat/images.go
@@ -22,6 +22,7 @@ import (
"github.com/gorilla/schema"
"github.com/opencontainers/go-digest"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// mergeNameAndTagOrDigest creates an image reference as string from the
@@ -98,21 +99,23 @@ func PruneImages(w http.ResponseWriter, r *http.Request) {
filters = append(filters, fmt.Sprintf("%s=%s", k, val))
}
}
- pruneCids, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, filters)
+ imagePruneReports, err := runtime.ImageRuntime().PruneImages(r.Context(), query.All, filters)
if err != nil {
utils.InternalServerError(w, err)
return
}
- for _, p := range pruneCids {
+ reclaimedSpace := uint64(0)
+ for _, p := range imagePruneReports {
idr = append(idr, types.ImageDeleteResponseItem{
- Deleted: p,
+ Deleted: p.Id,
})
+ reclaimedSpace = reclaimedSpace + p.Size
}
// FIXME/TODO to do this exactly correct, pruneimages needs to return idrs and space-reclaimed, then we are golden
ipr := types.ImagesPruneReport{
ImagesDeleted: idr,
- SpaceReclaimed: 1, // TODO we cannot supply this right now
+ SpaceReclaimed: reclaimedSpace,
}
utils.WriteResponse(w, http.StatusOK, handlers.ImagesPruneReport{ImagesPruneReport: ipr})
}
@@ -386,6 +389,12 @@ func LoadImages(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to create tempfile"))
return
}
+ defer func() {
+ err := os.Remove(f.Name())
+ if err != nil {
+ logrus.Errorf("Failed to remove temporary file: %v.", err)
+ }
+ }()
if err := SaveFromBody(f, r); err != nil {
utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "failed to write temporary file"))
return
diff --git a/pkg/api/handlers/compat/images_search.go b/pkg/api/handlers/compat/images_search.go
index b3ceae3ee..6808cdad5 100644
--- a/pkg/api/handlers/compat/images_search.go
+++ b/pkg/api/handlers/compat/images_search.go
@@ -8,6 +8,7 @@ import (
"github.com/containers/podman/v2/libpod/image"
"github.com/containers/podman/v2/pkg/api/handlers/utils"
"github.com/containers/podman/v2/pkg/auth"
+ "github.com/docker/docker/api/types/registry"
"github.com/gorilla/schema"
"github.com/pkg/errors"
)
@@ -77,5 +78,18 @@ func SearchImages(w http.ResponseWriter, r *http.Request) {
utils.BadRequest(w, "term", query.Term, err)
return
}
- utils.WriteResponse(w, http.StatusOK, results)
+
+ compatResults := make([]registry.SearchResult, 0, len(results))
+ for _, result := range results {
+ compatResult := registry.SearchResult{
+ Name: result.Name,
+ Description: result.Description,
+ StarCount: result.Stars,
+ IsAutomated: result.Automated == "[OK]",
+ IsOfficial: result.Official == "[OK]",
+ }
+ compatResults = append(compatResults, compatResult)
+ }
+
+ utils.WriteResponse(w, http.StatusOK, compatResults)
}
diff --git a/pkg/api/handlers/compat/info.go b/pkg/api/handlers/compat/info.go
index 4b3a390f1..5adbeb031 100644
--- a/pkg/api/handlers/compat/info.go
+++ b/pkg/api/handlers/compat/info.go
@@ -48,7 +48,7 @@ func GetInfo(w http.ResponseWriter, r *http.Request) {
stateInfo := getContainersState(runtime)
sysInfo := sysinfo.New(true)
- // FIXME: Need to expose if runtime supports Checkpoint'ing
+ // FIXME: Need to expose if runtime supports Checkpointing
// liveRestoreEnabled := criu.CheckForCriu() && configInfo.RuntimeSupportsCheckpoint()
info := &handlers.Info{Info: docker.Info{
diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go
index fe13971b0..f0b922885 100644
--- a/pkg/api/handlers/compat/networks.go
+++ b/pkg/api/handlers/compat/networks.go
@@ -131,7 +131,7 @@ func getNetworkResourceByNameOrID(nameOrID string, runtime *libpod.Runtime, filt
Name: conf.Name,
ID: network.GetNetworkID(conf.Name),
Created: time.Unix(int64(stat.Ctim.Sec), int64(stat.Ctim.Nsec)), // nolint: unconvert
- Scope: "",
+ Scope: "local",
Driver: network.DefaultNetworkDriver,
EnableIPv6: false,
IPAM: dockerNetwork.IPAM{
@@ -197,7 +197,7 @@ func ListNetworks(w http.ResponseWriter, r *http.Request) {
}
var reports []*types.NetworkResource
- logrus.Errorf("netNames: %q", strings.Join(netNames, ", "))
+ logrus.Debugf("netNames: %q", strings.Join(netNames, ", "))
for _, name := range netNames {
report, err := getNetworkResourceByNameOrID(name, runtime, query.Filters)
if err != nil {
@@ -239,7 +239,7 @@ func CreateNetwork(w http.ResponseWriter, r *http.Request) {
Internal: networkCreate.Internal,
Labels: networkCreate.Labels,
}
- if networkCreate.IPAM != nil && networkCreate.IPAM.Config != nil {
+ if networkCreate.IPAM != nil && len(networkCreate.IPAM.Config) > 0 {
if len(networkCreate.IPAM.Config) > 1 {
utils.InternalServerError(w, errors.New("compat network create can only support one IPAM config"))
return
diff --git a/pkg/api/handlers/compat/resize.go b/pkg/api/handlers/compat/resize.go
index bdc051d73..cc8c6ef0a 100644
--- a/pkg/api/handlers/compat/resize.go
+++ b/pkg/api/handlers/compat/resize.go
@@ -20,8 +20,8 @@ func ResizeTTY(w http.ResponseWriter, r *http.Request) {
// /containers/{id}/resize
query := struct {
- height uint16 `schema:"h"`
- width uint16 `schema:"w"`
+ Height uint16 `schema:"h"`
+ Width uint16 `schema:"w"`
}{
// override any golang type defaults
}
@@ -33,8 +33,8 @@ func ResizeTTY(w http.ResponseWriter, r *http.Request) {
}
sz := remotecommand.TerminalSize{
- Width: query.width,
- Height: query.height,
+ Width: query.Width,
+ Height: query.Height,
}
var status int
diff --git a/pkg/api/handlers/compat/volumes.go b/pkg/api/handlers/compat/volumes.go
index 71b848932..1188d8f84 100644
--- a/pkg/api/handlers/compat/volumes.go
+++ b/pkg/api/handlers/compat/volumes.go
@@ -3,6 +3,7 @@ package compat
import (
"encoding/json"
"net/http"
+ "net/url"
"time"
"github.com/containers/podman/v2/libpod"
@@ -207,7 +208,7 @@ func RemoveVolume(w http.ResponseWriter, r *http.Request) {
* using the volume at the same time".
*
* With this in mind, we only consider the `force` query parameter when we
- * hunt for specified volume by name, using it to seletively return a 204
+ * hunt for specified volume by name, using it to selectively return a 204
* or blow up depending on `force` being truthy or falsey/unset
* respectively.
*/
@@ -230,7 +231,7 @@ func RemoveVolume(w http.ResponseWriter, r *http.Request) {
utils.VolumeNotFound(w, name, err)
} else {
// Volume does not exist and `force` is truthy - this emulates what
- // Docker would do when told to `force` removal of a nonextant
+ // Docker would do when told to `force` removal of a nonexistent
// volume
utils.WriteResponse(w, http.StatusNoContent, nil)
}
@@ -254,22 +255,23 @@ func PruneVolumes(w http.ResponseWriter, r *http.Request) {
utils.Error(w, "Something went wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse parameters for %s", r.URL.String()))
return
}
- // TODO: We have no ability to pass pruning filters to `PruneVolumes()` so
- // we'll explicitly reject the request if we see any
- if len(query.Filters) > 0 {
- utils.InternalServerError(w, errors.New("filters for pruning volumes is not implemented"))
+
+ f := (url.Values)(query.Filters)
+ filterFuncs, err := filters.GenerateVolumeFilters(f)
+ if err != nil {
+ utils.Error(w, "Something when wrong.", http.StatusBadRequest, errors.Wrapf(err, "failed to parse filters for %s", f.Encode()))
return
}
- pruned, err := runtime.PruneVolumes(r.Context())
+ pruned, err := runtime.PruneVolumes(r.Context(), filterFuncs)
if err != nil {
utils.InternalServerError(w, err)
return
}
prunedIds := make([]string, 0, len(pruned))
- for k := range pruned {
+ for _, v := range pruned {
// XXX: This drops any pruning per-volume error messages on the floor
- prunedIds = append(prunedIds, k)
+ prunedIds = append(prunedIds, v.Id)
}
pruneResponse := docker_api_types.VolumesPruneReport{
VolumesDeleted: prunedIds,