diff options
author | Francisco Redondo Marchena <francisco.marchena@codethink.co.uk> | 2014-09-12 13:01:41 +0000 |
---|---|---|
committer | Francisco Redondo Marchena <francisco.marchena@codethink.co.uk> | 2014-09-12 15:53:58 +0000 |
commit | cfbb7cd7b06a953944a16966291190b90f07cdb5 (patch) | |
tree | 86de277c25b161122fc44816e35022c6cd532714 /morphlib/bins.py | |
parent | 368ac1d818b1f06b433a4367e76c366b410468cc (diff) | |
download | morph-cfbb7cd7b06a953944a16966291190b90f07cdb5.tar.gz |
Fix tarfile.chown for versions of python smaller than 2.7.3baserock/franred/bugfix/python-tarfile-chown
This workaround fix http://bugs.python.org/issue12841
The code added in this patch is from tarfile.py from python 2.7.3.
Also only use the workaround for tarfile.makefile when the ptyhon
is smaller than 2.7.4
Diffstat (limited to 'morphlib/bins.py')
-rw-r--r-- | morphlib/bins.py | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/morphlib/bins.py b/morphlib/bins.py index 23e3b812..560e68bb 100644 --- a/morphlib/bins.py +++ b/morphlib/bins.py @@ -24,6 +24,7 @@ Binaries are chunks, strata, and system images. import cliapp import logging import os +import sys import re import errno import stat @@ -35,20 +36,48 @@ import morphlib from morphlib.extractedtarball import ExtractedTarball from morphlib.mountableimage import MountableImage - # Work around http://bugs.python.org/issue16477 -def safe_makefile(self, tarinfo, targetpath): - '''Create a file, closing correctly in case of exception''' +if sys.version_info < (2, 7, 4): # pragma: no cover + def safe_makefile(self, tarinfo, targetpath): + '''Create a file, closing correctly in case of exception''' - source = self.extractfile(tarinfo) + source = self.extractfile(tarinfo) + try: + with open(targetpath, "wb") as target: + shutil.copyfileobj(source, target) + finally: + source.close() + tarfile.TarFile.makefile = safe_makefile + +# Work around http://bugs.python.org/issue12841 +if sys.version_info < (2, 7, 3): # pragma: no cover try: - with open(targetpath, "wb") as target: - shutil.copyfileobj(source, target) - finally: - source.close() + import grp, pwd + except ImportError: + grp = pwd = None -tarfile.TarFile.makefile = safe_makefile + def fixed_chown(self, tarinfo, targetpath): + '''Set owner of targetpath according to tarinfo.''' + if pwd and hasattr(os, "geteuid") and os.geteuid() == 0: + # We have to be root to do so. + try: + g = grp.getgrnam(tarinfo.gname)[2] + except KeyError: + g = tarinfo.gid + try: + u = pwd.getpwnam(tarinfo.uname)[2] + except KeyError: + u = tarinfo.uid + try: + if tarinfo.issym() and hasattr(os, "lchown"): + os.lchown(targetpath, u, g) + else: + if sys.platform != "os2emx": + os.chown(targetpath, u, g) + except EnvironmentError, e: + raise ExtractError("could not change owner") + tarfile.TarFile.chown = fixed_chown def create_chunk(rootdir, f, include, dump_memory_profile=None): '''Create a chunk from the contents of a directory. |