Skip to content

Commit 10a8179

Browse files
committed
dockerfile: deduplicate and cache config resolve requests
Signed-off-by: Tonis Tiigi <[email protected]>
1 parent f70727b commit 10a8179

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

frontend/dockerfile/builder/build.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const (
3434
)
3535

3636
func Build(ctx context.Context, c client.Client) (_ *client.Result, err error) {
37+
c = &withResolveCache{Client: c}
3738
bc, err := dockerui.NewClient(c)
3839
if err != nil {
3940
return nil, err
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package builder
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/mitchellh/hashstructure/v2"
8+
"github.com/moby/buildkit/client/llb/sourceresolver"
9+
"github.com/moby/buildkit/frontend/gateway/client"
10+
"github.com/moby/buildkit/util/flightcontrol"
11+
digest "github.com/opencontainers/go-digest"
12+
)
13+
14+
// withResolveCache wraps client.Client so that ResolveImageConfig
15+
// calls are cached and deduplicated via flightcontrol.CachedGroup
16+
type withResolveCache struct {
17+
client.Client
18+
g flightcontrol.CachedGroup[*resolveResult]
19+
}
20+
21+
type resolveResult struct {
22+
ref string
23+
dgst digest.Digest
24+
cfg []byte
25+
}
26+
27+
var _ client.Client = &withResolveCache{}
28+
29+
func (c *withResolveCache) ResolveImageConfig(ctx context.Context, ref string, opt sourceresolver.Opt) (string, digest.Digest, []byte, error) {
30+
c.g.CacheError = true
31+
optHash, err := hashstructure.Hash(opt, hashstructure.FormatV2, nil)
32+
if err != nil {
33+
return "", "", nil, err
34+
}
35+
key := fmt.Sprintf("%s,%d", ref, optHash)
36+
res, err := c.g.Do(ctx, key, func(ctx context.Context) (*resolveResult, error) {
37+
ref, dgst, cfg, err := c.Client.ResolveImageConfig(ctx, ref, opt)
38+
if err != nil {
39+
return nil, err
40+
}
41+
return &resolveResult{ref, dgst, cfg}, nil
42+
})
43+
if err != nil {
44+
return "", "", nil, err
45+
}
46+
return res.ref, res.dgst, res.cfg, nil
47+
}

0 commit comments

Comments
 (0)