github.com/zhouyu0/docker-note@v0.0.0-20190722021225-b8d3825084db/pkg/archive/archive_linux_test.go (about) 1 package archive // import "github.com/docker/docker/pkg/archive" 2 3 import ( 4 "io/ioutil" 5 "os" 6 "path/filepath" 7 "syscall" 8 "testing" 9 10 "github.com/docker/docker/pkg/system" 11 "golang.org/x/sys/unix" 12 "gotest.tools/assert" 13 "gotest.tools/skip" 14 ) 15 16 // setupOverlayTestDir creates files in a directory with overlay whiteouts 17 // Tree layout 18 // . 19 // ├── d1 # opaque, 0700 20 // │ └── f1 # empty file, 0600 21 // ├── d2 # opaque, 0750 22 // │ └── f1 # empty file, 0660 23 // └── d3 # 0700 24 // └── f1 # whiteout, 0644 25 func setupOverlayTestDir(t *testing.T, src string) { 26 skip.If(t, os.Getuid() != 0, "skipping test that requires root") 27 // Create opaque directory containing single file and permission 0700 28 err := os.Mkdir(filepath.Join(src, "d1"), 0700) 29 assert.NilError(t, err) 30 31 err = system.Lsetxattr(filepath.Join(src, "d1"), "trusted.overlay.opaque", []byte("y"), 0) 32 assert.NilError(t, err) 33 34 err = ioutil.WriteFile(filepath.Join(src, "d1", "f1"), []byte{}, 0600) 35 assert.NilError(t, err) 36 37 // Create another opaque directory containing single file but with permission 0750 38 err = os.Mkdir(filepath.Join(src, "d2"), 0750) 39 assert.NilError(t, err) 40 41 err = system.Lsetxattr(filepath.Join(src, "d2"), "trusted.overlay.opaque", []byte("y"), 0) 42 assert.NilError(t, err) 43 44 err = ioutil.WriteFile(filepath.Join(src, "d2", "f1"), []byte{}, 0660) 45 assert.NilError(t, err) 46 47 // Create regular directory with deleted file 48 err = os.Mkdir(filepath.Join(src, "d3"), 0700) 49 assert.NilError(t, err) 50 51 err = system.Mknod(filepath.Join(src, "d3", "f1"), unix.S_IFCHR, 0) 52 assert.NilError(t, err) 53 } 54 55 func checkOpaqueness(t *testing.T, path string, opaque string) { 56 xattrOpaque, err := system.Lgetxattr(path, "trusted.overlay.opaque") 57 assert.NilError(t, err) 58 59 if string(xattrOpaque) != opaque { 60 t.Fatalf("Unexpected opaque value: %q, expected %q", string(xattrOpaque), opaque) 61 } 62 63 } 64 65 func checkOverlayWhiteout(t *testing.T, path string) { 66 stat, err := os.Stat(path) 67 assert.NilError(t, err) 68 69 statT, ok := stat.Sys().(*syscall.Stat_t) 70 if !ok { 71 t.Fatalf("Unexpected type: %t, expected *syscall.Stat_t", stat.Sys()) 72 } 73 if statT.Rdev != 0 { 74 t.Fatalf("Non-zero device number for whiteout") 75 } 76 } 77 78 func checkFileMode(t *testing.T, path string, perm os.FileMode) { 79 stat, err := os.Stat(path) 80 assert.NilError(t, err) 81 82 if stat.Mode() != perm { 83 t.Fatalf("Unexpected file mode for %s: %o, expected %o", path, stat.Mode(), perm) 84 } 85 } 86 87 func TestOverlayTarUntar(t *testing.T) { 88 oldmask, err := system.Umask(0) 89 assert.NilError(t, err) 90 defer system.Umask(oldmask) 91 92 src, err := ioutil.TempDir("", "docker-test-overlay-tar-src") 93 assert.NilError(t, err) 94 defer os.RemoveAll(src) 95 96 setupOverlayTestDir(t, src) 97 98 dst, err := ioutil.TempDir("", "docker-test-overlay-tar-dst") 99 assert.NilError(t, err) 100 defer os.RemoveAll(dst) 101 102 options := &TarOptions{ 103 Compression: Uncompressed, 104 WhiteoutFormat: OverlayWhiteoutFormat, 105 } 106 archive, err := TarWithOptions(src, options) 107 assert.NilError(t, err) 108 defer archive.Close() 109 110 err = Untar(archive, dst, options) 111 assert.NilError(t, err) 112 113 checkFileMode(t, filepath.Join(dst, "d1"), 0700|os.ModeDir) 114 checkFileMode(t, filepath.Join(dst, "d2"), 0750|os.ModeDir) 115 checkFileMode(t, filepath.Join(dst, "d3"), 0700|os.ModeDir) 116 checkFileMode(t, filepath.Join(dst, "d1", "f1"), 0600) 117 checkFileMode(t, filepath.Join(dst, "d2", "f1"), 0660) 118 checkFileMode(t, filepath.Join(dst, "d3", "f1"), os.ModeCharDevice|os.ModeDevice) 119 120 checkOpaqueness(t, filepath.Join(dst, "d1"), "y") 121 checkOpaqueness(t, filepath.Join(dst, "d2"), "y") 122 checkOpaqueness(t, filepath.Join(dst, "d3"), "") 123 checkOverlayWhiteout(t, filepath.Join(dst, "d3", "f1")) 124 } 125 126 func TestOverlayTarAUFSUntar(t *testing.T) { 127 oldmask, err := system.Umask(0) 128 assert.NilError(t, err) 129 defer system.Umask(oldmask) 130 131 src, err := ioutil.TempDir("", "docker-test-overlay-tar-src") 132 assert.NilError(t, err) 133 defer os.RemoveAll(src) 134 135 setupOverlayTestDir(t, src) 136 137 dst, err := ioutil.TempDir("", "docker-test-overlay-tar-dst") 138 assert.NilError(t, err) 139 defer os.RemoveAll(dst) 140 141 archive, err := TarWithOptions(src, &TarOptions{ 142 Compression: Uncompressed, 143 WhiteoutFormat: OverlayWhiteoutFormat, 144 }) 145 assert.NilError(t, err) 146 defer archive.Close() 147 148 err = Untar(archive, dst, &TarOptions{ 149 Compression: Uncompressed, 150 WhiteoutFormat: AUFSWhiteoutFormat, 151 }) 152 assert.NilError(t, err) 153 154 checkFileMode(t, filepath.Join(dst, "d1"), 0700|os.ModeDir) 155 checkFileMode(t, filepath.Join(dst, "d1", WhiteoutOpaqueDir), 0700) 156 checkFileMode(t, filepath.Join(dst, "d2"), 0750|os.ModeDir) 157 checkFileMode(t, filepath.Join(dst, "d2", WhiteoutOpaqueDir), 0750) 158 checkFileMode(t, filepath.Join(dst, "d3"), 0700|os.ModeDir) 159 checkFileMode(t, filepath.Join(dst, "d1", "f1"), 0600) 160 checkFileMode(t, filepath.Join(dst, "d2", "f1"), 0660) 161 checkFileMode(t, filepath.Join(dst, "d3", WhiteoutPrefix+"f1"), 0600) 162 }