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 | |
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`.
-rw-r--r-- | src/buildstream/buildelement.py | 2 | ||||
-rw-r--r-- | src/buildstream/storage/_filebaseddirectory.py | 21 |
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"): |