Example #1
0
    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()
Example #3
0
 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()
Example #4
0
    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