Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Call enterDir/leaveDir if a directory's child may be selected #3000

Closed
wants to merge 1 commit into from

Conversation

hoelzro
Copy link
Contributor

@hoelzro hoelzro commented Oct 8, 2020

This allows leaveDir to set metadata properly for directories
with descendants that are selected by an include filter, even
if the directory in question isn't selected by that filter.

For example, let's say you have the following file in your repo:

/home/user/nested/data/values.txt

...and / and /home are owned by root, but /home/user and below are owned
by user.

If you run "restic restore -i /home/user/nested/data -t /tmp/restore $SNAPSHOT" as root,
/home/user/nested/ will currently be restored with root as the owner,
even though it's supposed to be owned by user.

This change makes sure that leaveDir is called to restore metadata to
nodes like /home/user/nested - enterDir is also called under the same
circumstances for purposes of symmetry.

This fixes GH #1402 and (I think) GH #2563

What does this PR change? What problem does it solve?

This PR changes directory traversal logic when restoring a snapshot, and it fixes a bug around restoration of metadata.

Was the change discussed in an issue or in the forum before?

This PR closes #1402 and closes #2563

Checklist

  • I have read the Contribution Guidelines
  • I have enabled maintainer edits for this PR
  • I have added tests for all changes in this PR
  • I have added documentation for the changes (in the manual)
  • There's a new file in changelog/unreleased/ that describes the changes for our users (template here)
  • I have run gofmt on the code in all commits
  • All commit messages are formatted in the same style as the other commits in the repo
  • I'm done, this Pull Request is ready for review

This allows leaveDir to set metadata properly for directories
with descendants that are selected by an include filter, even
if the directory in question isn't selected by that filter.

For example, let's say you have the following file in your repo:

    /home/user/nested/data/values.txt

...and / and /home are owned by root, but /home/user and below are owned
by user.

If you run "restic restore -i /home/user/nested/data -t /tmp/restore $SNAPSHOT" as root,
/home/user/nested/ will currently be restored with root as the owner,
even though it's supposed to be owned by user.

This change makes sure that leaveDir is called to restore metadata to
nodes like /home/user/nested - enterDir is also called under the same
circumstances for purposes of symmetry.

This fixes GH restic#1402 and (I think) GH restic#2563
@hoelzro
Copy link
Contributor Author

hoelzro commented Oct 8, 2020

I haven't added tests for this yet, since the issue can only manifest when restic is run as root. I'm open to to ideas on how I could write a test for this, though!

One behavior I'm uncertain of is leaveDir restoring metadata - if a directory already exists in the restoration target directory but no new files are actually created under it, that directory will still have its metadata restored. I'm not sure if that's the behavior users would expect or not, so I'm open to feedback on that!

@greatroar
Copy link
Contributor

Does the issue also manifest when the owner is the same, but the mode is different? In that case, backing up a directory with mode 710 (or some other unlikely value) would trigger the bug with needing root for the test.

@MichaelEischer
Copy link
Member

This PR spews out a large number of errors, when using a relative include pattern: restic restore latest --target test --include command_win.go:

ignoring error for /restic/.git/hooks: UtimesNano: no such file or directory
ignoring error for /restic/.git/info: UtimesNano: no such file or directory
ignoring error for /restic/.git/logs/refs/heads: UtimesNano: no such file or directory

How does this PR relate to #2906 which AFAIK fixes the exact same problem?

// #leaveDir restores dir metadata after visiting all children
return fs.MkdirAll(target, 0700)
},
enterDir: noop,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change breaks restoring empty directories.

@hoelzro
Copy link
Contributor Author

hoelzro commented Oct 9, 2020

@MichaelEischer Ah, I neglected to check if the target directory was created by restic before trying to restore the metadata - I fixed this, but that PR you linked to looks to be more comprehensive

@hoelzro hoelzro closed this Oct 9, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants