mirror of
https://github.com/containers/podman.git
synced 2025-06-21 17:38:12 +08:00
podman system prune support prune unused networks
This is an enhancement for the podman system prune feature. In this issue, it is mentioned that 'network prune' should be wired into 'podman system prune' https://github.com/containers/podman/issues/8673 Therefore, I add the function to remove unused networks. Signed-off-by: Toshiki Sonoda <sonoda.toshiki@fujitsu.com>
This commit is contained in:
@ -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)
|
pruneOptions.Filters, err = parse.FilterArgumentsIntoFilters(filters)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -106,6 +107,11 @@ func prune(cmd *cobra.Command, args []string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
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)))
|
fmt.Printf("Total reclaimed space: %s\n", units.HumanSize((float64)(response.ReclaimedSpace)))
|
||||||
return nil
|
return nil
|
||||||
|
@ -84,3 +84,18 @@ func PrintImagePruneResults(imagePruneReports []*reports.PruneReport, heading bo
|
|||||||
|
|
||||||
return nil
|
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()
|
||||||
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
% podman-system-prune(1)
|
% podman-system-prune(1)
|
||||||
|
|
||||||
## NAME
|
## 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
|
## SYNOPSIS
|
||||||
**podman system prune** [*options*]
|
**podman system prune** [*options*]
|
||||||
|
|
||||||
## DESCRIPTION
|
## 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.
|
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
|
## OPTIONS
|
||||||
#### **--all**, **-a**
|
#### **--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*
|
#### **--filter**=*filters*
|
||||||
|
|
||||||
|
@ -11,16 +11,16 @@ The system command allows you to manage the podman systems
|
|||||||
|
|
||||||
## COMMANDS
|
## COMMANDS
|
||||||
|
|
||||||
| Command | Man Page | Description |
|
| Command | Man Page | Description |
|
||||||
| ------- | ------------------------------------------------------------ | -------------------------------------------------------------------- |
|
| ------- | ------------------------------------------------------------ | ------------------------------------------------------------------------ |
|
||||||
| connection | [podman-system-connection(1)](podman-system-connection.1.md) | Manage the destination(s) for Podman service(s) |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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 |
|
| service | [podman-system-service(1)](podman-system-service.1.md) | Run an API service |
|
||||||
|
|
||||||
## SEE ALSO
|
## SEE ALSO
|
||||||
**[podman(1)](podman.1.md)**
|
**[podman(1)](podman.1.md)**
|
||||||
|
@ -28,6 +28,7 @@ type SystemPruneReport struct {
|
|||||||
PodPruneReport []*PodPruneReport
|
PodPruneReport []*PodPruneReport
|
||||||
ContainerPruneReports []*reports.PruneReport
|
ContainerPruneReports []*reports.PruneReport
|
||||||
ImagePruneReports []*reports.PruneReport
|
ImagePruneReports []*reports.PruneReport
|
||||||
|
NetworkPruneReports []*reports.PruneReport
|
||||||
VolumePruneReports []*reports.PruneReport
|
VolumePruneReports []*reports.PruneReport
|
||||||
ReclaimedSpace uint64
|
ReclaimedSpace uint64
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ func (ic *ContainerEngine) NetworkExists(ctx context.Context, networkname string
|
|||||||
}, nil
|
}, 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) {
|
func (ic *ContainerEngine) NetworkPrune(ctx context.Context, options entities.NetworkPruneOptions) ([]*entities.NetworkPruneReport, error) {
|
||||||
cons, err := ic.Libpod.GetAllContainers()
|
cons, err := ic.Libpod.GetAllContainers()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -137,7 +137,7 @@ func (ic *ContainerEngine) SetupRootless(_ context.Context, noMoveProcess bool)
|
|||||||
return nil
|
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) {
|
func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.SystemPruneOptions) (*entities.SystemPruneReport, error) {
|
||||||
var systemPruneReport = new(entities.SystemPruneReport)
|
var systemPruneReport = new(entities.SystemPruneReport)
|
||||||
filters := []string{}
|
filters := []string{}
|
||||||
@ -148,6 +148,9 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
|
|||||||
found := true
|
found := true
|
||||||
for found {
|
for found {
|
||||||
found = false
|
found = false
|
||||||
|
|
||||||
|
// TODO: Figure out cleaner way to handle all of the different PruneOptions
|
||||||
|
// Remove all unused pods.
|
||||||
podPruneReport, err := ic.prunePodHelper(ctx)
|
podPruneReport, err := ic.prunePodHelper(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -155,9 +158,10 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
|
|||||||
if len(podPruneReport) > 0 {
|
if len(podPruneReport) > 0 {
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
|
|
||||||
systemPruneReport.PodPruneReport = append(systemPruneReport.PodPruneReport, podPruneReport...)
|
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 := entities.ContainerPruneOptions{}
|
||||||
containerPruneOptions.Filters = (url.Values)(options.Filters)
|
containerPruneOptions.Filters = (url.Values)(options.Filters)
|
||||||
|
|
||||||
@ -165,16 +169,18 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
reclaimedSpace += reports.PruneReportsSize(containerPruneReports)
|
reclaimedSpace += reports.PruneReportsSize(containerPruneReports)
|
||||||
systemPruneReport.ContainerPruneReports = append(systemPruneReport.ContainerPruneReports, containerPruneReports...)
|
systemPruneReport.ContainerPruneReports = append(systemPruneReport.ContainerPruneReports, containerPruneReports...)
|
||||||
|
|
||||||
|
// Remove all unused images.
|
||||||
imagePruneOptions := entities.ImagePruneOptions{
|
imagePruneOptions := entities.ImagePruneOptions{
|
||||||
All: options.All,
|
All: options.All,
|
||||||
Filter: filters,
|
Filter: filters,
|
||||||
}
|
}
|
||||||
|
|
||||||
imageEngine := ImageEngine{Libpod: ic.Libpod}
|
imageEngine := ImageEngine{Libpod: ic.Libpod}
|
||||||
imagePruneReports, err := imageEngine.Prune(ctx, imagePruneOptions)
|
imagePruneReports, err := imageEngine.Prune(ctx, imagePruneOptions)
|
||||||
reclaimedSpace += reports.PruneReportsSize(imagePruneReports)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -182,10 +188,33 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
|
|||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reclaimedSpace += reports.PruneReportsSize(imagePruneReports)
|
||||||
systemPruneReport.ImagePruneReports = append(systemPruneReport.ImagePruneReports, 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 {
|
if options.Volume {
|
||||||
volumePruneOptions := entities.VolumePruneOptions{}
|
volumePruneOptions := entities.VolumePruneOptions{}
|
||||||
volumePruneOptions.Filters = (url.Values)(options.Filters)
|
volumePruneOptions.Filters = (url.Values)(options.Filters)
|
||||||
|
|
||||||
volumePruneReport, err := ic.VolumePrune(ctx, volumePruneOptions)
|
volumePruneReport, err := ic.VolumePrune(ctx, volumePruneOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -193,6 +222,7 @@ func (ic *ContainerEngine) SystemPrune(ctx context.Context, options entities.Sys
|
|||||||
if len(volumePruneReport) > 0 {
|
if len(volumePruneReport) > 0 {
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
|
|
||||||
reclaimedSpace += reports.PruneReportsSize(volumePruneReport)
|
reclaimedSpace += reports.PruneReportsSize(volumePruneReport)
|
||||||
systemPruneReport.VolumePruneReports = append(systemPruneReport.VolumePruneReports, volumePruneReport...)
|
systemPruneReport.VolumePruneReports = append(systemPruneReport.VolumePruneReports, volumePruneReport...)
|
||||||
}
|
}
|
||||||
|
@ -258,6 +258,29 @@ var _ = Describe("Podman prune", func() {
|
|||||||
Expect(pods.OutputToStringArray()).To(HaveLen(2))
|
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() {
|
It("podman system prune - pod,container stopped", func() {
|
||||||
session := podmanTest.Podman([]string{"pod", "create"})
|
session := podmanTest.Podman([]string{"pod", "create"})
|
||||||
session.WaitWithDefaultTimeout()
|
session.WaitWithDefaultTimeout()
|
||||||
|
Reference in New Issue
Block a user