Skip to content
This repository was archived by the owner on May 4, 2021. It is now read-only.

Commit 70cabaa

Browse files
author
jockeych
authored
fix the parent directory ownership when using COPY --archive (#317)
* fix the permssion of given directory * address comments and separate the logic of maintain ownership from mkdirAll func * fix typo
1 parent b8d2b1b commit 70cabaa

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

lib/fileio/copy.go

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func (c copier) CopyDir(source, target string, uid, gid int) error {
104104
if err := mkdirAll(target, os.ModePerm, uid, gid, false); err != nil {
105105
return fmt.Errorf("mkdir all %s: %s", target, err)
106106
}
107-
// Recursively copy directories and files.
107+
// Recursively copy contents of source directory.
108108
return c.copyDirContents(source, target, target, uid, gid, false)
109109
}
110110

@@ -115,11 +115,26 @@ func (c copier) CopyDirPreserveOwner(source, target string) error {
115115
log.Infof("* Ignoring copy of directory %s because it is blacklisted", source)
116116
return nil
117117
}
118-
// Make target parent directories (uid and gid will be computed from the sources one).
119-
if err := mkdirAll(target, os.ModePerm, 0, 0, true); err != nil {
120-
return fmt.Errorf("mkdir all %s: %s", target, err)
118+
// Copy the parent directory of target.
119+
targetParentDir := filepath.Dir(target)
120+
if err := mkdirAll(targetParentDir, os.ModePerm, 0, 0, true); err != nil {
121+
return fmt.Errorf("mkdir parent dir %s: %s", targetParentDir, err)
122+
}
123+
// If the source dir is a symlink, makisu would try to copy the contents rather than a link.
124+
fi, _ := os.Stat(source)
125+
sourceUid, sourceGid := fileOwners(fi)
126+
if _, err := os.Lstat(target); err != nil {
127+
if !os.IsNotExist(err) {
128+
return fmt.Errorf("stat %s: %s", target, err)
129+
} else if err := os.Mkdir(target, os.ModePerm); err != nil {
130+
return fmt.Errorf("mkdir %s: %s", target, err)
131+
}
121132
}
122-
// Recursively copy directories and files.
133+
// Preserve the source dir ownership.
134+
if err := os.Chown(target, sourceUid, sourceGid); err != nil {
135+
return fmt.Errorf("chown %s: %s", target, err)
136+
}
137+
// Recursively copy contents of source directory.
123138
return c.copyDirContents(source, target, target, 0, 0, true)
124139
}
125140

@@ -289,7 +304,7 @@ func (c copier) copyDir(src, dst string, uid, gid int, preserveOwner bool) error
289304

290305
// mkdirAll performs the same operation as os.MkdirAll, but also sets the given
291306
// permissions & owners on all created directories.
292-
func mkdirAll(dst string, mode os.FileMode, uid, gid int, preserveOwner bool) error {
307+
func mkdirAll(dst string, mode os.FileMode, uid, gid int, preserveParentOwner bool) error {
293308
if dst == "" {
294309
return errors.New("empty target directory")
295310
}
@@ -300,7 +315,6 @@ func mkdirAll(dst string, mode os.FileMode, uid, gid int, preserveOwner bool) er
300315

301316
split := strings.Split(abs, "/")
302317
split[0] = "/"
303-
304318
var prevDir string
305319
for _, dir := range split {
306320
absDir := filepath.Join(prevDir, dir)
@@ -312,8 +326,8 @@ func mkdirAll(dst string, mode os.FileMode, uid, gid int, preserveOwner bool) er
312326
}
313327

314328
// Update file info
315-
fi, _ = os.Lstat(absDir)
316-
if preserveOwner {
329+
fi, _ = os.Lstat(prevDir)
330+
if preserveParentOwner {
317331
uid, gid = fileOwners(fi)
318332
}
319333
if err := os.Chown(absDir, uid, gid); err != nil {
@@ -322,6 +336,7 @@ func mkdirAll(dst string, mode os.FileMode, uid, gid int, preserveOwner bool) er
322336
}
323337
prevDir = absDir
324338
}
339+
325340
return nil
326341
}
327342

0 commit comments

Comments
 (0)