github.com/fabiokung/docker@v0.11.2-0.20170222101415-4534dcd49497/cli/command/image/prune.go (about)

     1  package image
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"golang.org/x/net/context"
     7  
     8  	"github.com/docker/docker/cli"
     9  	"github.com/docker/docker/cli/command"
    10  	"github.com/docker/docker/opts"
    11  	units "github.com/docker/go-units"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  type pruneOptions struct {
    16  	force  bool
    17  	all    bool
    18  	filter opts.FilterOpt
    19  }
    20  
    21  // NewPruneCommand returns a new cobra prune command for images
    22  func NewPruneCommand(dockerCli *command.DockerCli) *cobra.Command {
    23  	opts := pruneOptions{filter: opts.NewFilterOpt()}
    24  
    25  	cmd := &cobra.Command{
    26  		Use:   "prune [OPTIONS]",
    27  		Short: "Remove unused images",
    28  		Args:  cli.NoArgs,
    29  		RunE: func(cmd *cobra.Command, args []string) error {
    30  			spaceReclaimed, output, err := runPrune(dockerCli, opts)
    31  			if err != nil {
    32  				return err
    33  			}
    34  			if output != "" {
    35  				fmt.Fprintln(dockerCli.Out(), output)
    36  			}
    37  			fmt.Fprintln(dockerCli.Out(), "Total reclaimed space:", units.HumanSize(float64(spaceReclaimed)))
    38  			return nil
    39  		},
    40  		Tags: map[string]string{"version": "1.25"},
    41  	}
    42  
    43  	flags := cmd.Flags()
    44  	flags.BoolVarP(&opts.force, "force", "f", false, "Do not prompt for confirmation")
    45  	flags.BoolVarP(&opts.all, "all", "a", false, "Remove all unused images, not just dangling ones")
    46  	flags.Var(&opts.filter, "filter", "Provide filter values (e.g. 'until=<timestamp>')")
    47  
    48  	return cmd
    49  }
    50  
    51  const (
    52  	allImageWarning = `WARNING! This will remove all images without at least one container associated to them.
    53  Are you sure you want to continue?`
    54  	danglingWarning = `WARNING! This will remove all dangling images.
    55  Are you sure you want to continue?`
    56  )
    57  
    58  func runPrune(dockerCli *command.DockerCli, opts pruneOptions) (spaceReclaimed uint64, output string, err error) {
    59  	pruneFilters := opts.filter.Value()
    60  	pruneFilters.Add("dangling", fmt.Sprintf("%v", !opts.all))
    61  
    62  	warning := danglingWarning
    63  	if opts.all {
    64  		warning = allImageWarning
    65  	}
    66  	if !opts.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), warning) {
    67  		return
    68  	}
    69  
    70  	report, err := dockerCli.Client().ImagesPrune(context.Background(), pruneFilters)
    71  	if err != nil {
    72  		return
    73  	}
    74  
    75  	if len(report.ImagesDeleted) > 0 {
    76  		output = "Deleted Images:\n"
    77  		for _, st := range report.ImagesDeleted {
    78  			if st.Untagged != "" {
    79  				output += fmt.Sprintln("untagged:", st.Untagged)
    80  			} else {
    81  				output += fmt.Sprintln("deleted:", st.Deleted)
    82  			}
    83  		}
    84  		spaceReclaimed = report.SpaceReclaimed
    85  	}
    86  
    87  	return
    88  }
    89  
    90  // RunPrune calls the Image Prune API
    91  // This returns the amount of space reclaimed and a detailed output string
    92  func RunPrune(dockerCli *command.DockerCli, all bool, filter opts.FilterOpt) (uint64, string, error) {
    93  	return runPrune(dockerCli, pruneOptions{force: true, all: all, filter: filter})
    94  }