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 }