示例#1
0
文件: backup.py 项目: audip/lunr
    def save(self, snapshot, backup_id, cinder):
        job_stats_path = self._stats_file(snapshot['origin'])
        logger.rename('lunr.storage.helper.backup.save')
        setproctitle("lunr-save: " + backup_id)
        size = snapshot['size'] / 1024 / 1024 / 1024

        try:
            op_start = time()
            worker = Worker(snapshot['origin'], conf=self.conf,
                            stats_path=job_stats_path)
        except exc.ClientException, e:
            if e.http_status != 404:
                raise
            op_start = time()
            conn = get_conn(self.conf)
            conn.put_container(snapshot['origin'])
            logger.warning("failed to retrieve manifest;"
                           " first time backup for this volume?")
            # TODO: write the block_size on the manifest at create?
            block_count, remainder = divmod(snapshot['size'], BLOCK_SIZE)
            if remainder:
                block_count += 1
            # initial backup is the only time the we need to worry about
            # creating a new manifest for the worker
            worker = Worker(snapshot['origin'], conf=self.conf,
                            manifest=Manifest.blank(block_count),
                            stats_path=job_stats_path)
示例#2
0
    def save(self, snapshot, backup_id, cinder):
        job_stats_path = self._stats_file(snapshot['origin'])
        logger.rename('lunr.storage.helper.backup.save')
        setproctitle("lunr-save: " + backup_id)
        size = snapshot['size'] / 1024 / 1024 / 1024

        try:
            op_start = time()
            worker = Worker(snapshot['origin'],
                            conf=self.conf,
                            stats_path=job_stats_path)
        except exc.ClientException, e:
            if e.http_status != 404:
                raise
            op_start = time()
            conn = get_conn(self.conf)
            conn.put_container(snapshot['origin'])
            logger.warning("failed to retrieve manifest;"
                           " first time backup for this volume?")
            # TODO: write the block_size on the manifest at create?
            block_count, remainder = divmod(snapshot['size'], BLOCK_SIZE)
            if remainder:
                block_count += 1
            # initial backup is the only time the we need to worry about
            # creating a new manifest for the worker
            worker = Worker(snapshot['origin'],
                            conf=self.conf,
                            manifest=Manifest.blank(block_count),
                            stats_path=job_stats_path)
示例#3
0
def app_factory(global_conf, **local_conf):
    """paste.deploy app factory for creating WSGI API server"""

    # Reload the paster config, since paster only passes us our config
    conf = LunrConfig.from_conf(global_conf['__file__'])
    # ensure global logger is named
    logger.rename(__name__)

    app = ApiWsgiApp(conf, urlmap)
    return app
示例#4
0
    def prune(self, volume, backup_id):
        logger.rename("lunr.storage.helper.backup.prune")
        setproctitle("lunr-prune: " + backup_id)

        try:
            op_start = time()
            worker = Worker(volume["id"], self.conf)
        except exc.ClientException, e:
            # If the manifest doesn't exist, We consider the backup deleted.
            # If anything else happens, we bail.
            if e.http_status != 404:
                raise
            logger.warning("No manifest found pruning volume: %s" % volume["id"])
            return
示例#5
0
    def prune(self, volume, backup_id):
        logger.rename('lunr.storage.helper.backup.prune')
        setproctitle("lunr-prune: " + backup_id)

        try:
            op_start = time()
            worker = Worker(volume['id'], self.conf)
        except exc.ClientException, e:
            # If the manifest doesn't exist, We consider the backup deleted.
            # If anything else happens, we bail.
            if e.http_status != 404:
                raise
            logger.warning('No manifest found pruning volume: %s' %
                           volume['id'])
            return
示例#6
0
 def audit(self, volume):
     logger.rename("lunr.storage.helper.backup.audit")
     setproctitle("lunr-audit: " + volume["id"])
     try:
         op_start = time()
         worker = Worker(volume["id"], self.conf)
     except exc.ClientException, e:
         if e.http_status != 404:
             raise
         op_start = time()
         conn = get_conn(self.conf)
         conn.put_container(volume["id"])
         logger.warning("failed to retrieve manifest;" " auditing volume with no backups")
         # creating a blank manifest for the worker
         worker = Worker(volume["id"], conf=self.conf, manifest=Manifest.blank(0))
示例#7
0
 def remove_lvm_snapshot(self, snapshot):
     try:
         op_start = time()
         volume = self.get(snapshot['origin'])
         logger.rename('lunr.storage.helper.volume.remove_lvm_snapshot')
         self.scrub.scrub_snapshot(snapshot, volume)
         self.remove(snapshot['path'])
         # TODO: Failure to scrub a snapshot is un-acceptable
         # If we catch an exception, we should mark the snapshot
         # Or make this as recoverable as possible
         duration = time() - op_start
         logger.info("STAT: remove_lvm_snapshot(%r) Time: %r" %
                     (volume['path'], duration))
     except Scrub, e:
         logger.exception(
             "scrub snapshot failed with '%r' after %r seconds" %
             (e, time() - op_start))
示例#8
0
 def audit(self, volume):
     logger.rename('lunr.storage.helper.backup.audit')
     setproctitle("lunr-audit: " + volume['id'])
     try:
         op_start = time()
         worker = Worker(volume['id'], self.conf)
     except exc.ClientException, e:
         if e.http_status != 404:
             raise
         op_start = time()
         conn = get_conn(self.conf)
         conn.put_container(volume['id'])
         logger.warning("failed to retrieve manifest;"
                        " auditing volume with no backups")
         # creating a blank manifest for the worker
         worker = Worker(volume['id'],
                         conf=self.conf,
                         manifest=Manifest.blank(0))
示例#9
0
 def remove_lvm_snapshot(self, snapshot):
     try:
         op_start = time()
         volume = self.get(snapshot['origin'])
         logger.rename('lunr.storage.helper.volume.remove_lvm_snapshot')
         self.scrub.scrub_snapshot(snapshot, volume)
         self.remove(snapshot['path'])
         # TODO: Failure to scrub a snapshot is un-acceptable
         # If we catch an exception, we should mark the snapshot
         # Or make this as recoverable as possible
         duration = time() - op_start
         logger.info("STAT: remove_lvm_snapshot(%r) Time: %r" %
                     (volume['path'],
                      duration))
     except Scrub, e:
         logger.exception(
             "scrub snapshot failed with '%r' after %r seconds" %
             (e, time() - op_start))
示例#10
0
 def restore(self, dest_volume, backup_source_volume_id,
             backup_id, size, cinder):
     op_start = time()
     logger.rename('lunr.storage.helper.volume.restore')
     setproctitle("lunr-restore: " + dest_volume['id'])
     job_stats_path = self._stats_file(dest_volume['id'])
     worker = Worker(backup_source_volume_id, conf=self.conf,
                     stats_path=job_stats_path)
     try:
         worker.restore(backup_id, dest_volume['path'],
                        dest_volume['id'], cinder)
     finally:
         os.unlink(job_stats_path)
     self.update_tags(dest_volume, {})
     duration = time() - op_start
     logger.info('STAT: Restore %r from %r. '
                 'Size: %r GB Time: %r s Speed: %r MB/s' %
                 (dest_volume['id'], backup_id, size, duration,
                  size * 1024 / duration))
示例#11
0
 def restore(self, dest_volume, backup_source_volume_id,
             backup_id, size, cinder):
     op_start = time()
     logger.rename('lunr.storage.helper.volume.restore')
     setproctitle("lunr-restore: " + dest_volume['id'])
     job_stats_path = self._stats_file(dest_volume['id'])
     worker = Worker(backup_source_volume_id, conf=self.conf,
                     stats_path=job_stats_path)
     try:
         worker.restore(backup_id, dest_volume['path'],
                        dest_volume['id'], cinder)
     finally:
         os.unlink(job_stats_path)
     self.update_tags(dest_volume, {})
     duration = time() - op_start
     logger.info('STAT: Restore %r from %r. '
                 'Size: %r GB Time: %r s Speed: %r MB/s' %
                 (dest_volume['id'], backup_id, size, duration,
                  size * 1024 / duration))
示例#12
0
 def remove_lvm_volume(self, volume):
     try:
         op_start = time()
         size = volume['size'] / 1024 / 1024 / 1024
         logger.rename('lunr.storage.helper.volume.remove_lvm_volume')
         setproctitle("lunr-remove: " + volume['id'])
         # Scrub the volume
         self.scrub.scrub_volume(volume['path'])
         # Remove the device
         self.remove(volume['path'])
         duration = time() - op_start
         logger.info('STAT: remove_lvm_volume(%r) '
                     'Size: %r GB Time: %r s Speed: %r MB/s' %
                     (volume['path'],
                      size, duration,  size * 1024 / duration))
     except ProcessError, e:
         logger.exception(
             "delete volume failed with '%r' after %r seconds" %
             (e, time() - op_start))
示例#13
0
    def copy_image(self, volume, image, glance, tmp_vol, scrub_callback):
        logger.rename('lunr.storage.helper.volume.copy_image')
        setproctitle("lunr-copy-image: " + volume['id'])
        copy_image_start = time()
        convert_dir = None
        try:
            if image.disk_format == 'raw':
                self.write_raw_image(glance, image, volume['path'])
                return

            convert_dir = self.prepare_tmp_vol(tmp_vol)

            if not os.path.exists(convert_dir):
                raise ValueError("Convert dir doesn't exist!")

            try:
                path = mkdtemp(dir=convert_dir)
                logger.info("Image convert tmp dir: %s" % path)
                image_file = os.path.join(path, 'image')
                self.write_raw_image(glance, image, image_file)

                if (image.disk_format == 'vhd' and
                        image.container_format == 'ovf'):
                    self.untar_image(path, image)
                    image_file = self.get_coalesced_vhd(path)

                op_start = time()
                out = execute('qemu-img', 'convert', '-O', 'raw', image_file,
                              volume['path'])
                duration = time() - op_start
                mbytes = os.path.getsize(image_file) / 1024 / 1024
                logger.info('STAT: image convert %r. Image Size: %r MB '
                            'Time: %r Speed: %r' %
                            (image.id, mbytes, duration, mbytes / duration))
            except Exception, e:
                logger.exception("Exception in image conversion")
                raise

        except Exception, e:
            # We have to clean this up no matter what happened.
            # Delete volume syncronously. Clean up db in callback.
            logger.exception('Unhandled exception in copy_image')
            self.remove_lvm_volume(volume)
示例#14
0
 def remove_lvm_volume(self, volume):
     try:
         op_start = time()
         size = volume['size'] / 1024 / 1024 / 1024
         logger.rename('lunr.storage.helper.volume.remove_lvm_volume')
         setproctitle("lunr-remove: " + volume['id'])
         # Scrub the volume
         self.scrub.scrub_volume(volume['path'])
         # Remove the device
         self.remove(volume['path'])
         duration = time() - op_start
         logger.info(
             'STAT: remove_lvm_volume(%r) '
             'Size: %r GB Time: %r s Speed: %r MB/s' %
             (volume['path'], size, duration, size * 1024 / duration))
     except ProcessError, e:
         logger.exception(
             "delete volume failed with '%r' after %r seconds" %
             (e, time() - op_start))
示例#15
0
    def copy_image(self, volume, image, glance, tmp_vol, scrub_callback):
        logger.rename('lunr.storage.helper.volume.copy_image')
        setproctitle("lunr-copy-image: " + volume['id'])
        copy_image_start = time()
        convert_dir = None
        try:
            if image.disk_format == 'raw':
                self.write_raw_image(glance, image, volume['path'])
                return

            convert_dir = self.prepare_tmp_vol(tmp_vol)

            if not os.path.exists(convert_dir):
                raise ValueError("Convert dir doesn't exist!")

            try:
                path = mkdtemp(dir=convert_dir)
                logger.info("Image convert tmp dir: %s" % path)
                image_file = os.path.join(path, 'image')
                self.write_raw_image(glance, image, image_file)

                if (image.disk_format == 'vhd'
                        and image.container_format == 'ovf'):
                    self.untar_image(path, image)
                    image_file = self.get_coalesced_vhd(path)

                op_start = time()
                out = execute('qemu-img', 'convert', '-O', 'raw', image_file,
                              volume['path'])
                duration = time() - op_start
                mbytes = os.path.getsize(image_file) / 1024 / 1024
                logger.info('STAT: image convert %r. Image Size: %r MB '
                            'Time: %r Speed: %r' %
                            (image.id, mbytes, duration, mbytes / duration))
            except Exception, e:
                logger.exception("Exception in image conversion")
                raise

        except Exception, e:
            # We have to clean this up no matter what happened.
            # Delete volume syncronously. Clean up db in callback.
            logger.exception('Unhandled exception in copy_image')
            self.remove_lvm_volume(volume)
示例#16
0
def app_factory(global_conf, **local_conf):
    """paste.deploy app factory for creating WSGI API server"""

    # Reload the paster config, since paster only passes us our config
    conf = LunrConfig.from_conf(global_conf['__file__'])

    # ensure global logger is named
    logger.rename(__name__)

    app = StorageWsgiApp(conf, urlmap)

    # Check for a valid volume config
    app.helper.volumes.check_config()

    try:
        app.helper.check_registration()
    except Exception:
        logger.exception('Registration failed')

    volumes = app.helper.volumes.list()
    app.helper.cgroups.load_initial_cgroups(volumes)
    app.helper.exports.init_initiator_allows()
    return app
示例#17
0
            if e.errcode != 5 or 'already exists' not in e.err:
                raise
            raise AlreadyExists("snapshot id '%s' already in use" % id)

    def _copy_clone(self, snapshot, clone_id, size, iscsi_device, cinder=None):
        def progress_callback(percent):
            try:
                if cinder:
                    cinder.update_volume_metadata(
                        clone_id, {'clone-progress': "%.2f%%" % percent})
            except CinderError, e:
                logger.warning(
                    "Error updating clone-progress metadata: %s" % e)

        op_start = time()
        logger.rename('lunr.storage.helper.volume._copy_clone')
        setproctitle("lunr-clone: %s %s" % (snapshot['origin'], clone_id))
        try:
            iscsi_device.copy_file_out(snapshot['path'],
                                       callback=progress_callback)
        except (ISCSINotConnected, ISCSICopyFailed), e:
            logger.error("copy_file_out failed: %s" % str(e))
            raise
        try:
            iscsi_device.disconnect()
        except ISCSILogoutFailed:
            raise ServiceUnavailable("Unable to disconnect")
        duration = time() - op_start
        logger.info('STAT: Clone %r to %r. '
                    'Size: %r GB Time: %r s Speed: %r MB/s' %
                    (snapshot['origin'], clone_id, size, duration,
示例#18
0
            if e.errcode != 5 or 'already exists' not in e.err:
                raise
            raise AlreadyExists("snapshot id '%s' already in use" % id)

    def _copy_clone(self, snapshot, clone_id, size, iscsi_device, cinder=None):
        def progress_callback(percent):
            try:
                if cinder:
                    cinder.update_volume_metadata(
                        clone_id, {'clone-progress': "%.2f%%" % percent})
            except CinderError, e:
                logger.warning("Error updating clone-progress metadata: %s" %
                               e)

        op_start = time()
        logger.rename('lunr.storage.helper.volume._copy_clone')
        setproctitle("lunr-clone: %s %s" % (snapshot['origin'], clone_id))
        try:
            iscsi_device.copy_file_out(snapshot['path'],
                                       callback=progress_callback)
        except (ISCSINotConnected, ISCSICopyFailed), e:
            logger.error("copy_file_out failed: %s" % str(e))
            raise
        try:
            iscsi_device.disconnect()
        except ISCSILogoutFailed:
            raise ServiceUnavailable("Unable to disconnect")
        duration = time() - op_start
        logger.info('STAT: Clone %r to %r. '
                    'Size: %r GB Time: %r s Speed: %r MB/s' %
                    (snapshot['origin'], clone_id, size, duration,