github.1git.de/docker/cli@v26.1.3+incompatible/cli/command/container/prune.go (about) 1 package container 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/docker/cli/cli" 8 "github.com/docker/cli/cli/command" 9 "github.com/docker/cli/cli/command/completion" 10 "github.com/docker/cli/opts" 11 "github.com/docker/docker/errdefs" 12 units "github.com/docker/go-units" 13 "github.com/pkg/errors" 14 "github.com/spf13/cobra" 15 ) 16 17 type pruneOptions struct { 18 force bool 19 filter opts.FilterOpt 20 } 21 22 // NewPruneCommand returns a new cobra prune command for containers 23 func NewPruneCommand(dockerCli command.Cli) *cobra.Command { 24 options := pruneOptions{filter: opts.NewFilterOpt()} 25 26 cmd := &cobra.Command{ 27 Use: "prune [OPTIONS]", 28 Short: "Remove all stopped containers", 29 Args: cli.NoArgs, 30 RunE: func(cmd *cobra.Command, args []string) error { 31 spaceReclaimed, output, err := runPrune(cmd.Context(), dockerCli, options) 32 if err != nil { 33 return err 34 } 35 if output != "" { 36 fmt.Fprintln(dockerCli.Out(), output) 37 } 38 fmt.Fprintln(dockerCli.Out(), "Total reclaimed space:", units.HumanSize(float64(spaceReclaimed))) 39 return nil 40 }, 41 Annotations: map[string]string{"version": "1.25"}, 42 ValidArgsFunction: completion.NoComplete, 43 } 44 45 flags := cmd.Flags() 46 flags.BoolVarP(&options.force, "force", "f", false, "Do not prompt for confirmation") 47 flags.Var(&options.filter, "filter", `Provide filter values (e.g. "until=<timestamp>")`) 48 49 return cmd 50 } 51 52 const warning = `WARNING! This will remove all stopped containers. 53 Are you sure you want to continue?` 54 55 func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint64, output string, err error) { 56 pruneFilters := command.PruneFilters(dockerCli, options.filter.Value()) 57 58 if !options.force { 59 r, err := command.PromptForConfirmation(ctx, dockerCli.In(), dockerCli.Out(), warning) 60 if err != nil { 61 return 0, "", err 62 } 63 if !r { 64 return 0, "", errdefs.Cancelled(errors.New("container prune has been cancelled")) 65 } 66 } 67 68 report, err := dockerCli.Client().ContainersPrune(ctx, pruneFilters) 69 if err != nil { 70 return 0, "", err 71 } 72 73 if len(report.ContainersDeleted) > 0 { 74 output = "Deleted Containers:\n" 75 for _, id := range report.ContainersDeleted { 76 output += id + "\n" 77 } 78 spaceReclaimed = report.SpaceReclaimed 79 } 80 81 return spaceReclaimed, output, nil 82 } 83 84 // RunPrune calls the Container Prune API 85 // This returns the amount of space reclaimed and a detailed output string 86 func RunPrune(ctx context.Context, dockerCli command.Cli, _ bool, filter opts.FilterOpt) (uint64, string, error) { 87 return runPrune(ctx, dockerCli, pruneOptions{force: true, filter: filter}) 88 }