def prepare_targets_for_detach(targets_for_detach): cfg = Cfg() for tgt_name in targets_for_detach: cfg.update_status(tgt_name, Constants.STATUS_LOST) if len(targets_for_detach): Message.info('Targets for detach: %s' % ' '.join(targets_for_detach))
def get_recently_added_nvme_node(self): try: self._last_found = self.__compare(self.get_local_nvme_nodes())[0] except: Message.warning('No new devices connected') return None return self._last_found
def _connect_runner(self, cfg, tgt_name, tgt_address, tgt_port): regular_connection = (tgt_name, tgt_address, tgt_port, self.uuid) connection_with_prefix = (self._update_nqn_with_prefix(tgt_name), tgt_address, tgt_port, self._update_nqn_with_prefix(self.uuid)) connection_without_prefix = (self._remove_prefix_from_nqn(tgt_name), tgt_address, tgt_port, self._remove_prefix_from_nqn(self.uuid)) connection_types = (regular_connection, connection_with_prefix, connection_without_prefix) for i, connection_type in enumerate(connection_types, 1): if not self.connect(*connection_type): if i == len(connection_types): return False continue cfg.update_status(tgt_name, Constants.STATUS_CONNECTED) Message.debug( 'Connected to {0} using with custom values:\n\ttarget_name: {1}\n\tinitiator uuid: {2}'.format( tgt_name, self._update_nqn_with_prefix(tgt_address), self._update_nqn_with_prefix(self.uuid) )) return True
def disconnect_lost(self): cfg = Cfg() for target in cfg.get_available_targets(): if target['status'] == Constants.STATUS_LOST: Message.info('Disconnecting %s' % target[Constants.CONFIG_TARGET_NAME]) self.save_disconnect(target[Constants.CONFIG_TARGET_NAME]) cfg.remove_element_by_name(target[Constants.CONFIG_TARGET_NAME])
def discovery_output(self, discovery_output): cfg = Config() if str(discovery_output).lower() == str( Constants.NVME_DISCOVERY_GENERIC_ERROR).lower(): for msg in [ 'Please mount target.', Constants.NVME_DISCOVERY_GENERIC_ERROR ]: Message.error(msg) list_of_discovered = [] self.discovery_response = self.try_convert_discovery_output_to_dictionary( str(discovery_output)) for response in self.discovery_response: try: list_of_discovered.append( dict(addr=response['traddr'], port=response['trsvcid'], name=response['subnqn'])) cfg.save_available_target(response['traddr'], response['trsvcid'], response['subnqn'], "discovered") except: Message.error('Output from nvme discover looks empty.') return [] return list_of_discovered
def __init__(self): self._all_modules_are_present = self._check_nvme_cli_modules() self._proper_nvme_cli_version = self._check_nvme_cli_version() if not self._all_modules_are_present or not self._proper_nvme_cli_version: Message.error_color("Unfulfilled part of the requirements. Exiting NVMe-Wheel... ") sys.exit(errno.EPERM)
def get_recently_added_nvme_node(self): try: self._last_found = self.__compare(self.get_local_nvme_nodes())[0] except: Message.warning('No new devices connected') return None return self._last_found
def __init__(self): self._all_modules_are_present = self._check_nvme_cli_modules() self._proper_nvme_cli_version = self._check_nvme_cli_version() if not self._all_modules_are_present or not self._proper_nvme_cli_version: Message.error_color( "Unfulfilled part of the requirements. Exiting NVMe-Wheel... ") sys.exit(errno.EPERM)
def save_available_target(tgt_address, tgt_port, tgt_name, tgt_status=None): # check that this element exist if run_check_if_exist_query(tgt_name): return False insert_element(tgt_address, tgt_port, tgt_name, tgt_status) Message.info('Found a new element %s -- %s:%s' % (tgt_name, tgt_address, tgt_port)) return True
def __compare(self, actual_nvme_devices): for previously_discovered in self._nvme_list: if previously_discovered in actual_nvme_devices: actual_nvme_devices.remove(previously_discovered) if len(actual_nvme_devices) != 1: Message.warning('More devices connected {connected}'.format(connected=actual_nvme_devices)) return actual_nvme_devices
def __compare(self, actual_nvme_devices): for previously_discovered in self._nvme_list: if previously_discovered in actual_nvme_devices: actual_nvme_devices.remove(previously_discovered) if len(actual_nvme_devices) != 1: Message.warning('More devices connected {connected}'.format(connected=actual_nvme_devices)) return actual_nvme_devices
def prepare_targets_for_detach(targets_for_detach): cfg = Cfg() for tgt_name in targets_for_detach: cfg.update_status(tgt_name, Constants.STATUS_LOST) if len(targets_for_detach): Message.info('Targets for detach: %s' % ' '.join(targets_for_detach))
def disconnect_lost(self): cfg = Cfg() for target in cfg.get_available_targets(): if target['status'] == Constants.STATUS_LOST: Message.info('Disconnecting %s' % target[Constants.CONFIG_TARGET_NAME]) self.save_disconnect(target[Constants.CONFIG_TARGET_NAME]) cfg.remove_element_by_name( target[Constants.CONFIG_TARGET_NAME])
def updated_local_path(*args, **kwargs): dl = DiscoverLocal() func_return = func(*args, **kwargs) # if a new target was connected, update database entry with nvme path try: update_node_id(args[1], dl.get_recently_added_nvme_node()) except: Message.error('Target name was not specify') return func_return
def remove_element_by_name(tgt_name=None): len_before = run_count_query(tgt_name) remove_element(tgt_name) len_after = run_count_query(tgt_name) if len_before == len_after: Message.info('Target was found') return False return True
def remove_element_by_name(tgt_name=None): len_before = run_count_query(tgt_name) remove_element(tgt_name) len_after = run_count_query(tgt_name) if len_before == len_after: Message.info('Target was found') return False return True
def updated_local_path(*args, **kwargs): dl = DiscoverLocal() func_return = func(*args, **kwargs) # if a new target was connected, update database entry with nvme path try: update_node_id(args[1], dl.get_recently_added_nvme_node()) except: Message.error('Target name was not specify') return func_return
def save_available_target(tgt_address, tgt_port, tgt_name, tgt_status=None): # check that this element exist if run_check_if_exist_query(tgt_name): return False insert_element(tgt_address, tgt_port, tgt_name, tgt_status) Message.info('Found a new element %s -- %s:%s' % (tgt_name, tgt_address, tgt_port)) return True
def read_uuid(): read_command = "sudo cat /sys/class/dmi/id/product_uuid" process = Popen(read_command, stdout=PIPE, shell=True) output = [] for line in process.stdout.readlines(): output.append(line) sanitize_output = ''.join(output).replace("\n", "").replace(" ", "") if not sanitize_output: Message.error("Can\'t read UUID, run script with higher privileges") sys.exit(1) return sanitize_output.lower()
def _check_nvme_cli_version(self): try: nvme_version = float(self.__external_command(False, Constants.NVME_VERSION).split()[2]) except (ValueError, IndexError): self.__print_information_about_supported_version_nvme_cli() return False if not (self.SUPPORTED_VERSION_NVME_CLI['min'] <= nvme_version <= self.SUPPORTED_VERSION_NVME_CLI['max']): self.__print_information_about_supported_version_nvme_cli() return False if nvme_version != self.SUPPORTED_VERSION_NVME_CLI['recommend']: Message.warning_color('Recommended version of nvme-cli == {recommend_version}, found {version}'. format(recommend_version=self.SUPPORTED_VERSION_NVME_CLI['recommend'], version=nvme_version)) return True
def _check_nvme_cli_modules(self): local_modules = self.__external_command(True, Constants.LSMOD_GREP_NVME) available_modules = [] for module in local_modules: try: if module.split()[0] in self.REQUIRED_NVME_MODULE_LIST: available_modules.append(module) except IndexError: continue if len(available_modules) != len(self.REQUIRED_NVME_MODULE_LIST): Message.error_color("Missing module: {missing}". format(missing=list(set(self.REQUIRED_NVME_MODULE_LIST) - set(available_modules)))) return False return True
def _check_nvme_cli_modules(self): local_modules = self.__external_command(True, Constants.LSMOD_GREP_NVME) available_modules = [] for module in local_modules: try: if module.split()[0] in self.REQUIRED_NVME_MODULE_LIST: available_modules.append(module) except IndexError: continue if len(available_modules) != len(self.REQUIRED_NVME_MODULE_LIST): Message.error_color( "Missing module: {missing}".format(missing=list( set(self.REQUIRED_NVME_MODULE_LIST) - set(available_modules)))) return False return True
def _check_nvme_cli_version(self): try: nvme_version = float( self.__external_command(False, Constants.NVME_VERSION).split()[2]) except (ValueError, IndexError): self.__print_information_about_supported_version_nvme_cli() return False if not (self.SUPPORTED_VERSION_NVME_CLI['min'] <= nvme_version <= self.SUPPORTED_VERSION_NVME_CLI['max']): self.__print_information_about_supported_version_nvme_cli() return False if nvme_version != self.SUPPORTED_VERSION_NVME_CLI['recommend']: Message.warning_color( 'Recommended version of nvme-cli == {recommend_version}, found {version}' .format(recommend_version=self. SUPPORTED_VERSION_NVME_CLI['recommend'], version=nvme_version)) return True
def crone(self): time_before_next_discovery = Cfg().get_cron_time() MAX_EXIT_COUNTER = 12 exit_counter = 0 while exit_counter < MAX_EXIT_COUNTER: found = self.find_detached_targets() if (not self.discovery()) and self.exit_counter_status: exit_counter = exit_counter + 1 Message.info( 'No targets at discovery service was found (%d/%d)' % (exit_counter, MAX_EXIT_COUNTER)) elif self.exit_counter_status: Message.info('Targets at discovery service was found') exit_counter = 0 self.prepare_targets_for_detach(found) self.disconnect_lost() self.connect_discovered() time.sleep(float(time_before_next_discovery)) Message.error( 'No targets at discovery service was found (%d/%d)\nExiting script...' % (exit_counter, MAX_EXIT_COUNTER)) exit(-1)
def discovery_output(self, discovery_output): cfg = Config() if str(discovery_output).lower() == str(Constants.NVME_DISCOVERY_GENERIC_ERROR).lower(): for msg in ['Please mount target.', Constants.NVME_DISCOVERY_GENERIC_ERROR]: Message.error(msg) list_of_discovered = [] self.discovery_response = self.try_convert_discovery_output_to_dictionary(str(discovery_output)) for response in self.discovery_response: try: list_of_discovered.append( dict( addr=response['traddr'], port=response['trsvcid'], name=response['subnqn'] )) cfg.save_available_target(response['traddr'], response['trsvcid'], response['subnqn'], "discovered") except: Message.error('Output from nvme discover looks empty.') return [] return list_of_discovered
def connect_discovered(self): cfg = Cfg() targets_with_discovered_status = [tgts for tgts in cfg.get_available_targets() if tgts['status'] == Constants.STATUS_DISCOVERED] for target in targets_with_discovered_status: tgt_name = target[Constants.CONFIG_TARGET_NAME] tgt_address = target[Constants.CONFIG_TARGET_ADDRESS] tgt_port = target[Constants.CONFIG_TARGET_PORT] Message.info('Connecting to %s - %s:%s' % (tgt_name, tgt_address, tgt_port)) if not self._connect_runner(cfg, tgt_name, tgt_address, tgt_port): Message.info('Connection process FAILED') else: Message.info('Connection process SUCCESS')
def connect_discovered(self): cfg = Cfg() for target in cfg.get_available_targets(): tgt_name = target[Constants.CONFIG_TARGET_NAME] tgt_address = target[Constants.CONFIG_TARGET_ADDRESS] tgt_port = target[Constants.CONFIG_TARGET_PORT] if target['status'] == Constants.STATUS_DISCOVERED: Message.info('Connecting to %s - %s:%s' % (tgt_name, tgt_address, tgt_port)) if self.connect(tgt_name, tgt_address, tgt_port): cfg.update_status(tgt_name, Constants.STATUS_CONNECTED) Message.info('Connection process SUCCESS') else: Message.info('Connection process FAILED')
def __print_information_about_supported_version_nvme_cli(self): Message.info('Supported versions of nvme-cli:') for key, value in self.SUPPORTED_VERSION_NVME_CLI.iteritems(): Message.info('{key}: {value}'.format(key=key, value=value)) Message.error_color('Can not find a proper version of nvme-cli')
def __print_information_about_supported_version_nvme_cli(self): Message.info('Supported versions of nvme-cli:') for key, value in self.SUPPORTED_VERSION_NVME_CLI.iteritems(): Message.info('{key}: {value}'.format(key=key, value=value)) Message.error_color('Can not find a proper version of nvme-cli')