github.com/ali-iotechsys/cli@v20.10.0+incompatible/cli/command/image/prune.go (about) 1 package image 2 3 import ( 4 "context" 5 "fmt" 6 "strings" 7 8 "github.com/docker/cli/cli" 9 "github.com/docker/cli/cli/command" 10 "github.com/docker/cli/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.Cli) *cobra.Command { 23 options := 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, options) 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 Annotations: map[string]string{"version": "1.25"}, 41 } 42 43 flags := cmd.Flags() 44 flags.BoolVarP(&options.force, "force", "f", false, "Do not prompt for confirmation") 45 flags.BoolVarP(&options.all, "all", "a", false, "Remove all unused images, not just dangling ones") 46 flags.Var(&options.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.Cli, options pruneOptions) (spaceReclaimed uint64, output string, err error) { 59 pruneFilters := options.filter.Value().Clone() 60 pruneFilters.Add("dangling", fmt.Sprintf("%v", !options.all)) 61 pruneFilters = command.PruneFilters(dockerCli, pruneFilters) 62 63 warning := danglingWarning 64 if options.all { 65 warning = allImageWarning 66 } 67 if !options.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), warning) { 68 return 0, "", nil 69 } 70 71 report, err := dockerCli.Client().ImagesPrune(context.Background(), pruneFilters) 72 if err != nil { 73 return 0, "", err 74 } 75 76 if len(report.ImagesDeleted) > 0 { 77 var sb strings.Builder 78 sb.WriteString("Deleted Images:\n") 79 for _, st := range report.ImagesDeleted { 80 if st.Untagged != "" { 81 sb.WriteString("untagged: ") 82 sb.WriteString(st.Untagged) 83 sb.WriteByte('\n') 84 } else { 85 sb.WriteString("deleted: ") 86 sb.WriteString(st.Deleted) 87 sb.WriteByte('\n') 88 } 89 } 90 output = sb.String() 91 spaceReclaimed = report.SpaceReclaimed 92 } 93 94 return spaceReclaimed, output, nil 95 } 96 97 // RunPrune calls the Image Prune API 98 // This returns the amount of space reclaimed and a detailed output string 99 func RunPrune(dockerCli command.Cli, all bool, filter opts.FilterOpt) (uint64, string, error) { 100 return runPrune(dockerCli, pruneOptions{force: true, all: all, filter: filter}) 101 }