github.com/ph/moby@v1.13.1/daemon/graphdriver/graphtest/testutil_unix.go (about) 1 // +build linux freebsd 2 3 package graphtest 4 5 import ( 6 "fmt" 7 "io/ioutil" 8 "os" 9 "path" 10 "syscall" 11 "testing" 12 13 "github.com/docker/docker/daemon/graphdriver" 14 ) 15 16 // InitLoopbacks ensures that the loopback devices are properly created within 17 // the system running the device mapper tests. 18 func InitLoopbacks() error { 19 statT, err := getBaseLoopStats() 20 if err != nil { 21 return err 22 } 23 // create at least 8 loopback files, ya, that is a good number 24 for i := 0; i < 8; i++ { 25 loopPath := fmt.Sprintf("/dev/loop%d", i) 26 // only create new loopback files if they don't exist 27 if _, err := os.Stat(loopPath); err != nil { 28 if mkerr := syscall.Mknod(loopPath, 29 uint32(statT.Mode|syscall.S_IFBLK), int((7<<8)|(i&0xff)|((i&0xfff00)<<12))); mkerr != nil { 30 return mkerr 31 } 32 os.Chown(loopPath, int(statT.Uid), int(statT.Gid)) 33 } 34 } 35 return nil 36 } 37 38 // getBaseLoopStats inspects /dev/loop0 to collect uid,gid, and mode for the 39 // loop0 device on the system. If it does not exist we assume 0,0,0660 for the 40 // stat data 41 func getBaseLoopStats() (*syscall.Stat_t, error) { 42 loop0, err := os.Stat("/dev/loop0") 43 if err != nil { 44 if os.IsNotExist(err) { 45 return &syscall.Stat_t{ 46 Uid: 0, 47 Gid: 0, 48 Mode: 0660, 49 }, nil 50 } 51 return nil, err 52 } 53 return loop0.Sys().(*syscall.Stat_t), nil 54 } 55 56 func verifyFile(t testing.TB, path string, mode os.FileMode, uid, gid uint32) { 57 fi, err := os.Stat(path) 58 if err != nil { 59 t.Fatal(err) 60 } 61 62 if fi.Mode()&os.ModeType != mode&os.ModeType { 63 t.Fatalf("Expected %s type 0x%x, got 0x%x", path, mode&os.ModeType, fi.Mode()&os.ModeType) 64 } 65 66 if fi.Mode()&os.ModePerm != mode&os.ModePerm { 67 t.Fatalf("Expected %s mode %o, got %o", path, mode&os.ModePerm, fi.Mode()&os.ModePerm) 68 } 69 70 if fi.Mode()&os.ModeSticky != mode&os.ModeSticky { 71 t.Fatalf("Expected %s sticky 0x%x, got 0x%x", path, mode&os.ModeSticky, fi.Mode()&os.ModeSticky) 72 } 73 74 if fi.Mode()&os.ModeSetuid != mode&os.ModeSetuid { 75 t.Fatalf("Expected %s setuid 0x%x, got 0x%x", path, mode&os.ModeSetuid, fi.Mode()&os.ModeSetuid) 76 } 77 78 if fi.Mode()&os.ModeSetgid != mode&os.ModeSetgid { 79 t.Fatalf("Expected %s setgid 0x%x, got 0x%x", path, mode&os.ModeSetgid, fi.Mode()&os.ModeSetgid) 80 } 81 82 if stat, ok := fi.Sys().(*syscall.Stat_t); ok { 83 if stat.Uid != uid { 84 t.Fatalf("%s no owned by uid %d", path, uid) 85 } 86 if stat.Gid != gid { 87 t.Fatalf("%s not owned by gid %d", path, gid) 88 } 89 } 90 } 91 92 func createBase(t testing.TB, driver graphdriver.Driver, name string) { 93 // We need to be able to set any perms 94 oldmask := syscall.Umask(0) 95 defer syscall.Umask(oldmask) 96 97 if err := driver.CreateReadWrite(name, "", nil); err != nil { 98 t.Fatal(err) 99 } 100 101 dir, err := driver.Get(name, "") 102 if err != nil { 103 t.Fatal(err) 104 } 105 defer driver.Put(name) 106 107 subdir := path.Join(dir, "a subdir") 108 if err := os.Mkdir(subdir, 0705|os.ModeSticky); err != nil { 109 t.Fatal(err) 110 } 111 if err := os.Chown(subdir, 1, 2); err != nil { 112 t.Fatal(err) 113 } 114 115 file := path.Join(dir, "a file") 116 if err := ioutil.WriteFile(file, []byte("Some data"), 0222|os.ModeSetuid); err != nil { 117 t.Fatal(err) 118 } 119 } 120 121 func verifyBase(t testing.TB, driver graphdriver.Driver, name string) { 122 dir, err := driver.Get(name, "") 123 if err != nil { 124 t.Fatal(err) 125 } 126 defer driver.Put(name) 127 128 subdir := path.Join(dir, "a subdir") 129 verifyFile(t, subdir, 0705|os.ModeDir|os.ModeSticky, 1, 2) 130 131 file := path.Join(dir, "a file") 132 verifyFile(t, file, 0222|os.ModeSetuid, 0, 0) 133 134 fis, err := readDir(dir) 135 if err != nil { 136 t.Fatal(err) 137 } 138 139 if len(fis) != 2 { 140 t.Fatal("Unexpected files in base image") 141 } 142 143 }