summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShahwat Dalal <sdalal29@bloomberg.net>2019-07-05 15:42:14 +0100
committerDaniel Silverstone <daniel.silverstone@codethink.co.uk>2019-09-05 09:09:25 +0000
commit07e35b3c688b4b105285550fa5a2bf216952df10 (patch)
tree5034a6eb66b41a5ad030766f9dbd88a0ae80ef68
parent6f81827dab46f3ae36962784ffe5cd020dd72493 (diff)
downloadbuildstream-07e35b3c688b4b105285550fa5a2bf216952df10.tar.gz
sources/tar.py: Ensure tar source files are readable
When non-readable files were being added to CAS, `add_object` was failing. Thus all sourced files must be readable if they are to be cached. The tar source has been modified to ensure this precondition.
-rw-r--r--src/buildstream/plugins/sources/tar.py21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/buildstream/plugins/sources/tar.py b/src/buildstream/plugins/sources/tar.py
index 3e9018bba..702b7ba56 100644
--- a/src/buildstream/plugins/sources/tar.py
+++ b/src/buildstream/plugins/sources/tar.py
@@ -66,6 +66,23 @@ from buildstream import utils
from ._downloadablefilesource import DownloadableFileSource
+class ReadableTarInfo(tarfile.TarInfo):
+ """
+ The goal is to override `TarFile`'s `extractall` semantics by ensuring that on extraction, the
+ files are readable by the owner of the file. This is done by overriding the accessor for the
+ `mode` attribute in `TarInfo`, the class that encapsulates the internal meta-data of the tarball,
+ so that the owner-read bit is always set.
+ """
+ @property
+ def mode(self):
+ # ensure file is readable by owner
+ return self.__permission | 0o400
+
+ @mode.setter
+ def mode(self, permission):
+ self.__permission = permission
+
+
class TarSource(DownloadableFileSource):
# pylint: disable=attribute-defined-outside-init
@@ -99,10 +116,10 @@ class TarSource(DownloadableFileSource):
def _get_tar(self):
if self.url.endswith('.lz'):
with self._run_lzip() as lzip_dec:
- with tarfile.open(fileobj=lzip_dec, mode='r:') as tar:
+ with tarfile.open(fileobj=lzip_dec, mode='r:', tarinfo=ReadableTarInfo) as tar:
yield tar
else:
- with tarfile.open(self._get_mirror_file()) as tar:
+ with tarfile.open(self._get_mirror_file(), tarinfo=ReadableTarInfo) as tar:
yield tar
def stage(self, directory):