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