Add DeepCopyFile for copies with additional permission bits

It's not needed for most of all the copying we do, except when we
generate the deltas

See also #204
This commit is contained in:
Ettore Di Giacinto 2021-05-04 11:14:16 +02:00
parent b0b95d1721
commit 958b8c32e1
2 changed files with 33 additions and 36 deletions

View File

@ -27,7 +27,6 @@ import (
"path/filepath"
"regexp"
system "github.com/docker/docker/pkg/system"
zstd "github.com/klauspost/compress/zstd"
gzip "github.com/klauspost/pgzip"
@ -584,47 +583,16 @@ type CopyJob struct {
Artifact string
}
func copyXattr(srcPath, dstPath, attr string) error {
data, err := system.Lgetxattr(srcPath, attr)
if err != nil {
return err
}
if data != nil {
if err := system.Lsetxattr(dstPath, attr, data, 0); err != nil {
return err
}
}
return nil
}
func doCopyXattrs(srcPath, dstPath string) error {
if err := copyXattr(srcPath, dstPath, "security.capability"); err != nil {
return err
}
return copyXattr(srcPath, dstPath, "trusted.overlay.opaque")
}
func worker(i int, wg *sync.WaitGroup, s <-chan CopyJob) {
defer wg.Done()
for job := range s {
//Info("#"+strconv.Itoa(i), "copying", job.Src, "to", job.Dst)
// if dir, err := helpers.IsDirectory(job.Src); err == nil && dir {
// err = helpers.CopyDir(job.Src, job.Dst)
// if err != nil {
// Warning("Error copying dir", job, err)
// }
// continue
// }
_, err := os.Lstat(job.Dst)
if err != nil {
Debug("Copying ", job.Src)
if err := helpers.CopyFile(job.Src, job.Dst); err != nil {
if err := helpers.DeepCopyFile(job.Src, job.Dst); err != nil {
Warning("Error copying", job, err)
}
doCopyXattrs(job.Src, job.Dst)
}
}
}

View File

@ -27,6 +27,7 @@ import (
"syscall"
"time"
"github.com/docker/docker/pkg/system"
"github.com/google/renameio"
copy "github.com/otiai10/copy"
"github.com/pkg/errors"
@ -196,12 +197,39 @@ func EnsureDir(fileName string) error {
return nil
}
// CopyFile copies the contents of the file named src to the file named
func CopyFile(src, dst string) (err error) {
return copy.Copy(src, dst, copy.Options{
Sync: true,
OnSymlink: func(string) copy.SymlinkAction { return copy.Shallow }})
}
func copyXattr(srcPath, dstPath, attr string) error {
data, err := system.Lgetxattr(srcPath, attr)
if err != nil {
return err
}
if data != nil {
if err := system.Lsetxattr(dstPath, attr, data, 0); err != nil {
return err
}
}
return nil
}
func doCopyXattrs(srcPath, dstPath string) error {
if err := copyXattr(srcPath, dstPath, "security.capability"); err != nil {
return err
}
return copyXattr(srcPath, dstPath, "trusted.overlay.opaque")
}
// DeepCopyFile copies the contents of the file named src to the file named
// by dst. The file will be created if it does not already exist. If the
// destination file exists, all it's contents will be replaced by the contents
// of the source file. The file mode will be copied from the source and
// the copied data is synced/flushed to stable storage.
func CopyFile(src, dst string) (err error) {
func DeepCopyFile(src, dst string) (err error) {
// Workaround for https://github.com/otiai10/copy/issues/47
fi, err := os.Lstat(src)
if err != nil {
@ -237,7 +265,8 @@ func CopyFile(src, dst string) (err error) {
fmt.Println("warning: failed chowning", dst, err.Error())
}
}
return err
return doCopyXattrs(src, dst)
}
func IsDirectory(path string) (bool, error) {