diff options
-rw-r--r-- | CONTRIBUTING.md | 2 | ||||
-rw-r--r-- | cmd/podman/system/prune.go | 6 | ||||
-rw-r--r-- | cmd/podman/utils/utils.go | 15 | ||||
-rw-r--r-- | docs/source/markdown/podman-system-prune.1.md | 6 | ||||
-rw-r--r-- | docs/source/markdown/podman-system.1.md | 20 | ||||
-rw-r--r-- | go.mod | 2 | ||||
-rw-r--r-- | go.sum | 6 | ||||
-rw-r--r-- | pkg/api/handlers/compat/containers_stats.go | 8 | ||||
-rw-r--r-- | pkg/domain/entities/system.go | 1 | ||||
-rw-r--r-- | pkg/domain/infra/abi/network.go | 2 | ||||
-rw-r--r-- | pkg/domain/infra/abi/system.go | 38 | ||||
-rw-r--r-- | test/apiv2/20-containers.at | 11 | ||||
-rw-r--r-- | test/e2e/prune_test.go | 23 | ||||
-rw-r--r-- | vendor/github.com/stretchr/testify/assert/assertions.go | 7 | ||||
-rw-r--r-- | vendor/modules.txt | 2 |
15 files changed, 122 insertions, 27 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6b63c7b5a..eddd35cba 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -70,7 +70,7 @@ $ cd $GOPATH/src/github.com/containers/podman ### Deal with make -Podman use a Makefile to realize common action like building etc... +Podman uses a Makefile to realize common actions like building etc... You can list available actions by using: ```shell diff --git a/cmd/podman/system/prune.go b/cmd/podman/system/prune.go index ff78f93bb..1d6ba8155 100644 --- a/cmd/podman/system/prune.go +++ b/cmd/podman/system/prune.go @@ -75,6 +75,7 @@ func prune(cmd *cobra.Command, args []string) error { } } + // Remove all unused pods, containers, images, networks, and volume data. pruneOptions.Filters, err = parse.FilterArgumentsIntoFilters(filters) if err != nil { return err @@ -106,6 +107,11 @@ func prune(cmd *cobra.Command, args []string) error { if err != nil { return err } + // Print Network prune results + err = utils.PrintNetworkPruneResults(response.NetworkPruneReports, true) + if err != nil { + return err + } fmt.Printf("Total reclaimed space: %s\n", units.HumanSize((float64)(response.ReclaimedSpace))) return nil diff --git a/cmd/podman/utils/utils.go b/cmd/podman/utils/utils.go index 6fd6647d0..73bb34983 100644 --- a/cmd/podman/utils/utils.go +++ b/cmd/podman/utils/utils.go @@ -84,3 +84,18 @@ func PrintImagePruneResults(imagePruneReports []*reports.PruneReport, heading bo return nil } + +func PrintNetworkPruneResults(networkPruneReport []*reports.PruneReport, heading bool) error { + var errs OutputErrors + if heading && len(networkPruneReport) > 0 { + fmt.Println("Deleted Networks") + } + for _, r := range networkPruneReport { + if r.Err == nil { + fmt.Println(r.Id) + } else { + errs = append(errs, r.Err) + } + } + return errs.PrintErrors() +} diff --git a/docs/source/markdown/podman-system-prune.1.md b/docs/source/markdown/podman-system-prune.1.md index fb9ed44d6..c4c17fbe5 100644 --- a/docs/source/markdown/podman-system-prune.1.md +++ b/docs/source/markdown/podman-system-prune.1.md @@ -1,13 +1,13 @@ % podman-system-prune(1) ## NAME -podman\-system\-prune - Remove all unused pod, container, image and volume data +podman\-system\-prune - Remove all unused pods, containers, images, networks, and volume data ## SYNOPSIS **podman system prune** [*options*] ## DESCRIPTION -**podman system prune** removes all unused containers (both dangling and unreferenced), pods and optionally, volumes from local storage. +**podman system prune** removes all unused containers (both dangling and unreferenced), pods, networks, and optionally, volumes from local storage. With the **--all** option, you can delete all unused images. Unused images are dangling images as well as any image that does not have any containers based on it. @@ -16,7 +16,7 @@ By default, volumes are not removed to prevent important data from being deleted ## OPTIONS #### **--all**, **-a** -Recursively remove all unused pod, container, image and volume data (Maximum 50 iterations.) +Recursively remove all unused pods, containers, images, networks, and volume data. (Maximum 50 iterations.) #### **--filter**=*filters* diff --git a/docs/source/markdown/podman-system.1.md b/docs/source/markdown/podman-system.1.md index ae18aca88..7469eb79d 100644 --- a/docs/source/markdown/podman-system.1.md +++ b/docs/source/markdown/podman-system.1.md @@ -11,16 +11,16 @@ The system command allows you to manage the podman systems ## COMMANDS -| Command | Man Page | Description | -| ------- | ------------------------------------------------------------ | -------------------------------------------------------------------- | -| connection | [podman-system-connection(1)](podman-system-connection.1.md) | Manage the destination(s) for Podman service(s) | -| df | [podman-system-df(1)](podman-system-df.1.md) | Show podman disk usage. | -| info | [podman-system-info(1)](podman-info.1.md) | Displays Podman related system information. | -| migrate | [podman-system-migrate(1)](podman-system-migrate.1.md) | Migrate existing containers to a new podman version. | -| prune | [podman-system-prune(1)](podman-system-prune.1.md) | Remove all unused pod, container, image and volume data. | -| renumber | [podman-system-renumber(1)](podman-system-renumber.1.md) | Migrate lock numbers to handle a change in maximum number of locks. | -| reset | [podman-system-reset(1)](podman-system-reset.1.md) | Reset storage back to initial state. | -| service | [podman-system-service(1)](podman-system-service.1.md) | Run an API service | +| Command | Man Page | Description | +| ------- | ------------------------------------------------------------ | ------------------------------------------------------------------------ | +| connection | [podman-system-connection(1)](podman-system-connection.1.md) | Manage the destination(s) for Podman service(s) | +| df | [podman-system-df(1)](podman-system-df.1.md) | Show podman disk usage. | +| info | [podman-system-info(1)](podman-info.1.md) | Displays Podman related system information. | +| migrate | [podman-system-migrate(1)](podman-system-migrate.1.md) | Migrate existing containers to a new podman version. | +| prune | [podman-system-prune(1)](podman-system-prune.1.md) | Remove all unused pods, containers, images, networks, and volume data. | +| renumber | [podman-system-renumber(1)](podman-system-renumber.1.md) | Migrate lock numbers to handle a change in maximum number of locks. | +| reset | [podman-system-reset(1)](podman-system-reset.1.md) | Reset storage back to initial state. | +| service | [podman-system-service(1)](podman-system-service.1.md) | Run an API service | ## SEE ALSO **[podman(1)](podman.1.md)** @@ -57,7 +57,7 @@ require ( github.com/sirupsen/logrus v1.8.1 github.com/spf13/cobra v1.4.0 github.com/spf13/pflag v1.0.5 - github.com/stretchr/testify v1.7.2 + github.com/stretchr/testify v1.7.4 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 github.com/uber/jaeger-client-go v2.30.0+incompatible github.com/ulikunitz/xz v0.5.10 @@ -1264,8 +1264,9 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v0.0.0-20170130113145-4d4bfba8f1d1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -1276,8 +1277,9 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.7.4 h1:wZRexSlwd7ZXfKINDLsO4r7WBt3gTKONc6K/VesHvHM= +github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/sylabs/sif/v2 v2.7.0/go.mod h1:TiyBWsgWeh5yBeQFNuQnvROwswqK7YJT8JA1L53bsXQ= github.com/sylabs/sif/v2 v2.7.1 h1:XXt9AP39sQfsMCGOGQ/XP9H47yqZOvAonalkaCaNIYM= diff --git a/pkg/api/handlers/compat/containers_stats.go b/pkg/api/handlers/compat/containers_stats.go index 6855e369b..66743ce06 100644 --- a/pkg/api/handlers/compat/containers_stats.go +++ b/pkg/api/handlers/compat/containers_stats.go @@ -132,6 +132,12 @@ streamLabel: // A label to flatten the scope InstanceID: "", } + cfg := ctnr.Config() + memoryLimit := cgroupStat.Memory.Usage.Limit + if cfg.Spec.Linux != nil && cfg.Spec.Linux.Resources != nil && cfg.Spec.Linux.Resources.Memory != nil && *cfg.Spec.Linux.Resources.Memory.Limit > 0 { + memoryLimit = uint64(*cfg.Spec.Linux.Resources.Memory.Limit) + } + systemUsage, _ := cgroups.GetSystemCPUUsage() s := StatsJSON{ Stats: Stats{ @@ -173,7 +179,7 @@ streamLabel: // A label to flatten the scope MaxUsage: cgroupStat.Memory.Usage.Limit, Stats: nil, Failcnt: 0, - Limit: cgroupStat.Memory.Usage.Limit, + Limit: memoryLimit, Commit: 0, CommitPeak: 0, PrivateWorkingSet: 0, diff --git a/pkg/domain/entities/system.go b/pkg/domain/entities/system.go index 21026477d..331d2bcdc 100644 --- a/pkg/domain/entities/system.go +++ b/pkg/domain/entities/system.go @@ -28,6 +28,7 @@ type SystemPruneReport struct { PodPruneReport []*PodPruneReport ContainerPruneReports []*reports.PruneReport ImagePruneReports []*reports.PruneReport + NetworkPruneReports []*reports.PruneReport VolumePruneReports []*reports.PruneReport ReclaimedSpace uint64 } diff --git a/pkg/domain/infra/abi/network.go b/pkg/domain/infra/abi/network.go index 47f7917f4..c5f3cf8b3 100644 --- a/pkg/domain/infra/abi/network.go +++ b/pkg/domain/infra/abi/network.go @@ -142,7 +142,7 @@ func (ic *ContainerEngine) NetworkExists(ctx context.Context, networkname string }, nil } -// Network prune removes unused cni networks +// Network prune removes unused networks func (ic *ContainerEngine) NetworkPrune(ctx context.Context, options entities.NetworkPruneOptions) ([]*entities.NetworkPruneReport, error) { cons, err := ic.Libpod.GetAllContainers() if err != nil { diff --git a/pkg/domain/infra/abi/system.go b/pkg/domain/infra/abi/system.go index 762f0d79a..820ba529b 100644 --- a/pkg/domain/infra/abi/system.go +++ b/pkg/domain/infra/abi/system.go @@ -137,7 +137,7 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, noMoveProcess bool) return nil } -// SystemPrune removes unused data from the system. Pruning pods, containers, volumes and images. +// SystemPrune removes unused data from the system. Pruning pods, containers, networks, volumes and images. func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.SystemPruneOptions) (*entities.SystemPruneReport, error) { var systemPruneReport = new(entities.SystemPruneReport) filters := []string{} @@ -148,6 +148,9 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys found := true for found { found = false + + // TODO: Figure out cleaner way to handle all of the different PruneOptions + // Remove all unused pods. podPruneReport, err := ic.prunePodHelper(ctx) if err != nil { return nil, err @@ -155,9 +158,10 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys if len(podPruneReport) > 0 { found = true } + systemPruneReport.PodPruneReport = append(systemPruneReport.PodPruneReport, podPruneReport...) - // TODO: Figure out cleaner way to handle all of the different PruneOptions + // Remove all unused containers. containerPruneOptions := entities.ContainerPruneOptions{} containerPruneOptions.Filters = (url.Values)(options.Filters) @@ -165,16 +169,18 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys if err != nil { return nil, err } + reclaimedSpace += reports.PruneReportsSize(containerPruneReports) systemPruneReport.ContainerPruneReports = append(systemPruneReport.ContainerPruneReports, containerPruneReports...) + + // Remove all unused images. imagePruneOptions := entities.ImagePruneOptions{ All: options.All, Filter: filters, } + imageEngine := ImageEngine{Libpod: ic.Libpod} imagePruneReports, err := imageEngine.Prune(ctx, imagePruneOptions) - reclaimedSpace += reports.PruneReportsSize(imagePruneReports) - if err != nil { return nil, err } @@ -182,10 +188,33 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys found = true } + reclaimedSpace += reports.PruneReportsSize(imagePruneReports) systemPruneReport.ImagePruneReports = append(systemPruneReport.ImagePruneReports, imagePruneReports...) + + // Remove all unused networks. + networkPruneOptions := entities.NetworkPruneOptions{} + networkPruneOptions.Filters = options.Filters + + networkPruneReport, err := ic.NetworkPrune(ctx, networkPruneOptions) + if err != nil { + return nil, err + } + if len(networkPruneReport) > 0 { + found = true + } + for _, net := range networkPruneReport { + systemPruneReport.NetworkPruneReports = append(systemPruneReport.NetworkPruneReports, &reports.PruneReport{ + Id: net.Name, + Err: net.Error, + Size: 0, + }) + } + + // Remove unused volume data. if options.Volume { volumePruneOptions := entities.VolumePruneOptions{} volumePruneOptions.Filters = (url.Values)(options.Filters) + volumePruneReport, err := ic.VolumePrune(ctx, volumePruneOptions) if err != nil { return nil, err @@ -193,6 +222,7 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys if len(volumePruneReport) > 0 { found = true } + reclaimedSpace += reports.PruneReportsSize(volumePruneReport) systemPruneReport.VolumePruneReports = append(systemPruneReport.VolumePruneReports, volumePruneReport...) } diff --git a/test/apiv2/20-containers.at b/test/apiv2/20-containers.at index 80bbcd60e..cfd6aab33 100644 --- a/test/apiv2/20-containers.at +++ b/test/apiv2/20-containers.at @@ -100,6 +100,17 @@ fi t DELETE libpod/containers/$cid 200 .[0].Id=$cid +# Issue #14676: make sure the stats show the memory limit specified for the container +if root; then + CTRNAME=ctr-with-limit + podman run --name $CTRNAME -d -m 512m -v /tmp:/tmp $IMAGE top + + t GET libpod/containers/$CTRNAME/stats?stream=false 200 \ + .memory_stats.limit=536870912 + + podman rm -f $CTRNAME +fi + # Issue #6799: it should be possible to start a container, even w/o args. t POST libpod/containers/create?name=test_noargs Image=${IMAGE} 201 \ .Id~[0-9a-f]\\{64\\} diff --git a/test/e2e/prune_test.go b/test/e2e/prune_test.go index 75adf1724..119c8d41e 100644 --- a/test/e2e/prune_test.go +++ b/test/e2e/prune_test.go @@ -258,6 +258,29 @@ var _ = Describe("Podman prune", func() { Expect(pods.OutputToStringArray()).To(HaveLen(2)) }) + It("podman system prune networks", func() { + // About netavark network backend test. + session := podmanTest.Podman([]string{"network", "create", "test"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + session = podmanTest.Podman([]string{"system", "prune", "-f"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + + // Default network should exists. + session = podmanTest.Podman([]string{"network", "ls", "-q", "--filter", "name=^podman$"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToStringArray()).To(HaveLen(1)) + + // Remove all unused networks. + session = podmanTest.Podman([]string{"network", "ls", "-q", "--filter", "name=^test$"}) + session.WaitWithDefaultTimeout() + Expect(session).Should(Exit(0)) + Expect(session.OutputToStringArray()).To(HaveLen(0)) + }) + It("podman system prune - pod,container stopped", func() { session := podmanTest.Podman([]string{"pod", "create"}) session.WaitWithDefaultTimeout() diff --git a/vendor/github.com/stretchr/testify/assert/assertions.go b/vendor/github.com/stretchr/testify/assert/assertions.go index 0357b2231..580fdea4c 100644 --- a/vendor/github.com/stretchr/testify/assert/assertions.go +++ b/vendor/github.com/stretchr/testify/assert/assertions.go @@ -563,16 +563,17 @@ func isEmpty(object interface{}) bool { switch objValue.Kind() { // collection types are empty when they have no element - case reflect.Array, reflect.Chan, reflect.Map, reflect.Slice: + case reflect.Chan, reflect.Map, reflect.Slice: return objValue.Len() == 0 - // pointers are empty if nil or if the value they point to is empty + // pointers are empty if nil or if the value they point to is empty case reflect.Ptr: if objValue.IsNil() { return true } deref := objValue.Elem().Interface() return isEmpty(deref) - // for all other types, compare against the zero value + // for all other types, compare against the zero value + // array types are empty when they match their zero-initialized state default: zero := reflect.Zero(objValue.Type()) return reflect.DeepEqual(object, zero.Interface()) diff --git a/vendor/modules.txt b/vendor/modules.txt index c2dafa52a..ae901ac5d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -642,7 +642,7 @@ github.com/spf13/cobra github.com/spf13/pflag # github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 github.com/stefanberger/go-pkcs11uri -# github.com/stretchr/testify v1.7.2 +# github.com/stretchr/testify v1.7.4 ## explicit github.com/stretchr/testify/assert github.com/stretchr/testify/require |