From 7ac4bf072f86891203a05f46f9de16f68fc2ffe6 Mon Sep 17 00:00:00 2001 From: Tonis Tiigi Date: Thu, 21 Mar 2019 23:09:09 -0700 Subject: [PATCH] dockerfile: add dockerignore override support Signed-off-by: Tonis Tiigi --- frontend/dockerfile/builder/build.go | 30 +++++++++---- frontend/dockerfile/dockerfile_test.go | 58 ++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/frontend/dockerfile/builder/build.go b/frontend/dockerfile/builder/build.go index 0eef68ce..3ace6dae 100644 --- a/frontend/dockerfile/builder/build.go +++ b/frontend/dockerfile/builder/build.go @@ -113,7 +113,7 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) { name := "load build definition from " + filename src := llb.Local(localNameDockerfile, - llb.FollowPaths([]string{filename}), + llb.FollowPaths([]string{filename, filename + ".dockerignore"}), llb.SessionID(c.BuildOpts().SessionID), llb.SharedKeyHint(localNameDockerfile), dockerfile2llb.WithInternalName(name), @@ -175,6 +175,8 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) { eg, ctx2 := errgroup.WithContext(ctx) var dtDockerfile []byte + var dtDockerignore []byte + var dtDockerignoreDefault []byte eg.Go(func() error { res, err := c.Solve(ctx2, client.SolveRequest{ Definition: def.ToPB(), @@ -194,6 +196,13 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) { if err != nil { return errors.Wrapf(err, "failed to read dockerfile") } + + dt, err := ref.ReadFile(ctx2, client.ReadRequest{ + Filename: filename + ".dockerignore", + }) + if err == nil { + dtDockerignore = dt + } return nil }) var excludes []string @@ -223,14 +232,11 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) { if err != nil { return err } - dtDockerignore, err := ref.ReadFile(ctx2, client.ReadRequest{ + dtDockerignoreDefault, err = ref.ReadFile(ctx2, client.ReadRequest{ Filename: dockerignoreFilename, }) - if err == nil { - excludes, err = dockerignore.ReadAll(bytes.NewBuffer(dtDockerignore)) - if err != nil { - return errors.Wrap(err, "failed to parse dockerignore") - } + if err != nil { + return nil } return nil }) @@ -240,6 +246,16 @@ func Build(ctx context.Context, c client.Client) (*client.Result, error) { return nil, err } + if dtDockerignore == nil { + dtDockerignore = dtDockerignoreDefault + } + if dtDockerignore != nil { + excludes, err = dockerignore.ReadAll(bytes.NewBuffer(dtDockerignore)) + if err != nil { + return nil, errors.Wrap(err, "failed to parse dockerignore") + } + } + if _, ok := opts["cmdline"]; !ok { ref, cmdline, ok := dockerfile2llb.DetectSyntax(bytes.NewBuffer(dtDockerfile)) if ok { diff --git a/frontend/dockerfile/dockerfile_test.go b/frontend/dockerfile/dockerfile_test.go index 6b0d8ee4..56244272 100644 --- a/frontend/dockerfile/dockerfile_test.go +++ b/frontend/dockerfile/dockerfile_test.go @@ -78,6 +78,7 @@ var allTests = []integration.Test{ testDockerfileAddArchiveWildcard, testCopyChownExistingDir, testCopyWildcardCache, + testDockerignoreOverride, } var fileOpTests = []integration.Test{ @@ -138,6 +139,63 @@ func TestIntegration(t *testing.T) { }))...) } +func testDockerignoreOverride(t *testing.T, sb integration.Sandbox) { + f := getFrontend(t, sb) + dockerfile := []byte(` +FROM busybox +COPY . . +RUN [ -f foo ] && [ ! -f bar ] +`) + + ignore := []byte(` +bar +`) + + dockerfile2 := []byte(` +FROM busybox +COPY . . +RUN [ ! -f foo ] && [ -f bar ] +`) + + ignore2 := []byte(` +foo +`) + + dir, err := tmpdir( + fstest.CreateFile("Dockerfile", dockerfile, 0600), + fstest.CreateFile("Dockerfile.dockerignore", ignore, 0600), + fstest.CreateFile("Dockerfile2", dockerfile2, 0600), + fstest.CreateFile("Dockerfile2.dockerignore", ignore2, 0600), + fstest.CreateFile("foo", []byte("contents0"), 0600), + fstest.CreateFile("bar", []byte("contents0"), 0600), + ) + require.NoError(t, err) + defer os.RemoveAll(dir) + + c, err := client.New(context.TODO(), sb.Address()) + require.NoError(t, err) + defer c.Close() + + _, err = f.Solve(context.TODO(), c, client.SolveOpt{ + LocalDirs: map[string]string{ + builder.DefaultLocalNameDockerfile: dir, + builder.DefaultLocalNameContext: dir, + }, + }, nil) + require.NoError(t, err) + + _, err = f.Solve(context.TODO(), c, client.SolveOpt{ + FrontendAttrs: map[string]string{ + "filename": "Dockerfile2", + }, + LocalDirs: map[string]string{ + builder.DefaultLocalNameDockerfile: dir, + builder.DefaultLocalNameContext: dir, + }, + }, nil) + require.NoError(t, err) +} + func testEmptyDestDir(t *testing.T, sb integration.Sandbox) { f := getFrontend(t, sb) isFileOp := getFileOp(t, sb)