summaryrefslogtreecommitdiff
path: root/morphlib/bins.py
diff options
context:
space:
mode:
authorFrancisco Redondo Marchena <francisco.marchena@codethink.co.uk>2014-09-12 13:01:41 +0000
committerFrancisco Redondo Marchena <francisco.marchena@codethink.co.uk>2014-09-12 15:53:58 +0000
commitcfbb7cd7b06a953944a16966291190b90f07cdb5 (patch)
tree86de277c25b161122fc44816e35022c6cd532714 /morphlib/bins.py
parent368ac1d818b1f06b433a4367e76c366b410468cc (diff)
downloadmorph-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.py47
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.