diff --git a/api/client/build.go b/api/client/build.go index e6a4749d39..f7f9c5b1fc 100644 --- a/api/client/build.go +++ b/api/client/build.go @@ -17,6 +17,7 @@ import ( "golang.org/x/net/context" "github.com/docker/docker/api" + "github.com/docker/docker/builder" "github.com/docker/docker/builder/dockerignore" Cli "github.com/docker/docker/cli" "github.com/docker/docker/opts" @@ -143,7 +144,7 @@ func (cli *DockerCli) CmdBuild(args ...string) error { } } - if err := validateContextDirectory(contextDir, excludes); err != nil { + if err := builder.ValidateContextDirectory(contextDir, excludes); err != nil { return fmt.Errorf("Error checking context: '%s'.", err) } @@ -281,54 +282,6 @@ func (cli *DockerCli) CmdBuild(args ...string) error { return nil } -// validateContextDirectory checks if all the contents of the directory -// can be read and returns an error if some files can't be read -// symlinks which point to non-existing files don't trigger an error -func validateContextDirectory(srcPath string, excludes []string) error { - contextRoot, err := getContextRoot(srcPath) - if err != nil { - return err - } - return filepath.Walk(contextRoot, func(filePath string, f os.FileInfo, err error) error { - // skip this directory/file if it's not in the path, it won't get added to the context - if relFilePath, err := filepath.Rel(contextRoot, filePath); err != nil { - return err - } else if skip, err := fileutils.Matches(relFilePath, excludes); err != nil { - return err - } else if skip { - if f.IsDir() { - return filepath.SkipDir - } - return nil - } - - if err != nil { - if os.IsPermission(err) { - return fmt.Errorf("can't stat '%s'", filePath) - } - if os.IsNotExist(err) { - return nil - } - return err - } - - // skip checking if symlinks point to non-existing files, such symlinks can be useful - // also skip named pipes, because they hanging on open - if f.Mode()&(os.ModeSymlink|os.ModeNamedPipe) != 0 { - return nil - } - - if !f.IsDir() { - currentFile, err := os.Open(filePath) - if err != nil && os.IsPermission(err) { - return fmt.Errorf("no permission to read from '%s'", filePath) - } - currentFile.Close() - } - return nil - }) -} - // validateTag checks if the given image name can be resolved. func validateTag(rawRepo string) (string, error) { _, err := reference.ParseNamed(rawRepo) diff --git a/builder/context.go b/builder/context.go new file mode 100644 index 0000000000..61ee97a8ad --- /dev/null +++ b/builder/context.go @@ -0,0 +1,57 @@ +package builder + +import ( + "fmt" + "os" + "path/filepath" + + "github.com/docker/docker/pkg/fileutils" +) + +// ValidateContextDirectory checks if all the contents of the directory +// can be read and returns an error if some files can't be read +// symlinks which point to non-existing files don't trigger an error +func ValidateContextDirectory(srcPath string, excludes []string) error { + contextRoot, err := getContextRoot(srcPath) + if err != nil { + return err + } + return filepath.Walk(contextRoot, func(filePath string, f os.FileInfo, err error) error { + // skip this directory/file if it's not in the path, it won't get added to the context + if relFilePath, err := filepath.Rel(contextRoot, filePath); err != nil { + return err + } else if skip, err := fileutils.Matches(relFilePath, excludes); err != nil { + return err + } else if skip { + if f.IsDir() { + return filepath.SkipDir + } + return nil + } + + if err != nil { + if os.IsPermission(err) { + return fmt.Errorf("can't stat '%s'", filePath) + } + if os.IsNotExist(err) { + return nil + } + return err + } + + // skip checking if symlinks point to non-existing files, such symlinks can be useful + // also skip named pipes, because they hanging on open + if f.Mode()&(os.ModeSymlink|os.ModeNamedPipe) != 0 { + return nil + } + + if !f.IsDir() { + currentFile, err := os.Open(filePath) + if err != nil && os.IsPermission(err) { + return fmt.Errorf("no permission to read from '%s'", filePath) + } + currentFile.Close() + } + return nil + }) +} diff --git a/api/client/utils_unix.go b/builder/context_unix.go similarity index 90% rename from api/client/utils_unix.go rename to builder/context_unix.go index ff10ddde9e..d1f72e0573 100644 --- a/api/client/utils_unix.go +++ b/builder/context_unix.go @@ -1,6 +1,6 @@ // +build !windows -package client +package builder import ( "path/filepath" diff --git a/api/client/utils_windows.go b/builder/context_windows.go similarity index 94% rename from api/client/utils_windows.go rename to builder/context_windows.go index 09c33dadd8..b8ba2ba231 100644 --- a/api/client/utils_windows.go +++ b/builder/context_windows.go @@ -1,6 +1,6 @@ // +build windows -package client +package builder import ( "path/filepath"