summaryrefslogtreecommitdiff
path: root/morphlib/bins.py
diff options
context:
space:
mode:
Diffstat (limited to 'morphlib/bins.py')
-rw-r--r--morphlib/bins.py59
1 files changed, 26 insertions, 33 deletions
diff --git a/morphlib/bins.py b/morphlib/bins.py
index c5bacc26..2e8ba0b3 100644
--- a/morphlib/bins.py
+++ b/morphlib/bins.py
@@ -78,8 +78,12 @@ if sys.version_info < (2, 7, 3): # pragma: no cover
raise ExtractError("could not change owner")
tarfile.TarFile.chown = fixed_chown
-def create_chunk(rootdir, chunkdir, include, dump_memory_profile=None):
- '''Create a chunk from the contents of a directory.'''
+def create_chunk(rootdir, f, include, dump_memory_profile=None):
+ '''Create a chunk from the contents of a directory.
+
+ ``f`` is an open file handle, to which the tar file is written.
+
+ '''
dump_memory_profile = dump_memory_profile or (lambda msg: None)
@@ -87,42 +91,31 @@ def create_chunk(rootdir, chunkdir, include, dump_memory_profile=None):
# chunk artifact. This is useful to avoid problems from smallish
# clock skew. It needs to be recent enough, however, that GNU tar
# does not complain about an implausibly old timestamp.
- normalized_timestamp = (683074800, 683074800)
+ normalized_timestamp = 683074800
dump_memory_profile('at beginning of create_chunk')
-
- def check_parent(name, paths):
- parent = os.path.dirname(name)
- if parent:
- path = os.path.join(rootdir, parent)
- if parent != rootdir and path not in paths:
- paths.append(path)
- check_parent(parent, paths)
-
- def filter_contents(dirname, filenames):
- paths = [os.path.join(rootdir, relname) for relname in include]
- for name in include:
- check_parent(name, paths)
-
- return [f for f in filenames if os.path.join(dirname, f) not in paths]
-
- logging.debug('Copying artifact into %s.' % chunkdir)
- shutil.copytree(rootdir, chunkdir,
- symlinks=True, ignore=filter_contents)
-
- path_triplets = [(relname, os.path.join(chunkdir, relname),
- os.path.join(rootdir, relname))
- for relname in include]
- for relname, filename, orig in path_triplets:
+
+ path_pairs = [(relname, os.path.join(rootdir, relname))
+ for relname in include]
+ tar = tarfile.open(fileobj=f, mode='w')
+ for relname, filename in path_pairs:
# Normalize mtime for everything.
- if not os.path.islink(filename):
- os.utime(filename, normalized_timestamp)
+ tarinfo = tar.gettarinfo(filename,
+ arcname=relname)
+ tarinfo.ctime = normalized_timestamp
+ tarinfo.mtime = normalized_timestamp
+ if tarinfo.isreg():
+ with open(filename, 'rb') as f:
+ tar.addfile(tarinfo, fileobj=f)
+ else:
+ tar.addfile(tarinfo)
+ tar.close()
- for relname, filename, orig in reversed(path_triplets):
- if os.path.isdir(orig) and not os.path.islink(orig):
+ for relname, filename in reversed(path_pairs):
+ if os.path.isdir(filename) and not os.path.islink(filename):
continue
else:
- os.remove(orig)
+ os.remove(filename)
dump_memory_profile('after removing in create_chunks')
@@ -216,7 +209,7 @@ def unpack_binary_from_file(f, dirname): # pragma: no cover
tf.close()
-def unpack_binary(filename, dirname): # pragma: no cover
+def unpack_binary(filename, dirname):
with open(filename, "rb") as f:
unpack_binary_from_file(f, dirname)