Skip to content

Commit

Permalink
Error when mount specs have paths that are a descendent of the root path
Browse files Browse the repository at this point in the history
to extract

This is a case that doesn't really make sense is is almost certainly
user error, so make a friendly message for it.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>
  • Loading branch information
cpuguy83 committed Jun 26, 2024
1 parent ec626f5 commit a4d7f29
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 0 deletions.
3 changes: 3 additions & 0 deletions load.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ func (s *Source) validate(failContext ...string) (retErr error) {

if s.DockerImage.Cmd != nil {
for _, mnt := range s.DockerImage.Cmd.Mounts {
if mnt.Dest == s.Path {
return errors.Wrap(errInvalidMountConfig, "")
}
if err := mnt.Spec.validate("docker image source with ref", "'"+s.DockerImage.Ref+"'"); err != nil {
retErr = goerrors.Join(retErr, err)
}
Expand Down
11 changes: 11 additions & 0 deletions source.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"bytes"
"fmt"
"io"
"path/filepath"

"github.com/moby/buildkit/client/llb"
"github.com/moby/buildkit/identity"
Expand Down Expand Up @@ -193,6 +194,8 @@ func (s *Source) AsMount(name string, sOpt SourceOpts, opts ...llb.ConstraintsOp
return s.asState(name, true, sOpt, opts...)
}

var errInvalidMountConfig = errors.New("invalid mount config")

// must not be called with a nil cmd pointer
// subPath must be a valid non-empty path
func generateSourceFromImage(st llb.State, cmd *Command, sOpts SourceOpts, subPath string, opts ...llb.ConstraintsOpt) (llb.State, error) {
Expand All @@ -217,6 +220,14 @@ func generateSourceFromImage(st llb.State, cmd *Command, sOpts SourceOpts, subPa
baseRunOpts := []llb.RunOption{CacheDirsToRunOpt(cmd.CacheDirs, "", "")}

for _, src := range cmd.Mounts {
if src.Dest == "/" {
return llb.Scratch(), errors.Wrap(errInvalidMountConfig, "mount destination must not be \"/\"")
}
if subPath != "/" && filepath.HasPrefix(src.Dest, subPath) {
// We cannot support this as the base mount for subPath will shadow the mount being done here.
return llb.Scratch(), errors.Wrapf(errInvalidMountConfig, "mount destination (%s) must not be a descendent of the target source path (%s)", src.Dest, subPath)
}

srcSt, err := src.Spec.AsMount(src.Dest, sOpts, opts...)
if err != nil {
return llb.Scratch(), err
Expand Down
26 changes: 26 additions & 0 deletions source_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/moby/buildkit/solver/pb"
"github.com/opencontainers/go-digest"
v1 "github.com/opencontainers/image-spec/specs-go/v1"
"gotest.tools/v3/assert"
)

func TestSourceGitSSH(t *testing.T) {
Expand Down Expand Up @@ -322,6 +323,31 @@ func TestSourceDockerImage(t *testing.T) {
checkCmd(t, ops[1:], &src, [][]expectMount{{rootMount}, {rootMount}})
})

t.Run("mount beneath subpath", func(t *testing.T) {
src := src
src.Path = "subpath"

img := *src.DockerImage
cmd := *img.Cmd

img.Cmd = &cmd
src.DockerImage = &img

img.Cmd.Mounts = []SourceMount{
{
Dest: src.Path,
Spec: Source{
Inline: &SourceInline{
Dir: &SourceInlineDir{},
},
},
},
}

_, err := src.AsState("test", SourceOpts{})
assert.ErrorIs(t, err, errInvalidMountConfig)
})

t.Run("subpath with include-exclude", func(t *testing.T) {
src := src
src.Path = "subdir"
Expand Down

0 comments on commit a4d7f29

Please sign in to comment.