Merge pull request #274 from vdemeester/remove-shell-parser

Remove shell parser for dockerfile2llb, using moby upstream package
docker-18.09
Tõnis Tiigi 2018-02-01 18:03:33 -08:00 committed by GitHub
commit 6d2595c6fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 22 deletions

View File

@ -15,6 +15,7 @@ import (
"github.com/docker/distribution/reference" "github.com/docker/distribution/reference"
"github.com/docker/docker/builder/dockerfile/instructions" "github.com/docker/docker/builder/dockerfile/instructions"
"github.com/docker/docker/builder/dockerfile/parser" "github.com/docker/docker/builder/dockerfile/parser"
"github.com/docker/docker/builder/dockerfile/shell"
"github.com/docker/docker/pkg/signal" "github.com/docker/docker/pkg/signal"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
"github.com/moby/buildkit/client/llb" "github.com/moby/buildkit/client/llb"
@ -59,7 +60,7 @@ func Dockerfile2LLB(ctx context.Context, dt []byte, opt ConvertOpt) (*llb.State,
metaArgs[i] = setBuildArgValue(metaArgs[i], opt.BuildArgs) metaArgs[i] = setBuildArgValue(metaArgs[i], opt.BuildArgs)
} }
shlex := NewShellLex(dockerfile.EscapeToken) shlex := shell.NewLex(dockerfile.EscapeToken)
metaResolver := opt.MetaResolver metaResolver := opt.MetaResolver
if metaResolver == nil { if metaResolver == nil {
@ -232,7 +233,7 @@ type dispatchOpt struct {
dispatchStatesByName map[string]*dispatchState dispatchStatesByName map[string]*dispatchState
metaArgs []instructions.ArgCommand metaArgs []instructions.ArgCommand
buildArgValues map[string]string buildArgValues map[string]string
shlex *ShellLex shlex *shell.Lex
sessionID string sessionID string
buildContext llb.State buildContext llb.State
} }
@ -491,7 +492,7 @@ func dispatchHealthcheck(d *dispatchState, c *instructions.HealthCheckCommand) e
return commitToHistory(&d.image, fmt.Sprintf("HEALTHCHECK %q", d.image.Config.Healthcheck), false, nil) return commitToHistory(&d.image, fmt.Sprintf("HEALTHCHECK %q", d.image.Config.Healthcheck), false, nil)
} }
func dispatchExpose(d *dispatchState, c *instructions.ExposeCommand, shlex *ShellLex) error { func dispatchExpose(d *dispatchState, c *instructions.ExposeCommand, shlex *shell.Lex) error {
ports := []string{} ports := []string{}
for _, p := range c.Ports { for _, p := range c.Ports {
ps, err := shlex.ProcessWords(p, toEnvList(d.buildArgs, d.image.Config.Env)) ps, err := shlex.ProcessWords(p, toEnvList(d.buildArgs, d.image.Config.Env))
@ -516,6 +517,7 @@ func dispatchExpose(d *dispatchState, c *instructions.ExposeCommand, shlex *Shel
return commitToHistory(&d.image, fmt.Sprintf("EXPOSE %v", ps), false, nil) return commitToHistory(&d.image, fmt.Sprintf("EXPOSE %v", ps), false, nil)
} }
func dispatchUser(d *dispatchState, c *instructions.UserCommand, commit bool) error { func dispatchUser(d *dispatchState, c *instructions.UserCommand, commit bool) error {
d.state = d.state.User(c.User) d.state = d.state.User(c.User)
d.image.Config.User = c.User d.image.Config.User = c.User
@ -601,7 +603,7 @@ func addEnv(env []string, k, v string, override bool) []string {
for i, envVar := range env { for i, envVar := range env {
envParts := strings.SplitN(envVar, "=", 2) envParts := strings.SplitN(envVar, "=", 2)
compareFrom := envParts[0] compareFrom := envParts[0]
if equalEnvKeys(compareFrom, k) { if shell.EqualEnvKeys(compareFrom, k) {
if override { if override {
env[i] = k + "=" + v env[i] = k + "=" + v
} }
@ -615,10 +617,6 @@ func addEnv(env []string, k, v string, override bool) []string {
return env return env
} }
func equalEnvKeys(from, to string) bool {
return from == to
}
func setBuildArgValue(c instructions.ArgCommand, values map[string]string) instructions.ArgCommand { func setBuildArgValue(c instructions.ArgCommand, values map[string]string) instructions.ArgCommand {
if v, ok := values[c.Key]; ok { if v, ok := values[c.Key]; ok {
c.Value = &v c.Value = &v

View File

@ -0,0 +1,9 @@
// +build !windows
package shell
// EqualEnvKeys compare two strings and returns true if they are equal. On
// Windows this comparison is case insensitive.
func EqualEnvKeys(from, to string) bool {
return from == to
}

View File

@ -0,0 +1,9 @@
package shell
import "strings"
// EqualEnvKeys compare two strings and returns true if they are equal. On
// Windows this comparison is case insensitive.
func EqualEnvKeys(from, to string) bool {
return strings.ToUpper(from) == strings.ToUpper(to)
}

View File

@ -1,4 +1,4 @@
package dockerfile2llb package shell
import ( import (
"bytes" "bytes"
@ -9,27 +9,25 @@ import (
"github.com/pkg/errors" "github.com/pkg/errors"
) )
// copied from moby/moby. Should be replaced by other utility package or turned into a special package. // Lex performs shell word splitting and variable expansion.
// ShellLex performs shell word splitting and variable expansion.
// //
// ShellLex takes a string and an array of env variables and // Lex takes a string and an array of env variables and
// process all quotes (" and ') as well as $xxx and ${xxx} env variable // process all quotes (" and ') as well as $xxx and ${xxx} env variable
// tokens. Tries to mimic bash shell process. // tokens. Tries to mimic bash shell process.
// It doesn't support all flavors of ${xx:...} formats but new ones can // It doesn't support all flavors of ${xx:...} formats but new ones can
// be added by adding code to the "special ${} format processing" section // be added by adding code to the "special ${} format processing" section
type ShellLex struct { type Lex struct {
escapeToken rune escapeToken rune
} }
// NewShellLex creates a new ShellLex which uses escapeToken to escape quotes. // NewLex creates a new Lex which uses escapeToken to escape quotes.
func NewShellLex(escapeToken rune) *ShellLex { func NewLex(escapeToken rune) *Lex {
return &ShellLex{escapeToken: escapeToken} return &Lex{escapeToken: escapeToken}
} }
// ProcessWord will use the 'env' list of environment variables, // ProcessWord will use the 'env' list of environment variables,
// and replace any env var references in 'word'. // and replace any env var references in 'word'.
func (s *ShellLex) ProcessWord(word string, env []string) (string, error) { func (s *Lex) ProcessWord(word string, env []string) (string, error) {
word, _, err := s.process(word, env) word, _, err := s.process(word, env)
return word, err return word, err
} }
@ -41,12 +39,12 @@ func (s *ShellLex) ProcessWord(word string, env []string) (string, error) {
// this splitting is done **after** the env var substitutions are done. // this splitting is done **after** the env var substitutions are done.
// Note, each one is trimmed to remove leading and trailing spaces (unless // Note, each one is trimmed to remove leading and trailing spaces (unless
// they are quoted", but ProcessWord retains spaces between words. // they are quoted", but ProcessWord retains spaces between words.
func (s *ShellLex) ProcessWords(word string, env []string) ([]string, error) { func (s *Lex) ProcessWords(word string, env []string) ([]string, error) {
_, words, err := s.process(word, env) _, words, err := s.process(word, env)
return words, err return words, err
} }
func (s *ShellLex) process(word string, env []string) (string, []string, error) { func (s *Lex) process(word string, env []string) (string, []string, error) {
sw := &shellWord{ sw := &shellWord{
envs: env, envs: env,
escapeToken: s.escapeToken, escapeToken: s.escapeToken,
@ -329,7 +327,7 @@ func (sw *shellWord) getEnv(name string) string {
for _, env := range sw.envs { for _, env := range sw.envs {
i := strings.Index(env, "=") i := strings.Index(env, "=")
if i < 0 { if i < 0 {
if equalEnvKeys(name, env) { if EqualEnvKeys(name, env) {
// Should probably never get here, but just in case treat // Should probably never get here, but just in case treat
// it like "var" and "var=" are the same // it like "var" and "var=" are the same
return "" return ""
@ -337,7 +335,7 @@ func (sw *shellWord) getEnv(name string) string {
continue continue
} }
compareName := env[:i] compareName := env[:i]
if !equalEnvKeys(name, compareName) { if !EqualEnvKeys(name, compareName) {
continue continue
} }
return env[i+1:] return env[i+1:]