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
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)
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 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)
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 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)
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))
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)
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 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
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'})