Skip to content

Commit

Permalink
Merge pull request #5029 from tonistiigi/dockerfile-resolve-cache
Browse files Browse the repository at this point in the history
dockerfile: deduplicate and cache config resolve requests
  • Loading branch information
AkihiroSuda authored Jun 20, 2024
2 parents f70727b + 10a8179 commit fded8f3
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 0 deletions.
1 change: 1 addition & 0 deletions frontend/dockerfile/builder/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const (
)

func Build(ctx context.Context, c client.Client) (_ *client.Result, err error) {
c = &withResolveCache{Client: c}
bc, err := dockerui.NewClient(c)
if err != nil {
return nil, err
Expand Down
47 changes: 47 additions & 0 deletions frontend/dockerfile/builder/resolvecache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package builder

import (
"context"
"fmt"

"github.com/mitchellh/hashstructure/v2"
"github.com/moby/buildkit/client/llb/sourceresolver"
"github.com/moby/buildkit/frontend/gateway/client"
"github.com/moby/buildkit/util/flightcontrol"
digest "github.com/opencontainers/go-digest"
)

// withResolveCache wraps client.Client so that ResolveImageConfig
// calls are cached and deduplicated via flightcontrol.CachedGroup
type withResolveCache struct {
client.Client
g flightcontrol.CachedGroup[*resolveResult]
}

type resolveResult struct {
ref string
dgst digest.Digest
cfg []byte
}

var _ client.Client = &withResolveCache{}

func (c *withResolveCache) ResolveImageConfig(ctx context.Context, ref string, opt sourceresolver.Opt) (string, digest.Digest, []byte, error) {
c.g.CacheError = true
optHash, err := hashstructure.Hash(opt, hashstructure.FormatV2, nil)
if err != nil {
return "", "", nil, err
}
key := fmt.Sprintf("%s,%d", ref, optHash)
res, err := c.g.Do(ctx, key, func(ctx context.Context) (*resolveResult, error) {
ref, dgst, cfg, err := c.Client.ResolveImageConfig(ctx, ref, opt)
if err != nil {
return nil, err
}
return &resolveResult{ref, dgst, cfg}, nil
})
if err != nil {
return "", "", nil, err
}
return res.ref, res.dgst, res.cfg, nil
}

0 comments on commit fded8f3

Please sign in to comment.