| 70 | ) |
| 71 | |
| 72 | func runPrune(ctx context.Context, dockerCli command.Cli, options pruneOptions) (spaceReclaimed uint64, output string, err error) { |
| 73 | pruneFilters := command.PruneFilters(dockerCli, options.filter.Value()) |
| 74 | pruneFilters.Add("dangling", strconv.FormatBool(!options.all)) |
| 75 | |
| 76 | warning := danglingWarning |
| 77 | if options.all { |
| 78 | warning = allImageWarning |
| 79 | } |
| 80 | if !options.force { |
| 81 | r, err := prompt.Confirm(ctx, dockerCli.In(), dockerCli.Out(), warning) |
| 82 | if err != nil { |
| 83 | return 0, "", err |
| 84 | } |
| 85 | if !r { |
| 86 | return 0, "", cancelledErr{errors.New("image prune has been cancelled")} |
| 87 | } |
| 88 | } |
| 89 | |
| 90 | res, err := dockerCli.Client().ImagePrune(ctx, client.ImagePruneOptions{ |
| 91 | Filters: pruneFilters, |
| 92 | }) |
| 93 | if err != nil { |
| 94 | return 0, "", err |
| 95 | } |
| 96 | |
| 97 | var sb strings.Builder |
| 98 | if len(res.Report.ImagesDeleted) > 0 { |
| 99 | sb.WriteString("Deleted Images:\n") |
| 100 | for _, st := range res.Report.ImagesDeleted { |
| 101 | if st.Untagged != "" { |
| 102 | sb.WriteString("untagged: ") |
| 103 | sb.WriteString(st.Untagged) |
| 104 | sb.WriteByte('\n') |
| 105 | } else { |
| 106 | sb.WriteString("deleted: ") |
| 107 | sb.WriteString(st.Deleted) |
| 108 | sb.WriteByte('\n') |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | return res.Report.SpaceReclaimed, sb.String(), nil |
| 114 | } |
| 115 | |
| 116 | type cancelledErr struct{ error } |
| 117 | |