def consume_in_thread(self): """Runs the ZmqProxy service.""" ipc_dir = CONF.rpc_zmq_ipc_dir consume_in = "tcp://%s:%s" % \ (CONF.rpc_zmq_bind_address, CONF.rpc_zmq_port) consumption_proxy = InternalContext(None) try: os.makedirs(ipc_dir) except os.error: if not os.path.isdir(ipc_dir): with excutils.save_and_reraise_exception(): LOG.error(_LE("Required IPC directory does not exist at" " %s") % (ipc_dir, )) try: self.register(consumption_proxy, consume_in, zmq.PULL) except zmq.ZMQError: if os.access(ipc_dir, os.X_OK): with excutils.save_and_reraise_exception(): LOG.error(_LE("Permission denied to IPC directory at" " %s") % (ipc_dir, )) with excutils.save_and_reraise_exception(): LOG.error(_LE("Could not create ZeroMQ receiver daemon. " "Socket may already be in use.")) super(ZmqProxy, self).consume_in_thread()
def consume_in_thread(self): """Runs the ZmqProxy service""" ipc_dir = CONF.rpc_zmq_ipc_dir consume_in = "tcp://%s:%s" % \ (CONF.rpc_zmq_bind_address, CONF.rpc_zmq_port) consumption_proxy = InternalContext(None) if not os.path.isdir(ipc_dir): try: utils.execute('mkdir', '-p', ipc_dir, run_as_root=True) utils.execute('chown', "%s:%s" % (os.getuid(), os.getgid()), ipc_dir, run_as_root=True) utils.execute('chmod', '750', ipc_dir, run_as_root=True) except utils.ProcessExecutionError: with excutils.save_and_reraise_exception(): LOG.error(_("Could not create IPC directory %s") % (ipc_dir, )) try: self.register(consumption_proxy, consume_in, zmq.PULL, out_bind=True) except zmq.ZMQError: with excutils.save_and_reraise_exception(): LOG.error(_("Could not create ZeroMQ receiver daemon. " "Socket may already be in use.")) super(ZmqProxy, self).consume_in_thread()
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 _vserver_create_if_not_exists(self, network_info): """Creates vserver if not exists with given parameters.""" vserver_name = self.configuration.netapp_vserver_name_template % \ network_info['server_id'] vserver_client = driver.NetAppApiClient( self.api_version, vserver=vserver_name, configuration=self.configuration) if not self._vserver_exists(vserver_name): LOG.debug('Vserver %s does not exist, creating' % vserver_name) self._create_vserver(vserver_name) nodes = self._get_cluster_nodes() node_network_info = zip(nodes, network_info['network_allocations']) netmask = utils.cidr_to_netmask(network_info['cidr']) try: for node, net_info in node_network_info: port = self._get_node_data_port(node) ip = net_info['ip_address'] self._create_lif_if_not_exists(vserver_name, net_info['id'], network_info['segmentation_id'], node, port, ip, netmask, vserver_client) except naapi.NaApiError: with excutils.save_and_reraise_exception(): LOG.error(_("Failed to create network interface")) self._delete_vserver(vserver_name, vserver_client) self._enable_nfs(vserver_client) security_services = network_info.get('security_services') if security_services: self._setup_security_services(security_services, vserver_client, vserver_name) return vserver_name
def _teardown_server(): # NOTE(vponomaryov): Verify that there are no dependent shares. # Without this verification we can get here exception in next case: # share-server-delete API was called after share creation scheduled # and share_server reached ACTIVE status, but before update # of share_server_id field for share. If so, after lock realese # this method starts executing when amount of dependent shares # has been changed. shares = self.db.share_get_all_by_share_server( context, share_server['id']) if shares: raise exception.ShareServerInUse( share_server_id=share_server['id']) self.db.share_server_update(context, share_server['id'], {'status': constants.STATUS_DELETING}) sec_services = self.db.share_network_get( context, share_server['share_network_id'])['security_services'] try: LOG.debug("Deleting share server") self.driver.teardown_server(share_server['backend_details'], security_services=sec_services) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_("Share server %s failed on deletion.") % share_server['id']) self.db.share_server_update( context, share_server['id'], {'status': constants.STATUS_ERROR}) else: self.db.share_server_delete(context, share_server['id'])
def _teardown_server(): # NOTE(vponomaryov): Verify that there are no dependent shares. # Without this verification we can get here exception in next case: # share-server-delete API was called after share creation scheduled # and share_server reached ACTIVE status, but before update # of share_server_id field for share. If so, after lock realese # this method starts executing when amount of dependent shares # has been changed. shares = self.db.share_get_all_by_share_server( context, share_server['id']) if shares: raise exception.ShareServerInUse( share_server_id=share_server['id']) self.db.share_server_update(context, share_server['id'], {'status': constants.STATUS_DELETING}) sec_services = self.db.share_network_get( context, share_server['share_network_id'])['security_services'] try: LOG.debug("Deleting share server") self.driver.teardown_server(share_server['backend_details'], security_services=sec_services) except Exception: with excutils.save_and_reraise_exception(): LOG.error(_("Share server %s failed on deletion."), share_server['id']) self.db.share_server_update( context, share_server['id'], {'status': constants.STATUS_ERROR}) else: self.db.share_server_delete(context, share_server['id'])
def delete_snapshot(self, context, snapshot_id): """Delete share snapshot.""" context = context.elevated() snapshot_ref = self.db.share_snapshot_get(context, snapshot_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_ref) 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, gigabytes=-snapshot_ref['size']) except Exception: reservations = None LOG.exception(_("Failed to update usages deleting snapshot")) if reservations: QUOTAS.commit(context, reservations, project_id=project_id)
def _setup_server(self, context, share_network, metadata=None): share_server_val = { 'host': self.host, 'share_network_id': share_network['id'], 'status': constants.STATUS_CREATING } share_server = self.db.share_server_create(context, share_server_val) try: allocation_number = self.driver.get_network_allocations_number() if allocation_number: self.network_api.allocate_network( context, share_server, share_network, count=allocation_number) share_network = self.db.share_network_get(context, share_network['id']) network_info = self._form_network_info(context, share_server, share_network) server_info = self.driver.setup_network(network_info, metadata=metadata) if server_info and isinstance(server_info, dict): self.db.share_server_backend_details_set(context, share_server['id'], server_info) return self.db.share_server_update( context, share_server['id'], {'status': constants.STATUS_ACTIVE}) except Exception: with excutils.save_and_reraise_exception(): self.db.share_server_update(context, share_server['id'], {'status': constants.STATUS_ERROR}) self.network_api.deallocate_network(context, share_network)
def _setup_server(self, context, share_server, metadata=None): share_network = self.db.share_network_get( context, share_server['share_network_id']) try: allocation_number = self.driver.get_network_allocations_number() if allocation_number: self.network_api.allocate_network(context, share_server, share_network, count=allocation_number) # If we reach here, then share_network was updated share_network = self.db.share_network_get( context, share_server['share_network_id']) network_info = self._form_server_setup_info( context, share_server, share_network) server_info = self.driver.setup_server(network_info, metadata=metadata) if server_info and isinstance(server_info, dict): self.db.share_server_backend_details_set( context, share_server['id'], server_info) return self.db.share_server_update( context, share_server['id'], {'status': constants.STATUS_ACTIVE}) except Exception: with excutils.save_and_reraise_exception(): self.db.share_server_update(context, share_server['id'], {'status': constants.STATUS_ERROR}) self.network_api.deallocate_network(context, share_network)
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 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 create_snapshot(self, context, share_id, snapshot_id): """Create snapshot for share.""" snapshot_ref = self.db.share_snapshot_get(context, snapshot_id) share_server = self._get_share_server(context, snapshot_ref['share']) try: model_update = self.driver.create_snapshot( context, snapshot_ref, share_server=share_server) if model_update: model_dict = model_update.to_dict() self.db.share_snapshot_update(context, snapshot_ref['id'], model_dict) except Exception: with excutils.save_and_reraise_exception(): self.db.share_snapshot_update(context, snapshot_ref['id'], {'status': 'error'}) self.db.share_snapshot_update(context, snapshot_ref['id'], {'status': 'available', 'progress': '100%'}) return snapshot_id
def _vserver_create_if_not_exists(self, network_info): """Creates vserver if not exists with given parameters.""" vserver_name = (self.configuration.netapp_vserver_name_template % network_info['server_id']) vserver_client = NetAppApiClient( self.api_version, vserver=vserver_name, configuration=self.configuration) if not self._vserver_exists(vserver_name): LOG.debug('Vserver %s does not exist, creating' % vserver_name) self._create_vserver(vserver_name) nodes = self._get_cluster_nodes() node_network_info = zip(nodes, network_info['network_allocations']) netmask = utils.cidr_to_netmask(network_info['cidr']) try: for node, net_info in node_network_info: port = self._get_node_data_port(node) ip = net_info['ip_address'] self._create_lif_if_not_exists( vserver_name, net_info['id'], network_info['segmentation_id'], node, port, ip, netmask, vserver_client) except naapi.NaApiError: with excutils.save_and_reraise_exception(): LOG.error(_("Failed to create network interface")) self._delete_vserver(vserver_name, vserver_client) self._enable_nfs(vserver_client) security_services = network_info.get('security_services') if security_services: self._setup_security_services(security_services, vserver_client, vserver_name) return vserver_name
def create_share(self, context, topic, share_id, snapshot_id=None, request_spec=None, filter_properties=None): try: self.driver.schedule_create_share(context, request_spec, filter_properties) except exception.NoValidHost as ex: self._set_share_error_state_and_notify("create_share", context, ex, request_spec) except Exception as ex: with excutils.save_and_reraise_exception(): self._set_share_error_state_and_notify("create_share", context, ex, request_spec)
def remove_path_on_error(path): """Protect code that wants to operate on PATH atomically. Any exception will cause PATH to be removed. """ try: yield except Exception: with excutils.save_and_reraise_exception(): delete_if_exists(path)
def _deny_access(self, context, access_ref, share_ref): access_id = access_ref['id'] try: self.driver.deny_access(context, share_ref, access_ref) except Exception: with excutils.save_and_reraise_exception(): self.db.share_access_update( context, access_id, {'state': access_ref.STATE_ERROR}) self.db.share_access_delete(context, access_id)
def logging_error(message): """Catches exception, write message to the log, re-raise. This is a common refinement of save_and_reraise that writes a specific message to the log. """ try: yield except Exception as error: with excutils.save_and_reraise_exception(): LOG.exception(message)
def rollback_and_reraise(self, msg=None, **kwargs): """Rollback a series of actions then re-raise the exception. .. note:: (sirp) This should only be called within an exception handler. """ with excutils.save_and_reraise_exception(): if msg: LOG.exception(msg, **kwargs) self._rollback()
def _serialize(data): """ Serialization wrapper We prefer using JSON, but it cannot encode all types. Error if a developer passes us bad data. """ try: return jsonutils.dumps(data, ensure_ascii=True) except TypeError: with excutils.save_and_reraise_exception(): LOG.error(_("JSON serialization failed."))
def _deactivate_network(self, context, share_network): self.db.share_network_update(context, share_network['id'], {'status': constants.STATUS_DEACTIVATING}) try: self.driver.teardown_network(share_network) except Exception as e: with excutils.save_and_reraise_exception(): self.db.share_network_update(context, share_network['id'], {'status': constants.STATUS_ERROR}) else: self.db.share_network_update(context, share_network['id'], {'status': constants.STATUS_INACTIVE})
def _deny_access(self, context, access_ref, share_ref, share_server): access_id = access_ref['id'] try: self.driver.deny_access(context, share_ref, access_ref, share_server=share_server) except Exception: with excutils.save_and_reraise_exception(): self.db.share_access_update(context, access_id, {'state': access_ref.STATE_ERROR}) self.db.share_access_delete(context, access_id)
def remove_path_on_error(path, remove=delete_if_exists): """Protect code that wants to operate on PATH atomically. Any exception will cause PATH to be removed. :param path: File to work with :param remove: Optional function to remove passed path """ try: yield except Exception: with excutils.save_and_reraise_exception(): remove(path)
def create_share(self, context, topic, share_id, snapshot_id=None, request_spec=None, filter_properties=None): try: self.driver.schedule_create_share(context, request_spec, filter_properties) except exception.NoValidHost as ex: self._set_share_error_state_and_notify('create_share', context, ex, request_spec) except Exception as ex: with excutils.save_and_reraise_exception(): self._set_share_error_state_and_notify('create_share', context, ex, request_spec)
def allow_access(self, context, access_id): """Allow access to some share.""" try: access_ref = self.db.share_access_get(context, access_id) share_ref = self.db.share_get(context, access_ref['share_id']) if access_ref['state'] == access_ref.STATE_NEW: self.driver.allow_access(context, share_ref, access_ref) self.db.share_access_update( context, access_id, {'state': access_ref.STATE_ACTIVE}) except Exception: with excutils.save_and_reraise_exception(): self.db.share_access_update( context, access_id, {'state': access_ref.STATE_ERROR})
def _activate_share_network(self, context, share_network, metadata=None): allocation_number = self.driver.get_network_allocations_number() if allocation_number: share_network = self.network_api.allocate_network( context, share_network, count=allocation_number) try: self.driver.setup_network(share_network, metadata=metadata) except exception.ManilaException: with excutils.save_and_reraise_exception(): self.network_api.deallocate_network(context, share_network) else: return share_network
def _vserver_create_if_not_exists(self, network_info): """Creates vserver if not exists with given parameters.""" vserver_name = self._get_vserver_name(network_info['id']) vserver_client = driver.NetAppApiClient( self.api_version, vserver=vserver_name, configuration=self.configuration) args = {'query': {'vserver-info': {'vserver-name': vserver_name}}} LOG.debug(_('Checking if vserver is configured')) vserver_info = self._client.send_request('vserver-get-iter', args) if not int(vserver_info.get_child_content('num-records')): LOG.debug(_('Vserver %s does not exist, creating') % vserver_name) self._create_vserver(vserver_name) nodes = self._get_cluster_nodes() node_network_info = zip(nodes, network_info['network_allocations']) netmask = utils.cidr_to_netmask(network_info['cidr']) try: for node, net_info in node_network_info: port = self._get_node_data_port(node) ip = net_info['ip_address'] self._create_lif_if_not_exists( vserver_name, net_info['id'], network_info['segmentation_id'], node, port, ip, netmask, vserver_client) except naapi.NaApiError: with excutils.save_and_reraise_exception(): LOG.error(_("Failed to create network interface")) self._delete_vserver(vserver_name, vserver_client) self._enable_nfs(vserver_client) if network_info.get('security_services'): for security_service in network_info['security_services']: if security_service['type'].lower() == "ldap": self._configure_ldap(security_service, vserver_client) elif security_service['type'].lower() == "active_directory": self._configure_active_directory(security_service, vserver_client) elif security_service['type'].lower() == "kerberos": self._configure_kerberos(vserver_name, security_service, vserver_client) else: raise exception.NetAppException( _('Unsupported protocol %s for NetApp driver') % security_service['type']) return vserver_name
def allow_access(self, context, access_id): """Allow access to some share.""" try: access_ref = self.db.share_access_get(context, access_id) share_ref = self.db.share_get(context, access_ref['share_id']) share_server = self._get_share_server(context, share_ref) if access_ref['state'] == access_ref.STATE_NEW: self.driver.allow_access(context, share_ref, access_ref, share_server=share_server) self.db.share_access_update(context, access_id, {'state': access_ref.STATE_ACTIVE}) except Exception: with excutils.save_and_reraise_exception(): self.db.share_access_update(context, access_id, {'state': access_ref.STATE_ERROR})
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 excutils.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 activate_network(self, context, share_network_id, metadata=None): share_network = self.db.share_network_get(context, share_network_id) if (hasattr(share_network, 'project_id') and context.project_id != share_network['project_id']): project_id = share_network['project_id'] else: project_id = context.project_id reservations = None try: reservations = QUOTAS.reserve(context, project_id=project_id, share_networks=-1) self._activate_share_network(context, share_network, metadata) except Exception: with excutils.save_and_reraise_exception(): if reservations: QUOTAS.commit(context, reservations, project_id=project_id)
def create_export(self, server, share_name, recreate=False): """Create share at samba server.""" share_path = os.path.join(self.configuration.share_mount_path, share_name) create_cmd = [ 'sudo', 'net', 'conf', 'addshare', share_name, share_path, 'writeable=y', 'guest_ok=y', ] try: self._ssh_exec( server, ['sudo', 'net', 'conf', 'showshare', share_name, ]) except exception.ProcessExecutionError as parent_e: # Share does not exist, create it try: self._ssh_exec(server, create_cmd) except Exception: # If we get here, then it will be useful # to log parent exception too. with excutils.save_and_reraise_exception(): LOG.error(parent_e) else: # Share exists if recreate: self._ssh_exec( server, ['sudo', 'net', 'conf', 'delshare', share_name, ]) self._ssh_exec(server, create_cmd) else: msg = _('Share section %s already defined.') % share_name raise exception.ShareBackendException(msg=msg) parameters = { 'browseable': 'yes', '\"create mask\"': '0755', '\"hosts deny\"': '0.0.0.0/0', # deny all by default '\"hosts allow\"': '127.0.0.1', '\"read only\"': 'no', } set_of_commands = [':', ] # : is just placeholder for param, value in parameters.items(): # These are combined in one list to run in one process # instead of big chain of one action calls. set_of_commands.extend(['&&', 'sudo', 'net', 'conf', 'setparm', share_name, param, value]) self._ssh_exec(server, set_of_commands) return '//%s/%s' % (server['public_address'], share_name)
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(_("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) 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_export(self, server, share_name, recreate=False): """Create share at samba server.""" create_cmd = [ 'sudo', 'net', 'conf', 'addshare', share_name, self.configuration.share_mount_path, 'writeable=y', 'guest_ok=y', ] try: self._ssh_exec( server, ['sudo', 'net', 'conf', 'showshare', share_name, ]) except exception.ProcessExecutionError as parent_e: # Share does not exist, create it try: self._ssh_exec(server, create_cmd) except Exception: # If we get here, then it will be useful # to log parent exception too. with excutils.save_and_reraise_exception(): LOG.error(parent_e) else: # Share exists if recreate: self._ssh_exec( server, ['sudo', 'net', 'conf', 'delshare', share_name, ]) self._ssh_exec(server, create_cmd) else: msg = _('Share section %s already defined.') % share_name raise exception.ShareBackendException(msg=msg) parameters = { 'browseable': 'yes', '\"create mask\"': '0755', '\"hosts deny\"': '0.0.0.0/0', # deny all by default '\"hosts allow\"': '127.0.0.1', '\"read only\"': 'no', } set_of_commands = [':', ] # : is just placeholder for param, value in parameters.items(): # These are combined in one list to run in one process # instead of big chain of one action calls. set_of_commands.extend(['&&', 'sudo', 'net', 'conf', 'setparm', share_name, param, value]) self._ssh_exec(server, set_of_commands) return '//%s/%s' % (server['public_address'], share_name)
def _activate_share_network(self, context, share_network, metadata=None): allocation_number = self.driver.get_network_allocations_number() if allocation_number: share_network = self.network_api.allocate_network( context, share_network, count=allocation_number) try: self.db.share_network_update(context, share_network['id'], {'status': constants.STATUS_ACTIVATING}) self.driver.setup_network(share_network, metadata=metadata) self.db.share_network_update(context, share_network['id'], {'status': constants.STATUS_ACTIVE}) except exception.ManilaException: with excutils.save_and_reraise_exception(): self.db.share_network_update(context, share_network['id'], {'status': constants.STATUS_ERROR}) self.network_api.deallocate_network(context, share_network) else: return share_network
def _teardown_server(): share_network = self.db.share_network_get( context, share_server['share_network_id']) network_info = self._form_network_info(context, share_server, share_network) self.db.share_server_update(context, share_server['id'], {'status': constants.STATUS_DELETING}) try: LOG.debug("Deleting share server") self.driver.teardown_network(network_info) except Exception as e: with excutils.save_and_reraise_exception(): LOG.error(_("Share server %s failed on deletion.") % share_server['id']) self.db.share_server_update(context, share_server['id'], {'status': constants.STATUS_ERROR}) else: self.db.share_server_delete(context, share_server['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 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 __iter__(self): """Return a result until we get a reply with an 'ending' flag.""" if self._done: raise StopIteration while True: try: data = self._dataqueue.get(timeout=self._timeout) result = self._process_data(data) except queue.Empty: self.done() raise rpc_common.Timeout() except Exception: with excutils.save_and_reraise_exception(): self.done() if self._got_ending: self.done() raise StopIteration if isinstance(result, Exception): self.done() raise result yield result
def create_snapshot(self, context, share_id, snapshot_id): """Create snapshot for share.""" snapshot_ref = self.db.share_snapshot_get(context, snapshot_id) try: snap_name = snapshot_ref['name'] model_update = self.driver.create_snapshot(context, snapshot_ref) if model_update: self.db.share_snapshot_update(context, snapshot_ref['id'], model_update) except Exception: with excutils.save_and_reraise_exception(): self.db.share_snapshot_update(context, snapshot_ref['id'], {'status': 'error'}) self.db.share_snapshot_update(context, snapshot_ref['id'], {'status': 'available', 'progress': '100%'}) return snapshot_id
def create_snapshot(self, context, share_id, snapshot_id): """Create snapshot for share.""" snapshot_ref = self.db.share_snapshot_get(context, snapshot_id) share_server = self._get_share_server(context, snapshot_ref['share']) try: model_update = self.driver.create_snapshot( context, snapshot_ref, share_server=share_server) if model_update: model_dict = model_update.to_dict() self.db.share_snapshot_update(context, snapshot_ref['id'], model_dict) except Exception: with excutils.save_and_reraise_exception(): self.db.share_snapshot_update(context, snapshot_ref['id'], {'status': 'error'}) self.db.share_snapshot_update(context, snapshot_ref['id'], { 'status': 'available', 'progress': '100%' }) return snapshot_id
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, gigabytes=-snapshot_ref['size']) except Exception: reservations = None LOG.exception(_("Failed to update usages deleting snapshot")) if reservations: QUOTAS.commit(context, reservations, project_id=project_id)
def create(self, context, share_proto, size, name, description, snapshot=None, availability_zone=None, metadata=None, share_network_id=None, volume_type=None): """Create new share.""" policy.check_policy(context, 'share', 'create') self._check_metadata_properties(context, metadata) if snapshot is not None: if snapshot['status'] != 'available': msg = _('status must be available') raise exception.InvalidShareSnapshot(reason=msg) if not size: size = snapshot['size'] snapshot_id = snapshot['id'] else: snapshot_id = None def as_int(s): try: return int(s) except (ValueError, TypeError): return s # tolerate size as stringified int size = as_int(size) if not isinstance(size, int) or size <= 0: msg = (_("Share size '%s' must be an integer and greater than 0") % size) raise exception.InvalidInput(reason=msg) if snapshot and size < snapshot['size']: msg = (_("Share size '%s' must be equal or greater " "than snapshot size") % size) raise exception.InvalidInput(reason=msg) if snapshot and volume_type: if volume_type['id'] != snapshot['volume_type_id']: msg = _("Invalid volume_type provided (requested type " "must match source snapshot, or be omitted). " "You should omit the argument.") raise exception.InvalidInput(reason=msg) # TODO(rushiagr): Find a suitable place to keep all the allowed # share types so that it becomes easier to add one if share_proto.lower() not in ['nfs', 'cifs']: msg = (_("Invalid share type provided: %s") % share_proto) raise exception.InvalidInput(reason=msg) try: reservations = QUOTAS.reserve(context, shares=1, gigabytes=size) except exception.OverQuota as e: overs = e.kwargs['overs'] usages = e.kwargs['usages'] quotas = e.kwargs['quotas'] def _consumed(name): return (usages[name]['reserved'] + usages[name]['in_use']) if 'gigabytes' in overs: msg = _("Quota exceeded for %(s_pid)s, tried to create " "%(s_size)sG share (%(d_consumed)dG of %(d_quota)dG " "already consumed)") LOG.warn( msg % { 's_pid': context.project_id, 's_size': size, 'd_consumed': _consumed('gigabytes'), 'd_quota': quotas['gigabytes'] }) raise exception.ShareSizeExceedsAvailableQuota() elif 'shares' in overs: msg = _("Quota exceeded for %(s_pid)s, tried to create " "share (%(d_consumed)d shares " "already consumed)") LOG.warn(msg % { 's_pid': context.project_id, 'd_consumed': _consumed('shares') }) raise exception.ShareLimitExceeded(allowed=quotas['shares']) if availability_zone is None: availability_zone = CONF.storage_availability_zone options = { 'size': size, 'user_id': context.user_id, 'project_id': context.project_id, 'snapshot_id': snapshot_id, 'share_network_id': share_network_id, 'availability_zone': availability_zone, 'metadata': metadata, 'status': "creating", 'scheduled_at': timeutils.utcnow(), 'display_name': name, 'display_description': description, 'share_proto': share_proto, 'volume_type_id': volume_type['id'] if volume_type else None } try: share = self.db.share_create(context, options) QUOTAS.commit(context, reservations) except Exception: with excutils.save_and_reraise_exception(): try: self.db.share_delete(context, share['id']) finally: QUOTAS.rollback(context, reservations) request_spec = { 'share_properties': options, 'share_proto': share_proto, 'share_id': share['id'], 'snapshot_id': share['snapshot_id'], 'volume_type': volume_type } filter_properties = {} self.scheduler_rpcapi.create_share(context, CONF.share_topic, share['id'], snapshot_id, request_spec=request_spec, filter_properties=filter_properties) return share
def create_snapshot(self, context, share, name, description, force=False): policy.check_policy(context, 'share', 'create_snapshot', share) if ((not force) and (share['status'] != "available")): msg = _("must be available") raise exception.InvalidShare(reason=msg) size = share['size'] try: reservations = QUOTAS.reserve(context, snapshots=1, gigabytes=size) except exception.OverQuota as e: overs = e.kwargs['overs'] usages = e.kwargs['usages'] quotas = e.kwargs['quotas'] def _consumed(name): return (usages[name]['reserved'] + usages[name]['in_use']) if 'gigabytes' in overs: msg = _("Quota exceeded for %(s_pid)s, tried to create " "%(s_size)sG snapshot (%(d_consumed)dG of " "%(d_quota)dG already consumed)") LOG.warn( msg % { 's_pid': context.project_id, 's_size': size, 'd_consumed': _consumed('gigabytes'), 'd_quota': quotas['gigabytes'] }) raise exception.ShareSizeExceedsAvailableQuota() elif 'snapshots' in overs: msg = _("Quota exceeded for %(s_pid)s, tried to create " "snapshot (%(d_consumed)d snapshots " "already consumed)") LOG.warn( msg % { 's_pid': context.project_id, 'd_consumed': _consumed('snapshots') }) raise exception.SnapshotLimitExceeded( allowed=quotas['snapshots']) options = { 'share_id': share['id'], 'size': share['size'], 'user_id': context.user_id, 'project_id': context.project_id, 'status': "creating", 'progress': '0%', 'share_size': share['size'], 'display_name': name, 'display_description': description, 'share_proto': share['share_proto'], 'export_location': share['export_location'] } try: snapshot = self.db.share_snapshot_create(context, options) QUOTAS.commit(context, reservations) except Exception: with excutils.save_and_reraise_exception(): try: self.db.snapshot_delete(context, share['id']) finally: QUOTAS.rollback(context, reservations) self.share_rpcapi.create_snapshot(context, share, snapshot) return snapshot
def setup_server(self, emc_share_driver, network_info, metadata=None): """Set up and configures share server with given network parameters.""" # Only support single security service with type 'active_directory' interface_info = [] vdm_name = 'vdm-' + network_info['server_id'] vlan_id = network_info['segmentation_id'] active_directory = None sec_services = [] if network_info.get('security_services'): sec_services = network_info['security_services'] is_valid, data = self._get_valid_security_service(sec_services) if is_valid: active_directory = data else: LOG.error(data) raise exception.EMCVnxXMLAPIError(err=data) try: # Refresh DataMover/VDM by the configuration moverRef = self.get_mover_ref_by_name(self._mover_name) if not self._vdm_exist(vdm_name): LOG.debug('Share Server %s not found. Creating', vdm_name) self._create_vdm(vdm_name, moverRef) status, vdmRef = self._XMLAPI_helper.get_vdm_by_name(vdm_name) if constants.STATUS_OK != status: message = (_('Could not get Share Server by name %(name)s. ' 'Reason: %(err)s.') % { 'name': vdm_name, 'err': vdmRef }) LOG.error(message) raise exception.EMCVnxXMLAPIError(err=message) netmask = utils.cidr_to_netmask(network_info['cidr']) allocated_interfaces = [] device_port = self._get_device_port(moverRef) for net_info in network_info['network_allocations']: ip = net_info['ip_address'] if_name = 'if-' + net_info['id'][-12:] if_info = {'ip': ip, 'if_name': if_name} interface_info.append(if_info) status, interface = self._XMLAPI_helper.create_mover_interface( if_name, device_port['name'], ip, moverRef['id'], netmask, vlan_id) if constants.STATUS_OK != status: message = (_('Interface creation failed. Reason: %s.') % interface) LOG.error(message) raise exception.EMCVnxXMLAPIError(err=message) allocated_interfaces.append(interface) if active_directory: self._configure_active_directory(active_directory, vdmRef, allocated_interfaces[0]) self._enable_nfs_service(vdmRef, allocated_interfaces[1]) return { 'share_server_name': vdm_name, 'share_server_id': vdmRef['id'], 'cifs_if': allocated_interfaces[0]['ip'], 'nfs_if': allocated_interfaces[1]['ip'], } except Exception as ex: with excutils.save_and_reraise_exception(): message = _('Could not setup server. Reason: %s.') % ex LOG.error(message) server_details = self._contruct_backend_details( vdm_name, vdmRef, interface_info) self.teardown_server(None, server_details, sec_services)
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() })