Merge pull request #38487 from LinuxMercedes/error-on-empty-dockerfile
Error on empty dockerfile
This commit is contained in:
commit
bba833928c
11 changed files with 158 additions and 58 deletions
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/docker/docker/api/types/backend"
|
||||
"github.com/docker/docker/builder"
|
||||
"github.com/docker/docker/builder/dockerignore"
|
||||
"github.com/docker/docker/errdefs"
|
||||
"github.com/docker/docker/pkg/fileutils"
|
||||
"github.com/docker/docker/pkg/urlutil"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/parser"
|
||||
|
@ -34,8 +35,9 @@ func Detect(config backend.BuildConfig) (remote builder.Source, dockerfile *pars
|
|||
case remoteURL == ClientSessionRemote:
|
||||
res, err := parser.Parse(config.Source)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, errdefs.InvalidParameter(err)
|
||||
}
|
||||
|
||||
return nil, res, nil
|
||||
case urlutil.IsGitURL(remoteURL):
|
||||
remote, dockerfile, err = newGitRemote(remoteURL, dockerfilePath)
|
||||
|
@ -106,7 +108,7 @@ func newURLRemote(url string, dockerfilePath string, progressReader func(in io.R
|
|||
switch contentType {
|
||||
case mimeTypes.TextPlain:
|
||||
res, err := parser.Parse(progressReader(content))
|
||||
return nil, res, err
|
||||
return nil, res, errdefs.InvalidParameter(err)
|
||||
default:
|
||||
source, err := FromArchive(progressReader(content))
|
||||
if err != nil {
|
||||
|
@ -146,11 +148,17 @@ func readAndParseDockerfile(name string, rc io.Reader) (*parser.Result, error) {
|
|||
br := bufio.NewReader(rc)
|
||||
if _, err := br.Peek(1); err != nil {
|
||||
if err == io.EOF {
|
||||
return nil, errors.Errorf("the Dockerfile (%s) cannot be empty", name)
|
||||
return nil, errdefs.InvalidParameter(errors.Errorf("the Dockerfile (%s) cannot be empty", name))
|
||||
}
|
||||
return nil, errors.Wrap(err, "unexpected error reading Dockerfile")
|
||||
}
|
||||
return parser.Parse(br)
|
||||
|
||||
dockerfile, err := parser.Parse(br)
|
||||
if err != nil {
|
||||
return nil, errdefs.InvalidParameter(errors.Wrapf(err, "failed to parse %s", name))
|
||||
}
|
||||
|
||||
return dockerfile, nil
|
||||
}
|
||||
|
||||
func openAt(remote builder.Source, path string) (driver.File, error) {
|
||||
|
|
|
@ -467,6 +467,61 @@ RUN for g in $(seq 0 8); do dd if=/dev/urandom of=rnd bs=1K count=1 seek=$((1024
|
|||
assert.Check(t, is.Contains(out.String(), "Successfully built"))
|
||||
}
|
||||
|
||||
func TestBuildWithEmptyDockerfile(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
defer setupTest(t)()
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
dockerfile string
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "empty-dockerfile",
|
||||
dockerfile: "",
|
||||
expectedErr: "cannot be empty",
|
||||
},
|
||||
{
|
||||
name: "empty-lines-dockerfile",
|
||||
dockerfile: `
|
||||
|
||||
|
||||
|
||||
`,
|
||||
expectedErr: "file with no instructions",
|
||||
},
|
||||
{
|
||||
name: "comment-only-dockerfile",
|
||||
dockerfile: `# this is a comment`,
|
||||
expectedErr: "file with no instructions",
|
||||
},
|
||||
}
|
||||
|
||||
apiclient := testEnv.APIClient()
|
||||
|
||||
for _, tc := range tests {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
w := tar.NewWriter(buf)
|
||||
writeTarRecord(t, w, "Dockerfile", tc.dockerfile)
|
||||
err := w.Close()
|
||||
assert.NilError(t, err)
|
||||
|
||||
_, err = apiclient.ImageBuild(ctx,
|
||||
buf,
|
||||
types.ImageBuildOptions{
|
||||
Remove: true,
|
||||
ForceRemove: true,
|
||||
})
|
||||
|
||||
assert.Check(t, is.Contains(err.Error(), tc.expectedErr))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func writeTarRecord(t *testing.T, w *tar.Writer, fn, contents string) {
|
||||
err := w.WriteHeader(&tar.Header{
|
||||
Name: fn,
|
||||
|
|
|
@ -26,7 +26,7 @@ github.com/imdario/mergo v0.3.6
|
|||
golang.org/x/sync 1d60e4601c6fd243af51cc01ddf169918a5407ca
|
||||
|
||||
# buildkit
|
||||
github.com/moby/buildkit d9f75920678e35090025bb89344c5370e2efc8e7
|
||||
github.com/moby/buildkit 34ff9c2366a878ada7938d2f9ede71741b0a220c
|
||||
github.com/tonistiigi/fsutil 2862f6bc5ac9b97124e552a5c108230b38a1b0ca
|
||||
github.com/grpc-ecosystem/grpc-opentracing 8e809c8a86450a29b90dcc9efbf062d0fe6d9746
|
||||
github.com/opentracing/opentracing-go 1361b9cd60be79c4c3a7fa9841b3c132e40066a7
|
||||
|
|
56
vendor/github.com/moby/buildkit/README.md
generated
vendored
56
vendor/github.com/moby/buildkit/README.md
generated
vendored
|
@ -31,19 +31,15 @@ Introductory blog post https://blog.mobyproject.org/introducing-buildkit-17e056c
|
|||
|
||||
### Used by
|
||||
|
||||
[Moby & Docker](https://github.com/moby/moby/pull/37151)
|
||||
BuildKit is used by the following projects:
|
||||
|
||||
[img](https://github.com/genuinetools/img)
|
||||
|
||||
[OpenFaaS Cloud](https://github.com/openfaas/openfaas-cloud)
|
||||
|
||||
[container build interface](https://github.com/containerbuilding/cbi)
|
||||
|
||||
[Knative Build Templates](https://github.com/knative/build-templates)
|
||||
|
||||
[boss](https://github.com/crosbymichael/boss)
|
||||
|
||||
[Rio](https://github.com/rancher/rio) (on roadmap)
|
||||
- [Moby & Docker](https://github.com/moby/moby/pull/37151)
|
||||
- [img](https://github.com/genuinetools/img)
|
||||
- [OpenFaaS Cloud](https://github.com/openfaas/openfaas-cloud)
|
||||
- [container build interface](https://github.com/containerbuilding/cbi)
|
||||
- [Knative Build Templates](https://github.com/knative/build-templates)
|
||||
- [boss](https://github.com/crosbymichael/boss)
|
||||
- [Rio](https://github.com/rancher/rio) (on roadmap)
|
||||
|
||||
### Quick start
|
||||
|
||||
|
@ -252,7 +248,7 @@ export JAEGER_TRACE=0.0.0.0:6831
|
|||
|
||||
### Supported runc version
|
||||
|
||||
During development, BuildKit is tested with the version of runc that is being used by the containerd repository. Please refer to [runc.md](https://github.com/containerd/containerd/blob/v1.2.0-rc.1/RUNC.md) for more information.
|
||||
During development, BuildKit is tested with the version of runc that is being used by the containerd repository. Please refer to [runc.md](https://github.com/containerd/containerd/blob/v1.2.1/RUNC.md) for more information.
|
||||
|
||||
### Running BuildKit without root privileges
|
||||
|
||||
|
@ -260,35 +256,5 @@ Please refer to [`docs/rootless.md`](docs/rootless.md).
|
|||
|
||||
### Contributing
|
||||
|
||||
Running tests:
|
||||
|
||||
```bash
|
||||
make test
|
||||
```
|
||||
|
||||
This runs all unit and integration tests in a containerized environment. Locally, every package can be tested separately with standard Go tools, but integration tests are skipped if local user doesn't have enough permissions or worker binaries are not installed.
|
||||
|
||||
```
|
||||
# test a specific package only
|
||||
make test TESTPKGS=./client
|
||||
|
||||
# run a specific test with all worker combinations
|
||||
make test TESTPKGS=./client TESTFLAGS="--run /TestCallDiskUsage -v"
|
||||
|
||||
# run all integration tests with a specific worker
|
||||
# supported workers: oci, oci-rootless, containerd, containerd-1.0
|
||||
make test TESTPKGS=./client TESTFLAGS="--run //worker=containerd -v"
|
||||
```
|
||||
|
||||
Updating vendored dependencies:
|
||||
|
||||
```bash
|
||||
# update vendor.conf
|
||||
make vendor
|
||||
```
|
||||
|
||||
Validating your updates before submission:
|
||||
|
||||
```bash
|
||||
make validate-all
|
||||
```
|
||||
Want to contribute to BuildKit? Awesome! You can find information about
|
||||
contributing to this project in the [CONTRIBUTING.md](/.github/CONTRIBUTING.md)
|
||||
|
|
16
vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_secrets.go
generated
vendored
16
vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_secrets.go
generated
vendored
|
@ -34,5 +34,21 @@ func dispatchSecret(m *instructions.Mount) (llb.RunOption, error) {
|
|||
opts = append(opts, llb.SecretOptional)
|
||||
}
|
||||
|
||||
if m.UID != nil || m.GID != nil || m.Mode != nil {
|
||||
var uid, gid, mode int
|
||||
if m.UID != nil {
|
||||
uid = int(*m.UID)
|
||||
}
|
||||
if m.GID != nil {
|
||||
gid = int(*m.GID)
|
||||
}
|
||||
if m.Mode != nil {
|
||||
mode = int(*m.Mode)
|
||||
} else {
|
||||
mode = 0400
|
||||
}
|
||||
opts = append(opts, llb.SecretFileOpt(uid, gid, mode))
|
||||
}
|
||||
|
||||
return llb.AddSecret(target, opts...), nil
|
||||
}
|
||||
|
|
17
vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_ssh.go
generated
vendored
17
vendor/github.com/moby/buildkit/frontend/dockerfile/dockerfile2llb/convert_ssh.go
generated
vendored
|
@ -15,7 +15,6 @@ func dispatchSSH(m *instructions.Mount) (llb.RunOption, error) {
|
|||
opts := []llb.SSHOption{llb.SSHID(m.CacheID)}
|
||||
|
||||
if m.Target != "" {
|
||||
// TODO(AkihiroSuda): support specifying permission bits
|
||||
opts = append(opts, llb.SSHSocketTarget(m.Target))
|
||||
}
|
||||
|
||||
|
@ -23,5 +22,21 @@ func dispatchSSH(m *instructions.Mount) (llb.RunOption, error) {
|
|||
opts = append(opts, llb.SSHOptional)
|
||||
}
|
||||
|
||||
if m.UID != nil || m.GID != nil || m.Mode != nil {
|
||||
var uid, gid, mode int
|
||||
if m.UID != nil {
|
||||
uid = int(*m.UID)
|
||||
}
|
||||
if m.GID != nil {
|
||||
gid = int(*m.GID)
|
||||
}
|
||||
if m.Mode != nil {
|
||||
mode = int(*m.Mode)
|
||||
} else {
|
||||
mode = 0600
|
||||
}
|
||||
opts = append(opts, llb.SSHSocketOpt(m.Target, uid, gid, mode))
|
||||
}
|
||||
|
||||
return llb.AddSSHSocket(opts...), nil
|
||||
}
|
||||
|
|
35
vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands_runmount.go
generated
vendored
35
vendor/github.com/moby/buildkit/frontend/dockerfile/instructions/commands_runmount.go
generated
vendored
|
@ -108,6 +108,9 @@ type Mount struct {
|
|||
CacheID string
|
||||
CacheSharing string
|
||||
Required bool
|
||||
Mode *uint64
|
||||
UID *uint64
|
||||
GID *uint64
|
||||
}
|
||||
|
||||
func parseMount(value string) (*Mount, error) {
|
||||
|
@ -180,11 +183,43 @@ func parseMount(value string) (*Mount, error) {
|
|||
return nil, errors.Errorf("unsupported sharing value %q", value)
|
||||
}
|
||||
m.CacheSharing = strings.ToLower(value)
|
||||
case "mode":
|
||||
mode, err := strconv.ParseUint(value, 8, 32)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("invalid value %s for mode", value)
|
||||
}
|
||||
m.Mode = &mode
|
||||
case "uid":
|
||||
uid, err := strconv.ParseUint(value, 10, 32)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("invalid value %s for uid", value)
|
||||
}
|
||||
m.UID = &uid
|
||||
case "gid":
|
||||
gid, err := strconv.ParseUint(value, 10, 32)
|
||||
if err != nil {
|
||||
return nil, errors.Errorf("invalid value %s for gid", value)
|
||||
}
|
||||
m.GID = &gid
|
||||
default:
|
||||
return nil, errors.Errorf("unexpected key '%s' in '%s'", key, field)
|
||||
}
|
||||
}
|
||||
|
||||
fileInfoAllowed := m.Type == MountTypeSecret || m.Type == MountTypeSSH
|
||||
|
||||
if m.Mode != nil && !fileInfoAllowed {
|
||||
return nil, errors.Errorf("mode not allowed for %q type mounts")
|
||||
}
|
||||
|
||||
if m.UID != nil && !fileInfoAllowed {
|
||||
return nil, errors.Errorf("uid not allowed for %q type mounts")
|
||||
}
|
||||
|
||||
if m.GID != nil && !fileInfoAllowed {
|
||||
return nil, errors.Errorf("gid not allowed for %q type mounts")
|
||||
}
|
||||
|
||||
if roAuto {
|
||||
if m.Type == MountTypeCache {
|
||||
m.ReadOnly = false
|
||||
|
|
5
vendor/github.com/moby/buildkit/frontend/dockerfile/parser/parser.go
generated
vendored
5
vendor/github.com/moby/buildkit/frontend/dockerfile/parser/parser.go
generated
vendored
|
@ -275,6 +275,11 @@ func Parse(rwc io.Reader) (*Result, error) {
|
|||
if len(warnings) > 0 {
|
||||
warnings = append(warnings, "[WARNING]: Empty continuation lines will become errors in a future release.")
|
||||
}
|
||||
|
||||
if root.StartLine < 0 {
|
||||
return nil, errors.New("file with no instructions.")
|
||||
}
|
||||
|
||||
return &Result{
|
||||
AST: root,
|
||||
Warnings: warnings,
|
||||
|
|
2
vendor/github.com/moby/buildkit/snapshot/snapshotter.go
generated
vendored
2
vendor/github.com/moby/buildkit/snapshot/snapshotter.go
generated
vendored
|
@ -96,7 +96,7 @@ func (cs *containerdSnapshotter) release() error {
|
|||
defer cs.mu.Unlock()
|
||||
var err error
|
||||
for _, f := range cs.releasers {
|
||||
if err1 := f(); err != nil && err == nil {
|
||||
if err1 := f(); err1 != nil && err == nil {
|
||||
err = err1
|
||||
}
|
||||
}
|
||||
|
|
4
vendor/github.com/moby/buildkit/solver/llbsolver/ops/exec.go
generated
vendored
4
vendor/github.com/moby/buildkit/solver/llbsolver/ops/exec.go
generated
vendored
|
@ -331,7 +331,7 @@ func (sm *sshMountInstance) Mount() ([]mount.Mount, error) {
|
|||
ID: sm.sm.mount.SSHOpt.ID,
|
||||
UID: int(sm.sm.mount.SSHOpt.Uid),
|
||||
GID: int(sm.sm.mount.SSHOpt.Gid),
|
||||
Mode: int(sm.sm.mount.SSHOpt.Mode),
|
||||
Mode: int(sm.sm.mount.SSHOpt.Mode & 0777),
|
||||
})
|
||||
if err != nil {
|
||||
cancel()
|
||||
|
@ -447,7 +447,7 @@ func (sm *secretMountInstance) Mount() ([]mount.Mount, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if err := os.Chmod(fp, os.FileMode(sm.sm.mount.SecretOpt.Mode)); err != nil {
|
||||
if err := os.Chmod(fp, os.FileMode(sm.sm.mount.SecretOpt.Mode&0777)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
8
vendor/github.com/moby/buildkit/vendor.conf
generated
vendored
8
vendor/github.com/moby/buildkit/vendor.conf
generated
vendored
|
@ -6,10 +6,10 @@ github.com/davecgh/go-spew v1.1.0
|
|||
github.com/pmezard/go-difflib v1.0.0
|
||||
golang.org/x/sys 1b2967e3c290b7c545b3db0deeda16e9be4f98a2
|
||||
|
||||
github.com/containerd/containerd 1a5f9a3434ac53c0e9d27093ecc588e0c281c333
|
||||
github.com/containerd/containerd 47b328aab79146a9e81e37704db60e7e04a09256
|
||||
github.com/containerd/typeurl a93fcdb778cd272c6e9b3028b2f42d813e785d40
|
||||
golang.org/x/sync 450f422ab23cf9881c94e2db30cac0eb1b7cf80c
|
||||
github.com/sirupsen/logrus v1.0.0
|
||||
github.com/sirupsen/logrus v1.0.3
|
||||
google.golang.org/grpc v1.12.0
|
||||
github.com/opencontainers/go-digest c9281466c8b2f606084ac71339773efd177436e7
|
||||
golang.org/x/net 0ed95abb35c445290478a5348a7b38bb154135fd
|
||||
|
@ -18,7 +18,7 @@ github.com/gogo/googleapis b23578765ee54ff6bceff57f397d833bf4ca6869
|
|||
github.com/golang/protobuf v1.1.0
|
||||
github.com/containerd/continuity bd77b46c8352f74eb12c85bdc01f4b90f69d66b4
|
||||
github.com/opencontainers/image-spec v1.0.1
|
||||
github.com/opencontainers/runc a00bf0190895aa465a5fbed0268888e2c8ddfe85
|
||||
github.com/opencontainers/runc 96ec2177ae841256168fcf76954f7177af9446eb
|
||||
github.com/Microsoft/go-winio v0.4.11
|
||||
github.com/containerd/fifo 3d5202aec260678c48179c56f40e6f38a095738c
|
||||
github.com/opencontainers/runtime-spec eba862dc2470385a233c7507392675cbeadf7353 # v1.0.1-45-geba862d
|
||||
|
@ -30,7 +30,7 @@ github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
|||
github.com/syndtr/gocapability db04d3cc01c8b54962a58ec7e491717d06cfcc16
|
||||
github.com/Microsoft/hcsshim v0.7.9
|
||||
golang.org/x/crypto 0709b304e793a5edb4a2c0145f281ecdc20838a4
|
||||
github.com/containerd/cri 8506fe836677cc3bb23a16b68145128243d843b5 # release/1.2 branch
|
||||
github.com/containerd/cri f913714917d2456d7e65a0be84962b1ce8acb487 # release/1.2 branch
|
||||
|
||||
github.com/urfave/cli 7bc6a0acffa589f415f88aca16cc1de5ffd66f9c
|
||||
github.com/morikuni/aec 39771216ff4c63d11f5e604076f9c45e8be1067b
|
||||
|
|
Loading…
Add table
Reference in a new issue