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  }