Browse code

Merge pull request #32495 from dnephin/cleanup-builder-dispatcher-env

Remove Builder.dockerfile field

Akihiro Suda authored on 2017/04/11 14:50:55
Showing 4 changed files
... ...
@@ -53,7 +53,6 @@ type Builder struct {
53 53
 	clientCtx context.Context
54 54
 	cancel    context.CancelFunc
55 55
 
56
-	dockerfile    *parser.Node
57 56
 	runConfig     *container.Config // runconfig for cmd, run, entrypoint etc.
58 57
 	flags         *BFlags
59 58
 	tmpContainers map[string]struct{}
... ...
@@ -103,7 +102,7 @@ func (bm *BuildManager) BuildFromContext(ctx context.Context, src io.ReadCloser,
103 103
 	if len(dockerfileName) > 0 {
104 104
 		buildOptions.Dockerfile = dockerfileName
105 105
 	}
106
-	b, err := NewBuilder(ctx, buildOptions, bm.backend, builder.DockerIgnoreContext{ModifiableContext: buildContext}, nil)
106
+	b, err := NewBuilder(ctx, buildOptions, bm.backend, builder.DockerIgnoreContext{ModifiableContext: buildContext})
107 107
 	if err != nil {
108 108
 		return "", err
109 109
 	}
... ...
@@ -114,7 +113,7 @@ func (bm *BuildManager) BuildFromContext(ctx context.Context, src io.ReadCloser,
114 114
 // NewBuilder creates a new Dockerfile builder from an optional dockerfile and a Config.
115 115
 // If dockerfile is nil, the Dockerfile specified by Config.DockerfileName,
116 116
 // will be read from the Context passed to Build().
117
-func NewBuilder(clientCtx context.Context, config *types.ImageBuildOptions, backend builder.Backend, buildContext builder.Context, dockerfile io.ReadCloser) (b *Builder, err error) {
117
+func NewBuilder(clientCtx context.Context, config *types.ImageBuildOptions, backend builder.Backend, buildContext builder.Context) (b *Builder, err error) {
118 118
 	if config == nil {
119 119
 		config = new(types.ImageBuildOptions)
120 120
 	}
... ...
@@ -139,14 +138,6 @@ func NewBuilder(clientCtx context.Context, config *types.ImageBuildOptions, back
139 139
 	b.imageContexts = &imageContexts{b: b}
140 140
 
141 141
 	parser.SetEscapeToken(parser.DefaultEscapeToken, &b.directive) // Assume the default token for escape
142
-
143
-	if dockerfile != nil {
144
-		b.dockerfile, err = parser.Parse(dockerfile, &b.directive)
145
-		if err != nil {
146
-			return nil, err
147
-		}
148
-	}
149
-
150 142
 	return b, nil
151 143
 }
152 144
 
... ...
@@ -193,15 +184,6 @@ func sanitizeRepoAndTags(names []string) ([]reference.Named, error) {
193 193
 	return repoAndTags, nil
194 194
 }
195 195
 
196
-func (b *Builder) processLabels() {
197
-	if len(b.options.Labels) == 0 {
198
-		return
199
-	}
200
-
201
-	node := parser.NodeFromLabels(b.options.Labels)
202
-	b.dockerfile.Children = append(b.dockerfile.Children, node)
203
-}
204
-
205 196
 // build runs the Dockerfile builder from a context and a docker object that allows to make calls
206 197
 // to Docker.
207 198
 //
... ...
@@ -222,11 +204,9 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri
222 222
 	b.Stderr = stderr
223 223
 	b.Output = out
224 224
 
225
-	// If Dockerfile was not parsed yet, extract it from the Context
226
-	if b.dockerfile == nil {
227
-		if err := b.readDockerfile(); err != nil {
228
-			return "", err
229
-		}
225
+	dockerfile, err := b.readDockerfile()
226
+	if err != nil {
227
+		return "", err
230 228
 	}
231 229
 
232 230
 	repoAndTags, err := sanitizeRepoAndTags(b.options.Tags)
... ...
@@ -234,17 +214,17 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri
234 234
 		return "", err
235 235
 	}
236 236
 
237
-	b.processLabels()
237
+	addNodesForLabelOption(dockerfile, b.options.Labels)
238 238
 
239 239
 	var shortImgID string
240
-	total := len(b.dockerfile.Children)
241
-	for _, n := range b.dockerfile.Children {
240
+	total := len(dockerfile.Children)
241
+	for _, n := range dockerfile.Children {
242 242
 		if err := b.checkDispatch(n, false); err != nil {
243 243
 			return "", perrors.Wrapf(err, "Dockerfile parse error line %d", n.StartLine)
244 244
 		}
245 245
 	}
246 246
 
247
-	for i, n := range b.dockerfile.Children {
247
+	for i, n := range dockerfile.Children {
248 248
 		select {
249 249
 		case <-b.clientCtx.Done():
250 250
 			logrus.Debug("Builder: build cancelled!")
... ...
@@ -306,6 +286,15 @@ func (b *Builder) build(stdout io.Writer, stderr io.Writer, out io.Writer) (stri
306 306
 	return b.image, nil
307 307
 }
308 308
 
309
+func addNodesForLabelOption(dockerfile *parser.Node, labels map[string]string) {
310
+	if len(labels) == 0 {
311
+		return
312
+	}
313
+
314
+	node := parser.NodeFromLabels(labels)
315
+	dockerfile.Children = append(dockerfile.Children, node)
316
+}
317
+
309 318
 // check if there are any leftover build-args that were passed but not
310 319
 // consumed during build. Print a warning, if there are any.
311 320
 func (b *Builder) warnOnUnusedBuildArgs() {
... ...
@@ -335,7 +324,7 @@ func (b *Builder) Cancel() {
335 335
 //
336 336
 // TODO: Remove?
337 337
 func BuildFromConfig(config *container.Config, changes []string) (*container.Config, error) {
338
-	b, err := NewBuilder(context.Background(), nil, nil, nil, nil)
338
+	b, err := NewBuilder(context.Background(), nil, nil, nil)
339 339
 	if err != nil {
340 340
 		return nil, err
341 341
 	}
... ...
@@ -2,45 +2,34 @@ package dockerfile
2 2
 
3 3
 import (
4 4
 	"strings"
5
-
6 5
 	"testing"
7 6
 
8
-	"github.com/docker/docker/api/types"
9
-	"github.com/docker/docker/api/types/container"
10 7
 	"github.com/docker/docker/builder/dockerfile/parser"
11 8
 	"github.com/docker/docker/pkg/testutil/assert"
12 9
 )
13 10
 
14
-func TestBuildProcessLabels(t *testing.T) {
11
+func TestAddNodesForLabelOption(t *testing.T) {
15 12
 	dockerfile := "FROM scratch"
16 13
 	d := parser.Directive{}
17 14
 	parser.SetEscapeToken(parser.DefaultEscapeToken, &d)
18
-	n, err := parser.Parse(strings.NewReader(dockerfile), &d)
15
+	nodes, err := parser.Parse(strings.NewReader(dockerfile), &d)
19 16
 	assert.NilError(t, err)
20 17
 
21
-	options := &types.ImageBuildOptions{
22
-		Labels: map[string]string{
23
-			"org.e": "cli-e",
24
-			"org.d": "cli-d",
25
-			"org.c": "cli-c",
26
-			"org.b": "cli-b",
27
-			"org.a": "cli-a",
28
-		},
29
-	}
30
-	b := &Builder{
31
-		runConfig:  &container.Config{},
32
-		options:    options,
33
-		directive:  d,
34
-		dockerfile: n,
18
+	labels := map[string]string{
19
+		"org.e": "cli-e",
20
+		"org.d": "cli-d",
21
+		"org.c": "cli-c",
22
+		"org.b": "cli-b",
23
+		"org.a": "cli-a",
35 24
 	}
36
-	b.processLabels()
25
+	addNodesForLabelOption(nodes, labels)
37 26
 
38 27
 	expected := []string{
39 28
 		"FROM scratch",
40 29
 		`LABEL "org.a"='cli-a' "org.b"='cli-b' "org.c"='cli-c' "org.d"='cli-d' "org.e"='cli-e'`,
41 30
 	}
42
-	assert.Equal(t, len(b.dockerfile.Children), 2)
43
-	for i, v := range b.dockerfile.Children {
31
+	assert.Equal(t, len(nodes.Children), 2)
32
+	for i, v := range nodes.Children {
44 33
 		assert.Equal(t, v.Original, expected[i])
45 34
 	}
46 35
 }
... ...
@@ -650,7 +650,7 @@ func (b *Builder) clearTmp() {
650 650
 }
651 651
 
652 652
 // readDockerfile reads a Dockerfile from the current context.
653
-func (b *Builder) readDockerfile() error {
653
+func (b *Builder) readDockerfile() (*parser.Node, error) {
654 654
 	// If no -f was specified then look for 'Dockerfile'. If we can't find
655 655
 	// that then look for 'dockerfile'.  If neither are found then default
656 656
 	// back to 'Dockerfile' and use that in the error message.
... ...
@@ -664,10 +664,9 @@ func (b *Builder) readDockerfile() error {
664 664
 		}
665 665
 	}
666 666
 
667
-	err := b.parseDockerfile()
668
-
667
+	nodes, err := b.parseDockerfile()
669 668
 	if err != nil {
670
-		return err
669
+		return nodes, err
671 670
 	}
672 671
 
673 672
 	// After the Dockerfile has been parsed, we need to check the .dockerignore
... ...
@@ -681,32 +680,27 @@ func (b *Builder) readDockerfile() error {
681 681
 	if dockerIgnore, ok := b.context.(builder.DockerIgnoreContext); ok {
682 682
 		dockerIgnore.Process([]string{b.options.Dockerfile})
683 683
 	}
684
-	return nil
684
+	return nodes, nil
685 685
 }
686 686
 
687
-func (b *Builder) parseDockerfile() error {
687
+func (b *Builder) parseDockerfile() (*parser.Node, error) {
688 688
 	f, err := b.context.Open(b.options.Dockerfile)
689 689
 	if err != nil {
690 690
 		if os.IsNotExist(err) {
691
-			return fmt.Errorf("Cannot locate specified Dockerfile: %s", b.options.Dockerfile)
691
+			return nil, fmt.Errorf("Cannot locate specified Dockerfile: %s", b.options.Dockerfile)
692 692
 		}
693
-		return err
693
+		return nil, err
694 694
 	}
695 695
 	defer f.Close()
696 696
 	if f, ok := f.(*os.File); ok {
697 697
 		// ignoring error because Open already succeeded
698 698
 		fi, err := f.Stat()
699 699
 		if err != nil {
700
-			return fmt.Errorf("Unexpected error reading Dockerfile: %v", err)
700
+			return nil, fmt.Errorf("Unexpected error reading Dockerfile: %v", err)
701 701
 		}
702 702
 		if fi.Size() == 0 {
703
-			return fmt.Errorf("The Dockerfile (%s) cannot be empty", b.options.Dockerfile)
703
+			return nil, fmt.Errorf("The Dockerfile (%s) cannot be empty", b.options.Dockerfile)
704 704
 		}
705 705
 	}
706
-	b.dockerfile, err = parser.Parse(f, &b.directive)
707
-	if err != nil {
708
-		return err
709
-	}
710
-
711
-	return nil
706
+	return parser.Parse(f, &b.directive)
712 707
 }
... ...
@@ -2,12 +2,12 @@ package dockerfile
2 2
 
3 3
 import (
4 4
 	"fmt"
5
-	"strings"
6 5
 	"testing"
7 6
 
8 7
 	"github.com/docker/docker/api/types"
9 8
 	"github.com/docker/docker/builder"
10 9
 	"github.com/docker/docker/pkg/archive"
10
+	"github.com/docker/docker/pkg/testutil/assert"
11 11
 )
12 12
 
13 13
 func TestEmptyDockerfile(t *testing.T) {
... ...
@@ -54,10 +54,7 @@ func TestNonExistingDockerfile(t *testing.T) {
54 54
 
55 55
 func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath, expectedError string) {
56 56
 	tarStream, err := archive.Tar(contextDir, archive.Uncompressed)
57
-
58
-	if err != nil {
59
-		t.Fatalf("Error when creating tar stream: %s", err)
60
-	}
57
+	assert.NilError(t, err)
61 58
 
62 59
 	defer func() {
63 60
 		if err = tarStream.Close(); err != nil {
... ...
@@ -66,10 +63,7 @@ func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath,
66 66
 	}()
67 67
 
68 68
 	context, err := builder.MakeTarSumContext(tarStream)
69
-
70
-	if err != nil {
71
-		t.Fatalf("Error when creating tar context: %s", err)
72
-	}
69
+	assert.NilError(t, err)
73 70
 
74 71
 	defer func() {
75 72
 		if err = context.Close(); err != nil {
... ...
@@ -83,13 +77,6 @@ func readAndCheckDockerfile(t *testing.T, testName, contextDir, dockerfilePath,
83 83
 
84 84
 	b := &Builder{options: options, context: context}
85 85
 
86
-	err = b.readDockerfile()
87
-
88
-	if err == nil {
89
-		t.Fatalf("No error when executing test: %s", testName)
90
-	}
91
-
92
-	if !strings.Contains(err.Error(), expectedError) {
93
-		t.Fatalf("Wrong error message. Should be \"%s\". Got \"%s\"", expectedError, err.Error())
94
-	}
86
+	_, err = b.readDockerfile()
87
+	assert.Error(t, err, expectedError)
95 88
 }