Fix restoring files as non-root user

As we cannot reliably detect in advance if we can set ownership, permissions,
timestamps or ext attributes, execute ALL the requested changes before
returning the first error we found.

Report total errors at end of restore and stop printing entire stacktraces
where just the error message is sufficient.

Fixes #655
This commit is contained in:
Pauline Middelink 2017-03-12 16:39:37 +01:00
parent 887e81188f
commit 642cd3bebf
2 changed files with 24 additions and 16 deletions

View file

@ -103,8 +103,10 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
Exitf(2, "creating restorer failed: %v\n", err)
}
totalErrors := 0
res.Error = func(dir string, node *restic.Node, err error) error {
Warnf("error for %s: %+v\n", dir, err)
Warnf("ignoring error for %s: %s\n", dir, err)
totalErrors++
return nil
}
@ -134,5 +136,9 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
Verbosef("restoring %s to %s\n", res.Snapshot(), opts.Target)
return res.RestoreTo(opts.Target)
err = res.RestoreTo(opts.Target)
if totalErrors > 0 {
Printf("There were %d errors\n", totalErrors)
}
return err
}

View file

@ -158,35 +158,37 @@ func (node *Node) CreateAt(path string, repo Repository, idx *HardlinkIndex) err
}
func (node Node) restoreMetadata(path string) error {
var err error
var firsterr error
err = lchown(path, int(node.UID), int(node.GID))
if err != nil {
return errors.Wrap(err, "Lchown")
if err := lchown(path, int(node.UID), int(node.GID)); err != nil {
firsterr = errors.Wrap(err, "Lchown")
}
if node.Type != "symlink" {
err = fs.Chmod(path, node.Mode)
if err != nil {
return errors.Wrap(err, "Chmod")
if err := fs.Chmod(path, node.Mode); err != nil {
if firsterr != nil {
firsterr = errors.Wrap(err, "Chmod")
}
}
}
if node.Type != "dir" {
err = node.RestoreTimestamps(path)
if err != nil {
if err := node.RestoreTimestamps(path); err != nil {
debug.Log("error restoring timestamps for dir %v: %v", path, err)
return err
if firsterr != nil {
firsterr = err
}
}
}
err = node.restoreExtendedAttributes(path)
if err != nil {
if err := node.restoreExtendedAttributes(path); err != nil {
debug.Log("error restoring extended attributes for %v: %v", path, err)
return err
if firsterr != nil {
firsterr = err
}
}
return nil
return firsterr
}
func (node Node) restoreExtendedAttributes(path string) error {