diff options
-rw-r--r-- | src/buildstream/storage/_casbaseddirectory.py | 7 | ||||
-rw-r--r-- | src/buildstream/storage/_filebaseddirectory.py | 9 | ||||
-rw-r--r-- | src/buildstream/storage/directory.py | 9 |
3 files changed, 25 insertions, 0 deletions
diff --git a/src/buildstream/storage/_casbaseddirectory.py b/src/buildstream/storage/_casbaseddirectory.py index 2762a6684..10d7a27d2 100644 --- a/src/buildstream/storage/_casbaseddirectory.py +++ b/src/buildstream/storage/_casbaseddirectory.py @@ -877,6 +877,13 @@ class CasBasedDirectory(Directory): return os.stat_result((st_mode, 0, 0, st_nlink, 0, 0, st_size, st_mtime, st_mtime, st_mtime)) + def file_digest(self, *path): + entry = self._entry_from_path(*path) + if entry.type != _FileType.REGULAR_FILE: + raise VirtualDirectoryError("Unsupported file type for digest: {}".format(entry.type)) + + return entry.digest.hash + def __iter__(self): yield from self.index.keys() diff --git a/src/buildstream/storage/_filebaseddirectory.py b/src/buildstream/storage/_filebaseddirectory.py index 99769ce76..f8b9f95a0 100644 --- a/src/buildstream/storage/_filebaseddirectory.py +++ b/src/buildstream/storage/_filebaseddirectory.py @@ -256,6 +256,15 @@ class FileBasedDirectory(Directory): except (VirtualDirectoryError, FileNotFoundError): return False + def file_digest(self, *path): + # Use descend() to avoid following symlinks (potentially escaping the sandbox) + subdir = self.descend(*path[:-1]) + if subdir.exists(path[-1]) and not subdir.isfile(path[-1]): + raise VirtualDirectoryError("Unsupported file type for digest") + + newpath = os.path.join(subdir.external_directory, path[-1]) + return utils.sha256sum(newpath) + def open_file(self, *path: str, mode: str = "r"): # Use descend() to avoid following symlinks (potentially escaping the sandbox) subdir = self.descend(*path[:-1]) diff --git a/src/buildstream/storage/directory.py b/src/buildstream/storage/directory.py index 3bd80dc3e..2dab9bcad 100644 --- a/src/buildstream/storage/directory.py +++ b/src/buildstream/storage/directory.py @@ -280,6 +280,15 @@ class Directory: """ raise NotImplementedError() + def file_digest(self, *paths: str) -> str: + """ Return a digest of a file. The digest algorithm is implementation- + defined. + + Args: + *paths: A list of strings which are all path components. + """ + raise NotImplementedError() + def _create_empty_file(self, *paths): with self.open_file(*paths, mode="w"): pass |