diff options
author | Jürg Billeter <j@bitron.ch> | 2020-03-03 15:51:02 +0100 |
---|---|---|
committer | Jürg Billeter <j@bitron.ch> | 2020-03-10 15:46:04 +0000 |
commit | f78e6ee55e98c91e2cef055e232df5b955ac7323 (patch) | |
tree | 519b1751a03410cd942cbec4e0aaa5fff76a5984 /src/buildstream/storage | |
parent | dd1a4554417a0e1b4f57827a0af1918ec05323ba (diff) | |
download | buildstream-f78e6ee55e98c91e2cef055e232df5b955ac7323.tar.gz |
_filebaseddirectory.py: Improve _exists() method
Use similar implementation as in `CasBasedDirectory`. This fixes
following symlinks to avoid the host filesystem and adds support for
`follow_symlinks=False`.
Diffstat (limited to 'src/buildstream/storage')
-rw-r--r-- | src/buildstream/storage/_filebaseddirectory.py | 21 |
1 files changed, 14 insertions, 7 deletions
diff --git a/src/buildstream/storage/_filebaseddirectory.py b/src/buildstream/storage/_filebaseddirectory.py index f14b3de1d..aafe33279 100644 --- a/src/buildstream/storage/_filebaseddirectory.py +++ b/src/buildstream/storage/_filebaseddirectory.py @@ -359,13 +359,20 @@ class FileBasedDirectory(Directory): result.files_written.append(relative_pathname) def _exists(self, *path, follow_symlinks=False): - """This is very simple but mirrors the cas based storage were it is less trivial""" - if follow_symlinks: - # The lexists is not ideal as it cant spot broken symlinks but this is a long - # standing bug in buildstream as exists follow absolute syslinks to real root - # and incorrectly thinks they are broken the new casbaseddirectory dose not have this bug. - return os.path.lexists(os.path.join(self.external_directory, *path)) - raise ImplError("_exists can only follow symlinks in filebaseddirectory") + try: + subdir = self.descend(*path[:-1], follow_symlinks=follow_symlinks) + newpath = os.path.join(subdir.external_directory, path[-1]) + st = os.lstat(newpath) + if follow_symlinks and stat.S_ISLNK(st.st_mode): + linklocation = os.readlink(newpath) + newpath = linklocation.split(os.path.sep) + if os.path.isabs(linklocation): + return subdir._find_root()._exists(*newpath, follow_symlinks=True) + return subdir._exists(*newpath, follow_symlinks=True) + else: + return True + except (VirtualDirectoryError, FileNotFoundError): + return False def _create_empty_file(self, name): with open(os.path.join(self.external_directory, name), "w"): |