summaryrefslogtreecommitdiff
path: root/morphlib/bins.py
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@codethink.co.uk>2012-11-15 17:37:06 +0000
committerRichard Maw <richard.maw@codethink.co.uk>2012-11-15 17:37:06 +0000
commitd4c7e23ad7373f671460a63d2250073d5a35feba (patch)
treedf297db013b94fc7e78524c9af739c93272aeb4e /morphlib/bins.py
parentdfdf35fe833c4e81bb08004d139cb1132c018d69 (diff)
parent5da1f9b9a94ef139729143aa2c1f649aa809b86b (diff)
downloadmorph-d4c7e23ad7373f671460a63d2250073d5a35feba.tar.gz
Merge branch 'samthursfield/handle-target-disk-full' of git://git.baserock.org/baserock/morph
A couple of nasties are fixed in here. Previously when the disk was full, Morph logged a backtrace into morph.log and then tried to unmount the disk image, but as there were still open file handles inside it the unmount would fail and the user would end up with a backtrace for a failed unmount and a stuck loopback device that they would need to fix manually.
Diffstat (limited to 'morphlib/bins.py')
-rw-r--r--morphlib/bins.py26
1 files changed, 21 insertions, 5 deletions
diff --git a/morphlib/bins.py b/morphlib/bins.py
index 71483172..622aa165 100644
--- a/morphlib/bins.py
+++ b/morphlib/bins.py
@@ -26,9 +26,24 @@ import os
import re
import errno
import stat
+import shutil
import tarfile
+# Work around http://bugs.python.org/issue16477
+def safe_makefile(self, tarinfo, targetpath):
+ '''Create a file, closing correctly in case of exception'''
+
+ source = self.extractfile(tarinfo)
+ try:
+ with open(targetpath, "wb") as target:
+ shutil.copyfileobj(source, target)
+ finally:
+ source.close()
+
+tarfile.TarFile.makefile = safe_makefile
+
+
def create_chunk(rootdir, f, regexps, dump_memory_profile=None):
'''Create a chunk from the contents of a directory.
@@ -187,11 +202,12 @@ def unpack_binary_from_file(f, dirname): # pragma: no cover
tf.makedev = monkey_patcher(tf.makedev)
tf.makelink = monkey_patcher(tf.makelink)
- tf.extractall(path=dirname)
- tf.close
+ try:
+ tf.extractall(path=dirname)
+ finally:
+ tf.close()
def unpack_binary(filename, dirname):
- f = open(filename, "rb")
- unpack_binary_from_file(f, dirname)
- f.close()
+ with open(filename, "rb") as f:
+ unpack_binary_from_file(f, dirname)