config: fix a default GC policy filter never matching any record

The first default GC policy is meant to prune the most easily
reproducible cache (local sources, cache mounts, git checkouts) once it
exceeds 512MB and has not been used for 48h. Its filter was written as a
single comma-joined string:

    "type==source.local,type==exec.cachemount,type==source.git.checkout"

Each element of the Filters slice is passed to
containerd/filters.ParseAll, where commas within one string are ANDed
together. A record only ever has a single type, so the AND can never be
satisfied: this policy matched nothing and was effectively a no-op.

Split the filter into separate slice elements so they are ORed, matching
the documented intent and the array form already used in user
buildkitd.toml configs.

Signed-off-by: ZRHann <zrhann@foxmail.com>
This commit is contained in:
ZRHann
2026-06-10 19:34:56 +08:00
parent 7a2c61eefd
commit b69e279bcd
2 changed files with 44 additions and 1 deletions

View File

@@ -78,7 +78,7 @@ func DefaultGCPolicy(cfg GCConfig, dstat disk.DiskStat) []GCPolicy {
return []GCPolicy{
// if build cache uses more than 512MB delete the most easily reproducible data after it has not been used for 2 days
{
Filters: []string{"type==source.local,type==exec.cachemount,type==source.git.checkout"},
Filters: []string{"type==source.local", "type==exec.cachemount", "type==source.git.checkout"},
KeepDuration: Duration{Duration: time.Duration(48) * time.Hour}, // 48h
MaxUsedSpace: DiskSpace{Bytes: 512 * 1e6}, // 512MB
},

View File

@@ -0,0 +1,43 @@
package config
import (
"testing"
"github.com/containerd/containerd/v2/pkg/filters"
"github.com/moby/buildkit/client"
"github.com/moby/buildkit/util/disk"
"github.com/stretchr/testify/require"
)
func TestDefaultGCPolicyFiltersMatch(t *testing.T) {
policies := DefaultGCPolicy(GCConfig{}, disk.DiskStat{Total: 1e12})
require.NotEmpty(t, policies)
rule := policies[0]
require.NotEmpty(t, rule.Filters)
f, err := filters.ParseAll(rule.Filters...)
require.NoError(t, err)
adapt := func(rt client.UsageRecordType) filters.Adaptor {
return filters.AdapterFunc(func(fieldpath []string) (string, bool) {
if len(fieldpath) == 1 && fieldpath[0] == "type" {
return string(rt), rt != ""
}
return "", false
})
}
for _, rt := range []client.UsageRecordType{
client.UsageRecordTypeLocalSource,
client.UsageRecordTypeCacheMount,
client.UsageRecordTypeGitCheckout,
} {
require.Truef(t, f.Match(adapt(rt)),
"first default GC policy should match record type %q", rt)
}
// It must not match unrelated records such as regular build cache.
require.Falsef(t, f.Match(adapt(client.UsageRecordTypeRegular)),
"first default GC policy should not match record type %q", client.UsageRecordTypeRegular)
}