dryRun validates the given options for each prune-function and constructs a confirmation message that depends on the cli options.
(ctx context.Context, dockerCli command.Cli, options pruneOptions)
| 127 | // dryRun validates the given options for each prune-function and constructs |
| 128 | // a confirmation message that depends on the cli options. |
| 129 | func dryRun(ctx context.Context, dockerCli command.Cli, options pruneOptions) (string, error) { |
| 130 | var ( |
| 131 | errs []error |
| 132 | warnings []string |
| 133 | ) |
| 134 | for contentType, pruneFn := range pruner.List() { |
| 135 | switch contentType { |
| 136 | case pruner.TypeVolume: |
| 137 | if !options.pruneVolumes { |
| 138 | continue |
| 139 | } |
| 140 | case pruner.TypeContainer, pruner.TypeNetwork, pruner.TypeImage, pruner.TypeBuildCache: |
| 141 | // no special handling; keeping the "exhaustive" linter happy. |
| 142 | default: |
| 143 | // other pruners; no special handling; keeping the "exhaustive" linter happy. |
| 144 | } |
| 145 | // Always run with "[pruner.PruneOptions.Confirmed] = false" |
| 146 | // to perform validation of the given options and produce |
| 147 | // a confirmation message for the pruner. |
| 148 | _, confirmMsg, err := pruneFn(ctx, dockerCli, pruner.PruneOptions{ |
| 149 | All: options.all, |
| 150 | Filter: options.filter, |
| 151 | }) |
| 152 | // A "canceled" error is expected in dry-run mode; any other error |
| 153 | // must be returned as a "fatal" error. |
| 154 | if err != nil && !errdefs.IsCanceled(err) && !errdefs.IsNotImplemented(err) { |
| 155 | errs = append(errs, err) |
| 156 | } |
| 157 | if confirmMsg != "" { |
| 158 | warnings = append(warnings, confirmMsg) |
| 159 | } |
| 160 | } |
| 161 | if len(errs) > 0 { |
| 162 | return "", errors.Join(errs...) |
| 163 | } |
| 164 | |
| 165 | var filters []string |
| 166 | pruneFilters := command.PruneFilters(dockerCli, options.filter.Value()) |
| 167 | if len(pruneFilters) > 0 { |
| 168 | // TODO remove fixed list of filters, and print all filters instead, |
| 169 | // because the list of filters that is supported by the engine may evolve over time. |
| 170 | for _, name := range []string{"label", "label!", "until"} { |
| 171 | for v := range pruneFilters[name] { |
| 172 | filters = append(filters, name+"="+v) |
| 173 | } |
| 174 | } |
| 175 | sort.Slice(filters, func(i, j int) bool { |
| 176 | return sortorder.NaturalLess(filters[i], filters[j]) |
| 177 | }) |
| 178 | } |
| 179 | |
| 180 | var buffer bytes.Buffer |
| 181 | t := template.Must(template.New("confirmation message").Parse(confirmationTemplate)) |
| 182 | _ = t.Execute(&buffer, map[string][]string{"warnings": warnings, "filters": filters}) |
| 183 | return buffer.String(), nil |
| 184 | } |