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
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
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 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 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
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'})
class SchedulerManager(manager.Manager): """Chooses a host to run instances on.""" def __init__(self, scheduler_driver=None, *args, **kwargs): self.zone_manager = zone_manager.ZoneManager() if not scheduler_driver: scheduler_driver = FLAGS.scheduler_driver self.driver = utils.import_object(scheduler_driver) self.driver.set_zone_manager(self.zone_manager) 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) @manager.periodic_task def _poll_child_zones(self, context): """Poll child zones periodically to get status.""" self.zone_manager.ping(context) def get_host_list(self, context=None): """Get a list of hosts from the ZoneManager.""" return self.zone_manager.get_host_list() def get_zone_list(self, context=None): """Get a list of zones from the ZoneManager.""" return self.zone_manager.get_zone_list() def get_zone_capabilities(self, context=None): """Get the normalized set of capabilities for this zone.""" return self.zone_manager.get_zone_capabilities(context) def update_service_capabilities(self, context=None, service_name=None, host=None, capabilities=None): """Process a capability update from a service node.""" if not capabilities: capabilities = {} self.zone_manager.update_service_capabilities(service_name, host, capabilities) def select(self, context=None, *args, **kwargs): """Select a list of hosts best matching the provided specs.""" return self.driver.select(context, *args, **kwargs) 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)