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

Fix file-not-found errors when handling broken symlinks #87

Merged
merged 2 commits into from
Nov 10, 2021

Conversation

Diomendius
Copy link
Contributor

If a directory source_dir exists and contains a file foo, and Dotter's config contains source_dir = "target_dir", Dotter will create target_dir and link target_dir/foo to source_dir/foo. If source_dir/foo is then deleted, dotter deploy will fail:

[ERROR] Failed to delete symlink "source_dir/foo" -> "target_dir/foo"
Caused by:
    detect symlink's current state
    get real path of source
    No such file or directory (os error 2)

I believe this is the same problem reported by @lumbo7332 in #55 (comment), and this PR should fix it. It does not address #55 itself, as that seems to be caused by Dotter not handling nonexistent source files gracefully, rather than anything to do with broken symlinks.

As one of my commit messages says, this contains a very minor change to Windows-specific code which I have not tested. This change, however, mirrors the change to the corresponding non-Windows function verbatim (the code could be DRY-er, apparently, but that's an issue for another PR) and so I would be very surprised if it causes any issue.

Call real_path in filesystem::compare_symlink instead of at its
call-sites in filesystem::RealFilesystem::compare_symlink and
filesystem::DryRunFilesystem::compare_symlink, to avoid real_path being
called unnecessarily and in particular when the path refers to a
non-existent file, which would cause an unhandled error.

This error would occur when deleting a file from within a source
directory and running dotter deploy; instead of deleting the
corresponding (now-broken) symlink, dotter would crash.

This is not the only cause for this crash, unfortunately.

I have not tested the changes to Windows code, but the only difference
is a pair of logging macros, so I can't see this causing problems.
Use symlink_metadata() instead of metadata() to avoid errors when the
file in question is a broken symlink.

If path points to a symlink, the is_dir() check would return whether the
link target is a directory, rather than returning false (as symlinks are
not dirs), but thankfully remove_dir_all removes the link rather than
recursively removing the link target in this case. I'm not certain this
could actually happen in practice though, as Dotter generally checks
things before calling remove_file() and does not currently create
symlinks to directories.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants