diff options
author | Jakub Guzik <jakubmguzik@gmail.com> | 2021-03-18 00:01:50 +0100 |
---|---|---|
committer | Jakub Guzik <jakubmguzik@gmail.com> | 2021-03-18 00:01:50 +0100 |
commit | 8ea02d0b6033b6ffdc68d38f3276410f4e2e8eb9 (patch) | |
tree | 5eb17180f9429c71e9435230da4d7e077ba7d044 /pkg | |
parent | e7dc59252bd722377938ac3e6b4fd7e077f05293 (diff) | |
download | podman-8ea02d0b6033b6ffdc68d38f3276410f4e2e8eb9.tar.gz podman-8ea02d0b6033b6ffdc68d38f3276410f4e2e8eb9.tar.bz2 podman-8ea02d0b6033b6ffdc68d38f3276410f4e2e8eb9.zip |
network prune filters for http compat and libpod api
Signed-off-by: Jakub Guzik <jakubmguzik@gmail.com>
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/api/handlers/compat/networks.go | 18 | ||||
-rw-r--r-- | pkg/api/handlers/libpod/networks.go | 17 | ||||
-rw-r--r-- | pkg/api/server/register_networks.go | 1 | ||||
-rw-r--r-- | pkg/domain/entities/network.go | 4 | ||||
-rw-r--r-- | pkg/domain/filters/containers.go | 11 | ||||
-rw-r--r-- | pkg/domain/infra/abi/network.go | 26 | ||||
-rw-r--r-- | pkg/util/filters.go | 25 |
7 files changed, 83 insertions, 19 deletions
diff --git a/pkg/api/handlers/compat/networks.go b/pkg/api/handlers/compat/networks.go index dfb1d7fda..7e06cad66 100644 --- a/pkg/api/handlers/compat/networks.go +++ b/pkg/api/handlers/compat/networks.go @@ -400,10 +400,24 @@ func Disconnect(w http.ResponseWriter, r *http.Request) { // Prune removes unused networks func Prune(w http.ResponseWriter, r *http.Request) { - // TODO Filters are not implemented runtime := r.Context().Value("runtime").(*libpod.Runtime) + filters, err := filtersFromRequest(r) + if err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, errors.Wrap(err, "Decode()")) + return + } + filterMap := map[string][]string{} + for _, filter := range filters { + split := strings.SplitN(filter, "=", 2) + if len(split) > 1 { + filterMap[split[0]] = append(filterMap[split[0]], split[1]) + } + } + ic := abi.ContainerEngine{Libpod: runtime} - pruneOptions := entities.NetworkPruneOptions{} + pruneOptions := entities.NetworkPruneOptions{ + Filters: filterMap, + } pruneReports, err := ic.NetworkPrune(r.Context(), pruneOptions) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) diff --git a/pkg/api/handlers/libpod/networks.go b/pkg/api/handlers/libpod/networks.go index a6c4f6d64..5982f50a7 100644 --- a/pkg/api/handlers/libpod/networks.go +++ b/pkg/api/handlers/libpod/networks.go @@ -177,10 +177,23 @@ func ExistsNetwork(w http.ResponseWriter, r *http.Request) { // Prune removes unused networks func Prune(w http.ResponseWriter, r *http.Request) { - // TODO Filters are not implemented runtime := r.Context().Value("runtime").(*libpod.Runtime) + decoder := r.Context().Value("decoder").(*schema.Decoder) + query := struct { + Filters map[string][]string `schema:"filters"` + }{ + // override any golang type defaults + } + + if err := decoder.Decode(&query, r.URL.Query()); err != nil { + utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) + return + } + + pruneOptions := entities.NetworkPruneOptions{ + Filters: query.Filters, + } ic := abi.ContainerEngine{Libpod: runtime} - pruneOptions := entities.NetworkPruneOptions{} pruneReports, err := ic.NetworkPrune(r.Context(), pruneOptions) if err != nil { utils.Error(w, "Something went wrong.", http.StatusInternalServerError, err) diff --git a/pkg/api/server/register_networks.go b/pkg/api/server/register_networks.go index c54de952f..a07c6a55e 100644 --- a/pkg/api/server/register_networks.go +++ b/pkg/api/server/register_networks.go @@ -172,7 +172,6 @@ func (s *APIServer) registerNetworkHandlers(r *mux.Router) error { // name: filters // type: string // description: | - // NOT IMPLEMENTED // Filters to process on the prune list, encoded as JSON (a map[string][]string). // Available filters: // - until=<timestamp> Prune networks created before this timestamp. The <timestamp> can be Unix timestamps, date formatted timestamps, or Go duration strings (e.g. 10m, 1h30m) computed relative to the daemon machine’s time. diff --git a/pkg/domain/entities/network.go b/pkg/domain/entities/network.go index f66a7f575..a89501664 100644 --- a/pkg/domain/entities/network.go +++ b/pkg/domain/entities/network.go @@ -92,4 +92,6 @@ type NetworkPruneReport struct { // NetworkPruneOptions describes options for pruning // unused cni networks -type NetworkPruneOptions struct{} +type NetworkPruneOptions struct { + Filters map[string][]string +} diff --git a/pkg/domain/filters/containers.go b/pkg/domain/filters/containers.go index 98b8f7e88..02727e841 100644 --- a/pkg/domain/filters/containers.go +++ b/pkg/domain/filters/containers.go @@ -8,7 +8,6 @@ import ( "github.com/containers/podman/v3/libpod" "github.com/containers/podman/v3/libpod/define" "github.com/containers/podman/v3/pkg/network" - "github.com/containers/podman/v3/pkg/timetype" "github.com/containers/podman/v3/pkg/util" "github.com/pkg/errors" ) @@ -186,18 +185,10 @@ func GenerateContainerFilterFuncs(filter string, filterValues []string, r *libpo return false }, nil case "until": - if len(filterValues) != 1 { - return nil, errors.Errorf("specify exactly one timestamp for %s", filter) - } - ts, err := timetype.GetTimestamp(filterValues[0], time.Now()) - if err != nil { - return nil, err - } - seconds, nanoseconds, err := timetype.ParseTimestamps(ts, 0) + until, err := util.ComputeUntilTimestamp(filter, filterValues) if err != nil { return nil, err } - until := time.Unix(seconds, nanoseconds) return func(c *libpod.Container) bool { if !until.IsZero() && c.CreatedTime().After((until)) { return true diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index edde8ece6..1a833332c 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -174,17 +174,37 @@ func (ic *ContainerEngine) NetworkPrune(ctx context.Context, options entities.Ne if err != nil { return nil, err } + networks, err := network.LoadCNIConfsFromDir(network.GetCNIConfDir(runtimeConfig)) + if err != nil { + return nil, err + } + // Gather up all the non-default networks that the // containers want - usedNetworks := make(map[string]bool) + networksToKeep := make(map[string]bool) for _, c := range cons { nets, _, err := c.Networks() if err != nil { return nil, err } for _, n := range nets { - usedNetworks[n] = true + networksToKeep[n] = true + } + } + if len(options.Filters) != 0 { + for _, n := range networks { + // This network will be kept anyway + if _, found := networksToKeep[n.Name]; found { + continue + } + ok, err := network.IfPassesPruneFilter(runtimeConfig, n, options.Filters) + if err != nil { + return nil, err + } + if !ok { + networksToKeep[n.Name] = true + } } } - return network.PruneNetworks(runtimeConfig, usedNetworks) + return network.PruneNetworks(runtimeConfig, networksToKeep) } diff --git a/pkg/util/filters.go b/pkg/util/filters.go new file mode 100644 index 000000000..bf16f89e3 --- /dev/null +++ b/pkg/util/filters.go @@ -0,0 +1,25 @@ +package util + +import ( + "time" + + "github.com/containers/podman/v3/pkg/timetype" + "github.com/pkg/errors" +) + +// ComputeUntilTimestamp extracts unitil timestamp from filters +func ComputeUntilTimestamp(filter string, filterValues []string) (time.Time, error) { + invalid := time.Time{} + if len(filterValues) != 1 { + return invalid, errors.Errorf("specify exactly one timestamp for %s", filter) + } + ts, err := timetype.GetTimestamp(filterValues[0], time.Now()) + if err != nil { + return invalid, err + } + seconds, nanoseconds, err := timetype.ParseTimestamps(ts, 0) + if err != nil { + return invalid, err + } + return time.Unix(seconds, nanoseconds), nil +} |