github.com/olljanat/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  }