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