diff options
author | Adam Coldrick <adam.coldrick@codethink.co.uk> | 2015-03-24 14:16:54 +0000 |
---|---|---|
committer | Morph (on behalf of Adam Coldrick) <adam.coldrick@codethink.co.uk> | 2015-03-24 14:16:54 +0000 |
commit | aa047d1b4ea195c1a5a70568a2b75f958f47fa99 (patch) | |
tree | 92ad20301b38f56b0e27506e87d7f5a1dcc6bd0f /morphlib/bins.py | |
parent | d1e4fa3639540a51dbb71612bf41a45018f164ea (diff) | |
download | morph-aa047d1b4ea195c1a5a70568a2b75f958f47fa99.tar.gz |
Morph build 271da1e1d62c40748b586dc0345d0f7d
System branch: master
Diffstat (limited to 'morphlib/bins.py')
-rw-r--r-- | morphlib/bins.py | 59 |
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) |