This is to keep the UX consistent. `unused-for` is still accepted and a synonym.
Signed-off-by: Tibor Vass <tibor@docker.com>
| ... | ... |
@@ -6436,7 +6436,7 @@ paths: |
| 6436 | 6436 |
type: "string" |
| 6437 | 6437 |
description: | |
| 6438 | 6438 |
A JSON encoded value of the filters (a `map[string][]string`) to process on the list of build cache objects. Available filters: |
| 6439 |
- - `unused-for=<duration>`: duration relative to daemon's time, during which build cache was not used, in Go's duration format (e.g., '24h') |
|
| 6439 |
+ - `until=<duration>`: duration relative to daemon's time, during which build cache was not used, in Go's duration format (e.g., '24h') |
|
| 6440 | 6440 |
- `id=<id>` |
| 6441 | 6441 |
- `parent=<id>` |
| 6442 | 6442 |
- `type=<string>` |
| ... | ... |
@@ -2,6 +2,7 @@ package buildkit |
| 2 | 2 |
|
| 3 | 3 |
import ( |
| 4 | 4 |
"context" |
| 5 |
+ "fmt" |
|
| 5 | 6 |
"io" |
| 6 | 7 |
"net" |
| 7 | 8 |
"strings" |
| ... | ... |
@@ -32,7 +33,21 @@ import ( |
| 32 | 32 |
grpcmetadata "google.golang.org/grpc/metadata" |
| 33 | 33 |
) |
| 34 | 34 |
|
| 35 |
-var errMultipleFilterValues = errors.New("filters expect only one value")
|
|
| 35 |
+type errMultipleFilterValues struct{}
|
|
| 36 |
+ |
|
| 37 |
+func (errMultipleFilterValues) Error() string { return "filters expect only one value" }
|
|
| 38 |
+ |
|
| 39 |
+func (errMultipleFilterValues) InvalidParameter() {}
|
|
| 40 |
+ |
|
| 41 |
+type errConflictFilter struct {
|
|
| 42 |
+ a, b string |
|
| 43 |
+} |
|
| 44 |
+ |
|
| 45 |
+func (e errConflictFilter) Error() string {
|
|
| 46 |
+ return fmt.Sprintf("conflicting filters: %q and %q", e.a, e.b)
|
|
| 47 |
+} |
|
| 48 |
+ |
|
| 49 |
+func (errConflictFilter) InvalidParameter() {}
|
|
| 36 | 50 |
|
| 37 | 51 |
var cacheFields = map[string]bool{
|
| 38 | 52 |
"id": true, |
| ... | ... |
@@ -130,6 +145,7 @@ func (b *Builder) Prune(ctx context.Context, opts types.BuildCachePruneOptions) |
| 130 | 130 |
|
| 131 | 131 |
validFilters := make(map[string]bool, 1+len(cacheFields)) |
| 132 | 132 |
validFilters["unused-for"] = true |
| 133 |
+ validFilters["until"] = true |
|
| 133 | 134 |
for k, v := range cacheFields {
|
| 134 | 135 |
validFilters[k] = v |
| 135 | 136 |
} |
| ... | ... |
@@ -502,6 +518,7 @@ func toBuildkitExtraHosts(inp []string) (string, error) {
|
| 502 | 502 |
hosts := make([]string, 0, len(inp)) |
| 503 | 503 |
for _, h := range inp {
|
| 504 | 504 |
parts := strings.Split(h, ":") |
| 505 |
+ |
|
| 505 | 506 |
if len(parts) != 2 || parts[0] == "" || net.ParseIP(parts[1]) == nil {
|
| 506 | 507 |
return "", errors.Errorf("invalid host %s", h)
|
| 507 | 508 |
} |
| ... | ... |
@@ -511,21 +528,30 @@ func toBuildkitExtraHosts(inp []string) (string, error) {
|
| 511 | 511 |
} |
| 512 | 512 |
|
| 513 | 513 |
func toBuildkitPruneInfo(opts types.BuildCachePruneOptions) (client.PruneInfo, error) {
|
| 514 |
- var unusedFor time.Duration |
|
| 515 |
- unusedForValues := opts.Filters.Get("unused-for")
|
|
| 514 |
+ var until time.Duration |
|
| 515 |
+ untilValues := opts.Filters.Get("until") // canonical
|
|
| 516 |
+ unusedForValues := opts.Filters.Get("unused-for") // deprecated synonym for "until" filter
|
|
| 516 | 517 |
|
| 517 |
- switch len(unusedForValues) {
|
|
| 518 |
- case 0: |
|
| 518 |
+ if len(untilValues) > 0 && len(unusedForValues) > 0 {
|
|
| 519 |
+ return client.PruneInfo{}, errConflictFilter{"until", "unused-for"}
|
|
| 520 |
+ } |
|
| 521 |
+ filterKey := "until" |
|
| 522 |
+ if len(unusedForValues) > 0 {
|
|
| 523 |
+ filterKey = "unused-for" |
|
| 524 |
+ } |
|
| 525 |
+ untilValues = append(untilValues, unusedForValues...) |
|
| 519 | 526 |
|
| 527 |
+ switch len(untilValues) {
|
|
| 528 |
+ case 0: |
|
| 529 |
+ // nothing to do |
|
| 520 | 530 |
case 1: |
| 521 | 531 |
var err error |
| 522 |
- unusedFor, err = time.ParseDuration(unusedForValues[0]) |
|
| 532 |
+ until, err = time.ParseDuration(untilValues[0]) |
|
| 523 | 533 |
if err != nil {
|
| 524 |
- return client.PruneInfo{}, errors.Wrap(err, "unused-for filter expects a duration (e.g., '24h')")
|
|
| 534 |
+ return client.PruneInfo{}, errors.Wrapf(err, "%q filter expects a duration (e.g., '24h')", filterKey)
|
|
| 525 | 535 |
} |
| 526 |
- |
|
| 527 | 536 |
default: |
| 528 |
- return client.PruneInfo{}, errMultipleFilterValues
|
|
| 537 |
+ return client.PruneInfo{}, errMultipleFilterValues{}
|
|
| 529 | 538 |
} |
| 530 | 539 |
|
| 531 | 540 |
bkFilter := make([]string, 0, opts.Filters.Len()) |
| ... | ... |
@@ -542,13 +568,13 @@ func toBuildkitPruneInfo(opts types.BuildCachePruneOptions) (client.PruneInfo, e |
| 542 | 542 |
bkFilter = append(bkFilter, cacheField+"=="+values[0]) |
| 543 | 543 |
} |
| 544 | 544 |
default: |
| 545 |
- return client.PruneInfo{}, errMultipleFilterValues
|
|
| 545 |
+ return client.PruneInfo{}, errMultipleFilterValues{}
|
|
| 546 | 546 |
} |
| 547 | 547 |
} |
| 548 | 548 |
} |
| 549 | 549 |
return client.PruneInfo{
|
| 550 | 550 |
All: opts.All, |
| 551 |
- KeepDuration: unusedFor, |
|
| 551 |
+ KeepDuration: until, |
|
| 552 | 552 |
KeepBytes: opts.KeepStorage, |
| 553 | 553 |
Filter: []string{strings.Join(bkFilter, ",")},
|
| 554 | 554 |
}, nil |