From 070b0517d5f05313f91d40f4455eff5f074d7961 Mon Sep 17 00:00:00 2001 From: Priya Wadhwa Date: Mon, 19 Mar 2018 10:42:40 -0700 Subject: [PATCH] Get escape token by parsing ENV command --- executor/cmd/root.go | 4 ---- pkg/commands/env.go | 30 ++++++++++++++++++++++-------- pkg/commands/env_test.go | 18 ++++++++++++++++++ pkg/dockerfile/dockerfile.go | 11 ----------- 4 files changed, 40 insertions(+), 23 deletions(-) diff --git a/executor/cmd/root.go b/executor/cmd/root.go index 974db7d26..a34a5f3cd 100644 --- a/executor/cmd/root.go +++ b/executor/cmd/root.go @@ -67,10 +67,6 @@ func execute() error { if err != nil { return err } - // Set the escape token - if err := dockerfile.SetEscapeToken(d); err != nil { - return err - } baseImage := stages[0].BaseName // Unpack file system to root diff --git a/pkg/commands/env.go b/pkg/commands/env.go index 400fbdc6e..f7f004940 100644 --- a/pkg/commands/env.go +++ b/pkg/commands/env.go @@ -17,9 +17,10 @@ limitations under the License. package commands import ( - "github.com/GoogleCloudPlatform/k8s-container-builder/pkg/dockerfile" + "bytes" "github.com/containers/image/manifest" "github.com/docker/docker/builder/dockerfile/instructions" + "github.com/docker/docker/builder/dockerfile/parser" "github.com/docker/docker/builder/dockerfile/shell" "github.com/sirupsen/logrus" "os" @@ -32,15 +33,20 @@ type EnvCommand struct { func (e *EnvCommand) ExecuteCommand(config *manifest.Schema2Config) error { logrus.Info("cmd: ENV") + // The dockerfile/shell package handles processing env values + // It handles escape characters and supports expansion from the config.Env array + // Shlex handles some of the following use cases (these and more are tested in integration tests) + // ""a'b'c"" -> "a'b'c" + // "Rex\ The\ Dog \" -> "Rex The Dog" + // "a\"b" -> "a"b" + envString := envToString(e.cmd) + p, err := parser.Parse(bytes.NewReader([]byte(envString))) + if err != nil { + return err + } + shlex := shell.NewLex(p.EscapeToken) newEnvs := e.cmd.Env for index, pair := range newEnvs { - // The dockerfile/shell package handles processing env values - // It handles escape characters and supports expansion from the config.Env array - // Shlex handles some of the following use cases (these and more are tested in integration tests) - // ""a'b'c"" -> "a'b'c" - // "Rex\ The\ Dog \" -> "Rex The Dog" - // "a\"b" -> "a"b" - shlex := shell.NewLex(dockerfile.EscapeToken) expandedValue, err := shlex.ProcessWord(pair.Value, config.Env) if err != nil { return err @@ -92,6 +98,14 @@ Loop: return nil } +func envToString(cmd *instructions.EnvCommand) string { + env := []string{"ENV"} + for _, kvp := range cmd.Env { + env = append(env, kvp.Key+"="+kvp.Value) + } + return strings.Join(env, " ") +} + // We know that no files have changed, so return an empty array func (e *EnvCommand) FilesToSnapshot() []string { return []string{} diff --git a/pkg/commands/env_test.go b/pkg/commands/env_test.go index 2399ff199..f0cccdaa4 100644 --- a/pkg/commands/env_test.go +++ b/pkg/commands/env_test.go @@ -53,3 +53,21 @@ func TestUpdateEnvConfig(t *testing.T) { updateConfigEnv(newEnvs, cfg) testutil.CheckErrorAndDeepEqual(t, false, nil, expectedEnvArray, cfg.Env) } + +func TestEnvToString(t *testing.T) { + envCmd := &instructions.EnvCommand{ + Env: []instructions.KeyValuePair{ + { + Key: "PATH", + Value: "/some/path", + }, + { + Key: "HOME", + Value: "/root", + }, + }, + } + expectedString := "ENV PATH=/some/path HOME=/root" + actualString := envToString(envCmd) + testutil.CheckErrorAndDeepEqual(t, false, nil, expectedString, actualString) +} diff --git a/pkg/dockerfile/dockerfile.go b/pkg/dockerfile/dockerfile.go index 5e036be7c..948cffa50 100644 --- a/pkg/dockerfile/dockerfile.go +++ b/pkg/dockerfile/dockerfile.go @@ -23,8 +23,6 @@ import ( "github.com/docker/docker/builder/dockerfile/parser" ) -var EscapeToken rune - // Parse parses the contents of a Dockerfile and returns a list of commands func Parse(b []byte) ([]instructions.Stage, error) { p, err := parser.Parse(bytes.NewReader(b)) @@ -37,12 +35,3 @@ func Parse(b []byte) ([]instructions.Stage, error) { } return stages, err } - -func SetEscapeToken(b []byte) error { - p, err := parser.Parse(bytes.NewReader(b)) - if err != nil { - return err - } - EscapeToken = p.EscapeToken - return nil -}