From 7065921aa487f99009e3bace196701946dcaea43 Mon Sep 17 00:00:00 2001 From: Andrei Kvapil Date: Thu, 23 Dec 2021 19:25:55 +0100 Subject: [PATCH] Fix copying ownership (#1725) * fix uid, gid overriding * fix ownership for staging building * add integration test * add check for ignored files * improve errors --- .../issue-1315/Dockerfile | 20 ++++++ pkg/util/fs_util.go | 61 ++++++++++++++++++- 2 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 integration/dockerfiles-with-context/issue-1315/Dockerfile diff --git a/integration/dockerfiles-with-context/issue-1315/Dockerfile b/integration/dockerfiles-with-context/issue-1315/Dockerfile new file mode 100644 index 0000000000..eff125aed0 --- /dev/null +++ b/integration/dockerfiles-with-context/issue-1315/Dockerfile @@ -0,0 +1,20 @@ +FROM alpine:3.11 as builder + +RUN mkdir -p /myapp/somedir \ + && touch /myapp/somedir/somefile \ + && chown 123:123 /myapp/somedir \ + && chown 321:321 /myapp/somedir/somefile + +FROM alpine:3.11 +COPY --from=builder /myapp /myapp +RUN printf "%s\n" \ + "0 0 /myapp/" \ + "123 123 /myapp/somedir" \ + "321 321 /myapp/somedir/somefile" \ + > /tmp/expected \ + && stat -c "%u %g %n" \ + /myapp/ \ + /myapp/somedir \ + /myapp/somedir/somefile \ + > /tmp/got \ + && diff -u /tmp/got /tmp/expected diff --git a/pkg/util/fs_util.go b/pkg/util/fs_util.go index 2158c6daa1..5a6be2f099 100644 --- a/pkg/util/fs_util.go +++ b/pkg/util/fs_util.go @@ -630,7 +630,7 @@ func CopyDir(src, dest string, context FileContext, uid, gid int64) ([]string, e logrus.Tracef("Creating directory %s", destPath) mode := fi.Mode() - uid, gid = DetermineTargetFileOwnership(fi, uid, gid) + uid, gid := DetermineTargetFileOwnership(fi, uid, gid) if err := mkdirAllWithPermissions(destPath, mode, uid, gid); err != nil { return nil, err } @@ -901,7 +901,64 @@ func CopyFileOrSymlink(src string, destDir string, root string) error { } return os.Symlink(link, destFile) } - return otiai10Cpy.Copy(src, destFile) + err := otiai10Cpy.Copy(src, destFile) + if err != nil { + return errors.Wrap(err, "copying file") + } + err = CopyOwnership(src, destDir) + if err != nil { + return errors.Wrap(err, "copying ownership") + } + return nil +} + +// CopyOwnership copies the file or directory ownership recursively at src to dest +func CopyOwnership(src string, destDir string) error { + return filepath.Walk(src, func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if IsSymlink(info) { + return nil + } + relPath, err := filepath.Rel(filepath.Dir(src), path) + if err != nil { + return err + } + destPath := filepath.Join(destDir, relPath) + + if CheckIgnoreList(src) && CheckIgnoreList(destPath) { + if !isExist(destPath) { + logrus.Debugf("Path %s ignored, but not exists", destPath) + return nil + } + if info.IsDir() { + return filepath.SkipDir + } + logrus.Debugf("Not copying ownership for %s, as it's ignored", destPath) + return nil + } + if CheckIgnoreList(destDir) && CheckIgnoreList(path) { + if !isExist(path) { + logrus.Debugf("Path %s ignored, but not exists", path) + return nil + } + if info.IsDir() { + return filepath.SkipDir + } + logrus.Debugf("Not copying ownership for %s, as it's ignored", path) + return nil + } + + info, err = os.Stat(path) + if err != nil { + return errors.Wrap(err, "reading ownership") + } + stat := info.Sys().(*syscall.Stat_t) + err = os.Chown(destPath, int(stat.Uid), int(stat.Gid)) + + return nil + }) } func createParentDirectory(path string) error {