ResourcesManager.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. import getpass
  2. import os
  3. import logging
  4. import shutil
  5. from git import Repo
  6. from kalliope.core.Models import Neuron
  7. from kalliope import Utils
  8. from kalliope.core.ConfigurationManager import YAMLLoader
  9. from kalliope.core.ConfigurationManager import SettingLoader
  10. from kalliope.core.NeuronLauncher import NeuronLauncher
  11. logging.basicConfig()
  12. logger = logging.getLogger("kalliope")
  13. TMP_GIT_FOLDER = "kalliope_new_neuron_temp_name"
  14. DNA_FILE_NAME = "dna.yml"
  15. INSTALL_FILE_NAME = "install.yml"
  16. class ResourcesManager(object):
  17. def __init__(self, action, **kwargs):
  18. super(ResourcesManager, self).__init__()
  19. # get settings
  20. sl = SettingLoader()
  21. self.settings = sl.settings
  22. # action to perform (delete, install, update)
  23. self.action = action
  24. # in case of update or install, url where
  25. self.git_url = kwargs.get('git_url', None)
  26. # temp path where we install the new module
  27. self.tmp_path = self.settings.resources.neuron_folder + os.sep + TMP_GIT_FOLDER
  28. self.dna_file_path = self.tmp_path + os.sep + DNA_FILE_NAME
  29. self.dna_file = None
  30. if self.action == "install":
  31. self.install()
  32. def install(self):
  33. """
  34. Neuron installation method
  35. :return:
  36. """
  37. if self.is_settings_ok():
  38. # first, we clone the repo
  39. self._clone_repo()
  40. # check the content of the cloned repo
  41. if self.is_neuron_ok():
  42. self.install_neuron()
  43. def is_settings_ok(self):
  44. """
  45. To be able to install a neuron, the user must has configured his settings
  46. :return: True if settings are ok
  47. """
  48. if self.settings.resources is None:
  49. message = "Resources folder not set in settings, cannot install a community neuron"
  50. logger.debug(message)
  51. Utils.print_danger(message)
  52. return False
  53. if self.settings.resources.neuron_folder is None:
  54. message = "No neuron folder set in settings, cannot install a community neuron"
  55. logger.debug(message)
  56. Utils.print_danger(message)
  57. return False
  58. return True
  59. def is_neuron_ok(self):
  60. """
  61. Check if the git cloned repo is fine to be installed
  62. :return:
  63. """
  64. Utils.print_info("Checking repository...")
  65. if not os.path.exists(self.dna_file_path):
  66. Utils.print_danger("Missing %s file" % DNA_FILE_NAME)
  67. return False
  68. # get the content of the DNA file
  69. self.dna_file = YAMLLoader().get_config(self.dna_file_path)
  70. logger.debug("[ResourcesManager] DNA file content: " + str(self.dna_file))
  71. if "neuron_name" not in self.dna_file:
  72. Utils.print_danger("The DNA of the neuron does not contains a \"neuron_name\" tag")
  73. os.remove(self.tmp_path)
  74. return False
  75. # check that a install.yml file is present
  76. install_file_path = self.tmp_path + os.sep + INSTALL_FILE_NAME
  77. if not os.path.exists(install_file_path):
  78. Utils.print_danger("Missing %s file" % DNA_FILE_NAME)
  79. return False
  80. return True
  81. def _clone_repo(self):
  82. """
  83. Use git to clone locally the neuron in a temp folder
  84. :return:
  85. """
  86. # clone the repo
  87. logger.debug("GIT clone into folder: %s" % self.tmp_path)
  88. Utils.print_info("Cloning repository...")
  89. # if the folder already exist we remove it
  90. if os.path.exists(self.tmp_path):
  91. shutil.rmtree(self.tmp_path)
  92. Repo.clone_from(self.git_url, self.tmp_path)
  93. def _rename_temp_neuron_folder(self):
  94. """
  95. Rename the temp folder of the cloned neuron
  96. Return the name of the path of the neuron to install
  97. :return: path of the neuron
  98. """
  99. neuron_name = self.dna_file["neuron_name"].lower()
  100. new_absolute_neuron_path = self.settings.resources.neuron_folder + os.sep + neuron_name
  101. try:
  102. os.rename(self.tmp_path, new_absolute_neuron_path)
  103. return new_absolute_neuron_path
  104. except OSError:
  105. # the folder already exist
  106. Utils.print_warning("The neuron %s already exist in the resource directory" % neuron_name)
  107. # remove the cloned repo
  108. shutil.rmtree(self.tmp_path)
  109. def install_neuron(self):
  110. # rename the folder
  111. new_neuron_path = self._rename_temp_neuron_folder()
  112. install_file_path = new_neuron_path + os.sep + INSTALL_FILE_NAME
  113. Utils.print_info("Starting neuron installation")
  114. # ask the sudo password
  115. pswd = getpass.getpass('Sudo password:')
  116. ansible_neuron_parameters = {
  117. "task_file": install_file_path,
  118. "sudo": True,
  119. "sudo_user": "root",
  120. "sudo_password": pswd
  121. }
  122. neuron = Neuron(name="ansible_playbook", parameters=ansible_neuron_parameters)
  123. NeuronLauncher.start_neuron(neuron)
  124. Utils.print_success("Neuron %s installed" % self.dna_file["neuron_name"])