Browse code

Make utils_daemon and volumes cross-platform compileable.

Signed-off-by: Rik Nijessen <riknijessen@gmail.com>

Rik Nijessen authored on 2015/03/12 00:42:49
Showing 10 changed files
... ...
@@ -8,12 +8,12 @@ import (
8 8
 	"path/filepath"
9 9
 	"sort"
10 10
 	"strings"
11
-	"syscall"
12 11
 
13 12
 	log "github.com/Sirupsen/logrus"
14 13
 	"github.com/docker/docker/daemon/execdriver"
15 14
 	"github.com/docker/docker/pkg/chrootarchive"
16 15
 	"github.com/docker/docker/pkg/symlink"
16
+	"github.com/docker/docker/pkg/system"
17 17
 	"github.com/docker/docker/volumes"
18 18
 )
19 19
 
... ...
@@ -385,15 +385,14 @@ func copyExistingContents(source, destination string) error {
385 385
 // copyOwnership copies the permissions and uid:gid of the source file
386 386
 // into the destination file
387 387
 func copyOwnership(source, destination string) error {
388
-	var stat syscall.Stat_t
389
-
390
-	if err := syscall.Stat(source, &stat); err != nil {
388
+	stat, err := system.Stat(source)
389
+	if err != nil {
391 390
 		return err
392 391
 	}
393 392
 
394
-	if err := os.Chown(destination, int(stat.Uid), int(stat.Gid)); err != nil {
393
+	if err := os.Chown(destination, int(stat.Uid()), int(stat.Gid())); err != nil {
395 394
 		return err
396 395
 	}
397 396
 
398
-	return os.Chmod(destination, os.FileMode(stat.Mode))
397
+	return os.Chmod(destination, os.FileMode(stat.Mode()))
399 398
 }
... ...
@@ -143,7 +143,7 @@ func Changes(layers []string, rw string) ([]Change, error) {
143 143
 type FileInfo struct {
144 144
 	parent     *FileInfo
145 145
 	name       string
146
-	stat       *system.Stat
146
+	stat       *system.Stat_t
147 147
 	children   map[string]*FileInfo
148 148
 	capability []byte
149 149
 	added      bool
... ...
@@ -6,7 +6,7 @@ import (
6 6
 	"syscall"
7 7
 )
8 8
 
9
-func Lstat(path string) (*Stat, error) {
9
+func Lstat(path string) (*Stat_t, error) {
10 10
 	s := &syscall.Stat_t{}
11 11
 	err := syscall.Lstat(path, s)
12 12
 	if err != nil {
... ...
@@ -2,7 +2,7 @@
2 2
 
3 3
 package system
4 4
 
5
-func Lstat(path string) (*Stat, error) {
5
+func Lstat(path string) (*Stat_t, error) {
6 6
 	// should not be called on cli code path
7 7
 	return nil, ErrNotSupportedPlatform
8 8
 }
... ...
@@ -4,7 +4,7 @@ import (
4 4
 	"syscall"
5 5
 )
6 6
 
7
-type Stat struct {
7
+type Stat_t struct {
8 8
 	mode uint32
9 9
 	uid  uint32
10 10
 	gid  uint32
... ...
@@ -13,30 +13,30 @@ type Stat struct {
13 13
 	mtim syscall.Timespec
14 14
 }
15 15
 
16
-func (s Stat) Mode() uint32 {
16
+func (s Stat_t) Mode() uint32 {
17 17
 	return s.mode
18 18
 }
19 19
 
20
-func (s Stat) Uid() uint32 {
20
+func (s Stat_t) Uid() uint32 {
21 21
 	return s.uid
22 22
 }
23 23
 
24
-func (s Stat) Gid() uint32 {
24
+func (s Stat_t) Gid() uint32 {
25 25
 	return s.gid
26 26
 }
27 27
 
28
-func (s Stat) Rdev() uint64 {
28
+func (s Stat_t) Rdev() uint64 {
29 29
 	return s.rdev
30 30
 }
31 31
 
32
-func (s Stat) Size() int64 {
32
+func (s Stat_t) Size() int64 {
33 33
 	return s.size
34 34
 }
35 35
 
36
-func (s Stat) Mtim() syscall.Timespec {
36
+func (s Stat_t) Mtim() syscall.Timespec {
37 37
 	return s.mtim
38 38
 }
39 39
 
40
-func (s Stat) GetLastModification() syscall.Timespec {
40
+func (s Stat_t) GetLastModification() syscall.Timespec {
41 41
 	return s.Mtim()
42 42
 }
... ...
@@ -4,11 +4,20 @@ import (
4 4
 	"syscall"
5 5
 )
6 6
 
7
-func fromStatT(s *syscall.Stat_t) (*Stat, error) {
8
-	return &Stat{size: s.Size,
7
+func fromStatT(s *syscall.Stat_t) (*Stat_t, error) {
8
+	return &Stat_t{size: s.Size,
9 9
 		mode: s.Mode,
10 10
 		uid:  s.Uid,
11 11
 		gid:  s.Gid,
12 12
 		rdev: s.Rdev,
13 13
 		mtim: s.Mtim}, nil
14 14
 }
15
+
16
+func Stat(path string) (*Stat_t, error) {
17
+	s := &syscall.Stat_t{}
18
+	err := syscall.Stat(path, s)
19
+	if err != nil {
20
+		return nil, err
21
+	}
22
+	return fromStatT(s)
23
+}
... ...
@@ -6,8 +6,8 @@ import (
6 6
 	"syscall"
7 7
 )
8 8
 
9
-func fromStatT(s *syscall.Stat_t) (*Stat, error) {
10
-	return &Stat{size: s.Size,
9
+func fromStatT(s *syscall.Stat_t) (*Stat_t, error) {
10
+	return &Stat_t{size: s.Size,
11 11
 		mode: uint32(s.Mode),
12 12
 		uid:  s.Uid,
13 13
 		gid:  s.Gid,
... ...
@@ -7,6 +7,11 @@ import (
7 7
 	"syscall"
8 8
 )
9 9
 
10
-func fromStatT(s *syscall.Win32FileAttributeData) (*Stat, error) {
10
+func fromStatT(s *syscall.Win32FileAttributeData) (*Stat_t, error) {
11 11
 	return nil, errors.New("fromStatT should not be called on windows path")
12 12
 }
13
+
14
+func Stat(path string) (*Stat_t, error) {
15
+	// should not be called on cli code path
16
+	return nil, ErrNotSupportedPlatform
17
+}
... ...
@@ -3,14 +3,14 @@
3 3
 package utils
4 4
 
5 5
 import (
6
+	"github.com/docker/docker/pkg/system"
6 7
 	"os"
7
-	"syscall"
8 8
 )
9 9
 
10 10
 // IsFileOwner checks whether the current user is the owner of the given file.
11 11
 func IsFileOwner(f string) bool {
12
-	if fileInfo, err := os.Stat(f); err == nil && fileInfo != nil {
13
-		if stat, ok := fileInfo.Sys().(*syscall.Stat_t); ok && int(stat.Uid) == os.Getuid() {
12
+	if fileInfo, err := system.Stat(f); err == nil && fileInfo != nil {
13
+		if int(fileInfo.Uid()) == os.Getuid() {
14 14
 			return true
15 15
 		}
16 16
 	}
17 17
new file mode 100644
... ...
@@ -0,0 +1,26 @@
0
+package utils
1
+
2
+import (
3
+	"os"
4
+	"path"
5
+	"testing"
6
+)
7
+
8
+func TestIsFileOwner(t *testing.T) {
9
+	var err error
10
+	var file *os.File
11
+
12
+	if file, err = os.Create(path.Join(os.TempDir(), "testIsFileOwner")); err != nil {
13
+		t.Fatalf("failed to create file: %s", err)
14
+	}
15
+	file.Close()
16
+
17
+	if ok := IsFileOwner(path.Join(os.TempDir(), "testIsFileOwner")); !ok {
18
+		t.Fatalf("User should be owner of file")
19
+	}
20
+
21
+	if err = os.Remove(path.Join(os.TempDir(), "testIsFileOwner")); err != nil {
22
+		t.Fatalf("failed to remove file: %s", err)
23
+	}
24
+
25
+}