Skip to content

Commit

Permalink
frontend/dockerfile: add RunCommand.FlagsUsed field
Browse files Browse the repository at this point in the history
The FlagsUsed contains a list of flags that were used, which allows the classic
(non-buildkit) builder in dockerd to produce an error when non-supported options
are used in a Dockerfile.

This is a short-term solution; a more permanent solution will be to keep track
of which version of the Dockerfile syntax is supported, and to have the classic
builder pass the maximum supported version of the syntax.

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
  • Loading branch information
thaJeztah committed Jan 27, 2021

Verified

This commit was signed with the committer’s verified signature.
thaJeztah Sebastiaan van Stijn
1 parent 40cf375 commit ebed917
Showing 5 changed files with 52 additions and 1 deletion.
9 changes: 9 additions & 0 deletions frontend/dockerfile/instructions/bflag.go
Original file line number Diff line number Diff line change
@@ -108,6 +108,15 @@ func (fl *Flag) IsUsed() bool {
return false
}

// Used returns a slice of flag names that are set
func (bf *BFlags) Used() []string {
used := make([]string, 0, len(bf.used))
for f := range bf.used {
used = append(used, f)
}
return used
}

// IsTrue checks if a bool flag is true
func (fl *Flag) IsTrue() bool {
if fl.flagType != boolType {
28 changes: 28 additions & 0 deletions frontend/dockerfile/instructions/bflag_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package instructions

import (
"sort"
"strings"
"testing"
)

@@ -184,4 +186,30 @@ func TestBuilderFlags(t *testing.T) {
if !flBool1.IsTrue() {
t.Fatalf("Test %s, bool1 should be true", bf.Args)
}

// ---

bf = NewBFlags()
_ = bf.AddBool("bool1", false)
_ = bf.AddBool("bool2", false)
_ = bf.AddBool("bool3", false)
_ = bf.AddBool("bool4", true)
_ = bf.AddBool("bool5", true)
_ = bf.AddString("str1", "")
_ = bf.AddString("str2", "")
_ = bf.AddString("str3", "def3")
_ = bf.AddString("str4", "def4")

bf.Args = []string{`--bool2=false`, `--bool3`, `--bool4=true`, `--bool5`, `--str2= `, `--str3=def3`, `--str4=my-val`}

if err = bf.Parse(); err != nil {
t.Fatalf("Test %q was supposed to work: %s", bf.Args, err)
}
used := bf.Used()
sort.Strings(used)
expected = "bool2, bool3, bool4, bool5, str2, str3, str4"
actual := strings.Join(used, ", ")
if actual != expected {
t.Fatalf("Test %s, expected '%s', got '%s'", bf.Args, expected, actual)
}
}
1 change: 1 addition & 0 deletions frontend/dockerfile/instructions/commands.go
Original file line number Diff line number Diff line change
@@ -269,6 +269,7 @@ type RunCommand struct {
withNameAndCode
withExternalData
ShellDependantCmdLine
FlagsUsed []string
}

// CmdCommand : CMD foo
2 changes: 1 addition & 1 deletion frontend/dockerfile/instructions/parse.go
Original file line number Diff line number Diff line change
@@ -375,7 +375,7 @@ func parseRun(req parseRequest) (*RunCommand, error) {
if err := req.flags.Parse(); err != nil {
return nil, err
}

cmd.FlagsUsed = req.flags.Used()
cmd.ShellDependantCmdLine = parseShellDependentCommand(req, false)
cmd.withNameAndCode = newWithNameAndCode(req)

13 changes: 13 additions & 0 deletions frontend/dockerfile/instructions/parse_test.go
Original file line number Diff line number Diff line change
@@ -226,3 +226,16 @@ func TestErrorCases(t *testing.T) {
require.Contains(t, err.Error(), c.expectedError)
}
}

func TestRunCmdFlagsUsed(t *testing.T) {
dockerfile := "RUN --mount=type=tmpfs,target=/foo/ echo hello"
r := strings.NewReader(dockerfile)
ast, err := parser.Parse(r)
require.NoError(t, err)

n := ast.AST.Children[0]
c, err := ParseInstruction(n)
require.NoError(t, err)
require.IsType(t, c, &RunCommand{})
require.Equal(t, []string{"mount"}, c.(*RunCommand).FlagsUsed)
}

0 comments on commit ebed917

Please sign in to comment.