Skip to content

Commit bf0ff2e

Browse files
authored
Merge branch 'moby:master' into pass-cache-imports-to-solve
2 parents 955f289 + e83d79a commit bf0ff2e

File tree

16 files changed

+620
-121
lines changed

16 files changed

+620
-121
lines changed

frontend/dockerfile/dockerfile2llb/convert.go

Lines changed: 108 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
"github.com/moby/buildkit/util/suggest"
4141
"github.com/moby/buildkit/util/system"
4242
dockerspec "github.com/moby/docker-image-spec/specs-go/v1"
43+
"github.com/moby/patternmatcher"
4344
"github.com/moby/sys/signal"
4445
digest "github.com/opencontainers/go-digest"
4546
ocispecs "github.com/opencontainers/image-spec/specs-go/v1"
@@ -258,6 +259,9 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
258259
if err != nil {
259260
return nil, err
260261
}
262+
if len(stages) == 0 {
263+
return nil, errors.New("dockerfile contains no stages to build")
264+
}
261265
validateStageNames(stages, lint)
262266

263267
shlex := shell.NewLex(dockerfile.EscapeToken)
@@ -315,6 +319,7 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
315319
platMatch, err := shlex.ProcessWordWithMatches(v, platEnv)
316320
reportUnusedFromArgs(metaArgsKeys(optMetaArgs), platMatch.Unmatched, st.Location, lint)
317321
reportRedundantTargetPlatform(st.Platform, platMatch, st.Location, platEnv, lint)
322+
reportConstPlatformDisallowed(st.Name, platMatch, st.Location, lint)
318323

319324
if err != nil {
320325
return nil, parser.WithLocation(errors.Wrapf(err, "failed to process arguments for platform %s", platMatch.Result), st.Location)
@@ -590,6 +595,20 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
590595
buildContext := &mutableOutput{}
591596
ctxPaths := map[string]struct{}{}
592597

598+
var dockerIgnoreMatcher *patternmatcher.PatternMatcher
599+
if opt.Client != nil && opt.Client.CopyIgnoredCheckEnabled {
600+
dockerIgnorePatterns, err := opt.Client.DockerIgnorePatterns(ctx)
601+
if err != nil {
602+
return nil, err
603+
}
604+
if len(dockerIgnorePatterns) > 0 {
605+
dockerIgnoreMatcher, err = patternmatcher.New(dockerIgnorePatterns)
606+
if err != nil {
607+
return nil, err
608+
}
609+
}
610+
}
611+
593612
for _, d := range allDispatchStates.states {
594613
if !opt.AllStages {
595614
if _, ok := allReachable[d]; !ok || d.noinit {
@@ -630,24 +649,27 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
630649
return nil, parser.WithLocation(err, d.stage.Location)
631650
}
632651
}
652+
633653
d.state = d.state.Network(opt.NetworkMode)
654+
634655
opt := dispatchOpt{
635-
allDispatchStates: allDispatchStates,
636-
metaArgs: optMetaArgs,
637-
buildArgValues: opt.BuildArgs,
638-
shlex: shlex,
639-
buildContext: llb.NewState(buildContext),
640-
proxyEnv: proxyEnv,
641-
cacheIDNamespace: opt.CacheIDNamespace,
642-
buildPlatforms: platformOpt.buildPlatforms,
643-
targetPlatform: platformOpt.targetPlatform,
644-
extraHosts: opt.ExtraHosts,
645-
shmSize: opt.ShmSize,
646-
ulimit: opt.Ulimits,
647-
cgroupParent: opt.CgroupParent,
648-
llbCaps: opt.LLBCaps,
649-
sourceMap: opt.SourceMap,
650-
lint: lint,
656+
allDispatchStates: allDispatchStates,
657+
metaArgs: optMetaArgs,
658+
buildArgValues: opt.BuildArgs,
659+
shlex: shlex,
660+
buildContext: llb.NewState(buildContext),
661+
proxyEnv: proxyEnv,
662+
cacheIDNamespace: opt.CacheIDNamespace,
663+
buildPlatforms: platformOpt.buildPlatforms,
664+
targetPlatform: platformOpt.targetPlatform,
665+
extraHosts: opt.ExtraHosts,
666+
shmSize: opt.ShmSize,
667+
ulimit: opt.Ulimits,
668+
cgroupParent: opt.CgroupParent,
669+
llbCaps: opt.LLBCaps,
670+
sourceMap: opt.SourceMap,
671+
lint: lint,
672+
dockerIgnoreMatcher: dockerIgnoreMatcher,
651673
}
652674

653675
if err = dispatchOnBuildTriggers(d, d.image.Config.OnBuild, opt); err != nil {
@@ -806,22 +828,23 @@ func toCommand(ic instructions.Command, allDispatchStates *dispatchStates) (comm
806828
}
807829

808830
type dispatchOpt struct {
809-
allDispatchStates *dispatchStates
810-
metaArgs []instructions.KeyValuePairOptional
811-
buildArgValues map[string]string
812-
shlex *shell.Lex
813-
buildContext llb.State
814-
proxyEnv *llb.ProxyEnv
815-
cacheIDNamespace string
816-
targetPlatform ocispecs.Platform
817-
buildPlatforms []ocispecs.Platform
818-
extraHosts []llb.HostIP
819-
shmSize int64
820-
ulimit []pb.Ulimit
821-
cgroupParent string
822-
llbCaps *apicaps.CapSet
823-
sourceMap *llb.SourceMap
824-
lint *linter.Linter
831+
allDispatchStates *dispatchStates
832+
metaArgs []instructions.KeyValuePairOptional
833+
buildArgValues map[string]string
834+
shlex *shell.Lex
835+
buildContext llb.State
836+
proxyEnv *llb.ProxyEnv
837+
cacheIDNamespace string
838+
targetPlatform ocispecs.Platform
839+
buildPlatforms []ocispecs.Platform
840+
extraHosts []llb.HostIP
841+
shmSize int64
842+
ulimit []pb.Ulimit
843+
cgroupParent string
844+
llbCaps *apicaps.CapSet
845+
sourceMap *llb.SourceMap
846+
lint *linter.Linter
847+
dockerIgnoreMatcher *patternmatcher.PatternMatcher
825848
}
826849

827850
func getEnv(state llb.State) shell.EnvGetter {
@@ -908,6 +931,7 @@ func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
908931
keepGitDir: c.KeepGitDir,
909932
checksum: checksum,
910933
location: c.Location(),
934+
ignoreMatcher: opt.dockerIgnoreMatcher,
911935
opt: opt,
912936
})
913937
}
@@ -942,12 +966,15 @@ func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
942966
err = dispatchArg(d, c, &opt)
943967
case *instructions.CopyCommand:
944968
l := opt.buildContext
969+
var ignoreMatcher *patternmatcher.PatternMatcher
945970
if len(cmd.sources) != 0 {
946971
src := cmd.sources[0]
947972
if !src.noinit {
948973
return errors.Errorf("cannot copy from stage %q, it needs to be defined before current stage %q", c.From, d.stageName)
949974
}
950975
l = src.state
976+
} else {
977+
ignoreMatcher = opt.dockerIgnoreMatcher
951978
}
952979
err = dispatchCopy(d, copyConfig{
953980
params: c.SourcesAndDest,
@@ -960,6 +987,7 @@ func dispatch(d *dispatchState, cmd command, opt dispatchOpt) error {
960987
link: c.Link,
961988
parents: c.Parents,
962989
location: c.Location(),
990+
ignoreMatcher: ignoreMatcher,
963991
opt: opt,
964992
})
965993
if err == nil {
@@ -1438,6 +1466,7 @@ func dispatchCopy(d *dispatchState, cfg copyConfig) error {
14381466
a = a.Copy(st, f, dest, opts...)
14391467
}
14401468
} else {
1469+
validateCopySourcePath(src, &cfg)
14411470
var patterns []string
14421471
if cfg.parents {
14431472
// detect optional pivot point
@@ -1554,6 +1583,7 @@ type copyConfig struct {
15541583
checksum digest.Digest
15551584
parents bool
15561585
location []parser.Range
1586+
ignoreMatcher *patternmatcher.PatternMatcher
15571587
opt dispatchOpt
15581588
}
15591589

@@ -1867,6 +1897,27 @@ func addReachableStages(s *dispatchState, stages map[*dispatchState]struct{}) {
18671897
}
18681898
}
18691899

1900+
func validateCopySourcePath(src string, cfg *copyConfig) error {
1901+
if cfg.ignoreMatcher == nil {
1902+
return nil
1903+
}
1904+
cmd := "Copy"
1905+
if cfg.isAddCommand {
1906+
cmd = "Add"
1907+
}
1908+
1909+
ok, err := cfg.ignoreMatcher.MatchesOrParentMatches(src)
1910+
if err != nil {
1911+
return err
1912+
}
1913+
if ok {
1914+
msg := linter.RuleCopyIgnoredFile.Format(cmd, src)
1915+
cfg.opt.lint.Run(&linter.RuleCopyIgnoredFile, cfg.location, msg)
1916+
}
1917+
1918+
return nil
1919+
}
1920+
18701921
func validateCircularDependency(states []*dispatchState) error {
18711922
var visit func(*dispatchState, []instructions.Command) []instructions.Command
18721923
if states == nil {
@@ -2300,6 +2351,31 @@ func reportRedundantTargetPlatform(platformVar string, nameMatch shell.ProcessWo
23002351
}
23012352
}
23022353

2354+
func reportConstPlatformDisallowed(stageName string, nameMatch shell.ProcessWordResult, location []parser.Range, lint *linter.Linter) {
2355+
if len(nameMatch.Matched) > 0 || len(nameMatch.Unmatched) > 0 {
2356+
// Some substitution happened so the platform was not a constant.
2357+
// Disable checking for this warning.
2358+
return
2359+
}
2360+
2361+
// Attempt to parse the platform result. If this fails, then it will fail
2362+
// later so just ignore.
2363+
p, err := platforms.Parse(nameMatch.Result)
2364+
if err != nil {
2365+
return
2366+
}
2367+
2368+
// Check if the platform os or architecture is used in the stage name
2369+
// at all. If it is, then disable this warning.
2370+
if strings.Contains(stageName, p.OS) || strings.Contains(stageName, p.Architecture) {
2371+
return
2372+
}
2373+
2374+
// Report the linter warning.
2375+
msg := linter.RuleFromPlatformFlagConstDisallowed.Format(nameMatch.Result)
2376+
lint.Run(&linter.RuleFromPlatformFlagConstDisallowed, location, msg)
2377+
}
2378+
23032379
type instructionTracker struct {
23042380
Loc []parser.Range
23052381
IsSet bool

0 commit comments

Comments
 (0)