diff --git a/client/llb/source.go b/client/llb/source.go index 0767dce42..a59a11312 100644 --- a/client/llb/source.go +++ b/client/llb/source.go @@ -196,6 +196,9 @@ func Local(name string, opts ...LocalOption) State { if gi.ExcludePatterns != "" { attrs[pb.AttrExcludePatterns] = gi.ExcludePatterns } + if gi.SharedKeyHint != "" { + attrs[pb.AttrSharedKeyHint] = gi.SharedKeyHint + } source := NewSource("local://"+name, attrs, gi.Metadata()) return NewState(source.Output()) @@ -239,11 +242,18 @@ func ExcludePatterns(p []string) LocalOption { }) } +func SharedKeyHint(h string) LocalOption { + return localOptionFunc(func(li *LocalInfo) { + li.SharedKeyHint = h + }) +} + type LocalInfo struct { opMetaWrapper SessionID string IncludePatterns string ExcludePatterns string + SharedKeyHint string } func HTTP(url string, opts ...HTTPOption) State { diff --git a/client/local.go b/client/local.go deleted file mode 100644 index 25c977079..000000000 --- a/client/local.go +++ /dev/null @@ -1,5 +0,0 @@ -package client - -func getSharedKey(dir string) (string, error) { - return dir, nil // not implemented -} diff --git a/frontend/dockerfile/builder/build.go b/frontend/dockerfile/builder/build.go index cc3031805..60d30c58e 100644 --- a/frontend/dockerfile/builder/build.go +++ b/frontend/dockerfile/builder/build.go @@ -41,6 +41,7 @@ func Build(ctx context.Context, c client.Client) error { src := llb.Local(LocalNameDockerfile, llb.IncludePatterns([]string{filename}), llb.SessionID(c.SessionID()), + llb.SharedKeyHint(defaultDockerfileName), ) var buildContext *llb.State if strings.HasPrefix(opts[LocalNameContext], gitPrefix) { @@ -70,7 +71,11 @@ func Build(ctx context.Context, c client.Client) error { eg.Go(func() error { dockerignoreState := buildContext if dockerignoreState == nil { - st := llb.Local(LocalNameContext, llb.SessionID(c.SessionID()), llb.IncludePatterns([]string{dockerignoreFilename})) + st := llb.Local(LocalNameContext, + llb.SessionID(c.SessionID()), + llb.IncludePatterns([]string{dockerignoreFilename}), + llb.SharedKeyHint(dockerignoreFilename), + ) dockerignoreState = &st } def, err := dockerignoreState.Marshal() diff --git a/frontend/dockerfile/dockerfile2llb/convert.go b/frontend/dockerfile/dockerfile2llb/convert.go index 878cf8e81..3252de203 100644 --- a/frontend/dockerfile/dockerfile2llb/convert.go +++ b/frontend/dockerfile/dockerfile2llb/convert.go @@ -167,7 +167,11 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State, if err := eg.Wait(); err != nil { return nil, nil, err } - buildContext := llb.Local(localNameContext, llb.SessionID(opt.SessionID), llb.ExcludePatterns(opt.Excludes)) + buildContext := llb.Local(localNameContext, + llb.SessionID(opt.SessionID), + llb.ExcludePatterns(opt.Excludes), + llb.SharedKeyHint(localNameContext), + ) if opt.BuildContext != nil { buildContext = *opt.BuildContext } diff --git a/solver/pb/attr.go b/solver/pb/attr.go index f507a2529..631c16610 100644 --- a/solver/pb/attr.go +++ b/solver/pb/attr.go @@ -4,6 +4,7 @@ const AttrKeepGitDir = "git.keepgitdir" const AttrLocalSessionID = "local.session" const AttrIncludePatterns = "local.includepattern" const AttrExcludePatterns = "local.excludepatterns" +const AttrSharedKeyHint = "local.sharedkeyhint" const AttrLLBDefinitionFilename = "llbbuild.filename" const AttrHTTPChecksum = "http.checksum" diff --git a/source/identifier.go b/source/identifier.go index 59ff0cb02..a5356de6f 100644 --- a/source/identifier.go +++ b/source/identifier.go @@ -86,6 +86,8 @@ func FromLLB(op *pb.Op_Source) (Identifier, error) { return nil, err } id.ExcludePatterns = patterns + case pb.AttrSharedKeyHint: + id.SharedKeyHint = v } } } @@ -149,6 +151,7 @@ type LocalIdentifier struct { SessionID string IncludePatterns []string ExcludePatterns []string + SharedKeyHint string } func NewLocalIdentifier(str string) (*LocalIdentifier, error) { diff --git a/source/local/local.go b/source/local/local.go index 3565f8ecd..34f20bd5a 100644 --- a/source/local/local.go +++ b/source/local/local.go @@ -79,7 +79,8 @@ func (ls *localSourceHandler) CacheKey(ctx context.Context) (string, error) { dt, err := json.Marshal(struct { SessionID string IncludePatterns []string - }{SessionID: sessionID, IncludePatterns: ls.src.IncludePatterns}) + ExcludePatterns []string + }{SessionID: sessionID, IncludePatterns: ls.src.IncludePatterns, ExcludePatterns: ls.src.ExcludePatterns}) if err != nil { return "", err } @@ -101,7 +102,7 @@ func (ls *localSourceHandler) Snapshot(ctx context.Context) (out cache.Immutable return nil, err } - sharedKey := keySharedKey + ":" + ls.src.Name + ":" + caller.SharedKey() + sharedKey := keySharedKey + ":" + ls.src.Name + ":" + ls.src.SharedKeyHint + ":" + caller.SharedKey() // TODO: replace caller.SharedKey() with source based hint from client(absolute-path+nodeid) var mutable cache.MutableRef sis, err := ls.md.Search(sharedKey)