def delete_snapshot(self, context, snapshot_id): """Delete share snapshot.""" context = context.elevated() snapshot_ref = self.db.share_snapshot_get(context, snapshot_id) share_server = self._get_share_server(context, snapshot_ref['share']) if context.project_id != snapshot_ref['project_id']: project_id = snapshot_ref['project_id'] else: project_id = context.project_id try: self.driver.delete_snapshot(context, snapshot_ref, share_server=share_server) except exception.ShareSnapshotIsBusy: self.db.share_snapshot_update(context, snapshot_ref['id'], {'status': 'available'}) except Exception: with excutils.save_and_reraise_exception(): self.db.share_snapshot_update(context, snapshot_ref['id'], {'status': 'error_deleting'}) else: self.db.share_snapshot_destroy(context, snapshot_id) try: reservations = QUOTAS.reserve( context, project_id=project_id, snapshots=-1, snapshot_gigabytes=-snapshot_ref['size']) except Exception: reservations = None LOG.exception(_LE("Failed to update usages deleting snapshot")) if reservations: QUOTAS.commit(context, reservations, project_id=project_id)
def create_share(self, context, share_id, request_spec=None, filter_properties=None, snapshot_id=None): """Creates a share.""" context = context.elevated() if filter_properties is None: filter_properties = {} share_ref = self.db.share_get(context, share_id) if snapshot_id is not None: snapshot_ref = self.db.share_snapshot_get(context, snapshot_id) else: snapshot_ref = None try: if snapshot_ref: self.driver.allocate_container_from_snapshot(context, share_ref, snapshot_ref) else: self.driver.allocate_container(context, share_ref) export_location = self.driver.create_share(context, share_ref) self.db.share_update(context, share_id, {'export_location': export_location}) self.driver.create_export(context, share_ref) except Exception: with excutils.save_and_reraise_exception(): self.db.share_update(context, share_id, {'status': 'error'}) else: self.db.share_update(context, share_id, {'status': 'available', 'launched_at': timeutils.utcnow()})
def delete_share(self, context, share_id): """Delete a share.""" context = context.elevated() share_ref = self.db.share_get(context, share_id) if context.project_id != share_ref['project_id']: project_id = share_ref['project_id'] else: project_id = context.project_id rules = self.db.share_access_get_all_for_share(context, share_id) try: for access_ref in rules: self._deny_access(context, access_ref, share_ref) self.driver.delete_share(context, share_ref) except Exception: with excutils.save_and_reraise_exception(): self.db.share_update(context, share_id, {'status': 'error_deleting'}) try: reservations = QUOTAS.reserve(context, project_id=project_id, shares=-1, gigabytes=-share_ref['size']) except Exception: reservations = None LOG.exception(_("Failed to update usages deleting share")) self.db.share_delete(context, share_id) LOG.info(_("share %s: deleted successfully"), share_ref['name']) if reservations: QUOTAS.commit(context, reservations, project_id=project_id)
def delete_share_instance(self, context, share_instance_id): """Delete a share instance.""" context = context.elevated() share_instance = self._get_share_instance(context, share_instance_id) share = self.db.share_get(context, share_instance["share_id"]) share_server = self._get_share_server(context, share_instance) try: self._remove_share_access_rules(context, share, share_instance, share_server) self.driver.delete_share(context, share_instance, share_server=share_server) except Exception: with excutils.save_and_reraise_exception(): self.db.share_instance_update(context, share_instance_id, {"status": constants.STATUS_ERROR_DELETING}) self.db.share_instance_delete(context, share_instance_id) LOG.info(_LI("Share instance %s: deleted successfully."), share_instance_id) if CONF.delete_share_server_with_last_share: share_server = self._get_share_server(context, share_instance) if share_server and len(share_server.share_instances) == 0: LOG.debug( "Scheduled deletion of share-server " "with id '%s' automatically by " "deletion of last share.", share_server["id"], ) self.delete_share_server(context, share_server)
def extend_share(self, context, share_id, new_size, reservations): context = context.elevated() share = self.db.share_get(context, share_id) share_server = self._get_share_server(context, share) project_id = share['project_id'] try: self.driver.extend_share( share, new_size, share_server=share_server) except Exception as e: LOG.exception(_LE("Extend share failed."), resource=share) try: self.db.share_update( context, share['id'], {'status': constants.STATUS_EXTENDING_ERROR} ) raise exception.ShareExtendingError( reason=six.text_type(e), share_id=share_id) finally: QUOTAS.rollback(context, reservations, project_id=project_id) QUOTAS.commit(context, reservations, project_id=project_id) share_update = { 'size': int(new_size), # NOTE(u_glide): translation to lower case should be removed in # a row with usage of upper case of share statuses in all places 'status': constants.STATUS_AVAILABLE.lower() } share = self.db.share_update(context, share['id'], share_update) LOG.info(_LI("Extend share completed successfully."), resource=share)
def unmanage_share(self, context, share_id): context = context.elevated() share_ref = self.db.share_get(context, share_id) share_server = self._get_share_server(context, share_ref) project_id = share_ref['project_id'] def share_manage_set_error_status(msg, exception): status = {'status': constants.STATUS_UNMANAGE_ERROR} self.db.share_update(context, share_id, status) LOG.error(msg, six.text_type(exception)) try: if self.driver.driver_handles_share_servers: msg = _("Unmanage share is not supported for " "driver_handles_share_servers=True mode.") raise exception.InvalidShare(reason=msg) if share_server: msg = _("Unmanage share is not supported for " "shares with share servers.") raise exception.InvalidShare(reason=msg) self.driver.unmanage(share_ref) except exception.InvalidShare as e: share_manage_set_error_status( _LE("Share can not be unmanaged: %s."), e) return try: reservations = QUOTAS.reserve(context, project_id=project_id, shares=-1, gigabytes=-share_ref['size']) QUOTAS.commit(context, reservations, project_id=project_id) except Exception as e: # Note(imalinovskiy): # Quota reservation errors here are not fatal, because # unmanage is administrator API and he/she could update user # quota usages later if it's required. LOG.warning(_LE("Failed to update quota usages: %s."), six.text_type(e)) if self.configuration.safe_get('unmanage_remove_access_rules'): try: self._remove_share_access_rules(context, share_ref, share_server) except Exception as e: share_manage_set_error_status( _LE("Can not remove access rules of share: %s."), e) return self.db.share_update(context, share_id, {'status': constants.STATUS_UNMANAGED, 'deleted': True})
def shrink_share(self, context, share_id, new_size): context = context.elevated() share = self.db.share_get(context, share_id) share_server = self._get_share_server(context, share) project_id = share['project_id'] new_size = int(new_size) def error_occurred(exc, msg, status=constants.STATUS_SHRINKING_ERROR): LOG.exception(msg, resource=share) self.db.share_update(context, share['id'], {'status': status}) raise exception.ShareShrinkingError( reason=six.text_type(exc), share_id=share_id) reservations = None try: size_decrease = int(share['size']) - new_size reservations = QUOTAS.reserve(context, project_id=share['project_id'], gigabytes=-size_decrease) except Exception as e: error_occurred( e, _LE("Failed to update quota on share shrinking.")) try: self.driver.shrink_share( share, new_size, share_server=share_server) # NOTE(u_glide): Replace following except block by error notification # when Manila has such mechanism. It's possible because drivers # shouldn't shrink share when this validation error occurs. except Exception as e: if isinstance(e, exception.ShareShrinkingPossibleDataLoss): msg = _LE("Shrink share failed due to possible data loss.") status = constants.STATUS_SHRINKING_POSSIBLE_DATA_LOSS_ERROR error_params = {'msg': msg, 'status': status} else: error_params = {'msg': _LE("Shrink share failed.")} try: error_occurred(e, **error_params) finally: QUOTAS.rollback(context, reservations, project_id=project_id) QUOTAS.commit(context, reservations, project_id=project_id) share_update = { 'size': new_size, 'status': constants.STATUS_AVAILABLE } share = self.db.share_update(context, share['id'], share_update) LOG.info(_LI("Shrink share completed successfully."), resource=share)
def create_share(self, context, share_id, request_spec=None, filter_properties=None, snapshot_id=None): """Creates a share.""" context = context.elevated() if filter_properties is None: filter_properties = {} share_ref = self.db.share_get(context, share_id) if snapshot_id is not None: snapshot_ref = self.db.share_snapshot_get(context, snapshot_id) else: snapshot_ref = None share_network_id = share_ref.get('share_network_id', None) if share_network_id: try: share_server = self._share_server_get_or_create( context, share_network_id) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_("Failed to get share server" " for share creation.")) self.db.share_update(context, share_id, {'status': 'error'}) share_ref = self.db.share_update( context, share_id, {'share_server_id': share_server['id']}) LOG.debug("Using share server %s" % share_server['id']) else: share_server = None try: if snapshot_ref: export_location = self.driver.create_share_from_snapshot( context, share_ref, snapshot_ref) else: export_location = self.driver.create_share( context, share_ref, share_server=share_server) self.db.share_update(context, share_id, {'export_location': export_location}) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_("Share %s failed on creation.") % share_id) self.db.share_update(context, share_id, {'status': 'error'}) else: LOG.info(_("Share created successfully.")) self.db.share_update(context, share_id, {'status': 'available', 'launched_at': timeutils.utcnow()})
def manage_share(self, context, share_id, driver_options): context = context.elevated() share_ref = self.db.share_get(context, share_id) project_id = share_ref['project_id'] try: if self.driver.driver_handles_share_servers: msg = _("Manage share is not supported for " "driver_handles_share_servers=True mode.") raise exception.InvalidShare(reason=msg) share_update = ( self.driver.manage_existing(share_ref, driver_options) or {}) if not share_update.get('size'): msg = _("Driver cannot calculate share size.") raise exception.InvalidShare(reason=msg) self._update_quota_usages(context, project_id, { "shares": 1, "gigabytes": share_update['size'], }) share_update.update({ 'status': 'available', 'launched_at': timeutils.utcnow(), }) # NOTE(vponomaryov): we should keep only those export locations # that driver has calculated to avoid incompatibilities with one # provided by user. if 'export_locations' in share_update: self.db.share_export_locations_update( context, share_id, share_update.pop('export_locations'), delete=True) self.db.share_update(context, share_id, share_update) except Exception: # NOTE(vponomaryov): set size as 1 because design expects size # to be set, it also will allow us to handle delete/unmanage # operations properly with this errored share according to quotas. self.db.share_update( context, share_id, {'status': constants.STATUS_MANAGE_ERROR, 'size': 1}) raise
def delete_share(self, context, share_id): """Delete a share.""" context = context.elevated() share_ref = self.db.share_get(context, share_id) share_server = self._get_share_server(context, share_ref) if context.project_id != share_ref['project_id']: project_id = share_ref['project_id'] else: project_id = context.project_id rules = self.db.share_access_get_all_for_share(context, share_id) try: for access_ref in rules: self._deny_access(context, access_ref, share_ref, share_server) self.driver.delete_share(context, share_ref, share_server=share_server) except Exception: with excutils.save_and_reraise_exception(): self.db.share_update(context, share_id, {'status': 'error_deleting'}) try: reservations = QUOTAS.reserve(context, project_id=project_id, shares=-1, gigabytes=-share_ref['size']) except Exception: reservations = None LOG.exception(_LE("Failed to update usages deleting share")) self.db.share_delete(context, share_id) LOG.info(_LI("Share %s: deleted successfully."), share_ref['name']) if reservations: QUOTAS.commit(context, reservations, project_id=project_id) if CONF.delete_share_server_with_last_share: share_server = self._get_share_server(context, share_ref) if share_server and not share_server.shares: LOG.debug( "Scheduled deletion of share-server " "with id '%s' automatically by " "deletion of last share.", share_server['id']) self.delete_share_server(context, share_server)
def delete_share(self, context, share_id): """Delete a share.""" context = context.elevated() share_ref = self.db.share_get(context, share_id) share_server = self._get_share_server(context, share_ref) if context.project_id != share_ref['project_id']: project_id = share_ref['project_id'] else: project_id = context.project_id try: self._remove_share_access_rules(context, share_ref, share_server) self.driver.delete_share(context, share_ref, share_server=share_server) except Exception: with excutils.save_and_reraise_exception(): self.db.share_update( context, share_id, {'status': constants.STATUS_ERROR_DELETING}) try: reservations = QUOTAS.reserve(context, project_id=project_id, shares=-1, gigabytes=-share_ref['size']) except Exception: reservations = None LOG.exception(_LE("Failed to update usages deleting share")) self.db.share_delete(context, share_id) LOG.info(_LI("Share %s: deleted successfully."), share_ref['name']) if reservations: QUOTAS.commit(context, reservations, project_id=project_id) if CONF.delete_share_server_with_last_share: share_server = self._get_share_server(context, share_ref) if share_server and not share_server.shares: LOG.debug("Scheduled deletion of share-server " "with id '%s' automatically by " "deletion of last share.", share_server['id']) self.delete_share_server(context, share_server)
def create_share(self, context, share_id, request_spec=None, filter_properties=None, snapshot_id=None): """Creates a share.""" context = context.elevated() if filter_properties is None: filter_properties = {} share_ref = self.db.share_get(context, share_id) if snapshot_id is not None: snapshot_ref = self.db.share_snapshot_get(context, snapshot_id) else: snapshot_ref = None share_network_id = share_ref.get('share_network_id', None) if share_network_id: share_network = self.db.share_network_get(context, share_network_id) if share_network['status'] == constants.STATUS_INACTIVE: share_network = self._activate_share_network( context, share_network) else: share_network = {} share_ref['network_info'] = share_network try: if snapshot_ref: export_location = self.driver.create_share_from_snapshot( context, share_ref, snapshot_ref) else: export_location = self.driver.create_share(context, share_ref) self.db.share_update(context, share_id, {'export_location': export_location}) except Exception: with excutils.save_and_reraise_exception(): self.db.share_update(context, share_id, {'status': 'error'}) else: self.db.share_update(context, share_id, {'status': 'available', 'launched_at': timeutils.utcnow()})
def delete_snapshot(self, context, snapshot_id): """Delete share snapshot.""" context = context.elevated() snapshot_ref = self.db.share_snapshot_get(context, snapshot_id) share_server = self._get_share_server(context, snapshot_ref["share"]) snapshot_instance = self.db.share_snapshot_instance_get( context, snapshot_ref.instance["id"], with_share_data=True ) snapshot_instance_id = snapshot_instance["id"] if context.project_id != snapshot_ref["project_id"]: project_id = snapshot_ref["project_id"] else: project_id = context.project_id try: self.driver.delete_snapshot(context, snapshot_instance, share_server=share_server) except exception.ShareSnapshotIsBusy: self.db.share_snapshot_instance_update( context, snapshot_instance_id, {"status": constants.STATUS_AVAILABLE} ) except Exception: with excutils.save_and_reraise_exception(): self.db.share_snapshot_instance_update( context, snapshot_instance_id, {"status": constants.STATUS_ERROR_DELETING} ) else: self.db.share_snapshot_destroy(context, snapshot_id) try: reservations = QUOTAS.reserve( context, project_id=project_id, snapshots=-1, snapshot_gigabytes=-snapshot_ref["size"] ) except Exception: reservations = None LOG.exception(_LE("Failed to update usages deleting snapshot")) if reservations: QUOTAS.commit(context, reservations, project_id=project_id)
def create_share(self, context, share_id, request_spec=None, filter_properties=None, snapshot_id=None): """Creates a share.""" context = context.elevated() if filter_properties is None: filter_properties = {} share_ref = self.db.share_get(context, share_id) share_network_id = share_ref.get('share_network_id', None) if share_network_id and not self.driver.driver_handles_share_servers: self.db.share_update(context, share_id, {'status': 'error'}) raise exception.ManilaException( "Driver does not expect share-network to be provided " "with current configuration.") if snapshot_id is not None: snapshot_ref = self.db.share_snapshot_get(context, snapshot_id) parent_share_server_id = snapshot_ref['share']['share_server_id'] else: snapshot_ref = None parent_share_server_id = None if parent_share_server_id: try: share_server = self.db.share_server_get(context, parent_share_server_id) LOG.debug("Using share_server " "%s for share %s" % (share_server['id'], share_id)) share_ref = self.db.share_update( context, share_id, {'share_server_id': share_server['id']}) except exception.ShareServerNotFound: with excutils.save_and_reraise_exception(): LOG.error(_LE("Share server %s does not exist."), parent_share_server_id) self.db.share_update(context, share_id, {'status': 'error'}) elif share_network_id: try: share_server, share_ref = self._provide_share_server_for_share( context, share_network_id, share_id) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE("Failed to get share server" " for share creation.")) self.db.share_update(context, share_id, {'status': 'error'}) else: share_server = None try: if snapshot_ref: export_locations = self.driver.create_share_from_snapshot( context, share_ref, snapshot_ref, share_server=share_server) else: export_locations = self.driver.create_share( context, share_ref, share_server=share_server) self.db.share_export_locations_update(context, share_id, export_locations) except Exception as e: with excutils.save_and_reraise_exception(): LOG.error(_LE("Share %s failed on creation."), share_id) detail_data = getattr(e, 'detail_data', {}) def get_export_location(details): if not isinstance(details, dict): return None return details.get('export_locations', details.get('export_location')) export_locations = get_export_location(detail_data) if export_locations: self.db.share_export_locations_update( context, share_id, export_locations) else: LOG.warning(_LW('Share information in exception ' 'can not be written to db because it ' 'contains %s and it is not a dictionary.'), detail_data) self.db.share_update(context, share_id, {'status': 'error'}) else: LOG.info(_LI("Share created successfully.")) self.db.share_update(context, share_id, {'status': 'available', 'launched_at': timeutils.utcnow()})
def create_share_instance( self, context, share_instance_id, request_spec=None, filter_properties=None, snapshot_id=None ): """Creates a share instance.""" context = context.elevated() share_instance = self._get_share_instance(context, share_instance_id) share_network_id = share_instance.get("share_network_id", None) if share_network_id and not self.driver.driver_handles_share_servers: self.db.share_instance_update(context, share_instance_id, {"status": constants.STATUS_ERROR}) raise exception.ManilaException( "Driver does not expect share-network to be provided " "with current configuration." ) if snapshot_id is not None: snapshot_ref = self.db.share_snapshot_get(context, snapshot_id) parent_share_server_id = snapshot_ref["share"]["share_server_id"] else: snapshot_ref = None parent_share_server_id = None if share_network_id or parent_share_server_id: try: share_server, share_instance = self._provide_share_server_for_share( context, share_network_id, share_instance, snapshot=snapshot_ref ) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_LE("Failed to get share server" " for share instance creation.")) self.db.share_instance_update(context, share_instance_id, {"status": constants.STATUS_ERROR}) else: share_server = None try: if snapshot_ref: export_locations = self.driver.create_share_from_snapshot( context, share_instance, snapshot_ref.instance, share_server=share_server ) else: export_locations = self.driver.create_share(context, share_instance, share_server=share_server) self.db.share_export_locations_update(context, share_instance["id"], export_locations) except Exception as e: with excutils.save_and_reraise_exception(): LOG.error(_LE("Share instance %s failed on creation."), share_instance_id) detail_data = getattr(e, "detail_data", {}) def get_export_location(details): if not isinstance(details, dict): return None return details.get("export_locations", details.get("export_location")) export_locations = get_export_location(detail_data) if export_locations: self.db.share_export_locations_update(context, share_instance["id"], export_locations) else: LOG.warning( _LW( "Share instance information in exception " "can not be written to db because it " "contains %s and it is not a dictionary." ), detail_data, ) self.db.share_instance_update(context, share_instance_id, {"status": constants.STATUS_ERROR}) else: LOG.info(_LI("Share instance created successfully.")) self.db.share_instance_update( context, share_instance_id, {"status": constants.STATUS_AVAILABLE, "launched_at": timeutils.utcnow()} )
def create_share(self, context, share_id, request_spec=None, filter_properties=None, snapshot_id=None): """Creates a share.""" context = context.elevated() if filter_properties is None: filter_properties = {} share_ref = self.db.share_get(context, share_id) if snapshot_id is not None: snapshot_ref = self.db.share_snapshot_get(context, snapshot_id) parent_share_server_id = snapshot_ref['share']['share_server_id'] else: snapshot_ref = None parent_share_server_id = None share_network_id = share_ref.get('share_network_id', None) if parent_share_server_id: try: share_server = self.db.share_server_get( context, parent_share_server_id) LOG.debug("Using share_server " "%s for share %s" % (share_server['id'], share_id)) share_ref = self.db.share_update( context, share_id, {'share_server_id': share_server['id']}) except exception.ShareServerNotFound: with excutils.save_and_reraise_exception(): LOG.error(_("Share server %s does not exist."), parent_share_server_id) self.db.share_update(context, share_id, {'status': 'error'}) elif share_network_id: try: share_server, share_ref = self._provide_share_server_for_share( context, share_network_id, share_id) except Exception: with excutils.save_and_reraise_exception(): LOG.error( _("Failed to get share server" " for share creation.")) self.db.share_update(context, share_id, {'status': 'error'}) else: share_server = None try: if snapshot_ref: export_location = self.driver.create_share_from_snapshot( context, share_ref, snapshot_ref, share_server=share_server) else: export_location = self.driver.create_share( context, share_ref, share_server=share_server) self.db.share_update(context, share_id, {'export_location': export_location}) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_("Share %s failed on creation."), share_id) self.db.share_update(context, share_id, {'status': 'error'}) else: LOG.info(_("Share created successfully.")) self.db.share_update(context, share_id, { 'status': 'available', 'launched_at': timeutils.utcnow() })