Exemplo n.º 1
0
    def create_snapshot(self, context, volume_id, snapshot_id):
        """Creates and exports the snapshot."""
        context = context.elevated()
        snapshot_ref = self.db.snapshot_get(context, snapshot_id)
        LOG.info(_("snapshot %s: creating"), snapshot_ref['name'])

        try:
            snap_name = snapshot_ref['name']
            LOG.debug(_("snapshot %(snap_name)s: creating") % locals())
            model_update = self.driver.create_snapshot(snapshot_ref)
            if model_update:
                self.db.snapshot_update(context, snapshot_ref['id'],
                                        model_update)

        except Exception:
            with utils.save_and_reraise_exception():
                self.db.snapshot_update(context,
                                        snapshot_ref['id'],
                                        {'status': 'error'})

        self.db.snapshot_update(context,
                                snapshot_ref['id'], {'status': 'available',
                                                     'progress': '100%'})
        LOG.debug(_("snapshot %s: created successfully"), snapshot_ref['name'])
        return snapshot_id
Exemplo n.º 2
0
    def create_snapshot(self, context, volume_id, snapshot_id):
        """Creates and exports the snapshot."""
        context = context.elevated()
        snapshot_ref = self.db.snapshot_get(context, snapshot_id)
        LOG.info(_("snapshot %s: creating"), snapshot_ref['name'])

        try:
            snap_name = snapshot_ref['name']
            LOG.debug(_("snapshot %(snap_name)s: creating") % locals())
            model_update = self.driver.create_snapshot(snapshot_ref)
            if model_update:
                self.db.snapshot_update(context, snapshot_ref['id'],
                                        model_update)

        except Exception:
            with utils.save_and_reraise_exception():
                self.db.snapshot_update(context,
                                        snapshot_ref['id'],
                                        {'status': 'error'})

        self.db.snapshot_update(context,
                                snapshot_ref['id'], {'status': 'available',
                                                     'progress': '100%'})
        LOG.debug(_("snapshot %s: created successfully"), snapshot_ref['name'])
        return snapshot_id
Exemplo n.º 3
0
class SchedulerManager(manager.Manager):
    """Chooses a host to run instances on."""
    def __init__(self, scheduler_driver=None, *args, **kwargs):
        if not scheduler_driver:
            scheduler_driver = FLAGS.scheduler_driver
        self.driver = utils.import_object(scheduler_driver)
        super(SchedulerManager, self).__init__(*args, **kwargs)

    def __getattr__(self, key):
        """Converts all method calls to use the schedule method"""
        return functools.partial(self._schedule, key)

    def get_host_list(self, context):
        """Get a list of hosts from the HostManager."""
        return self.driver.get_host_list()

    def get_service_capabilities(self, context):
        """Get the normalized set of capabilities for this zone."""
        return self.driver.get_service_capabilities()

    def update_service_capabilities(self,
                                    context,
                                    service_name=None,
                                    host=None,
                                    capabilities=None,
                                    **kwargs):
        """Process a capability update from a service node."""
        if capabilities is None:
            capabilities = {}
        self.driver.update_service_capabilities(service_name, host,
                                                capabilities)

    def _schedule(self, method, context, topic, *args, **kwargs):
        """Tries to call schedule_* method on the driver to retrieve host.

        Falls back to schedule(context, topic) if method doesn't exist.
        """
        driver_method = 'schedule_%s' % method
        try:
            real_meth = getattr(self.driver, driver_method)
            args = (context, ) + args
        except AttributeError, e:
            LOG.warning(
                _("Driver Method %(driver_method)s missing: %(e)s."
                  "Reverting to schedule()") % locals())
            real_meth = self.driver.schedule
            args = (context, topic, method) + args

        # Scheduler methods are responsible for casting.
        try:
            return real_meth(*args, **kwargs)
        except exception.NoValidHost as ex:
            self._set_instance_error(method, context, ex, *args, **kwargs)
        except Exception as ex:
            with utils.save_and_reraise_exception():
                self._set_instance_error(method, context, ex, *args, **kwargs)
Exemplo n.º 4
0
    def delete_snapshot(self, context, snapshot_id):
        """Deletes and unexports snapshot."""
        context = context.elevated()
        snapshot_ref = self.db.snapshot_get(context, snapshot_id)

        try:
            LOG.debug(_("snapshot %s: deleting"), snapshot_ref["name"])
            self.driver.delete_snapshot(snapshot_ref)
        except Exception:
            with utils.save_and_reraise_exception():
                self.db.snapshot_update(context, snapshot_ref["id"], {"status": "error_deleting"})

        self.db.snapshot_destroy(context, snapshot_id)
        LOG.debug(_("snapshot %s: deleted successfully"), snapshot_ref["name"])
        return True
Exemplo n.º 5
0
    def delete_snapshot(self, context, snapshot_id):
        """Deletes and unexports snapshot."""
        context = context.elevated()
        snapshot_ref = self.db.snapshot_get(context, snapshot_id)

        try:
            LOG.debug(_("snapshot %s: deleting"), snapshot_ref['name'])
            self.driver.delete_snapshot(snapshot_ref)
        except Exception:
            with utils.save_and_reraise_exception():
                self.db.snapshot_update(context, snapshot_ref['id'],
                                        {'status': 'error_deleting'})

        self.db.snapshot_destroy(context, snapshot_id)
        LOG.debug(_("snapshot %s: deleted successfully"), snapshot_ref['name'])
        return True
 def run_instance(self, context, topic, *args, **kwargs):
     """Tries to call schedule_run_instance on the driver.
     Sets instance vm_state to ERROR on exceptions
     """
     args = (context,) + args
     try:
         return self.driver.schedule_run_instance(*args, **kwargs)
     except exception.NoValidHost as ex:
         # don't reraise
         self._set_vm_state_and_notify('run_instance',
                                      {'vm_state': vm_states.ERROR},
                                       context, ex, *args, **kwargs)
     except Exception as ex:
         with utils.save_and_reraise_exception():
             self._set_vm_state_and_notify('run_instance',
                                          {'vm_state': vm_states.ERROR},
                                          context, ex, *args, **kwargs)
Exemplo n.º 7
0
    def create_volume(self, context, volume_id, snapshot_id=None):
        """Creates and exports the volume."""
        context = context.elevated()
        volume_ref = self.db.volume_get(context, volume_id)
        LOG.info(_("volume %s: creating"), volume_ref['name'])

        self.db.volume_update(context,
                              volume_id,
                              {'host': self.host})
        # NOTE(vish): so we don't have to get volume from db again
        #             before passing it to the driver.
        volume_ref['host'] = self.host

        try:
            vol_name = volume_ref['name']
            vol_size = volume_ref['size']
            LOG.debug(_("volume %(vol_name)s: creating lv of"
                    " size %(vol_size)sG") % locals())
            if snapshot_id is None:
                model_update = self.driver.create_volume(volume_ref)
            else:
                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
                model_update = self.driver.create_volume_from_snapshot(
                    volume_ref,
                    snapshot_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)

            LOG.debug(_("volume %s: creating export"), volume_ref['name'])
            model_update = self.driver.create_export(context, volume_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)
        except Exception:
            with utils.save_and_reraise_exception():
                self.db.volume_update(context,
                                      volume_ref['id'], {'status': 'error'})
                self._notify_vsa(context, volume_ref, 'error')

        now = utils.utcnow()
        self.db.volume_update(context,
                              volume_ref['id'], {'status': 'available',
                                                 'launched_at': now})
        LOG.debug(_("volume %s: created successfully"), volume_ref['name'])
        self._notify_vsa(context, volume_ref, 'available')
        self._reset_stats()
        return volume_id
Exemplo n.º 8
0
 def run_instance(self, context, topic, *args, **kwargs):
     """Tries to call schedule_run_instance on the driver.
     Sets instance vm_state to ERROR on exceptions
     """
     args = (context, ) + args
     try:
         return self.driver.schedule_run_instance(*args, **kwargs)
     except exception.NoValidHost as ex:
         # don't reraise
         self._set_vm_state_and_notify('run_instance',
                                       {'vm_state': vm_states.ERROR},
                                       context, ex, *args, **kwargs)
     except Exception as ex:
         with utils.save_and_reraise_exception():
             self._set_vm_state_and_notify('run_instance',
                                           {'vm_state': vm_states.ERROR},
                                           context, ex, *args, **kwargs)
Exemplo n.º 9
0
    def create_volume(self, context, volume_id, snapshot_id=None):
        """Creates and exports the volume."""
        context = context.elevated()
        volume_ref = self.db.volume_get(context, volume_id)
        LOG.info(_("volume %s: creating"), volume_ref['name'])

        self.db.volume_update(context,
                              volume_id,
                              {'host': self.host})
        # NOTE(vish): so we don't have to get volume from db again
        #             before passing it to the driver.
        volume_ref['host'] = self.host

        try:
            vol_name = volume_ref['name']
            vol_size = volume_ref['size']
            LOG.debug(_("volume %(vol_name)s: creating lv of"
                    " size %(vol_size)sG") % locals())
            if snapshot_id is None:
                model_update = self.driver.create_volume(volume_ref)
            else:
                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
                model_update = self.driver.create_volume_from_snapshot(
                    volume_ref,
                    snapshot_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)

            LOG.debug(_("volume %s: creating export"), volume_ref['name'])
            model_update = self.driver.create_export(context, volume_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)
        except Exception:
            with utils.save_and_reraise_exception():
                self.db.volume_update(context,
                                      volume_ref['id'], {'status': 'error'})
                self._notify_vsa(context, volume_ref, 'error')

        now = utils.utcnow()
        self.db.volume_update(context,
                              volume_ref['id'], {'status': 'available',
                                                 'launched_at': now})
        LOG.debug(_("volume %s: created successfully"), volume_ref['name'])
        self._notify_vsa(context, volume_ref, 'available')
        self._reset_stats()
        return volume_id
Exemplo n.º 10
0
def fetch(context, image_href, path, _user_id, _project_id):
    # TODO(vish): Improve context handling and add owner and auth data
    #             when it is added to glance.  Right now there is no
    #             auth checking in glance, so we assume that access was
    #             checked before we got here.
    (image_service,
     image_id) = nova.image.get_image_service(context, image_href)
    try:
        with open(path, "wb") as image_file:
            metadata = image_service.get(context, image_id, image_file)
    except Exception:
        with utils.save_and_reraise_exception():
            try:
                os.unlink(path)
            except OSError, e:
                if e.errno != errno.ENOENT:
                    LOG.warn("unable to remove stale image '%s': %s" %
                             (path, e.strerror))
Exemplo n.º 11
0
def fetch(context, image_href, path, _user_id, _project_id):
    # TODO(vish): Improve context handling and add owner and auth data
    #             when it is added to glance.  Right now there is no
    #             auth checking in glance, so we assume that access was
    #             checked before we got here.
    (image_service, image_id) = nova.image.get_image_service(context,
                                                             image_href)
    try:
        with open(path, "wb") as image_file:
            metadata = image_service.get(context, image_id, image_file)
    except Exception:
        with utils.save_and_reraise_exception():
            try:
                os.unlink(path)
            except OSError, e:
                if e.errno != errno.ENOENT:
                    LOG.warn("unable to remove stale image '%s': %s" %
                             (path, e.strerror))
Exemplo n.º 12
0
 def prep_resize(self, context, topic, *args, **kwargs):
     """Tries to call schedule_prep_resize on the driver.
     Sets instance vm_state to ACTIVE on NoHostFound
     Sets vm_state to ERROR on other exceptions
     """
     args = (context, ) + args
     try:
         return self.driver.schedule_prep_resize(*args, **kwargs)
     except exception.NoValidHost as ex:
         self._set_vm_state_and_notify('prep_resize', {
             'vm_state': vm_states.ACTIVE,
             'task_state': None
         }, context, ex, *args, **kwargs)
     except Exception as ex:
         with utils.save_and_reraise_exception():
             self._set_vm_state_and_notify('prep_resize',
                                           {'vm_state': vm_states.ERROR},
                                           context, ex, *args, **kwargs)
 def prep_resize(self, context, topic, *args, **kwargs):
     """Tries to call schedule_prep_resize on the driver.
     Sets instance vm_state to ACTIVE on NoHostFound
     Sets vm_state to ERROR on other exceptions
     """
     args = (context,) + args
     try:
         return self.driver.schedule_prep_resize(*args, **kwargs)
     except exception.NoValidHost as ex:
         self._set_vm_state_and_notify('prep_resize',
                                      {'vm_state': vm_states.ACTIVE,
                                       'task_state': None},
                                      context, ex, *args, **kwargs)
     except Exception as ex:
         with utils.save_and_reraise_exception():
             self._set_vm_state_and_notify('prep_resize',
                                          {'vm_state': vm_states.ERROR},
                                          context, ex, *args, **kwargs)
Exemplo n.º 14
0
 def __iter__(self):
     """Return a result until we get a 'None' response from consumer"""
     if self._done:
         raise StopIteration
     while True:
         try:
             self._iterator.next()
         except Exception:
             with utils.save_and_reraise_exception():
                 self.done()
         if self._got_ending:
             self.done()
             raise StopIteration
         result = self._result
         if isinstance(result, Exception):
             self.done()
             raise result
         yield result
 def __iter__(self):
     """Return a result until we get a 'None' response from consumer"""
     if self._done:
         raise StopIteration
     while True:
         try:
             self._iterator.next()
         except Exception:
             with utils.save_and_reraise_exception():
                 self.done()
         if self._got_ending:
             self.done()
             raise StopIteration
         result = self._result
         if isinstance(result, Exception):
             self.done()
             raise result
         yield result
Exemplo n.º 16
0
    def delete_snapshot(self, context, snapshot_id):
        """Deletes and unexports snapshot."""
        context = context.elevated()
        snapshot_ref = self.db.snapshot_get(context, snapshot_id)

        try:
            LOG.debug(_("snapshot %s: deleting"), snapshot_ref['name'])
            self.driver.delete_snapshot(snapshot_ref)
        except exception.SnapshotIsBusy:
            LOG.debug(_("snapshot %s: snapshot is busy"), snapshot_ref['name'])
            self.db.snapshot_update(context,
                                    snapshot_ref['id'],
                                    {'status': 'available'})
            return True
        except Exception:
            with utils.save_and_reraise_exception():
                self.db.snapshot_update(context,
                                        snapshot_ref['id'],
                                        {'status': 'error_deleting'})

        self.db.snapshot_destroy(context, snapshot_id)
        LOG.debug(_("snapshot %s: deleted successfully"), snapshot_ref['name'])
        return True
Exemplo n.º 17
0
class VolumeManager(manager.SchedulerDependentManager):
    """Manages attachable block storage devices."""
    def __init__(self, volume_driver=None, *args, **kwargs):
        """Load the driver from the one specified in args, or from flags."""
        if not volume_driver:
            volume_driver = FLAGS.volume_driver
        self.driver = utils.import_object(volume_driver)
        super(VolumeManager, self).__init__(service_name='volume',
                                                    *args, **kwargs)
        # NOTE(vish): Implementation specific db handling is done
        #             by the driver.
        self.driver.db = self.db
        self._last_volume_stats = []

    def init_host(self):
        """Do any initialization that needs to be run if this is a
           standalone service."""

        ctxt = context.get_admin_context()
        self.driver.do_setup(ctxt)
        self.driver.check_for_setup_error()

        volumes = self.db.volume_get_all_by_host(ctxt, self.host)
        LOG.debug(_("Re-exporting %s volumes"), len(volumes))
        for volume in volumes:
            if volume['status'] in ['available', 'in-use']:
                self.driver.ensure_export(ctxt, volume)
            else:
                LOG.info(_("volume %s: skipping export"), volume['name'])

    def create_volume(self, context, volume_id, snapshot_id=None):
        """Creates and exports the volume."""
        context = context.elevated()
        volume_ref = self.db.volume_get(context, volume_id)
        LOG.info(_("volume %s: creating"), volume_ref['name'])

        self.db.volume_update(context,
                              volume_id,
                              {'host': self.host})
        # NOTE(vish): so we don't have to get volume from db again
        #             before passing it to the driver.
        volume_ref['host'] = self.host

        try:
            vol_name = volume_ref['name']
            vol_size = volume_ref['size']
            LOG.debug(_("volume %(vol_name)s: creating lv of"
                    " size %(vol_size)sG") % locals())
            if snapshot_id is None:
                model_update = self.driver.create_volume(volume_ref)
            else:
                snapshot_ref = self.db.snapshot_get(context, snapshot_id)
                model_update = self.driver.create_volume_from_snapshot(
                    volume_ref,
                    snapshot_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)

            LOG.debug(_("volume %s: creating export"), volume_ref['name'])
            model_update = self.driver.create_export(context, volume_ref)
            if model_update:
                self.db.volume_update(context, volume_ref['id'], model_update)
        except Exception:
            with utils.save_and_reraise_exception():
                self.db.volume_update(context,
                                      volume_ref['id'], {'status': 'error'})
                self._notify_vsa(context, volume_ref, 'error')

        now = utils.utcnow()
        self.db.volume_update(context,
                              volume_ref['id'], {'status': 'available',
                                                 'launched_at': now})
        LOG.debug(_("volume %s: created successfully"), volume_ref['name'])
        self._notify_vsa(context, volume_ref, 'available')
        self._reset_stats()
        return volume_id

    def _notify_vsa(self, context, volume_ref, status):
        if volume_ref['volume_type_id'] is None:
            return

        if volume_types.is_vsa_drive(volume_ref['volume_type_id']):
            vsa_id = None
            for i in volume_ref.get('volume_metadata'):
                if i['key'] == 'to_vsa_id':
                    vsa_id = int(i['value'])
                    break

            if vsa_id:
                rpc.cast(context,
                         FLAGS.vsa_topic,
                         {"method": "vsa_volume_created",
                          "args": {"vol_id": volume_ref['id'],
                                   "vsa_id": vsa_id,
                                   "status": status}})

    def delete_volume(self, context, volume_id):
        """Deletes and unexports volume."""
        context = context.elevated()
        volume_ref = self.db.volume_get(context, volume_id)
        if volume_ref['attach_status'] == "attached":
            raise exception.Error(_("Volume is still attached"))
        if volume_ref['host'] != self.host:
            raise exception.Error(_("Volume is not local to this node"))

        self._reset_stats()
        try:
            LOG.debug(_("volume %s: removing export"), volume_ref['name'])
            self.driver.remove_export(context, volume_ref)
            LOG.debug(_("volume %s: deleting"), volume_ref['name'])
            self.driver.delete_volume(volume_ref)
        except exception.VolumeIsBusy, e:
            LOG.debug(_("volume %s: volume is busy"), volume_ref['name'])
            self.driver.ensure_export(context, volume_ref)
            self.db.volume_update(context, volume_ref['id'],
                                  {'status': 'available'})
            return True
        except Exception:
            with utils.save_and_reraise_exception():
                self.db.volume_update(context,
                                      volume_ref['id'],
                                      {'status': 'error_deleting'})