- Merge branch 'master' into sha-lom
- Extract out the tar handling from streamlayerformat into tarlayerformat - Add a new tarfileappender class to make it easy to append data to gzipped tars - Fix the gzipwrap to properly close - Have the .git injection use the new appender
This commit is contained in:
		
						commit
						d43109d7cb
					
				
					 48 changed files with 1232 additions and 532 deletions
				
			
		
							
								
								
									
										52
									
								
								util/tarfileappender.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								util/tarfileappender.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,52 @@ | |||
| import tarfile | ||||
| 
 | ||||
| from cStringIO import StringIO | ||||
| 
 | ||||
| from util.tarlayerformat import TarLayerFormat | ||||
| from util.gzipwrap import GzipWrap | ||||
| 
 | ||||
| class TarfileAppender(TarLayerFormat): | ||||
|   """ Helper class which allows for appending entries to a gzipped-tarfile and doing so | ||||
|       in a streaming manner. | ||||
|   """ | ||||
|   def __init__(self, base_tar_file, entries): | ||||
|     super(TarfileAppender, self).__init__(self._get_tar_iterator)     | ||||
|     self.entries = entries | ||||
|     self.base_tar_file = base_tar_file | ||||
|     self.last_info = None | ||||
| 
 | ||||
|   def get_stream(self): | ||||
|     return GzipWrap(self.get_generator()) | ||||
| 
 | ||||
|   def after_tar_layer(stream, current_layer): | ||||
|     pass | ||||
|        | ||||
|   def check_tar_info(self, tar_info): | ||||
|     self.last_info = tar_info | ||||
|     return True | ||||
| 
 | ||||
|   def _get_tar_iterator(self): | ||||
|     # Yield the contents of the base tar. | ||||
|     yield self.base_tar_file | ||||
| 
 | ||||
|     # Construct an in-memory tar containing the entries to append, and then yield | ||||
|     # its data. | ||||
|     def add_entry(arch, dir_path, contents=None): | ||||
|       info = tarfile.TarInfo(dir_path) | ||||
|       info.uid = self.last_info.uid | ||||
|       info.gid = self.last_info.gid | ||||
|       info.type = tarfile.REGTYPE if contents else tarfile.DIRTYPE | ||||
| 
 | ||||
|       if contents: | ||||
|         info.size = len(contents) | ||||
| 
 | ||||
|       arch.addfile(info, fileobj=StringIO(contents) if contents else None) | ||||
| 
 | ||||
|     append_tarball = StringIO() | ||||
|     with tarfile.open(fileobj=append_tarball, mode='w') as updated_archive: | ||||
|       for entry in self.entries: | ||||
|         add_entry(updated_archive, entry, self.entries[entry]) | ||||
| 
 | ||||
|     # To make tarfile happy. | ||||
|     append_tarball.seek(0) | ||||
|     yield append_tarball | ||||
		Reference in a new issue