summaryrefslogtreecommitdiff
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
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`.
-rw-r--r--src/buildstream/buildelement.py2
-rw-r--r--src/buildstream/storage/_filebaseddirectory.py21
2 files changed, 15 insertions, 8 deletions
diff --git a/src/buildstream/buildelement.py b/src/buildstream/buildelement.py
index aeafbcdda..acb079a56 100644
--- a/src/buildstream/buildelement.py
+++ b/src/buildstream/buildelement.py
@@ -280,7 +280,7 @@ class BuildElement(Element):
buildroot = self.get_variable("build-root")
buildroot_vdir = vdir.descend(*buildroot.lstrip(os.sep).split(os.sep))
- if buildroot_vdir._exists(marker_filename, follow_symlinks=True):
+ if buildroot_vdir._exists(marker_filename):
# Already prepared
return
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"):