github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/cmd/podman/system_prune.go (about)

     1  package main
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/containers/libpod/cmd/podman/cliconfig"
    10  	"github.com/containers/libpod/cmd/podman/shared"
    11  	"github.com/containers/libpod/pkg/adapter"
    12  	"github.com/pkg/errors"
    13  	"github.com/sirupsen/logrus"
    14  	"github.com/spf13/cobra"
    15  )
    16  
    17  var (
    18  	pruneSystemCommand     cliconfig.SystemPruneValues
    19  	pruneSystemDescription = `
    20  	podman system prune
    21  
    22          Remove unused data
    23  `
    24  	_pruneSystemCommand = &cobra.Command{
    25  		Use:   "prune",
    26  		Args:  noSubArgs,
    27  		Short: "Remove unused data",
    28  		Long:  pruneSystemDescription,
    29  		RunE: func(cmd *cobra.Command, args []string) error {
    30  			pruneSystemCommand.InputArgs = args
    31  			pruneSystemCommand.GlobalFlags = MainGlobalOpts
    32  			pruneSystemCommand.Remote = remoteclient
    33  			return pruneSystemCmd(&pruneSystemCommand)
    34  		},
    35  	}
    36  )
    37  
    38  func init() {
    39  	pruneSystemCommand.Command = _pruneSystemCommand
    40  	pruneSystemCommand.SetHelpTemplate(HelpTemplate())
    41  	pruneSystemCommand.SetUsageTemplate(UsageTemplate())
    42  	flags := pruneSystemCommand.Flags()
    43  	flags.BoolVarP(&pruneSystemCommand.All, "all", "a", false, "Remove all unused data")
    44  	flags.BoolVarP(&pruneSystemCommand.Force, "force", "f", false, "Do not prompt for confirmation")
    45  	flags.BoolVar(&pruneSystemCommand.Volume, "volumes", false, "Prune volumes")
    46  
    47  }
    48  
    49  func pruneSystemCmd(c *cliconfig.SystemPruneValues) error {
    50  
    51  	// Prompt for confirmation if --force is not set
    52  	if !c.Force {
    53  		reader := bufio.NewReader(os.Stdin)
    54  		volumeString := ""
    55  		if c.Volume {
    56  			volumeString = `
    57          - all volumes not used by at least one container`
    58  		}
    59  		fmt.Printf(`
    60  WARNING! This will remove:
    61          - all stopped containers%s
    62          - all stopped pods
    63          - all dangling images
    64          - all build cache
    65  Are you sure you want to continue? [y/N] `, volumeString)
    66  		answer, err := reader.ReadString('\n')
    67  		if err != nil {
    68  			return errors.Wrapf(err, "error reading input")
    69  		}
    70  		if strings.ToLower(answer)[0] != 'y' {
    71  			return nil
    72  		}
    73  	}
    74  
    75  	runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
    76  	if err != nil {
    77  		return errors.Wrapf(err, "could not get runtime")
    78  	}
    79  	defer runtime.DeferredShutdown(false)
    80  
    81  	// We must clean out pods first because if they may have infra containers
    82  	fmt.Println("Deleted Pods")
    83  	pruneValues := cliconfig.PodPruneValues{
    84  		PodmanCommand: c.PodmanCommand,
    85  	}
    86  	ctx := getContext()
    87  	ok, failures, lasterr := runtime.PrunePods(ctx, &pruneValues)
    88  
    89  	if err := printCmdResults(ok, failures); err != nil {
    90  		return err
    91  	}
    92  
    93  	rmWorkers := shared.Parallelize("rm")
    94  	fmt.Println("Deleted Containers")
    95  	ok, failures, err = runtime.Prune(ctx, rmWorkers, []string{})
    96  	if err != nil {
    97  		if lasterr != nil {
    98  			logrus.Errorf("%q", err)
    99  		}
   100  		lasterr = err
   101  	}
   102  	if err := printCmdResults(ok, failures); err != nil {
   103  		return err
   104  	}
   105  
   106  	if c.Bool("volumes") {
   107  		fmt.Println("Deleted Volumes")
   108  		err := volumePrune(runtime, getContext())
   109  		if err != nil {
   110  			if lasterr != nil {
   111  				logrus.Errorf("%q", lasterr)
   112  			}
   113  			lasterr = err
   114  		}
   115  	}
   116  
   117  	// Call prune; if any cids are returned, print them and then
   118  	// return err in case an error also came up
   119  	// TODO: support for filters in system prune
   120  	pruneCids, err := runtime.PruneImages(ctx, c.All, []string{})
   121  	if len(pruneCids) > 0 {
   122  		fmt.Println("Deleted Images")
   123  		for _, cid := range pruneCids {
   124  			fmt.Println(cid)
   125  		}
   126  	}
   127  	if err != nil {
   128  		if lasterr != nil {
   129  			logrus.Errorf("%q", lasterr)
   130  		}
   131  		lasterr = err
   132  	}
   133  	return lasterr
   134  }