github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/pkg/archive/archive_linux.go (about) 1 //go:build !wasip1 2 3 package archive // import "github.com/Prakhar-Agarwal-byte/moby/pkg/archive" 4 5 import ( 6 "archive/tar" 7 "os" 8 "path/filepath" 9 "strings" 10 11 "github.com/Prakhar-Agarwal-byte/moby/pkg/system" 12 "github.com/pkg/errors" 13 "golang.org/x/sys/unix" 14 ) 15 16 func getWhiteoutConverter(format WhiteoutFormat, inUserNS bool) (tarWhiteoutConverter, error) { 17 if format == OverlayWhiteoutFormat { 18 if inUserNS { 19 return nil, errors.New("specifying OverlayWhiteoutFormat is not allowed in userns") 20 } 21 return overlayWhiteoutConverter{}, nil 22 } 23 return nil, nil 24 } 25 26 type overlayWhiteoutConverter struct{} 27 28 func (overlayWhiteoutConverter) ConvertWrite(hdr *tar.Header, path string, fi os.FileInfo) (wo *tar.Header, err error) { 29 // convert whiteouts to AUFS format 30 if fi.Mode()&os.ModeCharDevice != 0 && hdr.Devmajor == 0 && hdr.Devminor == 0 { 31 // we just rename the file and make it normal 32 dir, filename := filepath.Split(hdr.Name) 33 hdr.Name = filepath.Join(dir, WhiteoutPrefix+filename) 34 hdr.Mode = 0o600 35 hdr.Typeflag = tar.TypeReg 36 hdr.Size = 0 37 } 38 39 if fi.Mode()&os.ModeDir != 0 { 40 // convert opaque dirs to AUFS format by writing an empty file with the prefix 41 opaque, err := system.Lgetxattr(path, "trusted.overlay.opaque") 42 if err != nil { 43 return nil, err 44 } 45 if len(opaque) == 1 && opaque[0] == 'y' { 46 delete(hdr.PAXRecords, paxSchilyXattr+"trusted.overlay.opaque") 47 48 // create a header for the whiteout file 49 // it should inherit some properties from the parent, but be a regular file 50 wo = &tar.Header{ 51 Typeflag: tar.TypeReg, 52 Mode: hdr.Mode & int64(os.ModePerm), 53 Name: filepath.Join(hdr.Name, WhiteoutOpaqueDir), 54 Size: 0, 55 Uid: hdr.Uid, 56 Uname: hdr.Uname, 57 Gid: hdr.Gid, 58 Gname: hdr.Gname, 59 AccessTime: hdr.AccessTime, 60 ChangeTime: hdr.ChangeTime, 61 } //#nosec G305 -- An archive is being created, not extracted. 62 } 63 } 64 65 return 66 } 67 68 func (c overlayWhiteoutConverter) ConvertRead(hdr *tar.Header, path string) (bool, error) { 69 base := filepath.Base(path) 70 dir := filepath.Dir(path) 71 72 // if a directory is marked as opaque by the AUFS special file, we need to translate that to overlay 73 if base == WhiteoutOpaqueDir { 74 err := unix.Setxattr(dir, "trusted.overlay.opaque", []byte{'y'}, 0) 75 if err != nil { 76 return false, errors.Wrapf(err, "setxattr(%q, trusted.overlay.opaque=y)", dir) 77 } 78 // don't write the file itself 79 return false, err 80 } 81 82 // if a file was deleted and we are using overlay, we need to create a character device 83 if strings.HasPrefix(base, WhiteoutPrefix) { 84 originalBase := base[len(WhiteoutPrefix):] 85 originalPath := filepath.Join(dir, originalBase) 86 87 if err := unix.Mknod(originalPath, unix.S_IFCHR, 0); err != nil { 88 return false, errors.Wrapf(err, "failed to mknod(%q, S_IFCHR, 0)", originalPath) 89 } 90 if err := os.Chown(originalPath, hdr.Uid, hdr.Gid); err != nil { 91 return false, err 92 } 93 94 // don't write the file itself 95 return false, nil 96 } 97 98 return true, nil 99 }