From 2ef1dec7e8d405f237b68ca104d457d78b8caed1 Mon Sep 17 00:00:00 2001 From: Erik Hollensbe Date: Tue, 26 Aug 2014 12:25:44 -0700 Subject: [PATCH] builder: Refactors according to @tiborvass's comments Docker-DCO-1.1-Signed-off-by: Erik Hollensbe (github: erikh) --- builder/builder.go | 15 -------- builder/dispatchers.go | 34 ++++++++--------- builder/evaluator.go | 84 ++++++++++++++++++++++-------------------- builder/internals.go | 82 +++++++++++++++++++++-------------------- builder/job.go | 4 +- builder/support.go | 2 +- 6 files changed, 106 insertions(+), 115 deletions(-) delete mode 100644 builder/builder.go diff --git a/builder/builder.go b/builder/builder.go deleted file mode 100644 index 685f27b061..0000000000 --- a/builder/builder.go +++ /dev/null @@ -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{}{}, - } -} diff --git a/builder/dispatchers.go b/builder/dispatchers.go index fe0b5be579..8abdb51d8a 100644 --- a/builder/dispatchers.go +++ b/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 // // 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") } diff --git a/builder/evaluator.go b/builder/evaluator.go index ec8edc98c8..33d8f080e0 100644 --- a/builder/evaluator.go +++ b/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 err != nil { - return "", err - } - if len(fileBytes) == 0 { + if fi.Size() == 0 { return "", ErrDockerfileEmpty } - ast, err := parser.Parse(bytes.NewReader(fileBytes)) + + f, err := os.Open(filename) if err != nil { return "", err } - b.Dockerfile = ast + defer f.Close() - for i, n := range b.Dockerfile.Children { + ast, err := parser.Parse(f) + if err != nil { + return "", err + } + + 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 { 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 } diff --git a/builder/internals.go b/builder/internals.go index 51b2b63ab9..1767d7d9dd 100644 --- a/builder/internals.go +++ b/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)) } } } diff --git a/builder/job.go b/builder/job.go index e1233e0a08..1aa2c3b6b9 100644 --- a/builder/job.go +++ b/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) } diff --git a/builder/support.go b/builder/support.go index bae97e370f..de5d57b501 100644 --- a/builder/support.go +++ b/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, "${}")