summaryrefslogtreecommitdiff
path: root/morphlib/stagingarea.py
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2012-05-14 17:34:50 +0000
committerRichard Maw <richard.maw@codethink.co.uk>2012-05-14 17:34:50 +0000
commit41c647ec20d3e58348535e5d2f76f80e977b47ce (patch)
treec249faf7f1c5c8047213b67619448b605a7d1690 /morphlib/stagingarea.py
parentcd8170c8f7a6c8c82d43f8b992c07041fa22a31b (diff)
downloadmorph-41c647ec20d3e58348535e5d2f76f80e977b47ce.tar.gz
builder: use the same tar extract logic for all artifacts
Before only the staging area had symbolic links handled, now strata and systems will have the same logic.
Diffstat (limited to 'morphlib/stagingarea.py')
-rw-r--r--morphlib/stagingarea.py84
1 files changed, 2 insertions, 82 deletions
diff --git a/morphlib/stagingarea.py b/morphlib/stagingarea.py
index 8c84ac36..4f6d76bf 100644
--- a/morphlib/stagingarea.py
+++ b/morphlib/stagingarea.py
@@ -18,8 +18,6 @@ import errno
import logging
import os
import shutil
-import stat
-import tarfile
import morphlib
@@ -91,86 +89,8 @@ class StagingArea(object):
'''
logging.debug('Installing artifact %s' %
- getattr(handle, 'name', 'unknown name'))
- tf = tarfile.open(fileobj=handle)
-
- # This is evil, but necessary. For some reason Python's system
- # call wrappers (os.mknod and such) do not (always?) set the
- # filename attribute of the OSError exception they raise. We
- # fix that by monkey patching the tf instance with wrappers
- # for the relevant methods to add things. The wrapper further
- # ignores EEXIST errors, since we do not (currently!) care about
- # overwriting files.
-
- def follow_symlink(path): # pragma: no cover
- try:
- return os.stat(path)
- except OSError:
- return None
-
- def prepare_extract(tarinfo, targetpath): # pragma: no cover
- '''Prepare to extract a tar file member onto targetpath?
-
- If the target already exist, and we can live with it or
- remove it, we do so. Otherwise, raise an error.
-
- It's OK to extract if:
-
- * the target does not exist
- * the member is a directory a directory and the
- target is a directory or a symlink to a directory
- (just extract, no need to remove)
- * the member is not a directory, and the target is not a directory
- or a symlink to a directory (remove target, then extract)
-
- '''
-
- try:
- existing = os.lstat(targetpath)
- except OSError:
- return True # target does not exist
-
- if tarinfo.isdir():
- if stat.S_ISDIR(existing.st_mode):
- return True
- elif stat.S_ISLNK(existing.st_mode):
- st = follow_symlink(targetpath)
- return st and stat.S_ISDIR(st.st_mode)
- else:
- if stat.S_ISDIR(existing.st_mode):
- return False
- elif stat.S_ISLNK(existing.st_mode):
- st = follow_symlink(targetpath)
- if st and not stat.S_ISDIR(st.st_mode):
- os.remove(targetpath)
- return True
- else:
- os.remove(targetpath)
- return True
- return False
-
- def monkey_patcher(real):
- def make_something(tarinfo, targetpath): # pragma: no cover
- prepare_extract(tarinfo, targetpath)
- try:
- return real(tarinfo, targetpath)
- except OSError, e:
- if e.errno != errno.EEXIST:
- if e.filename is None:
- e.filename = targetpath
- raise e
- else:
- raise
- return make_something
-
- tf.makedir = monkey_patcher(tf.makedir)
- tf.makefile = monkey_patcher(tf.makefile)
- tf.makeunknown = monkey_patcher(tf.makeunknown)
- tf.makefifo = monkey_patcher(tf.makefifo)
- tf.makedev = monkey_patcher(tf.makedev)
- tf.makelink = monkey_patcher(tf.makelink)
-
- tf.extractall(path=self.dirname)
+ getattr(handle, 'name', 'unknown name'))
+ morphlib.bins.unpack_binary_from_file(handle, self.dirname)
def remove(self):
'''Remove the entire staging area.