Skip to content

Commit

Permalink
First tests for CopyIgnoredFile check
Browse files Browse the repository at this point in the history
Signed-off-by: Talon Bowler <talon.bowler@docker.com>
  • Loading branch information
daghack committed Jul 10, 2024
1 parent 8100733 commit 9fa8d35
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 58 deletions.
81 changes: 43 additions & 38 deletions frontend/dockerfile/dockerfile2llb/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -591,13 +591,16 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
buildContext := &mutableOutput{}
ctxPaths := map[string]struct{}{}

var dockerIgnoreMatcher *patternmatcher.PatternMatcher
dockerIgnorePatterns, err := opt.Client.DockerIgnorePatterns(ctx)
if err != nil {
return nil, err
}
dockerIgnoreMatcher, err := patternmatcher.New(dockerIgnorePatterns)
if err != nil {
return nil, err
if len(dockerIgnorePatterns) > 0 {
dockerIgnoreMatcher, err = patternmatcher.New(dockerIgnorePatterns)
if err != nil {
return nil, err
}
}

for _, d := range allDispatchStates.states {
Expand Down Expand Up @@ -644,23 +647,24 @@ func toDispatchState(ctx context.Context, dt []byte, opt ConvertOpt) (*dispatchS
d.state = d.state.Network(opt.NetworkMode)

opt := dispatchOpt{
allDispatchStates: allDispatchStates,
metaArgs: optMetaArgs,
buildArgValues: opt.BuildArgs,
shlex: shlex,
buildContext: llb.NewState(buildContext),
proxyEnv: proxyEnv,
cacheIDNamespace: opt.CacheIDNamespace,
buildPlatforms: platformOpt.buildPlatforms,
targetPlatform: platformOpt.targetPlatform,
extraHosts: opt.ExtraHosts,
shmSize: opt.ShmSize,
ulimit: opt.Ulimits,
cgroupParent: opt.CgroupParent,
llbCaps: opt.LLBCaps,
sourceMap: opt.SourceMap,
lint: lint,
dockerIgnoreMatcher: dockerIgnoreMatcher,
allDispatchStates: allDispatchStates,
metaArgs: optMetaArgs,
buildArgValues: opt.BuildArgs,
shlex: shlex,
buildContext: llb.NewState(buildContext),
proxyEnv: proxyEnv,
cacheIDNamespace: opt.CacheIDNamespace,
buildPlatforms: platformOpt.buildPlatforms,
targetPlatform: platformOpt.targetPlatform,
extraHosts: opt.ExtraHosts,
shmSize: opt.ShmSize,
ulimit: opt.Ulimits,
cgroupParent: opt.CgroupParent,
llbCaps: opt.LLBCaps,
sourceMap: opt.SourceMap,
lint: lint,
dockerIgnoreMatcher: dockerIgnoreMatcher,
copyIgnoredCheckEnabled: opt.Client.CopyIgnoredCheckEnabled,
}

if err = dispatchOnBuildTriggers(d, d.image.Config.OnBuild, opt); err != nil {
Expand Down Expand Up @@ -819,23 +823,24 @@ func toCommand(ic instructions.Command, allDispatchStates *dispatchStates) (comm
}

type dispatchOpt struct {
allDispatchStates *dispatchStates
metaArgs []instructions.KeyValuePairOptional
buildArgValues map[string]string
shlex *shell.Lex
buildContext llb.State
proxyEnv *llb.ProxyEnv
cacheIDNamespace string
targetPlatform ocispecs.Platform
buildPlatforms []ocispecs.Platform
extraHosts []llb.HostIP
shmSize int64
ulimit []pb.Ulimit
cgroupParent string
llbCaps *apicaps.CapSet
sourceMap *llb.SourceMap
lint *linter.Linter
dockerIgnoreMatcher *patternmatcher.PatternMatcher
allDispatchStates *dispatchStates
metaArgs []instructions.KeyValuePairOptional
buildArgValues map[string]string
shlex *shell.Lex
buildContext llb.State
proxyEnv *llb.ProxyEnv
cacheIDNamespace string
targetPlatform ocispecs.Platform
buildPlatforms []ocispecs.Platform
extraHosts []llb.HostIP
shmSize int64
ulimit []pb.Ulimit
cgroupParent string
llbCaps *apicaps.CapSet
sourceMap *llb.SourceMap
lint *linter.Linter
dockerIgnoreMatcher *patternmatcher.PatternMatcher
copyIgnoredCheckEnabled bool
}

func getEnv(state llb.State) shell.EnvGetter {
Expand Down Expand Up @@ -1889,7 +1894,7 @@ func addReachableStages(s *dispatchState, stages map[*dispatchState]struct{}) {
}

func validateCopySourcePath(src string, cfg *copyConfig) error {
if cfg.ignoreMatcher == nil {
if cfg.ignoreMatcher == nil || !cfg.opt.copyIgnoredCheckEnabled {
return nil
}
cmd := "Copy"
Expand Down
61 changes: 61 additions & 0 deletions frontend/dockerfile/dockerfile_lint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,68 @@ var lintTests = integration.TestFuncs(
testRedundantTargetPlatform,
testSecretsUsedInArgOrEnv,
testInvalidDefaultArgInFrom,
testCopyIgnoredFiles,
)

func testCopyIgnoredFiles(t *testing.T, sb integration.Sandbox) {
dockerignore := []byte(`
Dockerfile
`)
dockerfile := []byte(`
FROM scratch
COPY Dockerfile .
ADD Dockerfile /windy
`)
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
DockerIgnore: dockerignore,
})

checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
DockerIgnore: dockerignore,
FrontendAttrs: map[string]string{
"build-arg:BUILDKIT_DOCKERFILE_CHECK_COPYIGNORED_EXPERIMENT": "true",
},
BuildErrLocation: 3,
StreamBuildErrRegexp: regexp.MustCompile(`failed to solve: failed to compute cache key: failed to calculate checksum of ref [^\s]+ "/Dockerfile": not found`),
Warnings: []expectedLintWarning{
{
RuleName: "CopyIgnoredFile",
Description: "Attempting to Copy file that is excluded by .dockerignore",
Detail: `Attempting to Copy file "Dockerfile" that is excluded by .dockerignore`,
URL: "https://docs.docker.com/go/dockerfile/rule/copy-ignored-file/",
Level: 1,
Line: 3,
},
{
RuleName: "CopyIgnoredFile",
Description: "Attempting to Copy file that is excluded by .dockerignore",
Detail: `Attempting to Add file "Dockerfile" that is excluded by .dockerignore`,
URL: "https://docs.docker.com/go/dockerfile/rule/copy-ignored-file/",
Level: 1,
Line: 4,
},
},
})

dockerignore = []byte(`
foobar
`)
dockerfile = []byte(`
FROM scratch AS base
COPY Dockerfile /foobar
ADD Dockerfile /windy
FROM base
COPY --from=base /foobar /Dockerfile
`)
checkLinterWarnings(t, sb, &lintTestParams{
Dockerfile: dockerfile,
DockerIgnore: dockerignore,
})
}

func testSecretsUsedInArgOrEnv(t *testing.T, sb integration.Sandbox) {
dockerfile := []byte(`
FROM scratch
Expand Down Expand Up @@ -1205,6 +1265,7 @@ func checkUnmarshal(t *testing.T, sb integration.Sandbox, lintTest *lintTestPara
_, err = lintTest.Client.Build(sb.Context(), client.SolveOpt{
LocalMounts: map[string]fsutil.FS{
dockerui.DefaultLocalNameDockerfile: lintTest.TmpDir,
dockerui.DefaultLocalNameContext: lintTest.TmpDir,
},
}, "", frontend, nil)
require.NoError(t, err)
Expand Down
49 changes: 29 additions & 20 deletions frontend/dockerui/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,28 +45,30 @@ const (

// Don't forget to update frontend documentation if you add
// a new build-arg: frontend/dockerfile/docs/reference.md
keyCacheNSArg = "build-arg:BUILDKIT_CACHE_MOUNT_NS"
keyMultiPlatformArg = "build-arg:BUILDKIT_MULTI_PLATFORM"
keyHostnameArg = "build-arg:BUILDKIT_SANDBOX_HOSTNAME"
keyDockerfileLintArg = "build-arg:BUILDKIT_DOCKERFILE_CHECK"
keyContextKeepGitDirArg = "build-arg:BUILDKIT_CONTEXT_KEEP_GIT_DIR"
keySourceDateEpoch = "build-arg:SOURCE_DATE_EPOCH"
keyCacheNSArg = "build-arg:BUILDKIT_CACHE_MOUNT_NS"
keyMultiPlatformArg = "build-arg:BUILDKIT_MULTI_PLATFORM"
keyHostnameArg = "build-arg:BUILDKIT_SANDBOX_HOSTNAME"
keyDockerfileLintArg = "build-arg:BUILDKIT_DOCKERFILE_CHECK"
keyContextKeepGitDirArg = "build-arg:BUILDKIT_CONTEXT_KEEP_GIT_DIR"
keySourceDateEpoch = "build-arg:SOURCE_DATE_EPOCH"
keyCopyIgnoredCheckEnabled = "build-arg:BUILDKIT_DOCKERFILE_CHECK_COPYIGNORED_EXPERIMENT"
)

type Config struct {
BuildArgs map[string]string
CacheIDNamespace string
CgroupParent string
Epoch *time.Time
ExtraHosts []llb.HostIP
Hostname string
ImageResolveMode llb.ResolveMode
Labels map[string]string
NetworkMode pb.NetMode
ShmSize int64
Target string
Ulimits []pb.Ulimit
LinterConfig *linter.Config
BuildArgs map[string]string
CacheIDNamespace string
CgroupParent string
Epoch *time.Time
ExtraHosts []llb.HostIP
Hostname string
ImageResolveMode llb.ResolveMode
Labels map[string]string
NetworkMode pb.NetMode
ShmSize int64
Target string
Ulimits []pb.Ulimit
LinterConfig *linter.Config
CopyIgnoredCheckEnabled bool

CacheImports []client.CacheOptionsEntry
TargetPlatforms []ocispecs.Platform // nil means default
Expand Down Expand Up @@ -286,6 +288,13 @@ func (bc *Client) init() error {
return errors.Wrapf(err, "failed to parse %s", keyDockerfileLintArg)
}
}

if v, ok := opts[keyCopyIgnoredCheckEnabled]; ok {
bc.CopyIgnoredCheckEnabled, err = strconv.ParseBool(v)
if err != nil {
return errors.Wrapf(err, "failed to parse %s", keyCopyIgnoredCheckEnabled)
}
}
return nil
}

Expand Down Expand Up @@ -466,7 +475,7 @@ func (bc *Client) DockerIgnorePatterns(ctx context.Context) ([]string, error) {
if err != nil {
return nil, err
}
if bctx.context == nil {
if bctx.context != nil {
return nil, nil
}

Expand Down

0 comments on commit 9fa8d35

Please sign in to comment.