def main(self): manifest = BundleManifest.read_from_fileobj( self.args['manifest'], privkey_filename=self.args['privatekey']) for part in manifest.image_parts: part_path = os.path.join(self.args['source'], part.filename) while part_path.startswith('./'): part_path = part_path[2:] if os.path.exists(part_path): part.filename = part_path else: raise RuntimeError( "bundle part '{0}' does not exist; you may need to use " "-s to specify where to find the bundle's parts" .format(part_path)) part_reader_out_r, part_reader_out_w = open_pipe_fileobjs() part_reader = multiprocessing.Process( target=self.__read_bundle_parts, args=(manifest, part_reader_out_w)) part_reader.start() part_reader_out_w.close() waitpid_in_thread(part_reader.pid) image_filename = os.path.join(self.args['destination'], manifest.image_name) with open(image_filename, 'w') as image: unbundlestream = UnbundleStream.from_other( self, source=part_reader_out_r, dest=image, enc_key=manifest.enc_key, enc_iv=manifest.enc_iv, image_size=manifest.image_size, sha1_digest=manifest.image_digest, show_progress=self.args.get('show_progress', False)) unbundlestream.main() return image_filename
def __create_download_pipeline(self, outfile): downloadbundle = DownloadBundle.from_other( self, dest=outfile, bucket=self.args['bucket'], manifest=self.args.get('manifest'), local_manifest=self.args.get('local_manifest'), show_progress=False) downloadbundle_p = multiprocessing.Process(target=downloadbundle.main) downloadbundle_p.start() waitpid_in_thread(downloadbundle_p.pid) outfile.close()
def main(self): dest_dir = self.args.get('destination') manifest = self.args.get('manifest') #Setup the destination fileobj... if dest_dir == "-": #Write to stdout dest_file = os.fdopen(os.dup(os.sys.stdout.fileno()), 'w') dest_file_name = None else: #write to local file path... dest_file = open(dest_dir + "/" + manifest.image_name, 'w') dest_file_name = dest_file.name #check for avail space if the resulting image size is known if manifest: d_stat = os.statvfs(dest_file_name) avail_space = d_stat.f_frsize * d_stat.f_favail if manifest.image_size > avail_space: raise ValueError('Image size:{0} exceeds destination free ' 'space:{1}' .format(manifest.image_size, avail_space)) #setup progress bar... try: label = self.args.get('progressbar_label', 'UnBundling image') pbar = self.get_progressbar(label=label, maxval=manifest.image_size) except NameError: pbar = None try: #Start the unbundle... unbundle_r, unbundle_w = open_pipe_fileobjs() writer = spawn_process(self._concatenate_parts_to_file_for_pipe, outfile=unbundle_w, image_parts=manifest.image_parts, source_dir=self.args.get('source'), debug=self.args.get('debug')) unbundle_w.close() waitpid_in_thread(writer.pid) self.log.debug('Using enc key:' + str(manifest.enc_key)) self.log.debug('using enc iv:' + str(manifest.enc_iv)) digest = UnbundleStream(source=unbundle_r, destination=dest_file, enc_key=manifest.enc_key, enc_iv=manifest.enc_iv, progressbar=pbar, maxbytes=self.args.get('maxbytes'), config=self.config).main() digest = digest.strip() if dest_file: dest_file.close() #Verify the Checksum matches the manifest if digest != manifest.image_digest: raise ValueError('Digest mismatch. Extracted image appears ' 'to be corrupt (expected digest: {0}, ' 'actual: {1})' .format(manifest.image_digest, digest)) self.log.debug("\nExpected digest:{0}\n Actual digest:{1}" .format(str(manifest.image_digest), str(digest))) except KeyboardInterrupt: print 'Caught keyboard interrupt' if dest_file: os.remove(dest_file.name) return except Exception: traceback.print_exc() if dest_file: try: os.remove(dest_file.name) except OSError: print "Could not remove failed destination file." raise finally: dest_file.close() return dest_file_name