def run_ansible_playbook_module(install_file_path): """ Run the install.yml file through an Ansible playbook using the dedicated neuron ! :param install_file_path: the path of the Ansible playbook to run. :return: """ logger.debug("[ResourcesManager] Run ansible playbook") Utils.print_info("Starting neuron installation") # ask the sudo password pswd = getpass.getpass('Sudo password:') if not pswd or pswd == "": Utils.print_warning("You must enter a sudo password") return False else: ansible_neuron_parameters = { "task_file": install_file_path, "sudo": True, "sudo_user": "******", "sudo_password": pswd } neuron = Neuron(name="ansible_playbook", parameters=ansible_neuron_parameters) NeuronLauncher.start_neuron(neuron) return True
def _get_target_folder(resources, module_type): """ Return the folder from the resources and given a module type :param resources: Resource object :type resources: Resources :param module_type: type of the module (TYPE_NEURON, TYPE_STT, TYPE_TTS, TYPE_TRIGGER, TYPE_SIGNAL) :return: path of the folder """ module_type_converter = dict() # dict to get the path behind a type of resource try: module_type_converter = { TYPE_NEURON: resources.neuron_folder, TYPE_STT: resources.stt_folder, TYPE_TTS: resources.tts_folder, TYPE_TRIGGER: resources.trigger_folder, TYPE_SIGNAL: resources.signal_folder } except AttributeError: # will be raised if the resource folder is not set in settings pass # Let's find the right path depending of the type try: folder_path = module_type_converter[module_type] except KeyError: folder_path = None # No folder_path has been found message = "No %s folder set in settings." % module_type if folder_path is None: logger.debug(message) Utils.print_danger(message) return folder_path
def install(self): """ Module installation method. """ # first, we clone the repo self._clone_repo(path=self.tmp_path, git_url=self.git_url) # check the content of the cloned repo if self.is_repo_ok(dna_file_path=self.dna_file_path, install_file_path=self.install_file_path): # Load the dna.yml file self.dna = DnaLoader(self.dna_file_path).get_dna() if self.dna is not None: logger.debug("[ResourcesManager] DNA file content: " + str(self.dna)) if self.is_settings_ok(resources=self.settings.resources, dna=self.dna): # the dna file is ok, check the supported version if self._check_supported_version( current_version=self.settings.intelora_version, supported_versions=self.dna. intelora_supported_version): # Let's find the target folder depending the type module_type = self.dna.module_type.lower() target_folder = self._get_target_folder( resources=self.settings.resources, module_type=module_type) if target_folder is not None: # let's move the tmp folder in the right folder and get a new path for the module module_name = self.dna.name.lower() target_path = self._rename_temp_folder( name=self.dna.name.lower(), target_folder=target_folder, tmp_path=self.tmp_path) # if the target_path exists, then run the install file within the new repository if target_path is not None: self.install_file_path = target_path + os.sep + INSTALL_FILE_NAME if self.run_ansible_playbook_module( install_file_path=self. install_file_path): Utils.print_success( "Module: %s installed" % module_name) else: Utils.print_danger( "Module: %s not installed" % module_name) else: logger.debug( "[ResourcesManager] installation cancelled, deleting temp repo %s" % str(self.tmp_path)) shutil.rmtree(self.tmp_path)
def wait_before_stop(self): logger.debug( "[Ambient_sounds] Wait %s minutes before checking if the thread is alive" % self.auto_stop_minutes) Utils.print_info( "[Ambient_sounds] Wait %s minutes before stopping the ambient sound" % self.auto_stop_minutes) sleep(self.auto_stop_minutes * 60) # *60 to convert received minutes into seconds logger.debug("[Ambient_sounds] Time is over, Stop player") Utils.print_info( "[Ambient_sounds] Time is over, stopping the ambient sound") self.stop_last_process()
def __init__(self, file_path=None): sl = SettingLoader() self.settings = sl.settings self.file_path = file_path if self.file_path is None: # we don't provide a file path, so search for the default one self.file_path = Utils.get_real_file_path(FILE_NAME) else: self.file_path = Utils.get_real_file_path(file_path) # if the returned file path is none, the file doesn't exist if self.file_path is None: raise BrainNotFound("brain file not found") self.yaml_config = self.get_yaml_config() self.brain = self.load_brain()
def _clone_repo(path, git_url): """ Use git to clone locally the neuron in a temp folder :return: """ # clone the repo logger.debug("[ResourcesManager] GIT clone into folder: %s" % path) Utils.print_info("Cloning repository...") # if the folder already exist we remove it if os.path.exists(path): shutil.rmtree(path) else: os.makedirs(path) Repo.clone_from(git_url, path)
def _replace_global_variables(cls, parameter, settings): """ replace a parameter that contains bracket by the instantiated parameter from the var file This function will call itself multiple time to handle different level of parameter in a neuron :param parameter: the parameter to update. can be a dict, a list or a string :param settings: the settings :return: the parameter dict """ if isinstance(parameter, str) \ or isinstance(parameter, six.text_type) \ or isinstance(parameter, int): if Utils.is_containing_bracket(parameter): return cls._get_global_variable(sentence=parameter, settings=settings) if isinstance(parameter, list): new_parameter_list = list() for el in parameter: new_parameter_list.append( cls._replace_global_variables(el, settings=settings)) return new_parameter_list if isinstance(parameter, dict): for key, value in parameter.items(): parameter[key] = cls._replace_global_variables( value, settings=settings) return parameter
def _rename_temp_folder(name, target_folder, tmp_path): """ Rename the temp folder of the cloned repo Return the name of the path to install :return: path to install, None if already exists """ logger.debug("[ResourcesManager] Rename temp folder") new_absolute_neuron_path = target_folder + os.sep + name try: shutil.move(tmp_path, new_absolute_neuron_path) return new_absolute_neuron_path except shutil.Error: # the folder already exist Utils.print_warning("The module %s already exist in the path %s" % (name, target_folder)) # remove the cloned repo logger.debug("[ResourcesManager] Deleting temp folder %s" % str(tmp_path)) shutil.rmtree(tmp_path)
def get_parameters(cls, synapse_order, user_order): """ Class method to get all params coming from a string order. Returns a dict of key/value. """ params = dict() if Utils.is_containing_bracket(synapse_order): params = cls._associate_order_params_to_values(user_order, synapse_order) logger.debug("[NeuronParameterLoader.get_parameters]Parameters for order: %s" % params) # we place the dict of parameters load from order into a cache in Cortex so the user can save it later Cortex.add_parameters_from_order(params) return params
def _associate_order_params_to_values(cls, order, order_to_check): """ Associate the variables from the order to the incoming user order :param order_to_check: the order to check incoming from the brain :type order_to_check: str :param order: the order from user :type order: str :return: the dict corresponding to the key / value of the params """ logger.debug("[NeuronParameterLoader._associate_order_params_to_values] user order: %s, " "order from synapse: %s" % (order, order_to_check)) list_word_in_order = Utils.remove_spaces_in_brackets(order_to_check).split() # remove sentence before order which are sentences not matching anyway truncate_list_word_said = order.split() # make dict var:value dict_var = dict() for idx, ow in enumerate(list_word_in_order): if not Utils.is_containing_bracket(ow): while truncate_list_word_said and ow.lower() != truncate_list_word_said[0].lower(): truncate_list_word_said = truncate_list_word_said[1:] else: # remove bracket and grab the next value / stop value var_name = ow.replace("{{", "").replace("}}", "") stop_value = Utils.get_next_value_list(list_word_in_order[idx:]) if stop_value is None: dict_var[var_name] = " ".join(truncate_list_word_said) break for word_said in truncate_list_word_said: if word_said.lower() == stop_value.lower(): # Do not consider the case break if var_name in dict_var: dict_var[var_name] += " " + word_said truncate_list_word_said = truncate_list_word_said[1:] else: dict_var[var_name] = word_said truncate_list_word_said = truncate_list_word_said[1:] return dict_var
def _get_global_variable(sentence, settings): """ Get the global variable from the sentence with brackets :param sentence: the sentence to check :return: the global variable """ sentence_no_spaces = Utils.remove_spaces_in_brackets(sentence=sentence) list_of_bracket_params = Utils.find_all_matching_brackets( sentence=sentence_no_spaces) for param_with_bracket in list_of_bracket_params: param_no_brackets = param_with_bracket.replace("{{", "").replace( "}}", "") if param_no_brackets in settings.variables: logger.debug("Replacing variable %s with %s" % (param_with_bracket, settings.variables[param_no_brackets])) # need to check if the variable is an integer variable = settings.variables[param_no_brackets] if isinstance(variable, int): variable = str(variable) sentence_no_spaces = sentence_no_spaces.replace( param_with_bracket, variable) return sentence_no_spaces
def serialize(self): """ This method allows to serialize in a proper way this object :return: A dict of name and parameters :rtype: Dict """ self.user_order = Utils.encode_text_utf8(self.user_order) return { 'user_order': self.user_order, 'matched_synapses': [e.serialize() for e in self.list_processed_matched_synapse], 'status': self.status }
def _check_supported_version(current_version, supported_versions): """ The dna file contains supported Intelora version for the module to install. Check if supported versions are match the current installed version. If not, ask the user to confirm the installation anyway :param current_version: current version installed of Intelora. E.g 0.4.0 :param supported_versions: list of supported version :return: True if the version is supported or user has confirmed the installation """ logger.debug( "[ResourcesManager] Current installed version of Intelora: %s" % str(current_version)) logger.debug("[ResourcesManager] Module supported version: %s" % str(supported_versions)) supported_version_found = False # Extract major version match_current_version = re.search('^[\d]*[.][\d]*', current_version) if match_current_version: current_version = match_current_version.group(0) for supported_version in supported_versions: if version.parse(str(current_version)) == version.parse( str(supported_version)): # we found the exact version supported_version_found = True break if not supported_version_found: # we ask the user if we want to install the module even if the version doesn't match Utils.print_info("Current installed version of Intelora: %s" % current_version) Utils.print_info("Module supported versions: %s" % str(supported_versions)) Utils.print_warning( "The neuron seems to be not supported by your current version of Intelora" ) supported_version_found = Utils.query_yes_no("install it anyway?") logger.debug( "[ResourcesManager] install it anyway user answer: %s" % supported_version_found) logger.debug("[ResourcesManager] check_supported_version: %s" % str(supported_version_found)) return supported_version_found
def is_repo_ok(dna_file_path, install_file_path): """ Check if the git cloned repo is fine to be installed :return: True if repo is ok to be installed, False otherwise """ Utils.print_info("Checking repository...") repo_ok = True # check that a install.yml file is present if not os.path.exists(install_file_path): Utils.print_danger("Missing %s file" % INSTALL_FILE_NAME) repo_ok = False if not os.path.exists(dna_file_path): Utils.print_danger("Missing %s file" % DNA_FILE_NAME) repo_ok = False return repo_ok
def uninstall(self, neuron_name=None, tts_name=None, stt_name=None, trigger_name=None, signal_name=None): """ Uninstall a community resource """ target_path_to_delete = None module_name = "" if neuron_name is not None: target_path_to_delete = self._get_target_folder( resources=self.settings.resources, module_type=TYPE_NEURON) module_name = neuron_name if tts_name is not None: target_path_to_delete = self._get_target_folder( resources=self.settings.resources, module_type=TYPE_TTS) module_name = tts_name if stt_name is not None: target_path_to_delete = self._get_target_folder( resources=self.settings.resources, module_type=TYPE_STT) module_name = stt_name if trigger_name is not None: target_path_to_delete = self._get_target_folder( resources=self.settings.resources, module_type=TYPE_TRIGGER) module_name = trigger_name if signal_name is not None: target_path_to_delete = self._get_target_folder( resources=self.settings.resources, module_type=TYPE_SIGNAL) module_name = signal_name if target_path_to_delete is not None: try: shutil.rmtree(target_path_to_delete + os.sep + module_name.lower()) Utils.print_success("Module %s deleted" % module_name.lower()) except shutil.Error: Utils.print_warning( "The module %s doest not exist in the path %s" % (module_name.lower(), target_path_to_delete)) except OSError: Utils.print_warning( "The module %s doest not exist in the path %s" % (module_name.lower(), target_path_to_delete))
def is_settings_ok(resources, dna): """ Test if required settings files in config of Intelora are ok. The resource object must not be empty Check id the use have set the an installation path in his settings for the target module type :param resources: the Resources model :param dna: DNA info about the module to install :return: """ settings_ok = True if resources is None: message = "Resources folder not set in settings, cannot install." logger.debug(message) Utils.print_danger(message) settings_ok = False else: if dna.module_type == "neuron" and resources.neuron_folder is None: message = "Resources folder for neuron installation not set in settings, cannot install." logger.debug(message) Utils.print_danger(message) settings_ok = False if dna.module_type == "stt" and resources.stt_folder is None: message = "Resources folder for stt installation not set in settings, cannot install." logger.debug(message) Utils.print_danger(message) settings_ok = False if dna.module_type == "tts" and resources.tts_folder is None: message = "Resources folder for tts installation not set in settings, cannot install." logger.debug(message) Utils.print_danger(message) settings_ok = False if dna.module_type == "trigger" and resources.trigger_folder is None: message = "Resources folder for trigger installation not set in settings, cannot install." logger.debug(message) Utils.print_danger(message) settings_ok = False if dna.module_type == "signal" and resources.signal_folder is None: message = "Resources folder for signal installation not set in settings, cannot install." logger.debug(message) Utils.print_danger(message) settings_ok = False return settings_ok