From f0a9c2e3f4ea101c8a56a31ae6cb11559bc78683 Mon Sep 17 00:00:00 2001 From: Daniel Nephin Date: Fri, 24 Feb 2017 17:19:45 -0500 Subject: [PATCH] Allow ARG to come before FROM to support variables in FROM. Signed-off-by: Daniel Nephin --- builder/dockerfile/builder.go | 7 ++++++- builder/dockerfile/dispatchers.go | 19 +++++++++++++++++-- builder/dockerfile/internals.go | 4 ++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/builder/dockerfile/builder.go b/builder/dockerfile/builder.go index 219ba2d3c3..c1d1e1b128 100644 --- a/builder/dockerfile/builder.go +++ b/builder/dockerfile/builder.go @@ -72,7 +72,7 @@ type Builder struct { tmpContainers map[string]struct{} image string // imageID imageContexts *imageContexts // helper for storing contexts from builds - noBaseImage bool + noBaseImage bool // A flag to track the use of `scratch` as the base image maintainer string cmdSet bool disableCommit bool @@ -328,6 +328,11 @@ func (b *Builder) warnOnUnusedBuildArgs() { } } +// hasFromImage returns true if the builder has processed a `FROM ` line +func (b *Builder) hasFromImage() bool { + return b.image != "" || b.noBaseImage +} + // Cancel cancels an ongoing Dockerfile build. func (b *Builder) Cancel() { b.cancel() diff --git a/builder/dockerfile/dispatchers.go b/builder/dockerfile/dispatchers.go index 8007addf8e..52c4a4064d 100644 --- a/builder/dockerfile/dispatchers.go +++ b/builder/dockerfile/dispatchers.go @@ -22,6 +22,7 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/strslice" "github.com/docker/docker/builder" + "github.com/docker/docker/pkg/shellvar" "github.com/docker/docker/pkg/signal" "github.com/docker/go-connections/nat" "github.com/pkg/errors" @@ -218,7 +219,17 @@ func from(b *Builder, args []string, attributes map[string]bool, original string return err } - name := args[0] + getBuildArg := func(key string) (string, bool) { + value, ok := b.options.BuildArgs[key] + if value != nil { + return *value, ok + } + return "", ok + } + name, err := shellvar.Substitute(args[0], getBuildArg) + if err != nil { + return err + } var image builder.Image @@ -360,7 +371,7 @@ func workdir(b *Builder, args []string, attributes map[string]bool, original str // RUN [ "echo", "hi" ] # echo hi // func run(b *Builder, args []string, attributes map[string]bool, original string) error { - if b.image == "" && !b.noBaseImage { + if !b.hasFromImage() { return errors.New("Please provide a source image with `from` prior to run") } @@ -790,6 +801,10 @@ func arg(b *Builder, args []string, attributes map[string]bool, original string) } b.allowedBuildArgs[name] = value + // Arg before FROM doesn't add a layer + if !b.hasFromImage() { + return nil + } return b.commit("", b.runConfig.Cmd, fmt.Sprintf("ARG %s", arg)) } diff --git a/builder/dockerfile/internals.go b/builder/dockerfile/internals.go index 80385c4f66..5ad4db9d93 100644 --- a/builder/dockerfile/internals.go +++ b/builder/dockerfile/internals.go @@ -44,7 +44,7 @@ func (b *Builder) commit(id string, autoCmd strslice.StrSlice, comment string) e if b.disableCommit { return nil } - if b.image == "" && !b.noBaseImage { + if !b.hasFromImage() { return errors.New("Please provide a source image with `from` prior to commit") } b.runConfig.Image = b.image @@ -503,7 +503,7 @@ func (b *Builder) probeCache() (bool, error) { } func (b *Builder) create() (string, error) { - if b.image == "" && !b.noBaseImage { + if !b.hasFromImage() { return "", errors.New("Please provide a source image with `from` prior to run") } b.runConfig.Image = b.image