summaryrefslogtreecommitdiff
path: root/src/buildstream/storage
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2020-03-03 15:51:02 +0100
committerJürg Billeter <j@bitron.ch>2020-03-10 15:46:04 +0000
commitf78e6ee55e98c91e2cef055e232df5b955ac7323 (patch)
tree519b1751a03410cd942cbec4e0aaa5fff76a5984 /src/buildstream/storage
parentdd1a4554417a0e1b4f57827a0af1918ec05323ba (diff)
downloadbuildstream-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.py21
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"):