diff --git a/daemon/volumes.go b/daemon/volumes.go index a15e3084b2..ac01c6a982 100644 --- a/daemon/volumes.go +++ b/daemon/volumes.go @@ -10,7 +10,7 @@ import ( "github.com/dotcloud/docker/archive" "github.com/dotcloud/docker/daemon/execdriver" - "github.com/dotcloud/docker/utils" + "github.com/dotcloud/docker/pkg/symlink" ) type BindMap struct { @@ -213,7 +213,7 @@ func createVolumes(container *Container) error { } // Create the mountpoint - rootVolPath, err := utils.FollowSymlinkInScope(filepath.Join(container.basefs, volPath), container.basefs) + rootVolPath, err := symlink.FollowSymlinkInScope(filepath.Join(container.basefs, volPath), container.basefs) if err != nil { return err } diff --git a/pkg/libcontainer/mount/init.go b/pkg/libcontainer/mount/init.go index 12f833a966..e5f2b43cab 100644 --- a/pkg/libcontainer/mount/init.go +++ b/pkg/libcontainer/mount/init.go @@ -11,6 +11,7 @@ import ( "github.com/dotcloud/docker/pkg/label" "github.com/dotcloud/docker/pkg/libcontainer" "github.com/dotcloud/docker/pkg/libcontainer/mount/nodes" + "github.com/dotcloud/docker/pkg/symlink" "github.com/dotcloud/docker/pkg/system" ) @@ -127,6 +128,12 @@ func setupBindmounts(rootfs string, bindMounts libcontainer.Mounts) error { if err != nil { return err } + + dest, err = symlink.FollowSymlinkInScope(dest, rootfs) + if err != nil { + return err + } + if err := createIfNotExists(dest, stat.IsDir()); err != nil { return fmt.Errorf("Creating new bind-mount target, %s", err) } diff --git a/pkg/symlink/MAINTAINERS b/pkg/symlink/MAINTAINERS new file mode 100644 index 0000000000..68a97d2fc2 --- /dev/null +++ b/pkg/symlink/MAINTAINERS @@ -0,0 +1,2 @@ +Michael Crosby (@crosbymichael) +Victor Vieux (@vieux) diff --git a/utils/fs.go b/pkg/symlink/fs.go similarity index 64% rename from utils/fs.go rename to pkg/symlink/fs.go index e07ced75d7..e91d33db4b 100644 --- a/utils/fs.go +++ b/pkg/symlink/fs.go @@ -1,43 +1,12 @@ -package utils +package symlink import ( "fmt" "os" "path/filepath" "strings" - "syscall" ) -// TreeSize walks a directory tree and returns its total size in bytes. -func TreeSize(dir string) (size int64, err error) { - data := make(map[uint64]struct{}) - err = filepath.Walk(dir, func(d string, fileInfo os.FileInfo, e error) error { - // Ignore directory sizes - if fileInfo == nil { - return nil - } - - s := fileInfo.Size() - if fileInfo.IsDir() || s == 0 { - return nil - } - - // Check inode to handle hard links correctly - inode := fileInfo.Sys().(*syscall.Stat_t).Ino - // inode is not a uint64 on all platforms. Cast it to avoid issues. - if _, exists := data[uint64(inode)]; exists { - return nil - } - // inode is not a uint64 on all platforms. Cast it to avoid issues. - data[uint64(inode)] = struct{}{} - - size += s - - return nil - }) - return -} - // FollowSymlink will follow an existing link and scope it to the root // path provided. func FollowSymlinkInScope(link, root string) (string, error) { diff --git a/utils/fs_test.go b/pkg/symlink/fs_test.go similarity index 99% rename from utils/fs_test.go rename to pkg/symlink/fs_test.go index 9affc00e91..1f12aa3a60 100644 --- a/utils/fs_test.go +++ b/pkg/symlink/fs_test.go @@ -1,4 +1,4 @@ -package utils +package symlink import ( "io/ioutil" diff --git a/utils/testdata/fs/a/d b/pkg/symlink/testdata/fs/a/d similarity index 100% rename from utils/testdata/fs/a/d rename to pkg/symlink/testdata/fs/a/d diff --git a/utils/testdata/fs/a/e b/pkg/symlink/testdata/fs/a/e similarity index 100% rename from utils/testdata/fs/a/e rename to pkg/symlink/testdata/fs/a/e diff --git a/utils/testdata/fs/a/f b/pkg/symlink/testdata/fs/a/f similarity index 100% rename from utils/testdata/fs/a/f rename to pkg/symlink/testdata/fs/a/f diff --git a/utils/testdata/fs/b/h b/pkg/symlink/testdata/fs/b/h similarity index 100% rename from utils/testdata/fs/b/h rename to pkg/symlink/testdata/fs/b/h diff --git a/utils/testdata/fs/g b/pkg/symlink/testdata/fs/g similarity index 100% rename from utils/testdata/fs/g rename to pkg/symlink/testdata/fs/g diff --git a/server/buildfile.go b/server/buildfile.go index eeafbb5b4c..faaac0d3d4 100644 --- a/server/buildfile.go +++ b/server/buildfile.go @@ -20,6 +20,7 @@ import ( "github.com/dotcloud/docker/archive" "github.com/dotcloud/docker/daemon" "github.com/dotcloud/docker/nat" + "github.com/dotcloud/docker/pkg/symlink" "github.com/dotcloud/docker/registry" "github.com/dotcloud/docker/runconfig" "github.com/dotcloud/docker/utils" @@ -404,7 +405,7 @@ func (b *buildFile) addContext(container *daemon.Container, orig, dest string, r ) if destPath != container.RootfsPath() { - destPath, err = utils.FollowSymlinkInScope(destPath, container.RootfsPath()) + destPath, err = symlink.FollowSymlinkInScope(destPath, container.RootfsPath()) if err != nil { return err } diff --git a/utils/utils.go b/utils/utils.go index 4ef44b5617..7ffcc06b93 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -21,6 +21,7 @@ import ( "strconv" "strings" "sync" + "syscall" "time" "github.com/dotcloud/docker/dockerversion" @@ -1091,3 +1092,33 @@ func ParseKeyValueOpt(opt string) (string, string, error) { } return strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1]), nil } + +// TreeSize walks a directory tree and returns its total size in bytes. +func TreeSize(dir string) (size int64, err error) { + data := make(map[uint64]struct{}) + err = filepath.Walk(dir, func(d string, fileInfo os.FileInfo, e error) error { + // Ignore directory sizes + if fileInfo == nil { + return nil + } + + s := fileInfo.Size() + if fileInfo.IsDir() || s == 0 { + return nil + } + + // Check inode to handle hard links correctly + inode := fileInfo.Sys().(*syscall.Stat_t).Ino + // inode is not a uint64 on all platforms. Cast it to avoid issues. + if _, exists := data[uint64(inode)]; exists { + return nil + } + // inode is not a uint64 on all platforms. Cast it to avoid issues. + data[uint64(inode)] = struct{}{} + + size += s + + return nil + }) + return +}