mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
idtools.MkdirAs*: error out if dir exists as file
Standard golang's `os.MkdirAll()` function returns "not a directory" error in case a directory to be created already exists but is not a directory (e.g. a file). Our own `idtools.MkdirAs*()` functions do not replicate the behavior. This is a bug since all `Mkdir()`-like functions are expected to ensure the required directory exists and is indeed a directory, and return an error otherwise. As the code is using our in-house `system.Stat()` call returning a type which is incompatible with that of golang's `os.Stat()`, I had to amend the `system` package with `IsDir()`. A test case is also provided. Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
parent
c672fbd69c
commit
2aa13f86f0
3 changed files with 23 additions and 0 deletions
|
@ -10,6 +10,7 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"github.com/docker/docker/pkg/system"
|
||||
"github.com/opencontainers/runc/libcontainer/user"
|
||||
|
@ -29,6 +30,9 @@ func mkdirAs(path string, mode os.FileMode, ownerUID, ownerGID int, mkAll, chown
|
|||
|
||||
stat, err := system.Stat(path)
|
||||
if err == nil {
|
||||
if !stat.IsDir() {
|
||||
return &os.PathError{"mkdir", path, syscall.ENOTDIR}
|
||||
}
|
||||
if !chownExisting {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -378,6 +378,20 @@ func TestLookupUserAndGroupThatDoesNotExist(t *testing.T) {
|
|||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
// TestMkdirIsNotDir checks that mkdirAs() function (used by MkdirAll...)
|
||||
// returns a correct error in case a directory which it is about to create
|
||||
// already exists but is a file (rather than a directory).
|
||||
func TestMkdirIsNotDir(t *testing.T) {
|
||||
file, err := ioutil.TempFile("", t.Name())
|
||||
if err != nil {
|
||||
t.Fatalf("Couldn't create temp dir: %v", err)
|
||||
}
|
||||
defer os.Remove(file.Name())
|
||||
|
||||
err = mkdirAs(file.Name(), 0755, 0, 0, false, false)
|
||||
assert.EqualError(t, err, "mkdir "+file.Name()+": not a directory")
|
||||
}
|
||||
|
||||
func RequiresRoot(t *testing.T) {
|
||||
skip.IfCondition(t, os.Getuid() != 0, "skipping test that requires root")
|
||||
}
|
||||
|
|
|
@ -47,6 +47,11 @@ func (s StatT) Mtim() syscall.Timespec {
|
|||
return s.mtim
|
||||
}
|
||||
|
||||
// IsDir reports whether s describes a directory.
|
||||
func (s StatT) IsDir() bool {
|
||||
return s.mode&syscall.S_IFDIR != 0
|
||||
}
|
||||
|
||||
// Stat takes a path to a file and returns
|
||||
// a system.StatT type pertaining to that file.
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue