Skip to content
This repository was archived by the owner on Oct 13, 2023. It is now read-only.

Commit b0d190a

Browse files
authored
Merge pull request #410 from thaJeztah/19.03_backport_fix_buildkit_prunegc_filter_config
[19.03 backport] daemon/config: fix filter type in BuildKit GC config Upstream-commit: e2e3abec71f30e533a01e8f1f9669e55b1361fc1 Component: engine
2 parents c7ec6e8 + b2a43ee commit b0d190a

4 files changed

Lines changed: 104 additions & 5 deletions

File tree

components/engine/api/types/filters/parse.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ func NewArgs(initialArgs ...KeyValuePair) Args {
3636
return args
3737
}
3838

39+
// Keys returns all the keys in list of Args
40+
func (args Args) Keys() []string {
41+
keys := make([]string, 0, len(args.fields))
42+
for k := range args.fields {
43+
keys = append(keys, k)
44+
}
45+
return keys
46+
}
47+
3948
// MarshalJSON returns a JSON byte representation of the Args
4049
func (args Args) MarshalJSON() ([]byte, error) {
4150
if len(args.fields) == 0 {

components/engine/builder/builder-next/controller.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/containerd/containerd/content/local"
99
"github.com/containerd/containerd/platforms"
1010
"github.com/docker/docker/api/types"
11+
"github.com/docker/docker/api/types/filters"
1112
"github.com/docker/docker/builder/builder-next/adapters/containerimage"
1213
"github.com/docker/docker/builder/builder-next/adapters/localinlinecache"
1314
"github.com/docker/docker/builder/builder-next/adapters/snapshot"
@@ -232,7 +233,7 @@ func getGCPolicy(conf config.BuilderConfig, root string) ([]client.PruneInfo, er
232233
gcPolicy[i], err = toBuildkitPruneInfo(types.BuildCachePruneOptions{
233234
All: p.All,
234235
KeepStorage: b,
235-
Filters: p.Filter,
236+
Filters: filters.Args(p.Filter),
236237
})
237238
if err != nil {
238239
return nil, err

components/engine/daemon/config/builder.go

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,57 @@
11
package config
22

3-
import "github.com/docker/docker/api/types/filters"
3+
import (
4+
"encoding/json"
5+
"fmt"
6+
"sort"
7+
"strings"
8+
9+
"github.com/docker/docker/api/types/filters"
10+
)
411

512
// BuilderGCRule represents a GC rule for buildkit cache
613
type BuilderGCRule struct {
7-
All bool `json:",omitempty"`
8-
Filter filters.Args `json:",omitempty"`
9-
KeepStorage string `json:",omitempty"`
14+
All bool `json:",omitempty"`
15+
Filter BuilderGCFilter `json:",omitempty"`
16+
KeepStorage string `json:",omitempty"`
17+
}
18+
19+
// BuilderGCFilter contains garbage-collection filter rules for a BuildKit builder
20+
type BuilderGCFilter filters.Args
21+
22+
// MarshalJSON returns a JSON byte representation of the BuilderGCFilter
23+
func (x *BuilderGCFilter) MarshalJSON() ([]byte, error) {
24+
f := filters.Args(*x)
25+
keys := f.Keys()
26+
sort.Strings(keys)
27+
arr := make([]string, 0, len(keys))
28+
for _, k := range keys {
29+
values := f.Get(k)
30+
for _, v := range values {
31+
arr = append(arr, fmt.Sprintf("%s=%s", k, v))
32+
}
33+
}
34+
return json.Marshal(arr)
35+
}
36+
37+
// UnmarshalJSON fills the BuilderGCFilter values structure from JSON input
38+
func (x *BuilderGCFilter) UnmarshalJSON(data []byte) error {
39+
var arr []string
40+
f := filters.NewArgs()
41+
if err := json.Unmarshal(data, &arr); err != nil {
42+
// backwards compat for deprecated buggy form
43+
err := json.Unmarshal(data, &f)
44+
*x = BuilderGCFilter(f)
45+
return err
46+
}
47+
for _, s := range arr {
48+
fields := strings.SplitN(s, "=", 2)
49+
name := strings.ToLower(strings.TrimSpace(fields[0]))
50+
value := strings.TrimSpace(fields[1])
51+
f.Add(name, value)
52+
}
53+
*x = BuilderGCFilter(f)
54+
return nil
1055
}
1156

1257
// BuilderGCConfig contains GC config for a buildkit builder
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
package config
2+
3+
import (
4+
"testing"
5+
6+
"github.com/docker/docker/api/types/filters"
7+
"github.com/google/go-cmp/cmp"
8+
"gotest.tools/assert"
9+
"gotest.tools/fs"
10+
)
11+
12+
func TestBuilderGC(t *testing.T) {
13+
tempFile := fs.NewFile(t, "config", fs.WithContent(`{
14+
"builder": {
15+
"gc": {
16+
"enabled": true,
17+
"policy": [
18+
{"keepStorage": "10GB", "filter": ["unused-for=2200h"]},
19+
{"keepStorage": "50GB", "filter": {"unused-for": {"3300h": true}}},
20+
{"keepStorage": "100GB", "all": true}
21+
]
22+
}
23+
}
24+
}`))
25+
defer tempFile.Remove()
26+
configFile := tempFile.Path()
27+
28+
cfg, err := MergeDaemonConfigurations(&Config{}, nil, configFile)
29+
assert.NilError(t, err)
30+
assert.Assert(t, cfg.Builder.GC.Enabled)
31+
f1 := filters.NewArgs()
32+
f1.Add("unused-for", "2200h")
33+
f2 := filters.NewArgs()
34+
f2.Add("unused-for", "3300h")
35+
expectedPolicy := []BuilderGCRule{
36+
{KeepStorage: "10GB", Filter: BuilderGCFilter(f1)},
37+
{KeepStorage: "50GB", Filter: BuilderGCFilter(f2)}, /* parsed from deprecated form */
38+
{KeepStorage: "100GB", All: true},
39+
}
40+
assert.DeepEqual(t, cfg.Builder.GC.Policy, expectedPolicy, cmp.AllowUnexported(BuilderGCFilter{}))
41+
// double check to please the skeptics
42+
assert.Assert(t, filters.Args(cfg.Builder.GC.Policy[0].Filter).UniqueExactMatch("unused-for", "2200h"))
43+
assert.Assert(t, filters.Args(cfg.Builder.GC.Policy[1].Filter).UniqueExactMatch("unused-for", "3300h"))
44+
}

0 commit comments

Comments
 (0)