Quellcode durchsuchen

builder: Refactors according to @tiborvass's comments

Docker-DCO-1.1-Signed-off-by: Erik Hollensbe <github@hollensbe.org> (github: erikh)
Erik Hollensbe vor 11 Jahren
Ursprung
Commit
2ef1dec7e8
6 geänderte Dateien mit 105 neuen und 114 gelöschten Zeilen
  1. 0 15
      builder/builder.go
  2. 17 17
      builder/dispatchers.go
  3. 43 39
      builder/evaluator.go
  4. 42 40
      builder/internals.go
  5. 2 2
      builder/job.go
  6. 1 1
      builder/support.go

+ 0 - 15
builder/builder.go

@@ -1,15 +0,0 @@
-package builder
-
-import (
-	"github.com/docker/docker/runconfig"
-)
-
-// Create a new builder. See
-func NewBuilder(opts *BuildOpts) *BuildFile {
-	return &BuildFile{
-		Dockerfile:    nil,
-		Config:        &runconfig.Config{},
-		Options:       opts,
-		TmpContainers: map[string]struct{}{},
-	}
-}

+ 17 - 17
builder/dispatchers.go

@@ -18,7 +18,7 @@ import (
 )
 
 // dispatch with no layer / parsing. This is effectively not a command.
-func nullDispatch(b *BuildFile, args []string, attributes map[string]bool) error {
+func nullDispatch(b *Builder, args []string, attributes map[string]bool) error {
 	return nil
 }
 
@@ -27,7 +27,7 @@ func nullDispatch(b *BuildFile, args []string, attributes map[string]bool) error
 // Sets the environment variable foo to bar, also makes interpolation
 // in the dockerfile available from the next statement on via ${foo}.
 //
-func env(b *BuildFile, args []string, attributes map[string]bool) error {
+func env(b *Builder, args []string, attributes map[string]bool) error {
 	if len(args) != 2 {
 		return fmt.Errorf("ENV accepts two arguments")
 	}
@@ -48,7 +48,7 @@ func env(b *BuildFile, args []string, attributes map[string]bool) error {
 // MAINTAINER some text <maybe@an.email.address>
 //
 // Sets the maintainer metadata.
-func maintainer(b *BuildFile, args []string, attributes map[string]bool) error {
+func maintainer(b *Builder, args []string, attributes map[string]bool) error {
 	if len(args) != 1 {
 		return fmt.Errorf("MAINTAINER requires only one argument")
 	}
@@ -62,7 +62,7 @@ func maintainer(b *BuildFile, args []string, attributes map[string]bool) error {
 // Add the file 'foo' to '/path'. Tarball and Remote URL (git, http) handling
 // exist here. If you do not wish to have this automatic handling, use COPY.
 //
-func add(b *BuildFile, args []string, attributes map[string]bool) error {
+func add(b *Builder, args []string, attributes map[string]bool) error {
 	if len(args) != 2 {
 		return fmt.Errorf("ADD requires two arguments")
 	}
@@ -74,7 +74,7 @@ func add(b *BuildFile, args []string, attributes map[string]bool) error {
 //
 // Same as 'ADD' but without the tar and remote url handling.
 //
-func dispatchCopy(b *BuildFile, args []string, attributes map[string]bool) error {
+func dispatchCopy(b *Builder, args []string, attributes map[string]bool) error {
 	if len(args) != 2 {
 		return fmt.Errorf("COPY requires two arguments")
 	}
@@ -86,16 +86,16 @@ func dispatchCopy(b *BuildFile, args []string, attributes map[string]bool) error
 //
 // This sets the image the dockerfile will build on top of.
 //
-func from(b *BuildFile, args []string, attributes map[string]bool) error {
+func from(b *Builder, args []string, attributes map[string]bool) error {
 	if len(args) != 1 {
 		return fmt.Errorf("FROM requires one argument")
 	}
 
 	name := args[0]
 
-	image, err := b.Options.Daemon.Repositories().LookupImage(name)
+	image, err := b.Daemon.Repositories().LookupImage(name)
 	if err != nil {
-		if b.Options.Daemon.Graph().IsNotExist(err) {
+		if b.Daemon.Graph().IsNotExist(err) {
 			image, err = b.pullImage(name)
 		}
 
@@ -118,7 +118,7 @@ func from(b *BuildFile, args []string, attributes map[string]bool) error {
 // special cases. search for 'OnBuild' in internals.go for additional special
 // cases.
 //
-func onbuild(b *BuildFile, args []string, attributes map[string]bool) error {
+func onbuild(b *Builder, args []string, attributes map[string]bool) error {
 	triggerInstruction := strings.ToUpper(strings.TrimSpace(args[0]))
 	switch triggerInstruction {
 	case "ONBUILD":
@@ -137,7 +137,7 @@ func onbuild(b *BuildFile, args []string, attributes map[string]bool) error {
 //
 // Set the working directory for future RUN/CMD/etc statements.
 //
-func workdir(b *BuildFile, args []string, attributes map[string]bool) error {
+func workdir(b *Builder, args []string, attributes map[string]bool) error {
 	if len(args) != 1 {
 		return fmt.Errorf("WORKDIR requires exactly one argument")
 	}
@@ -165,7 +165,7 @@ func workdir(b *BuildFile, args []string, attributes map[string]bool) error {
 // RUN echo hi          # sh -c echo hi
 // RUN [ "echo", "hi" ] # echo hi
 //
-func run(b *BuildFile, args []string, attributes map[string]bool) error {
+func run(b *Builder, args []string, attributes map[string]bool) error {
 	args = handleJsonArgs(args, attributes)
 
 	if b.image == "" {
@@ -220,7 +220,7 @@ func run(b *BuildFile, args []string, attributes map[string]bool) error {
 // Set the default command to run in the container (which may be empty).
 // Argument handling is the same as RUN.
 //
-func cmd(b *BuildFile, args []string, attributes map[string]bool) error {
+func cmd(b *Builder, args []string, attributes map[string]bool) error {
 	b.Config.Cmd = handleJsonArgs(args, attributes)
 
 	if err := b.commit("", b.Config.Cmd, fmt.Sprintf("CMD %v", cmd)); err != nil {
@@ -239,7 +239,7 @@ func cmd(b *BuildFile, args []string, attributes map[string]bool) error {
 // Handles command processing similar to CMD and RUN, only b.Config.Entrypoint
 // is initialized at NewBuilder time instead of through argument parsing.
 //
-func entrypoint(b *BuildFile, args []string, attributes map[string]bool) error {
+func entrypoint(b *Builder, args []string, attributes map[string]bool) error {
 	b.Config.Entrypoint = handleJsonArgs(args, attributes)
 
 	// if there is no cmd in current Dockerfile - cleanup cmd
@@ -258,7 +258,7 @@ func entrypoint(b *BuildFile, args []string, attributes map[string]bool) error {
 // Expose ports for links and port mappings. This all ends up in
 // b.Config.ExposedPorts for runconfig.
 //
-func expose(b *BuildFile, args []string, attributes map[string]bool) error {
+func expose(b *Builder, args []string, attributes map[string]bool) error {
 	portsTab := args
 
 	if b.Config.ExposedPorts == nil {
@@ -285,7 +285,7 @@ func expose(b *BuildFile, args []string, attributes map[string]bool) error {
 // Set the user to 'foo' for future commands and when running the
 // ENTRYPOINT/CMD at container run time.
 //
-func user(b *BuildFile, args []string, attributes map[string]bool) error {
+func user(b *Builder, args []string, attributes map[string]bool) error {
 	if len(args) != 1 {
 		return fmt.Errorf("USER requires exactly one argument")
 	}
@@ -299,7 +299,7 @@ func user(b *BuildFile, args []string, attributes map[string]bool) error {
 // Expose the volume /foo for use. Will also accept the JSON form, but either
 // way requires exactly one argument.
 //
-func volume(b *BuildFile, args []string, attributes map[string]bool) error {
+func volume(b *Builder, args []string, attributes map[string]bool) error {
 	if len(args) != 1 {
 		return fmt.Errorf("Volume cannot be empty")
 	}
@@ -319,6 +319,6 @@ func volume(b *BuildFile, args []string, attributes map[string]bool) error {
 }
 
 // INSERT is no longer accepted, but we still parse it.
-func insert(b *BuildFile, args []string, attributes map[string]bool) error {
+func insert(b *Builder, args []string, attributes map[string]bool) error {
 	return fmt.Errorf("INSERT has been deprecated. Please use ADD instead")
 }

+ 43 - 39
builder/evaluator.go

@@ -20,11 +20,9 @@
 package builder
 
 import (
-	"bytes"
 	"errors"
 	"fmt"
 	"io"
-	"io/ioutil"
 	"os"
 	"path"
 	"strings"
@@ -42,10 +40,10 @@ var (
 	ErrDockerfileEmpty = errors.New("Dockerfile cannot be empty")
 )
 
-var evaluateTable map[string]func(*BuildFile, []string, map[string]bool) error
+var evaluateTable map[string]func(*Builder, []string, map[string]bool) error
 
 func init() {
-	evaluateTable = map[string]func(*BuildFile, []string, map[string]bool) error{
+	evaluateTable = map[string]func(*Builder, []string, map[string]bool) error{
 		"env":            env,
 		"maintainer":     maintainer,
 		"add":            add,
@@ -66,23 +64,7 @@ func init() {
 
 // internal struct, used to maintain configuration of the Dockerfile's
 // processing as it evaluates the parsing result.
-type BuildFile struct {
-	Dockerfile *parser.Node      // the syntax tree of the dockerfile
-	Config     *runconfig.Config // runconfig for cmd, run, entrypoint etc.
-	Options    *BuildOpts        // see below
-
-	// both of these are controlled by the Remove and ForceRemove options in BuildOpts
-	TmpContainers map[string]struct{} // a map of containers used for removes
-
-	image       string         // image name for commit processing
-	maintainer  string         // maintainer name. could probably be removed.
-	cmdSet      bool           // indicates is CMD was set in current Dockerfile
-	context     *tarsum.TarSum // the context is a tarball that is uploaded by the client
-	contextPath string         // the path of the temporary directory the local context is unpacked to (server side)
-
-}
-
-type BuildOpts struct {
+type Builder struct {
 	Daemon *daemon.Daemon
 	Engine *engine.Engine
 
@@ -104,6 +86,19 @@ type BuildOpts struct {
 	// Deprecated, original writer used for ImagePull. To be removed.
 	OutOld          io.Writer
 	StreamFormatter *utils.StreamFormatter
+
+	Config *runconfig.Config // runconfig for cmd, run, entrypoint etc.
+
+	// both of these are controlled by the Remove and ForceRemove options in BuildOpts
+	TmpContainers map[string]struct{} // a map of containers used for removes
+
+	dockerfile  *parser.Node   // the syntax tree of the dockerfile
+	image       string         // image name for commit processing
+	maintainer  string         // maintainer name. could probably be removed.
+	cmdSet      bool           // indicates is CMD was set in current Dockerfile
+	context     *tarsum.TarSum // the context is a tarball that is uploaded by the client
+	contextPath string         // the path of the temporary directory the local context is unpacked to (server side)
+
 }
 
 // Run the builder with the context. This is the lynchpin of this package. This
@@ -118,38 +113,48 @@ type BuildOpts struct {
 //   processing.
 // * Print a happy message and return the image ID.
 //
-func (b *BuildFile) Run(context io.Reader) (string, error) {
+func (b *Builder) Run(context io.Reader) (string, error) {
 	if err := b.readContext(context); err != nil {
 		return "", err
 	}
 
 	filename := path.Join(b.contextPath, "Dockerfile")
-	if _, err := os.Stat(filename); os.IsNotExist(err) {
+
+	fi, err := os.Stat(filename)
+	if os.IsNotExist(err) {
 		return "", fmt.Errorf("Cannot build a directory without a Dockerfile")
 	}
-	fileBytes, err := ioutil.ReadFile(filename)
+	if fi.Size() == 0 {
+		return "", ErrDockerfileEmpty
+	}
+
+	f, err := os.Open(filename)
 	if err != nil {
 		return "", err
 	}
-	if len(fileBytes) == 0 {
-		return "", ErrDockerfileEmpty
-	}
-	ast, err := parser.Parse(bytes.NewReader(fileBytes))
+
+	defer f.Close()
+
+	ast, err := parser.Parse(f)
 	if err != nil {
 		return "", err
 	}
 
-	b.Dockerfile = ast
+	b.dockerfile = ast
+
+	// some initializations that would not have been supplied by the caller.
+	b.Config = &runconfig.Config{}
+	b.TmpContainers = map[string]struct{}{}
 
-	for i, n := range b.Dockerfile.Children {
+	for i, n := range b.dockerfile.Children {
 		if err := b.dispatch(i, n); err != nil {
-			if b.Options.ForceRemove {
+			if b.ForceRemove {
 				b.clearTmp()
 			}
 			return "", err
 		}
-		fmt.Fprintf(b.Options.OutStream, " ---> %s\n", utils.TruncateID(b.image))
-		if b.Options.Remove {
+		fmt.Fprintf(b.OutStream, " ---> %s\n", utils.TruncateID(b.image))
+		if b.Remove {
 			b.clearTmp()
 		}
 	}
@@ -158,7 +163,7 @@ func (b *BuildFile) Run(context io.Reader) (string, error) {
 		return "", fmt.Errorf("No image was generated. Is your Dockerfile empty?\n")
 	}
 
-	fmt.Fprintf(b.Options.OutStream, "Successfully built %s\n", utils.TruncateID(b.image))
+	fmt.Fprintf(b.OutStream, "Successfully built %s\n", utils.TruncateID(b.image))
 	return b.image, nil
 }
 
@@ -168,7 +173,7 @@ func (b *BuildFile) Run(context io.Reader) (string, error) {
 // Child[Node, Node, Node] where Child is from parser.Node.Children and each
 // node comes from parser.Node.Next. This forms a "line" with a statement and
 // arguments and we process them in this normalized form by hitting
-// evaluateTable with the leaf nodes of the command and the BuildFile object.
+// evaluateTable with the leaf nodes of the command and the Builder object.
 //
 // ONBUILD is a special case; in this case the parser will emit:
 // Child[Node, Child[Node, Node...]] where the first node is the literal
@@ -176,14 +181,13 @@ func (b *BuildFile) Run(context io.Reader) (string, error) {
 // such as `RUN` in ONBUILD RUN foo. There is special case logic in here to
 // deal with that, at least until it becomes more of a general concern with new
 // features.
-func (b *BuildFile) dispatch(stepN int, ast *parser.Node) error {
+func (b *Builder) dispatch(stepN int, ast *parser.Node) error {
 	cmd := ast.Value
 	attrs := ast.Attributes
 	strs := []string{}
 	msg := fmt.Sprintf("Step %d : %s", stepN, strings.ToUpper(cmd))
 
 	if cmd == "onbuild" {
-		fmt.Fprintf(b.Options.OutStream, "%#v\n", ast.Next.Children[0].Value)
 		ast = ast.Next.Children[0]
 		strs = append(strs, b.replaceEnv(ast.Value))
 		msg += " " + ast.Value
@@ -195,7 +199,7 @@ func (b *BuildFile) dispatch(stepN int, ast *parser.Node) error {
 		msg += " " + ast.Value
 	}
 
-	fmt.Fprintf(b.Options.OutStream, "%s\n", msg)
+	fmt.Fprintln(b.OutStream, msg)
 
 	// XXX yes, we skip any cmds that are not valid; the parser should have
 	// picked these out already.
@@ -203,7 +207,7 @@ func (b *BuildFile) dispatch(stepN int, ast *parser.Node) error {
 		return f(b, strs, attrs)
 	}
 
-	fmt.Fprintf(b.Options.ErrStream, "# Skipping unknown instruction %s\n", strings.ToUpper(cmd))
+	fmt.Fprintf(b.ErrStream, "# Skipping unknown instruction %s\n", strings.ToUpper(cmd))
 
 	return nil
 }

+ 42 - 40
builder/internals.go

@@ -30,7 +30,7 @@ import (
 	"github.com/docker/docker/utils"
 )
 
-func (b *BuildFile) readContext(context io.Reader) error {
+func (b *Builder) readContext(context io.Reader) error {
 	tmpdirPath, err := ioutil.TempDir("", "docker-build")
 	if err != nil {
 		return err
@@ -50,7 +50,7 @@ func (b *BuildFile) readContext(context io.Reader) error {
 	return nil
 }
 
-func (b *BuildFile) commit(id string, autoCmd []string, comment string) error {
+func (b *Builder) commit(id string, autoCmd []string, comment string) error {
 	if b.image == "" {
 		return fmt.Errorf("Please provide a source image with `from` prior to commit")
 	}
@@ -68,15 +68,15 @@ func (b *BuildFile) commit(id string, autoCmd []string, comment string) error {
 			return nil
 		}
 
-		container, warnings, err := b.Options.Daemon.Create(b.Config, "")
+		container, warnings, err := b.Daemon.Create(b.Config, "")
 		if err != nil {
 			return err
 		}
 		for _, warning := range warnings {
-			fmt.Fprintf(b.Options.OutStream, " ---> [Warning] %s\n", warning)
+			fmt.Fprintf(b.OutStream, " ---> [Warning] %s\n", warning)
 		}
 		b.TmpContainers[container.ID] = struct{}{}
-		fmt.Fprintf(b.Options.OutStream, " ---> Running in %s\n", utils.TruncateID(container.ID))
+		fmt.Fprintf(b.OutStream, " ---> Running in %s\n", utils.TruncateID(container.ID))
 		id = container.ID
 
 		if err := container.Mount(); err != nil {
@@ -84,7 +84,7 @@ func (b *BuildFile) commit(id string, autoCmd []string, comment string) error {
 		}
 		defer container.Unmount()
 	}
-	container := b.Options.Daemon.Get(id)
+	container := b.Daemon.Get(id)
 	if container == nil {
 		return fmt.Errorf("An error occured while creating the container")
 	}
@@ -93,7 +93,7 @@ func (b *BuildFile) commit(id string, autoCmd []string, comment string) error {
 	autoConfig := *b.Config
 	autoConfig.Cmd = autoCmd
 	// Commit the container
-	image, err := b.Options.Daemon.Commit(container, "", "", "", b.maintainer, true, &autoConfig)
+	image, err := b.Daemon.Commit(container, "", "", "", b.maintainer, true, &autoConfig)
 	if err != nil {
 		return err
 	}
@@ -101,7 +101,7 @@ func (b *BuildFile) commit(id string, autoCmd []string, comment string) error {
 	return nil
 }
 
-func (b *BuildFile) runContextCommand(args []string, allowRemote bool, allowDecompression bool, cmdName string) error {
+func (b *Builder) runContextCommand(args []string, allowRemote bool, allowDecompression bool, cmdName string) error {
 	if b.context == nil {
 		return fmt.Errorf("No context given. Impossible to use %s", cmdName)
 	}
@@ -200,7 +200,7 @@ func (b *BuildFile) runContextCommand(args []string, allowRemote bool, allowDeco
 	}
 
 	// Hash path and check the cache
-	if b.Options.UtilizeCache {
+	if b.UtilizeCache {
 		var (
 			hash string
 			sums = b.context.GetSums()
@@ -244,7 +244,7 @@ func (b *BuildFile) runContextCommand(args []string, allowRemote bool, allowDeco
 	}
 
 	// Create the container
-	container, _, err := b.Options.Daemon.Create(b.Config, "")
+	container, _, err := b.Daemon.Create(b.Config, "")
 	if err != nil {
 		return err
 	}
@@ -268,27 +268,27 @@ func (b *BuildFile) runContextCommand(args []string, allowRemote bool, allowDeco
 	return nil
 }
 
-func (b *BuildFile) pullImage(name string) (*imagepkg.Image, error) {
+func (b *Builder) pullImage(name string) (*imagepkg.Image, error) {
 	remote, tag := parsers.ParseRepositoryTag(name)
-	pullRegistryAuth := b.Options.AuthConfig
-	if len(b.Options.AuthConfigFile.Configs) > 0 {
+	pullRegistryAuth := b.AuthConfig
+	if len(b.AuthConfigFile.Configs) > 0 {
 		// The request came with a full auth config file, we prefer to use that
 		endpoint, _, err := registry.ResolveRepositoryName(remote)
 		if err != nil {
 			return nil, err
 		}
-		resolvedAuth := b.Options.AuthConfigFile.ResolveAuthConfig(endpoint)
+		resolvedAuth := b.AuthConfigFile.ResolveAuthConfig(endpoint)
 		pullRegistryAuth = &resolvedAuth
 	}
-	job := b.Options.Engine.Job("pull", remote, tag)
-	job.SetenvBool("json", b.Options.StreamFormatter.Json())
+	job := b.Engine.Job("pull", remote, tag)
+	job.SetenvBool("json", b.StreamFormatter.Json())
 	job.SetenvBool("parallel", true)
 	job.SetenvJson("authConfig", pullRegistryAuth)
-	job.Stdout.Add(b.Options.OutOld)
+	job.Stdout.Add(b.OutOld)
 	if err := job.Run(); err != nil {
 		return nil, err
 	}
-	image, err := b.Options.Daemon.Repositories().LookupImage(name)
+	image, err := b.Daemon.Repositories().LookupImage(name)
 	if err != nil {
 		return nil, err
 	}
@@ -296,7 +296,7 @@ func (b *BuildFile) pullImage(name string) (*imagepkg.Image, error) {
 	return image, nil
 }
 
-func (b *BuildFile) processImageFrom(img *imagepkg.Image) error {
+func (b *Builder) processImageFrom(img *imagepkg.Image) error {
 	b.image = img.ID
 
 	if img.Config != nil {
@@ -309,7 +309,7 @@ func (b *BuildFile) processImageFrom(img *imagepkg.Image) error {
 
 	// Process ONBUILD triggers if they exist
 	if nTriggers := len(b.Config.OnBuild); nTriggers != 0 {
-		fmt.Fprintf(b.Options.ErrStream, "# Executing %d build triggers\n", nTriggers)
+		fmt.Fprintf(b.ErrStream, "# Executing %d build triggers\n", nTriggers)
 	}
 
 	// Copy the ONBUILD triggers, and remove them from the config, since the config will be commited.
@@ -330,7 +330,8 @@ func (b *BuildFile) processImageFrom(img *imagepkg.Image) error {
 		}
 
 		// FIXME we have to run the evaluator manually here. This does not belong
-		// in this function.
+		// in this function. Once removed, the init() in evaluator.go should no
+		// longer be necessary.
 
 		if f, ok := evaluateTable[strings.ToLower(stepInstruction)]; ok {
 			if err := f(b, splitStep[1:], nil); err != nil {
@@ -344,17 +345,17 @@ func (b *BuildFile) processImageFrom(img *imagepkg.Image) error {
 	return nil
 }
 
-// probeCache checks to see if image-caching is enabled (`b.Options.UtilizeCache`)
+// probeCache checks to see if image-caching is enabled (`b.UtilizeCache`)
 // and if so attempts to look up the current `b.image` and `b.Config` pair
-// in the current server `b.Options.Daemon`. If an image is found, probeCache returns
+// in the current server `b.Daemon`. If an image is found, probeCache returns
 // `(true, nil)`. If no image is found, it returns `(false, nil)`. If there
 // is any error, it returns `(false, err)`.
-func (b *BuildFile) probeCache() (bool, error) {
-	if b.Options.UtilizeCache {
-		if cache, err := b.Options.Daemon.ImageGetCached(b.image, b.Config); err != nil {
+func (b *Builder) probeCache() (bool, error) {
+	if b.UtilizeCache {
+		if cache, err := b.Daemon.ImageGetCached(b.image, b.Config); err != nil {
 			return false, err
 		} else if cache != nil {
-			fmt.Fprintf(b.Options.OutStream, " ---> Using cache\n")
+			fmt.Fprintf(b.OutStream, " ---> Using cache\n")
 			log.Debugf("[BUILDER] Use cached version")
 			b.image = cache.ID
 			return true, nil
@@ -365,19 +366,20 @@ func (b *BuildFile) probeCache() (bool, error) {
 	return false, nil
 }
 
-func (b *BuildFile) create() (*daemon.Container, error) {
+func (b *Builder) create() (*daemon.Container, error) {
 	if b.image == "" {
 		return nil, fmt.Errorf("Please provide a source image with `from` prior to run")
 	}
 	b.Config.Image = b.image
 
 	// Create the container
-	c, _, err := b.Options.Daemon.Create(b.Config, "")
+	c, _, err := b.Daemon.Create(b.Config, "")
 	if err != nil {
 		return nil, err
 	}
+
 	b.TmpContainers[c.ID] = struct{}{}
-	fmt.Fprintf(b.Options.OutStream, " ---> Running in %s\n", utils.TruncateID(c.ID))
+	fmt.Fprintf(b.OutStream, " ---> Running in %s\n", utils.TruncateID(c.ID))
 
 	// override the entry point that may have been picked up from the base image
 	c.Path = b.Config.Cmd[0]
@@ -386,16 +388,16 @@ func (b *BuildFile) create() (*daemon.Container, error) {
 	return c, nil
 }
 
-func (b *BuildFile) run(c *daemon.Container) error {
+func (b *Builder) run(c *daemon.Container) error {
 	var errCh chan error
-	if b.Options.Verbose {
+	if b.Verbose {
 		errCh = utils.Go(func() error {
 			// FIXME: call the 'attach' job so that daemon.Attach can be made private
 			//
 			// FIXME (LK4D4): Also, maybe makes sense to call "logs" job, it is like attach
 			// but without hijacking for stdin. Also, with attach there can be race
 			// condition because of some output already was printed before it.
-			return <-b.Options.Daemon.Attach(c, nil, nil, b.Options.OutStream, b.Options.ErrStream)
+			return <-b.Daemon.Attach(c, nil, nil, b.OutStream, b.ErrStream)
 		})
 	}
 
@@ -422,7 +424,7 @@ func (b *BuildFile) run(c *daemon.Container) error {
 	return nil
 }
 
-func (b *BuildFile) checkPathForAddition(orig string) error {
+func (b *Builder) checkPathForAddition(orig string) error {
 	origPath := path.Join(b.contextPath, orig)
 	origPath, err := filepath.EvalSymlinks(origPath)
 	if err != nil {
@@ -443,7 +445,7 @@ func (b *BuildFile) checkPathForAddition(orig string) error {
 	return nil
 }
 
-func (b *BuildFile) addContext(container *daemon.Container, orig, dest string, decompress bool) error {
+func (b *Builder) addContext(container *daemon.Container, orig, dest string, decompress bool) error {
 	var (
 		err        error
 		destExists = true
@@ -548,14 +550,14 @@ func fixPermissions(destination string, uid, gid int) error {
 	})
 }
 
-func (b *BuildFile) clearTmp() {
+func (b *Builder) clearTmp() {
 	for c := range b.TmpContainers {
-		tmp := b.Options.Daemon.Get(c)
-		if err := b.Options.Daemon.Destroy(tmp); err != nil {
-			fmt.Fprintf(b.Options.OutStream, "Error removing intermediate container %s: %s\n", utils.TruncateID(c), err.Error())
+		tmp := b.Daemon.Get(c)
+		if err := b.Daemon.Destroy(tmp); err != nil {
+			fmt.Fprintf(b.OutStream, "Error removing intermediate container %s: %s\n", utils.TruncateID(c), err.Error())
 		} else {
 			delete(b.TmpContainers, c)
-			fmt.Fprintf(b.Options.OutStream, "Removing intermediate container %s\n", utils.TruncateID(c))
+			fmt.Fprintf(b.OutStream, "Removing intermediate container %s\n", utils.TruncateID(c))
 		}
 	}
 }

+ 2 - 2
builder/job.go

@@ -85,7 +85,7 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) engine.Status {
 
 	sf := utils.NewStreamFormatter(job.GetenvBool("json"))
 
-	opts := &BuildOpts{
+	builder := &Builder{
 		Daemon: b.Daemon,
 		Engine: b.Engine,
 		OutStream: &utils.StdoutFormater{
@@ -106,7 +106,7 @@ func (b *BuilderJob) CmdBuild(job *engine.Job) engine.Status {
 		AuthConfigFile:  configFile,
 	}
 
-	id, err := NewBuilder(opts).Run(context)
+	id, err := builder.Run(context)
 	if err != nil {
 		return job.Error(err)
 	}

+ 1 - 1
builder/support.go

@@ -10,7 +10,7 @@ var (
 )
 
 // handle environment replacement. Used in dispatcher.
-func (b *BuildFile) replaceEnv(str string) string {
+func (b *Builder) replaceEnv(str string) string {
 	for _, match := range TOKEN_ENV_INTERPOLATION.FindAllString(str, -1) {
 		match = match[strings.Index(match, "$"):]
 		matchKey := strings.Trim(match, "${}")