Signed-off-by: Rik Nijessen <riknijessen@gmail.com>
| ... | ... |
@@ -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 |
} |
| ... | ... |
@@ -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 |
+} |
| ... | ... |
@@ -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 |
+} |