Skip to content

Commit

Permalink
remove symlinks and fix hardlink unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
Priya Wadhwa committed Aug 10, 2018
1 parent 3d128d3 commit 2808197
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 31 deletions.
13 changes: 1 addition & 12 deletions pkg/util/fs_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ func GetFSFromImage(root string, img v1.Image) error {

fs := map[string]struct{}{}
whiteouts := map[string]struct{}{}
symlinks := map[string]struct{}{}
hardlinks := map[string]*hardlink{}

for i := len(layers) - 1; i >= 0; i-- {
Expand Down Expand Up @@ -106,7 +105,6 @@ func GetFSFromImage(root string, img v1.Image) error {
logrus.Debugf("skipping symlink from %s to %s because %s is whitelisted", hdr.Linkname, path, hdr.Linkname)
continue
}
symlinks[filepath.Clean(filepath.Join("/", hdr.Name))] = struct{}{}
}
if hdr.Typeflag == tar.TypeLink {
// If linkname no longer exists, extract hardlink as regular file
Expand All @@ -116,7 +114,7 @@ func GetFSFromImage(root string, img v1.Image) error {
continue
}
_, previouslyAdded := fs[linkname]
if previouslyAdded || checkSymlinks(linkname, symlinks) || checkWhiteouts(linkname, whiteouts) {
if previouslyAdded || checkWhiteouts(linkname, whiteouts) {
if h, ok := hardlinks[linkname]; ok {
h.links = append(h.links, hdr)
continue
Expand Down Expand Up @@ -287,15 +285,6 @@ func checkWhiteouts(path string, whiteouts map[string]struct{}) bool {
return false
}

func checkSymlinks(path string, symlinks map[string]struct{}) bool {
for sym := range symlinks {
if path == sym {
return true
}
}
return false
}

func CheckWhitelist(path string) bool {
for _, wl := range whitelist {
if HasFilepathPrefix(path, wl) {
Expand Down
43 changes: 36 additions & 7 deletions pkg/util/fs_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ func fileExists(p string) checker {
return func(root string, t *testing.T) {
_, err := os.Stat(filepath.Join(root, p))
if err != nil {
t.Fatalf("File does not exist")
t.Fatalf("File %s does not exist", filepath.Join(root, p))
}
}
}
Expand Down Expand Up @@ -381,6 +381,24 @@ func linkPointsTo(src, dst string) checker {
}
}

func filesAreHardlinks(first, second string) checker {
return func(root string, t *testing.T) {
fi1, err := os.Stat(filepath.Join(root, first))
if err != nil {
t.Fatalf("error getting file %s", first)
}
fi2, err := os.Stat(filepath.Join(second))
if err != nil {
t.Fatalf("error getting file %s", second)
}
stat1 := getSyscallStat_t(fi1)
stat2 := getSyscallStat_t(fi2)
if stat1.Ino != stat2.Ino {
t.Errorf("%s and %s aren't hardlinks as they dont' have the same inode", first, second)
}
}
}

func fileHeader(name string, contents string, mode int64) *tar.Header {
return &tar.Header{
Name: name,
Expand Down Expand Up @@ -425,6 +443,7 @@ func TestExtractFile(t *testing.T) {
type tc struct {
name string
hdrs []*tar.Header
tmpdir string
contents []byte
checkers []checker
}
Expand Down Expand Up @@ -496,13 +515,15 @@ func TestExtractFile(t *testing.T) {
},
},
{
name: "hardlink",
name: "hardlink",
tmpdir: "/tmp/hardlink",
hdrs: []*tar.Header{
fileHeader("/bin/gzip", "gzip-binary", 0751),
hardlinkHeader("/bin/uncompress", "/bin/gzip"),
hardlinkHeader("/bin/uncompress", "/tmp/hardlink/bin/gzip"),
},
checkers: []checker{
linkPointsTo("/bin/uncompress", "/bin/gzip"),
fileExists("/bin/gzip"),
filesAreHardlinks("/bin/uncompress", "/tmp/hardlink/bin/gzip"),
},
},
}
Expand All @@ -511,11 +532,19 @@ func TestExtractFile(t *testing.T) {
t.Run(tc.name, func(t *testing.T) {
tc := tc
t.Parallel()
r, err := ioutil.TempDir("", "")
if err != nil {
t.Fatal(err)
r := ""
var err error

if tc.tmpdir != "" {
r = tc.tmpdir
} else {
r, err = ioutil.TempDir("", "")
if err != nil {
t.Fatal(err)
}
}
defer os.RemoveAll(r)

for _, hdr := range tc.hdrs {
if err := extractFile(r, hdr, bytes.NewReader(tc.contents)); err != nil {
t.Fatal(err)
Expand Down
32 changes: 20 additions & 12 deletions pkg/util/tar_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,24 +89,32 @@ func Whiteout(p string, w *tar.Writer) error {
func checkHardlink(p string, hardlinks map[uint64]string, i os.FileInfo) (bool, string) {
hardlink := false
linkDst := ""
if sys := i.Sys(); sys != nil {
if stat, ok := sys.(*syscall.Stat_t); ok {
nlinks := stat.Nlink
if nlinks > 1 {
inode := stat.Ino
if original, exists := hardlinks[inode]; exists && original != p {
hardlink = true
logrus.Debugf("%s inode exists in hardlinks map, linking to %s", p, original)
linkDst = original
} else {
hardlinks[inode] = p
}
stat := getSyscallStat_t(i)
if stat != nil {
nlinks := stat.Nlink
if nlinks > 1 {
inode := stat.Ino
if original, exists := hardlinks[inode]; exists && original != p {
hardlink = true
logrus.Debugf("%s inode exists in hardlinks map, linking to %s", p, original)
linkDst = original
} else {
hardlinks[inode] = p
}
}
}
return hardlink, linkDst
}

func getSyscallStat_t(i os.FileInfo) *syscall.Stat_t {
if sys := i.Sys(); sys != nil {
if stat, ok := sys.(*syscall.Stat_t); ok {
return stat
}
}
return nil
}

// UnpackLocalTarArchive unpacks the tar archive at path to the directory dest
// Returns true if the path was actually unpacked
func UnpackLocalTarArchive(path, dest string) error {
Expand Down

0 comments on commit 2808197

Please sign in to comment.