builder: produce error when using unsupported Dockerfile option
With the promotion of the experimental Dockerfile syntax to "stable", the Dockerfile
syntax now includes some options that are supported by BuildKit, but not (yet)
supported in the classic builder.
As a result, parsing a Dockerfile may succeed, but any flag that's known to BuildKit,
but not supported by the classic builder is silently ignored;
$ mkdir buildkit_flags && cd buildkit_flags
$ touch foo.txt
For example, `RUN --mount`:
DOCKER_BUILDKIT=0 docker build --no-cache -f- . <<EOF
FROM busybox
RUN --mount=type=cache,target=/foo echo hello
EOF
Sending build context to Docker daemon 2.095kB
Step 1/2 : FROM busybox
---> 219ee5171f80
Step 2/2 : RUN --mount=type=cache,target=/foo echo hello
---> Running in 022fdb856bc8
hello
Removing intermediate container 022fdb856bc8
---> e9f0988844d1
Successfully built e9f0988844d1
Or `COPY --chmod` (same for `ADD --chmod`):
DOCKER_BUILDKIT=0 docker build --no-cache -f- . <<EOF
FROM busybox
COPY --chmod=0777 /foo.txt /foo.txt
EOF
Sending build context to Docker daemon 2.095kB
Step 1/2 : FROM busybox
---> 219ee5171f80
Step 2/2 : COPY --chmod=0777 /foo.txt /foo.txt
---> 8b7117932a2a
Successfully built 8b7117932a2a
Note that unknown flags still produce and error, for example, the below fails because `--hello` is an unknown flag;
DOCKER_BUILDKIT=0 docker build -<<EOF
FROM busybox
RUN --hello echo hello
EOF
Sending build context to Docker daemon 2.048kB
Error response from daemon: dockerfile parse error line 2: Unknown flag: hello
With this patch applied
----------------------------
With this patch applied, flags that are known in the Dockerfile spec, but are not
supported by the classic builder, produce an error, which includes a link to the
documentation how to enable BuildKit:
DOCKER_BUILDKIT=0 docker build --no-cache -f- . <<EOF
FROM busybox
RUN --mount=type=cache,target=/foo echo hello
EOF
Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM busybox
---> b97242f89c8a
Step 2/2 : RUN --mount=type=cache,target=/foo echo hello
the --mount option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled
DOCKER_BUILDKIT=0 docker build --no-cache -f- . <<EOF
FROM busybox
COPY --chmod=0777 /foo.txt /foo.txt
EOF
Sending build context to Docker daemon 2.095kB
Step 1/2 : FROM busybox
---> b97242f89c8a
Step 2/2 : COPY --chmod=0777 /foo.txt /foo.txt
the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
(cherry picked from commit a09c0276a2
)
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
653b58cc8a
commit
915b239519
2 changed files with 50 additions and 0 deletions
|
@ -92,6 +92,9 @@ func dispatchLabel(d dispatchRequest, c *instructions.LabelCommand) error {
|
||||||
// exist here. If you do not wish to have this automatic handling, use COPY.
|
// exist here. If you do not wish to have this automatic handling, use COPY.
|
||||||
//
|
//
|
||||||
func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error {
|
func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error {
|
||||||
|
if c.Chmod != "" {
|
||||||
|
return errors.New("the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled")
|
||||||
|
}
|
||||||
downloader := newRemoteSourceDownloader(d.builder.Output, d.builder.Stdout)
|
downloader := newRemoteSourceDownloader(d.builder.Output, d.builder.Stdout)
|
||||||
copier := copierFromDispatchRequest(d, downloader, nil)
|
copier := copierFromDispatchRequest(d, downloader, nil)
|
||||||
defer copier.Cleanup()
|
defer copier.Cleanup()
|
||||||
|
@ -111,6 +114,9 @@ func dispatchAdd(d dispatchRequest, c *instructions.AddCommand) error {
|
||||||
// Same as 'ADD' but without the tar and remote url handling.
|
// Same as 'ADD' but without the tar and remote url handling.
|
||||||
//
|
//
|
||||||
func dispatchCopy(d dispatchRequest, c *instructions.CopyCommand) error {
|
func dispatchCopy(d dispatchRequest, c *instructions.CopyCommand) error {
|
||||||
|
if c.Chmod != "" {
|
||||||
|
return errors.New("the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled")
|
||||||
|
}
|
||||||
var im *imageMount
|
var im *imageMount
|
||||||
var err error
|
var err error
|
||||||
if c.From != "" {
|
if c.From != "" {
|
||||||
|
@ -346,6 +352,12 @@ func dispatchRun(d dispatchRequest, c *instructions.RunCommand) error {
|
||||||
if !system.IsOSSupported(d.state.operatingSystem) {
|
if !system.IsOSSupported(d.state.operatingSystem) {
|
||||||
return system.ErrNotSupportedOperatingSystem
|
return system.ErrNotSupportedOperatingSystem
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(c.FlagsUsed) > 0 {
|
||||||
|
// classic builder RUN currently does not support any flags, so fail on the first one
|
||||||
|
return errors.Errorf("the --%s option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled", c.FlagsUsed[0])
|
||||||
|
}
|
||||||
|
|
||||||
stateRunConfig := d.state.runConfig
|
stateRunConfig := d.state.runConfig
|
||||||
cmdFromArgs, argsEscaped := resolveCmdLine(c.ShellDependantCmdLine, stateRunConfig, d.state.operatingSystem, c.Name(), c.String())
|
cmdFromArgs, argsEscaped := resolveCmdLine(c.ShellDependantCmdLine, stateRunConfig, d.state.operatingSystem, c.Name(), c.String())
|
||||||
buildArgs := d.state.buildArgs.FilterAllowed(stateRunConfig.Env)
|
buildArgs := d.state.buildArgs.FilterAllowed(stateRunConfig.Env)
|
||||||
|
|
|
@ -3,6 +3,7 @@ package dockerfile // import "github.com/docker/docker/builder/dockerfile"
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -570,3 +571,40 @@ func TestRunIgnoresHealthcheck(t *testing.T) {
|
||||||
assert.NilError(t, dispatch(sb, run))
|
assert.NilError(t, dispatch(sb, run))
|
||||||
assert.Check(t, is.DeepEqual(expectedTest, sb.state.runConfig.Healthcheck.Test))
|
assert.Check(t, is.DeepEqual(expectedTest, sb.state.runConfig.Healthcheck.Test))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDispatchUnsupportedOptions(t *testing.T) {
|
||||||
|
b := newBuilderWithMockBackend()
|
||||||
|
sb := newDispatchRequest(b, '`', nil, NewBuildArgs(make(map[string]*string)), newStagesBuildResults())
|
||||||
|
sb.state.baseImage = &mockImage{}
|
||||||
|
sb.state.operatingSystem = runtime.GOOS
|
||||||
|
|
||||||
|
t.Run("ADD with chmod", func(t *testing.T) {
|
||||||
|
cmd := &instructions.AddCommand{SourcesAndDest: []string{".", "."}, Chmod: "0655"}
|
||||||
|
err := dispatch(sb, cmd)
|
||||||
|
assert.Error(t, err, "the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("COPY with chmod", func(t *testing.T) {
|
||||||
|
cmd := &instructions.CopyCommand{SourcesAndDest: []string{".", "."}, Chmod: "0655"}
|
||||||
|
err := dispatch(sb, cmd)
|
||||||
|
assert.Error(t, err, "the --chmod option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("RUN with unsupported options", func(t *testing.T) {
|
||||||
|
cmd := &instructions.RunCommand{
|
||||||
|
ShellDependantCmdLine: instructions.ShellDependantCmdLine{
|
||||||
|
CmdLine: strslice.StrSlice{"echo foo"},
|
||||||
|
PrependShell: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// classic builder "RUN" currently doesn't support any flags, but testing
|
||||||
|
// both "known" flags and "bogus" flags for completeness, and in case
|
||||||
|
// one or more of these flags will be supported in future
|
||||||
|
for _, f := range []string{"mount", "network", "security", "any-flag"} {
|
||||||
|
cmd.FlagsUsed = []string{f}
|
||||||
|
err := dispatch(sb, cmd)
|
||||||
|
assert.Error(t, err, fmt.Sprintf("the --%s option requires BuildKit. Refer to https://docs.docker.com/go/buildkit/ to learn how to build images with BuildKit enabled", f))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue