summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorBaron Lenardson <lenardson.baron@gmail.com>2020-12-22 20:02:08 -0600
committerBaron Lenardson <lenardson.baron@gmail.com>2020-12-30 19:57:35 -0600
commitb90f7f90952f16e0c1b05e8f750b56bb43711b5e (patch)
treeba33228b57820f0f59b9b9563b2e79ce407dd2ed /libpod
parentc6c9b45985790af50a78da4c222e10672f92c629 (diff)
downloadpodman-b90f7f90952f16e0c1b05e8f750b56bb43711b5e.tar.gz
podman-b90f7f90952f16e0c1b05e8f750b56bb43711b5e.tar.bz2
podman-b90f7f90952f16e0c1b05e8f750b56bb43711b5e.zip
Rework pruning to report reclaimed space
This change adds code to report the reclaimed space after a prune. Reclaimed space from volumes, images, and containers is recorded during the prune call in a PruneReport struct. These structs are collected into a slice during a system prune and processed afterwards to calculate the total reclaimed space. Closes #8658 Signed-off-by: Baron Lenardson <lenardson.baron@gmail.com>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/image/prune.go23
-rw-r--r--libpod/runtime_ctr.go27
-rw-r--r--libpod/runtime_volume.go25
-rw-r--r--libpod/volume.go14
4 files changed, 66 insertions, 23 deletions
diff --git a/libpod/image/prune.go b/libpod/image/prune.go
index b38265a7e..3c06a89c2 100644
--- a/libpod/image/prune.go
+++ b/libpod/image/prune.go
@@ -6,6 +6,7 @@ import (
"time"
"github.com/containers/podman/v2/libpod/events"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/containers/podman/v2/pkg/timetype"
"github.com/containers/storage"
"github.com/pkg/errors"
@@ -110,7 +111,8 @@ func (ir *Runtime) GetPruneImages(ctx context.Context, all bool, filterFuncs []I
// PruneImages prunes dangling and optionally all unused images from the local
// image store
-func (ir *Runtime) PruneImages(ctx context.Context, all bool, filter []string) ([]string, error) {
+func (ir *Runtime) PruneImages(ctx context.Context, all bool, filter []string) ([]*reports.PruneReport, error) {
+ preports := make([]*reports.PruneReport, 0)
filterFuncs := make([]ImageFilter, 0, len(filter))
for _, f := range filter {
filterSplit := strings.SplitN(f, "=", 2)
@@ -125,7 +127,6 @@ func (ir *Runtime) PruneImages(ctx context.Context, all bool, filter []string) (
filterFuncs = append(filterFuncs, generatedFunc)
}
- pruned := []string{}
prev := 0
for {
toPrune, err := ir.GetPruneImages(ctx, all, filterFuncs)
@@ -143,6 +144,13 @@ func (ir *Runtime) PruneImages(ctx context.Context, all bool, filter []string) (
if err != nil {
return nil, err
}
+ nameOrID := img.ID()
+ s, err := img.Size(ctx)
+ imgSize := *s
+ if err != nil {
+ logrus.Warnf("Failed to collect image size for: %s, %s", nameOrID, err)
+ imgSize = 0
+ }
if err := img.Remove(ctx, false); err != nil {
if errors.Cause(err) == storage.ErrImageUsedByContainer {
logrus.Warnf("Failed to prune image %s as it is in use: %v.\nA container associated with containers/storage (e.g., Buildah, CRI-O, etc.) maybe associated with this image.\nUsing the rmi command with the --force option will remove the container and image, but may cause failures for other dependent systems.", img.ID(), err)
@@ -151,13 +159,18 @@ func (ir *Runtime) PruneImages(ctx context.Context, all bool, filter []string) (
return nil, errors.Wrap(err, "failed to prune image")
}
defer img.newImageEvent(events.Prune)
- nameOrID := img.ID()
+
if len(repotags) > 0 {
nameOrID = repotags[0]
}
- pruned = append(pruned, nameOrID)
+
+ preports = append(preports, &reports.PruneReport{
+ Id: nameOrID,
+ Err: nil,
+ Size: uint64(imgSize),
+ })
}
}
- return pruned, nil
+ return preports, nil
}
diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go
index 14b537ca2..f22e48746 100644
--- a/libpod/runtime_ctr.go
+++ b/libpod/runtime_ctr.go
@@ -14,6 +14,7 @@ import (
"github.com/containers/podman/v2/libpod/events"
"github.com/containers/podman/v2/libpod/shutdown"
"github.com/containers/podman/v2/pkg/cgroups"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/containers/podman/v2/pkg/rootless"
"github.com/containers/storage"
"github.com/containers/storage/pkg/stringid"
@@ -884,9 +885,8 @@ func (r *Runtime) GetExecSessionContainer(id string) (*Container, error) {
// PruneContainers removes stopped and exited containers from localstorage. A set of optional filters
// can be provided to be more granular.
-func (r *Runtime) PruneContainers(filterFuncs []ContainerFilter) (map[string]int64, map[string]error, error) {
- pruneErrors := make(map[string]error)
- prunedContainers := make(map[string]int64)
+func (r *Runtime) PruneContainers(filterFuncs []ContainerFilter) ([]*reports.PruneReport, error) {
+ preports := make([]*reports.PruneReport, 0)
// We add getting the exited and stopped containers via a filter
containerStateFilter := func(c *Container) bool {
if c.PodID() != "" {
@@ -906,23 +906,28 @@ func (r *Runtime) PruneContainers(filterFuncs []ContainerFilter) (map[string]int
filterFuncs = append(filterFuncs, containerStateFilter)
delContainers, err := r.GetContainers(filterFuncs...)
if err != nil {
- return nil, nil, err
+ return nil, err
}
for _, c := range delContainers {
- ctr := c
- size, err := ctr.RWSize()
+ report := new(reports.PruneReport)
+ report.Id = c.ID()
+ report.Err = nil
+ report.Size = 0
+ size, err := c.RWSize()
if err != nil {
- pruneErrors[ctr.ID()] = err
+ report.Err = err
+ preports = append(preports, report)
continue
}
- err = r.RemoveContainer(context.Background(), ctr, false, false)
+ err = r.RemoveContainer(context.Background(), c, false, false)
if err != nil {
- pruneErrors[ctr.ID()] = err
+ report.Err = err
} else {
- prunedContainers[ctr.ID()] = size
+ report.Size = (uint64)(size)
}
+ preports = append(preports, report)
}
- return prunedContainers, pruneErrors, nil
+ return preports, nil
}
// MountStorageContainer mounts the storage container's root filesystem
diff --git a/libpod/runtime_volume.go b/libpod/runtime_volume.go
index 10c32a119..9d985f905 100644
--- a/libpod/runtime_volume.go
+++ b/libpod/runtime_volume.go
@@ -5,6 +5,7 @@ import (
"github.com/containers/podman/v2/libpod/define"
"github.com/containers/podman/v2/libpod/events"
+ "github.com/containers/podman/v2/pkg/domain/entities/reports"
"github.com/pkg/errors"
)
@@ -133,22 +134,32 @@ func (r *Runtime) GetAllVolumes() ([]*Volume, error) {
}
// PruneVolumes removes unused volumes from the system
-func (r *Runtime) PruneVolumes(ctx context.Context, filterFuncs []VolumeFilter) (map[string]error, error) {
- reports := make(map[string]error)
+func (r *Runtime) PruneVolumes(ctx context.Context, filterFuncs []VolumeFilter) ([]*reports.PruneReport, error) {
+ preports := make([]*reports.PruneReport, 0)
vols, err := r.Volumes(filterFuncs...)
if err != nil {
return nil, err
}
for _, vol := range vols {
+ report := new(reports.PruneReport)
+ volSize, err := vol.Size()
+ if err != nil {
+ volSize = 0
+ }
+ report.Size = volSize
+ report.Id = vol.Name()
if err := r.RemoveVolume(ctx, vol, false); err != nil {
if errors.Cause(err) != define.ErrVolumeBeingUsed && errors.Cause(err) != define.ErrVolumeRemoved {
- reports[vol.Name()] = err
+ report.Err = err
+ } else {
+ // We didn't remove the volume for some reason
+ continue
}
- continue
+ } else {
+ vol.newVolumeEvent(events.Prune)
}
- vol.newVolumeEvent(events.Prune)
- reports[vol.Name()] = nil
+ preports = append(preports, report)
}
- return reports, nil
+ return preports, nil
}
diff --git a/libpod/volume.go b/libpod/volume.go
index 0535bf4db..ed08d375f 100644
--- a/libpod/volume.go
+++ b/libpod/volume.go
@@ -1,6 +1,8 @@
package libpod
import (
+ "os"
+ "path/filepath"
"time"
"github.com/containers/podman/v2/libpod/define"
@@ -79,6 +81,18 @@ func (v *Volume) Name() string {
return v.config.Name
}
+// Returns the size on disk of volume
+func (v *Volume) Size() (uint64, error) {
+ var size uint64
+ err := filepath.Walk(v.config.MountPoint, func(path string, info os.FileInfo, err error) error {
+ if err == nil && !info.IsDir() {
+ size += (uint64)(info.Size())
+ }
+ return err
+ })
+ return size, err
+}
+
// Driver retrieves the volume's driver.
func (v *Volume) Driver() string {
return v.config.Driver