mirror of
https://github.com/octoleo/restic.git
synced 2024-11-10 23:31:09 +00:00
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:
parent
887e81188f
commit
642cd3bebf
@ -103,8 +103,10 @@ func runRestore(opts RestoreOptions, gopts GlobalOptions, args []string) error {
|
|||||||
Exitf(2, "creating restorer failed: %v\n", err)
|
Exitf(2, "creating restorer failed: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
totalErrors := 0
|
||||||
res.Error = func(dir string, node *restic.Node, err error) error {
|
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
|
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)
|
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
|
||||||
}
|
}
|
||||||
|
@ -158,35 +158,37 @@ func (node *Node) CreateAt(path string, repo Repository, idx *HardlinkIndex) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (node Node) restoreMetadata(path string) error {
|
func (node Node) restoreMetadata(path string) error {
|
||||||
var err error
|
var firsterr error
|
||||||
|
|
||||||
err = lchown(path, int(node.UID), int(node.GID))
|
if err := lchown(path, int(node.UID), int(node.GID)); err != nil {
|
||||||
if err != nil {
|
firsterr = errors.Wrap(err, "Lchown")
|
||||||
return errors.Wrap(err, "Lchown")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type != "symlink" {
|
if node.Type != "symlink" {
|
||||||
err = fs.Chmod(path, node.Mode)
|
if err := fs.Chmod(path, node.Mode); err != nil {
|
||||||
if err != nil {
|
if firsterr != nil {
|
||||||
return errors.Wrap(err, "Chmod")
|
firsterr = errors.Wrap(err, "Chmod")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.Type != "dir" {
|
if node.Type != "dir" {
|
||||||
err = node.RestoreTimestamps(path)
|
if err := node.RestoreTimestamps(path); err != nil {
|
||||||
if err != nil {
|
|
||||||
debug.Log("error restoring timestamps for dir %v: %v", path, err)
|
debug.Log("error restoring timestamps for dir %v: %v", path, err)
|
||||||
return err
|
if firsterr != nil {
|
||||||
|
firsterr = err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = node.restoreExtendedAttributes(path)
|
if err := node.restoreExtendedAttributes(path); err != nil {
|
||||||
if err != nil {
|
|
||||||
debug.Log("error restoring extended attributes for %v: %v", path, err)
|
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 {
|
func (node Node) restoreExtendedAttributes(path string) error {
|
||||||
|
Loading…
Reference in New Issue
Block a user