From d411bd6dafb112d9376267fb14009a47a10d040e Mon Sep 17 00:00:00 2001 From: xanonid Date: Sat, 23 Jun 2018 00:11:02 +0200 Subject: [PATCH] Track file ownership and use file ownership from base images (#209) * Track file ownership and use file ownership from base images * Fix fs_util_test - use current uid/gid. --- pkg/util/bucket_util.go | 2 +- pkg/util/fs_util.go | 32 ++++++++++++++++++++++++++++---- pkg/util/fs_util_test.go | 4 ++++ pkg/util/util.go | 6 ++++++ 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/pkg/util/bucket_util.go b/pkg/util/bucket_util.go index 8113ebdd9..8051ce1cc 100644 --- a/pkg/util/bucket_util.go +++ b/pkg/util/bucket_util.go @@ -58,7 +58,7 @@ func getTarFromBucket(bucketName, directory string) (string, error) { } defer reader.Close() tarPath := filepath.Join(directory, constants.ContextTar) - if err := CreateFile(tarPath, reader, 0600); err != nil { + if err := CreateFile(tarPath, reader, 0600, 0, 0); err != nil { return "", err } logrus.Debugf("Copied tarball %s from GCS bucket %s to %s", constants.ContextTar, bucketName, tarPath) diff --git a/pkg/util/fs_util.go b/pkg/util/fs_util.go index 825009d7f..42c339667 100644 --- a/pkg/util/fs_util.go +++ b/pkg/util/fs_util.go @@ -24,6 +24,7 @@ import ( "os" "path/filepath" "strings" + "syscall" "time" "github.com/google/go-containerregistry/pkg/v1" @@ -165,6 +166,8 @@ func extractFile(dest string, hdr *tar.Header, tr io.Reader) error { base := filepath.Base(path) dir := filepath.Dir(path) mode := hdr.FileInfo().Mode() + uid := hdr.Uid + gid := hdr.Gid switch hdr.Typeflag { case tar.TypeReg: logrus.Debugf("creating file %s", path) @@ -186,6 +189,9 @@ func extractFile(dest string, hdr *tar.Header, tr io.Reader) error { if _, err = io.Copy(currFile, tr); err != nil { return err } + if err = currFile.Chown(uid, gid); err != nil { + return err + } currFile.Close() case tar.TypeDir: @@ -197,6 +203,9 @@ func extractFile(dest string, hdr *tar.Header, tr io.Reader) error { if err := os.Chmod(path, mode); err != nil { return err } + if err := os.Chown(path, uid, gid); err != nil { + return err + } case tar.TypeLink: logrus.Debugf("link from %s to %s", hdr.Linkname, path) @@ -208,6 +217,7 @@ func extractFile(dest string, hdr *tar.Header, tr io.Reader) error { if err := os.Symlink(filepath.Clean(filepath.Join("/", hdr.Linkname)), path); err != nil { return err } + case tar.TypeSymlink: logrus.Debugf("symlink from %s to %s", hdr.Linkname, path) // The base directory for a symlink may not exist before it is created. @@ -218,6 +228,7 @@ func extractFile(dest string, hdr *tar.Header, tr io.Reader) error { if err := os.Symlink(hdr.Linkname, path); err != nil { return err } + } return nil } @@ -359,7 +370,7 @@ func FilepathExists(path string) bool { } // CreateFile creates a file at path and copies over contents from the reader -func CreateFile(path string, reader io.Reader, perm os.FileMode) error { +func CreateFile(path string, reader io.Reader, perm os.FileMode, uid uint32, gid uint32) error { // Create directory path if it doesn't exist baseDir := filepath.Dir(path) if _, err := os.Lstat(baseDir); os.IsNotExist(err) { @@ -376,7 +387,10 @@ func CreateFile(path string, reader io.Reader, perm os.FileMode) error { if _, err := io.Copy(dest, reader); err != nil { return err } - return dest.Chmod(perm) + if err := dest.Chmod(perm); err != nil { + return err + } + return dest.Chown(int(uid), int(gid)) } // AddPathToVolumeWhitelist adds the given path to the volume whitelist @@ -409,7 +423,8 @@ func DownloadFileToDest(rawurl, dest string) error { return err } defer resp.Body.Close() - if err := CreateFile(dest, resp.Body, 0600); err != nil { + // TODO: set uid and gid according to current user + if err := CreateFile(dest, resp.Body, 0600, 0, 0); err != nil { return err } mTime := time.Time{} @@ -437,9 +452,16 @@ func CopyDir(src, dest string) error { destPath := filepath.Join(dest, file) if fi.IsDir() { logrus.Infof("Creating directory %s", destPath) + + uid := int(fi.Sys().(*syscall.Stat_t).Uid) + gid := int(fi.Sys().(*syscall.Stat_t).Gid) + if err := os.MkdirAll(destPath, fi.Mode()); err != nil { return err } + if err := os.Chown(destPath, uid, gid); err != nil { + return err + } } else if fi.Mode()&os.ModeSymlink != 0 { // If file is a symlink, we want to create the same relative symlink if err := CopySymlink(fullPath, destPath); err != nil { @@ -477,7 +499,9 @@ func CopyFile(src, dest string) error { return err } defer srcFile.Close() - return CreateFile(dest, srcFile, fi.Mode()) + uid := fi.Sys().(*syscall.Stat_t).Uid + gid := fi.Sys().(*syscall.Stat_t).Gid + return CreateFile(dest, srcFile, fi.Mode(), uid, gid) } // HasFilepathPrefix checks if the given file path begins with prefix diff --git a/pkg/util/fs_util_test.go b/pkg/util/fs_util_test.go index a9c871632..404a0f088 100644 --- a/pkg/util/fs_util_test.go +++ b/pkg/util/fs_util_test.go @@ -382,6 +382,8 @@ func fileHeader(name string, contents string, mode int64) *tar.Header { Size: int64(len(contents)), Mode: mode, Typeflag: tar.TypeReg, + Uid: os.Getuid(), + Gid: os.Getgid(), } } @@ -409,6 +411,8 @@ func dirHeader(name string, mode int64) *tar.Header { Size: 0, Typeflag: tar.TypeDir, Mode: mode, + Uid: os.Getuid(), + Gid: os.Getgid(), } } diff --git a/pkg/util/util.go b/pkg/util/util.go index f81b19cd5..c95935ec9 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -23,6 +23,8 @@ import ( "github.com/sirupsen/logrus" "io" "os" + "strconv" + "syscall" ) // SetLogLevel sets the logrus logging level @@ -46,6 +48,10 @@ func Hasher() func(string) (string, error) { h.Write([]byte(fi.Mode().String())) h.Write([]byte(fi.ModTime().String())) + h.Write([]byte(strconv.FormatUint(uint64(fi.Sys().(*syscall.Stat_t).Uid), 36))) + h.Write([]byte(",")) + h.Write([]byte(strconv.FormatUint(uint64(fi.Sys().(*syscall.Stat_t).Gid), 36))) + if fi.Mode().IsRegular() { f, err := os.Open(p) if err != nil {