diff --git a/non_graf_installer/python-installer/oginstaller-v2.py b/non_graf_installer/python-installer/oginstaller-v2.py deleted file mode 100644 index 8ed0b46..0000000 --- a/non_graf_installer/python-installer/oginstaller-v2.py +++ /dev/null @@ -1,217 +0,0 @@ -import npyscreen -import json -import os -from git import Repo - -CONFIGS_DIR = "/tmp/oginstall" -os.makedirs(CONFIGS_DIR, exist_ok=True) - -REPO_URL = "https://ognproject.evlt.uma.es/gitea/opengnsys/ogcore.git" - -def get_git_tags(): - try: - repo_path = os.path.join(CONFIGS_DIR, "opengnsys_repo") - if not os.path.exists(repo_path): - print("Clonando el repositorio...") - Repo.clone_from(REPO_URL, repo_path) - else: - print("Usando repositorio existente en", repo_path) - - repo = Repo(repo_path) - tags = [tag.name for tag in repo.tags if tag.name.startswith("opengnsys")] - return tags - except Exception as e: - print("Error al obtener los tags:", str(e)) - return [] - -class ComponentSelectionForm(npyscreen.ActionForm): - def create(self): - self.components = self.add(npyscreen.TitleMultiSelect, max_height=6, name="Selecciona los componentes", - values=["ogCore", "ogGui", "ogDhcp", "ogBoot", "ogRepository"], scroll_exit=True) - self.tags = get_git_tags() - self.tag = self.add(npyscreen.TitleSelectOne, max_height=10, name="Selecciona el tag", - values=self.tags, scroll_exit=True) - - def beforeEditing(self): - npyscreen.blank_terminal() - - def on_ok(self): - npyscreen.blank_terminal() - selected_components = [self.components.values[i] for i in self.components.value] - if not selected_components or not self.tag.value: - npyscreen.notify_confirm("Debes seleccionar al menos un componente y un tag.", title="Error") - return - selected_tag = self.tags[self.tag.value[0]] - self.parentApp.selected_components = selected_components - self.parentApp.selected_tag = selected_tag - self.parentApp.current_component_index = 0 - self.parentApp.switchForm(selected_components[0]) - - def on_cancel(self): - if npyscreen.notify_yes_no("¿Estás seguro de que deseas salir?", title="Confirmación"): - self.parentApp.setNextForm(None) - -class ComponentForm(npyscreen.ActionForm): - component_name = None - - def create(self): - self.fields = {} - - def beforeEditing(self): - npyscreen.blank_terminal() - self.fields.clear() - self._recreate_form() - - def _recreate_form(self): - """Limpia y recrea los widgets del formulario.""" - self._clear_widgets() - self.configure_fields() - - def configure_fields(self): - """Método para definir los campos de configuración para cada componente""" - pass - - def _clear_widgets(self): - """Limpia todos los widgets del formulario.""" - self._widgets__ = [] - self._widgets_by_id__ = {} - self._contained_widgets = [] - - def validate_fields(self): - """Validaciones personalizadas para contraseñas.""" - password_field = None - confirmation_field = None - - # Identificar los campos de contraseña y confirmación - for key, field_data in self.fields.items(): - if field_data.get("is_password_field"): - password_field = field_data["widget"] - if field_data.get("is_password_confirmation"): - confirmation_field = field_data["widget"] - - # Validar contraseñas si ambos campos están definidos - if password_field and confirmation_field: - if password_field.value != confirmation_field.value: - npyscreen.notify_confirm("Las contraseñas no coinciden. Por favor, revísalas.", title="Error") - return False - return True - - def add_password_field(self, key, name, is_confirmation=False, default_value=""): - """Añade un campo de contraseña con metadatos.""" - widget = self.add(npyscreen.TitlePassword, name=name, value=default_value) - self.fields[key] = { - "widget": widget, - "is_password_field": not is_confirmation, - "is_password_confirmation": is_confirmation, - } - - def on_ok(self): - if not self.validate_fields(): - return # Si las validaciones fallan, no proceder - - npyscreen.blank_terminal() - config_data = {"release": self.parentApp.selected_tag} - for key, field_data in self.fields.items(): - config_data[key] = field_data["widget"].value - - config_file = os.path.join(CONFIGS_DIR, f"config_{self.component_name}.json") - with open(config_file, "w") as f: - json.dump(config_data, f) - npyscreen.notify_confirm(f"Configuración de {self.component_name} guardada en {config_file}", title="Confirmación") - - self.parentApp.current_component_index += 1 - if self.parentApp.current_component_index < len(self.parentApp.selected_components): - next_component = self.parentApp.selected_components[self.parentApp.current_component_index] - self.parentApp.switchForm(next_component) - else: - self.parentApp.setNextForm(None) - - def on_cancel(self): - if npyscreen.notify_yes_no("¿Estás seguro de que deseas salir?", title="Confirmación"): - self.parentApp.setNextForm(None) - -class OgCoreForm(ComponentForm): - component_name = "ogCore" - - def configure_fields(self): - self.fields["username"] = {"widget": self.add(npyscreen.TitleText, name="Usuario administrador (ogadmin):", value="ogadmin")} - self.add_password_field("password", "Contraseña:" , default_value="12345678") - self.add_password_field("confirm_password", "Confirmar Contraseña:", is_confirmation=True, default_value="12345678") - -class OgGuiForm(ComponentForm): - component_name = "ogGui" - - def configure_fields(self): - self.fields["ogcore_ip"] = {"widget": self.add(npyscreen.TitleText, name="URL Api OgCore (https://127.0.0.1:8443):", value="https://127.0.0.1:8443")} - self.fields["mercure_ip"] = {"widget": self.add(npyscreen.TitleText, name="Mercue IP (127.0.0.1):", value="127.0.0.1")} -class OgDhcpForm(ComponentForm): - component_name = "ogDhcp" - - def configure_fields(self): - self.fields["ogbootIP"] = {"widget": self.add(npyscreen.TitleText, name="IP servidor de Boot (127.0.0.1):", value="127.0.0.1")} - self.fields["ogDhcpIP"] = {"widget": self.add(npyscreen.TitleText, name="IP servidor de DHCP (127.0.0.1):", value="127.0.0.1")} - self.fields["ogDhcp_Dir"] = {"widget": self.add(npyscreen.TitleText, name="Directorio de ogdhcp (/opt/opengnsys/ogdhcp):", value="/opt/opengnsys/ogdhcp")} - self.fields["interfaces"] = {"widget": self.add(npyscreen.TitleText, name="Interfaces Boot (eth0,eth1):", value="eth0,eth1")} - - def on_ok(self): - if not self.validate_fields(): - return # Si las validaciones fallan, no proceder - - npyscreen.blank_terminal() - config_data = {"release": self.parentApp.selected_tag} - for key, field_data in self.fields.items(): - if key == "interfaces": - config_data[key] = [iface.strip() for iface in field_data["widget"].value.split(",")] - else: - config_data[key] = field_data["widget"].value - - config_file = os.path.join(CONFIGS_DIR, f"config_{self.component_name}.json") - with open(config_file, "w") as f: - json.dump(config_data, f) - npyscreen.notify_confirm(f"Configuración de {self.component_name} guardada en {config_file}", title="Confirmación") - - self.parentApp.current_component_index += 1 - if self.parentApp.current_component_index < len(self.parentApp.selected_components): - next_component = self.parentApp.selected_components[self.parentApp.current_component_index] - self.parentApp.switchForm(next_component) - else: - self.parentApp.setNextForm(None) - -class OgBootForm(ComponentForm): - component_name = "ogBoot" - - def configure_fields(self): - self.fields["ogCore_ServerIP"] = {"widget": self.add(npyscreen.TitleText, name="ogCore IP:", value="")} - self.fields["ogBoot_ServerIP"] = {"widget": self.add(npyscreen.TitleText, name="ogBoot Server IP:", value="")} - self.fields["ogBoot_Dir"] = {"widget": self.add(npyscreen.TitleText, name="ogCore Dir (/opt/opengnsys/ogboot):", value="/opt/opengnsys/ogboot")} - self.fields["ogLive_Default"] = {"widget": self.add(npyscreen.TitleText, name="ogLive por defecto:", value="https://ognproject.evlt.uma.es/oglive/ogLive-noble-6.8.0-31-generic-amd64-r20250116.538e3fa_20250120.iso")} - self.fields["ogBootSambaUser"] = {"widget": self.add(npyscreen.TitleText, name="ogBoot Samba User (opengnsys):", value="opengnsys")} - self.add_password_field("ogBootSambaPass", "ogBoot Samba Pass (og):", default_value="og") - self.add_password_field("confirm_ogBootSambaPass", "Confirmar ogBoot Samba Pass (og):", is_confirmation=True, default_value="og") - - -class OgRepositoryForm(ComponentForm): - component_name = "ogRepository" - - def configure_fields(self): - self.fields["ogrepository_ip"] = {"widget": self.add(npyscreen.TitleText, name="ogRepository IP:", value="127.0.0.1")} - self.fields["ogcore_server_ip"] = {"widget": self.add(npyscreen.TitleText, name="ogCoreserver IP(127.0.0.1):", value="127.0.0.1")} - self.fields["ogrepository_samba_user"] = {"widget": self.add(npyscreen.TitleText, name="Samba User:", value="opengnsys")} - self.add_password_field("ogrepository_samba_pass", "Samba Password:", default_value="og") - self.add_password_field("confirm_repository_password", "Confirmar Samba Password:", is_confirmation=True, default_value="og") - -class ConfigApp(npyscreen.NPSAppManaged): - def onStart(self): - self.addForm("MAIN", ComponentSelectionForm, name="Selección de Componentes") - self.addForm("ogCore", OgCoreForm, name="Configuración de ogCore") - self.addForm("ogGui", OgGuiForm, name="Configuración de ogGui") - self.addForm("ogDhcp", OgDhcpForm, name="Configuración de ogDhcp") - self.addForm("ogBoot", OgBootForm, name="Configuración de ogBoot") - self.addForm("ogRepository", OgRepositoryForm, name="Configuración de ogRepository") - self.selected_components = [] - self.selected_tag = "" - self.current_component_index = 0 - -if __name__ == "__main__": - app = ConfigApp() - app.run() diff --git a/non_graf_installer/python-installer/oginstaller-v3.py b/non_graf_installer/python-installer/oginstaller-v3.py index 52aa79e..d44c9ea 100644 --- a/non_graf_installer/python-installer/oginstaller-v3.py +++ b/non_graf_installer/python-installer/oginstaller-v3.py @@ -9,6 +9,7 @@ import socket import sys # Importar sys para leer los argumentos del script import logging # Importar el módulo logging import shutil # Importar para verificar el tamaño del terminal +import json # Importar para manejar JSON CONFIGS_DIR = "/tmp/oginstall" LOGS_DIR = "/var/log/oginstaller" @@ -183,11 +184,24 @@ class MononodoConfigForm(npyscreen.ActionForm): name="IP del servidor (mononodo):", value=get_default_ip() ) + self.samba_user = self.add( + npyscreen.TitleText, + name="Usuario Samba:", + value="opengnsys" + ) + self.samba_pass = self.add( + npyscreen.TitlePassword, + name="Contraseña Samba:", + value="og", + scroll_exit=True + ) def on_ok(self): """Guardar la configuración y pasar al siguiente formulario.""" logging.debug(f"Entrando en MononodoConfigForm") self.parentApp.server_ip = self.server_ip.value + self.parentApp.samba_user = self.samba_user.value + self.parentApp.samba_pass = self.samba_pass.value self.parentApp.setNextForm("MAIN") def on_cancel(self): @@ -218,6 +232,17 @@ class MultinodoConfigForm(npyscreen.ActionForm): name="IP del servidor Boot:", value=get_default_ip() ) + self.samba_user = self.add( + npyscreen.TitleText, + name="Usuario Samba:", + value="opengnsys" + ) + self.samba_pass = self.add( + npyscreen.TitlePassword, + name="Contraseña Samba:", + value="og", + scroll_exit=True + ) def on_ok(self): """Guardar la configuración y pasar al siguiente formulario.""" @@ -225,6 +250,8 @@ class MultinodoConfigForm(npyscreen.ActionForm): self.parentApp.dhcp_ip = self.dhcp_ip.value self.parentApp.core_ip = self.core_ip.value self.parentApp.boot_ip = self.boot_ip.value + self.parentApp.samba_user = self.samba_user.value + self.parentApp.samba_pass = self.samba_pass.value self.parentApp.setNextForm("MAIN") def on_cancel(self): @@ -552,6 +579,20 @@ class OgBootForm(ComponentForm): elif self.parentApp.installation_type == "multinodo": return self.parentApp.core_ip + def get_samba_user(self): + """Obtiene el usuario Samba.""" + if self.parentApp.installation_type == "mononodo": + return self.parentApp.samba_user + elif self.parentApp.installation_type == "multinodo": + return self.parentApp.samba_user + + def get_samba_user_pass(self): + """Obtiene la contraseña del usuario Samba.""" + if self.parentApp.installation_type == "mononodo": + return self.parentApp.samba_pass + elif self.parentApp.installation_type == "multinodo": + return self.parentApp.samba_pass + def configure_fields(self): # Obtener la lista de oglives oglives = get_oglive_list() @@ -594,26 +635,26 @@ class OgBootForm(ComponentForm): highlighted=True ) } - # self.fields["sambaUser"] = {"widget": self.add(npyscreen.TitleText, name="Usuario Samba:", value="opengnsys", rely=20)} - self.add(npyscreen.FixedText, value="Usuario Samba:", editable=False, rely=14, relx=2, color="SAFE" , highlighted=True) - self.fields["sambaUser"] = { - "widget": self.add( - npyscreen.Textfield, - value="opengnsys", - rely=15, # Línea siguiente - relx=18, - highlighted=True - ) - } - #self.fields["sambaUserPass"] = {"widget": self.add(npyscreen.TitlePassword, name="Contraseña Samba:", value="og", rely=22)} - self.fields["sambaUserPass"] = { - "widget": self.add( - npyscreen.TitlePassword, - name="Contraseña Samba:", - value="og", - rely=16, # Línea siguiente - ) - } + # # self.fields["sambaUser"] = {"widget": self.add(npyscreen.TitleText, name="Usuario Samba:", value="opengnsys", rely=20)} + # self.add(npyscreen.FixedText, value="Usuario Samba:", editable=False, rely=14, relx=2, color="SAFE" , highlighted=True) + # self.fields["sambaUser"] = { + # "widget": self.add( + # npyscreen.Textfield, + # value="opengnsys", + # rely=15, # Línea siguiente + # relx=18, + # highlighted=True + # ) + # } + # #self.fields["sambaUserPass"] = {"widget": self.add(npyscreen.TitlePassword, name="Contraseña Samba:", value="og", rely=22)} + # self.fields["sambaUserPass"] = { + # "widget": self.add( + # npyscreen.TitlePassword, + # name="Contraseña Samba:", + # value="og", + # rely=16, # Línea siguiente + # ) + # } #self.fields["port"] = {"widget": self.add(npyscreen.TitleText, name="Puerto Boot:", value="8082",hidden=True, rely=16)} self.add(npyscreen.FixedText, value="Puerto Boot:", editable=False, rely=12, relx=2, color="SAFE" , highlighted=True,hidden=True) self.fields["port"] = { @@ -640,8 +681,10 @@ class OgBootForm(ComponentForm): "ip": self.fields["ip"]["widget"].value, "port": self.fields["port"]["widget"].value, "ogcoreUrl": self.fields["ogcoreUrl"]["widget"].value, - "sambaUser": self.fields["sambaUser"]["widget"].value, - "sambaUserPass": self.fields["sambaUserPass"]["widget"].value, + "sambaUser": self.get_samba_user(), + "sambaUserPass": self.get_samba_user_pass(), + # "sambaUser": self.fields["sambaUser"]["widget"].value, + # "sambaUserPass": self.fields["sambaUserPass"]["widget"].value, } # Continuar con el siguiente formulario @@ -669,6 +712,20 @@ class OgRepositoryForm(ComponentForm): return self.parentApp.server_ip elif self.parentApp.installation_type == "multinodo": return self.parentApp.core_ip + + def get_samba_user(self): + """Obtiene el usuario Samba.""" + if self.parentApp.installation_type == "mononodo": + return self.parentApp.samba_user + elif self.parentApp.installation_type == "multinodo": + return self.parentApp.samba_user + + def get_samba_user_pass(self): + """Obtiene la contraseña del usuario Samba.""" + if self.parentApp.installation_type == "mononodo": + return self.parentApp.samba_pass + elif self.parentApp.installation_type == "multinodo": + return self.parentApp.samba_pass def configure_fields(self): # Campo para la IP del Repositorio @@ -694,26 +751,26 @@ class OgRepositoryForm(ComponentForm): ) } - # Campo para el Usuario Samba - self.add(npyscreen.FixedText, value="Usuario Samba:", editable=False, rely=8, relx=2, color="SAFE" , highlighted=True) - self.fields["sambaUser"] = { - "widget": self.add( - npyscreen.Textfield, - value="opengnsys", - rely=9, # Línea siguiente - relx=18 , - ) - } + # # Campo para el Usuario Samba + # self.add(npyscreen.FixedText, value="Usuario Samba:", editable=False, rely=8, relx=2, color="SAFE" , highlighted=True) + # self.fields["sambaUser"] = { + # "widget": self.add( + # npyscreen.Textfield, + # value="opengnsys", + # rely=9, # Línea siguiente + # relx=18 , + # ) + # } - # Campo para la Contraseña Samba - self.fields["sambaUserPass"] = { - "widget": self.add( - npyscreen.TitlePassword, - name="Contraseña Samba:", - value="og", - rely=11 # Mantener el uso de TitlePassword - ) - } + # # Campo para la Contraseña Samba + # self.fields["sambaUserPass"] = { + # "widget": self.add( + # npyscreen.TitlePassword, + # name="Contraseña Samba:", + # value="og", + # rely=11 # Mantener el uso de TitlePassword + # ) + # } class InstallationProgressForm(npyscreen.Form): """Formulario para mostrar el progreso de instalación y el log en tiempo real.""" @@ -730,8 +787,8 @@ class InstallationProgressForm(npyscreen.Form): self.log_box = self.add( npyscreen.BoxTitle, name="Log de instalación", - max_height=8, - rely=8, + max_height=20, + rely=10, relx=2, scroll_exit=True ) @@ -744,13 +801,14 @@ class InstallationProgressForm(npyscreen.Form): bar_length = 30 # Longitud de la barra filled_length = int(bar_length * current // total) bar = f"[{'=' * filled_length}{' ' * (bar_length - filled_length)}] {progress_percentage}%" - self.progress_box.values.append(bar) - self.progress_box.values.append(message) + self.progress_box.values = [bar, message] + else: + self.progress_box.values = [message] self.progress_box.display() def update_log(self, new_line): """Actualiza el log en tiempo real en la parte inferior.""" - max_lines = 10 # Número máximo de líneas a mostrar + max_lines = 14 # Número máximo de líneas a mostrar self.log_box.values.append(new_line.strip()) # Agregar la nueva línea self.log_box.values = self.log_box.values[-max_lines:] # Mantener solo las últimas `max_lines` líneas self.log_box.display() @@ -813,6 +871,74 @@ def install_components_with_ui(form, components, selected_tag): else: form.update_progress("Paquete ogclient instalado correctamente.") installed_packages.append("ogclient") + # Si hemos instalado ogcore, configuramos las variables del archivo env.json + + if "ogcore" in installed_packages: + form.update_progress("Configurando variables de entorno para ogcore...") + print ("Configurando variables de entorno para ogcore...") + logging.debug("Configurando variables de entorno para ogcore...") + + ogDhcpIp = form.parentApp.server_ip if form.parentApp.installation_type == "mononodo" else form.parentApp.dhcp_ip + ogCoreIp = form.parentApp.server_ip if form.parentApp.installation_type == "mononodo" else form.parentApp.core_ip + ogBootIp = form.parentApp.server_ip if form.parentApp.installation_type == "mononodo" else form.parentApp.boot_ip + + env_path = "/opt/opengnsys/ogcore/api/env.json" + shutil.copy(env_path, env_path + ".bak") # Hacer una copia de seguridad del archivo original + with open(env_path, "r") as env_file: + data = json.load(env_file) + + # Modificar los valores + data["vars"]["OG_DHCP_API_URL"] = f"{ogDhcpIp}:8081" + data["vars"]["OG_CORE_IP"] = ogCoreIp + data["vars"]["OG_BOOT_IP"] = ogBootIp + + with open(env_path, "w", encoding="utf-8") as f: + json.dump(data, f, indent=4) + form.update_progress("Variables de entorno para ogcore configuradas correctamente.") + + ## Si la password de samba no es la por defecto o el usuario samba no es por defecto, cambiarla en los oglives y en el sistema con el comando smbpasswd + ## Si el paquete ogboot está instalado se cambia la password en los oglives. Si el paquete ogrepository está instalado se cambia la password en el sistema. + samba_user = form.parentApp.samba_user + samba_pass = form.parentApp.samba_pass + is_ogrepository_installed = "ogrepository" in installed_packages + is_ogboot_installed = "ogboot" in installed_packages + passwd_changed = (samba_pass != "og" or samba_user != "opengnsys") + + if passwd_changed and (is_ogrepository_installed or is_ogboot_installed): + form.update_progress("Cambiando la contraseña del usuario Samba...") + change_pass_command = f"echo -e '{samba_pass}\n{samba_pass}' | smbpasswd -s -a {samba_user}" + change_pass_process = subprocess.Popen( + change_pass_command, shell=True, text=True, stdout=log_file, stderr=log_file, bufsize=1 + ) + change_pass_process.wait() + log_file.flush() + form.update_progress("Cambiando la contraseña del usuario de Samba en los oglves ...") + + if change_pass_process.returncode != 0: + error_message = f"Error al cambiar la contraseña del usuario Samba. Consulta el archivo de registro: {log_file_path}" + form.update_progress(error_message) + failed_packages.append("Cambio de contraseña Samba") + else: + form.update_progress("Contraseña del usuario Samba cambiada correctamente.") + + if passwd_changed and is_ogboot_installed: + form.update_progress("Cambiando la contraseña del usuario Samba en los oglives...") + change_pass_command = "/opt/opengnsys/ogboot/bin/setsmbpass" + env= os.environ.copy() + env['SAMBAUSER'] = samba_user + env['SAMBAPASS'] = samba_pass + change_pass_process = subprocess.Popen( + change_pass_command, shell=True, text=True, stdout=log_file, stderr=log_file, bufsize=1 , env=env + ) + change_pass_process.wait() + log_file.flush() + if change_pass_process.returncode != 0: + error_message = f"Error al cambiar la contraseña del usuario Samba en los oglives. Consulta el archivo de registro: {log_file_path}" + form.update_progress(error_message) + failed_packages.append("Cambio de contraseña Samba en oglives") + else: + form.update_progress("Contraseña del usuario Samba en oglives cambiada correctamente.") + except Exception as e: try: form.update_progress(f"Error durante la instalación: {e}") @@ -854,7 +980,7 @@ class MyApp(npyscreen.NPSAppManaged): self.repo_ip = None # IP del servidor Repository self.dhcp_ip = None # IP del servidor DHCP self.core_ip = None # IP del servidor Core - self.boot_ip = None # IP del servidor Bootdpkg + self.boot_ip = None # IP del servidor Boot dpkg self.selected_components = [] # Componentes seleccionados self.selected_tag = None # Versión seleccionada self.configurations = {} # Configuraciones de los componentes @@ -958,7 +1084,7 @@ class MyApp(npyscreen.NPSAppManaged): self.switchForm("INSTALLATION_PROGRESS") install_components_with_ui(form, self.selected_components, self.selected_tag) -def check_terminal_size(min_width=80, min_height=24): +def check_terminal_size(min_width=80, min_height=32): """Verifica si el tamaño del terminal es suficiente.""" terminal_size = shutil.get_terminal_size() if terminal_size.columns < min_width or terminal_size.lines < min_height: diff --git a/non_graf_installer/python-installer/oginstaller.py b/non_graf_installer/python-installer/oginstaller.py deleted file mode 100755 index 08cb6ba..0000000 --- a/non_graf_installer/python-installer/oginstaller.py +++ /dev/null @@ -1,220 +0,0 @@ -import curses -import json -import os -from git import Repo - -CONFIGS_DIR = "/tmp/oginstall" -os.makedirs(CONFIGS_DIR, exist_ok=True) - -REPO_URL = "https://ognproject.evlt.uma.es/gitea/opengnsys/ogcore.git" - -def get_git_tags(): - try: - repo_path = os.path.join(CONFIGS_DIR, "opengnsys_repo") - if not os.path.exists(repo_path): - print("Clonando el repositorio...") - Repo.clone_from(REPO_URL, repo_path) - else: - print("Usando repositorio existente en", repo_path) - - repo = Repo(repo_path) - tags = [tag.name for tag in repo.tags] - if tags: - print("Tags encontrados:", tags) - else: - print("No se encontraron tags con el patrón especificado.") - - return tags - except Exception as e: - print("Error al obtener los tags:", str(e)) - return [] - -def get_password(stdscr, y, x, prompt, default=""): - stdscr.addstr(y, x, prompt, curses.color_pair(1)) - password = "" - masked_password = "" - - stdscr.move(y, x + len(prompt)) # Coloca el cursor después del prompt - - while True: - key = stdscr.getch() - if key in (curses.KEY_BACKSPACE, 127): # Maneja el retroceso - if len(password) > 0: - password = password[:-1] - masked_password = "*" * len(password) - stdscr.move(y, x + len(prompt)) # Mueve el cursor después del prompt - stdscr.addstr(y, x + len(prompt), " " * (len(masked_password) + 1)) # Borra la línea - stdscr.addstr(y, x + len(prompt), masked_password) # Vuelve a mostrar los asteriscos actualizados - elif key == ord("\n"): # Confirmar con Enter - if not password and default: # Si el usuario no ingresó nada, usa el valor predeterminado - password = default - break - elif 32 <= key <= 126: # Rango de caracteres imprimibles - password += chr(key) - masked_password = "*" * len(password) - stdscr.addstr(y, x + len(prompt), masked_password) # Muestra asteriscos - - return password - -def get_input(stdscr, y, x, prompt, default=""): - max_y, max_x = stdscr.getmaxyx() - if x + len(prompt) >= max_x: - raise ValueError("El prompt es demasiado largo para caber en la pantalla.") - - stdscr.addstr(y, x, prompt, curses.color_pair(1)) - input_text = "" - prompt_end_x = x + len(prompt) # Calcula la posición final del prompt - stdscr.move(y, prompt_end_x) # Coloca el cursor después del prompt - - while True: - key = stdscr.getch() - if key in (curses.KEY_BACKSPACE, 127): # Maneja el retroceso - if len(input_text) > 0: - input_text = input_text[:-1] - stdscr.move(y, prompt_end_x) # Mueve el cursor después del prompt - stdscr.clrtoeol() # Limpia la línea desde la posición actual hacia el final - stdscr.addstr(y, prompt_end_x, input_text) # Vuelve a mostrar el texto actualizado - stdscr.move(y, prompt_end_x + len(input_text)) - elif key == ord("\n"): # Confirmar con Enter - if not input_text and default: # Usa el valor predeterminado si está vacío - input_text = default - break - elif 32 <= key <= 126: # Rango de caracteres imprimibles - if prompt_end_x + len(input_text) < max_x - 1: - input_text += chr(key) - stdscr.addstr(y, prompt_end_x, input_text) # Muestra el texto actualizado - stdscr.move(y, prompt_end_x + len(input_text)) # Mueve el cursor al final del texto - - return input_text - -def main(stdscr): - # Inicializar colores - curses.start_color() - curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE) - stdscr.bkgd(' ', curses.color_pair(1)) - - curses.curs_set(0) - stdscr.clear() - - # Paso 1: Seleccionar componentes - components = ["ogCore", "ogGui", "ogDhcp", "ogBoot", "ogRepository"] - selected_components = [] - current_index = 0 - - # Mostrar instrucciones y opciones de componentes - stdscr.addstr(1, 2, "Selecciona los componentes (usa Flechas para navegar, Espacio para seleccionar, Enter para continuar):", curses.color_pair(1) | curses.A_BOLD) - - while True: - for idx, comp in enumerate(components): - if comp in selected_components: - stdscr.addstr(idx + 3, 4, f"[X] {comp}", curses.color_pair(1)) - else: - stdscr.addstr(idx + 3, 4, f"[ ] {comp}", curses.color_pair(1)) - stdscr.addstr(current_index + 3, 4, f"> {components[current_index]}", curses.color_pair(1)) - - key = stdscr.getch() - - if key == curses.KEY_UP and current_index > 0: - current_index -= 1 - elif key == curses.KEY_DOWN and current_index < len(components) - 1: - current_index += 1 - elif key == ord(" "): - component = components[current_index] - if component in selected_components: - selected_components.remove(component) - else: - selected_components.append(component) - elif key == ord("\n"): - break - - stdscr.refresh() - - # Menu de selección de releases - tags = get_git_tags() - tag_index = 0 - - stdscr.clear() - - while True: - for idx, tag in enumerate(tags): - if idx == tag_index: - stdscr.addstr(idx + 3, 4, f"> {tag}", curses.color_pair(1)) - else: - stdscr.addstr(idx + 3, 4, f" {tag}", curses.color_pair(1)) - - key = stdscr.getch() - - if key == curses.KEY_UP and tag_index > 0: - tag_index -= 1 - elif key == curses.KEY_DOWN and tag_index < len(tags) - 1: - tag_index += 1 - elif key == ord("\n"): - break - - stdscr.refresh() - - # Configuración específica de cada componente seleccionado - curses.echo() - for component in selected_components: - stdscr.clear() - stdscr.addstr(1, 2, f"Configuración para {component}:", curses.color_pair(1) | curses.A_BOLD) - curses.curs_set(1) - - config_data = {} - if component == "ogCore": - user = get_input(stdscr, 3, 0, "Usuario administrador (ogadmin): ", "ogadmin") - password = get_password(stdscr, 4, 0, "Contraseña (por defecto '12345678'): ", "12345678") - config_data = {"username": user, "password": password, "container_version": tags[tag_index]} - - elif component == "ogGui": - ogcore_ip = get_input(stdscr, 3, 0, "URL Api OgCore (https://127.0.0.1:8443): " , "https://127.0.0.1:8443") - config_data = {"ogcore_ip": ogcore_ip, "container_version": tags[tag_index]} - - elif component == "ogDhcp": - ogbootIP = get_input(stdscr, 3, 0, "IP servidor de Boot (127.0.0.1): ", "127.0.0.1") - ogdhcpIP = get_input(stdscr, 4, 0, "IP servidor de DHCP (127.0.0.1): ", "127.0.0.1") - ogdhcpDir = get_input(stdscr, 5, 0, "Directorio de ogdhcp (/opt/opengnsys/ogdhcp): ", "/opt/opengnsys/ogdhcp") - interfaces = get_input(stdscr, 6, 0, "Interfaces Boot (eth0,eth1): ", "eth0,eth1") - json_array_interfaces = interfaces.split(",") - config_data = {"ogbootIP": ogbootIP, "ogDhcpIP": ogdhcpIP , "ogDhcp_Dir" : ogdhcpDir , "interfaces": json_array_interfaces, "release": tags[tag_index]} - - elif component == "ogBoot": - ogcore_ip = get_input(stdscr, 3, 0, "ogCore Ip Server: ", "") - ogboot_server_ip = get_input(stdscr, 4, 0, "ogBoot Server IP: ", "") - ogcore_dir = get_input(stdscr, 5, 0, "ogCore Dir (/opt/opengnsys/ogboot): ", "/opt/opengnsys/ogboot") - ogLive_default = get_input(stdscr, 6, 0, "ogLive por defecto (ogLive-noble-6.8.0-31-generic-amd64-r20241128.62778c9_20241129): ", "ogLive-noble-6.8.0-31-generic-amd64-r20241128.62778c9_20241129") - ogboot_samba_user = get_input(stdscr, 7, 0, "ogBoot Samba User (opengnsys): ", "opengnsys") - ogboot_samba_pass = get_password(stdscr, 8, 0, "ogBoot Samba Pass (og): ", "og") - config_data = { - "ogCore_ServerIP": ogcore_ip, - "ogBoot_ServerIP": ogboot_server_ip, - "ogBoot_Dir": ogcore_dir, - "ogLive_Default": "https://ognproject.evlt.uma.es/oglive/" + ogLive_default + ".iso", - "ogBootSambaUser": ogboot_samba_user, - "ogBootSambaPass": ogboot_samba_pass, - "release": tags[tag_index] - } - - elif component == "ogRepository": - ogrepository_ip = get_input(stdscr, 3, 0, "ogRepository IP Server (127.0.0.1): ", "") - ogrepository_samba_user = get_input(stdscr, 4, 0, "ogRepository Sambauser (opengnsys): ", "opengnsys") - ogrepository_samba_pass = get_password(stdscr, 5, 0, "ogRepository Sambapass (og): ", "og") - config_data = { - "ogrepository_ip": ogrepository_ip, - "ogrepository_samba_user": ogrepository_samba_user, - "ogrepository_samba_pass": ogrepository_samba_pass, - "release": tags[tag_index] - } - - # Guardar en archivo JSON - config_file = os.path.join(CONFIGS_DIR, f"config_{component}.json") - with open(config_file, "w") as f: - json.dump(config_data, f) - stdscr.clear() - stdscr.addstr(2, 2, f"Configuración de {component} guardada en {config_file}", curses.color_pair(1)) - stdscr.refresh() - stdscr.getch() - - curses.noecho() # Desactivar el eco después de la entrada - -curses.wrapper(main) diff --git a/non_graf_installer/python-installer/opengnsys_installer-v2.sh b/non_graf_installer/python-installer/opengnsys_installer-v2.sh deleted file mode 100755 index 1eb9aa4..0000000 --- a/non_graf_installer/python-installer/opengnsys_installer-v2.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - -# Setup installer environment - - -BRANCH=${BRANCH:-main} -GIT_SSL_NO_VERIFY=1 -GIT_REPO="https://ognproject.evlt.uma.es/gitea/api/v1/repos/opengnsys/oginstaller/archive/$BRANCH.zip" -export GIT_SSL_NO_VERIFY -DEVEL=$1 - -if [ "$DEVEL" == "devel" ]; then - INSTALL_DEVEL=1 -elif [ "$DEVEL" == "nightly" ]; then - INSTALL_NIGHTLY=1 -else - INSTALL_STABLE=1 -fi - -install_packages() { - apt-get update - apt-get install -y curl jq unzip python3 python3-git -} - - -create_python_venv() { - apt-get install -y python3-venv - python3 -m venv /tmp/oginstall/venv - source /tmp/oginstall/venv/bin/activate - pip install -r /tmp/oginstall/requirements.txt -} - -download_installer() { - - rm -f /tmp/oginstaller.zip - rm -rf /tmp/oginstaller-$BRANCH - rm -rf /tmp/oginstaller - - curl -q -k $GIT_REPO -H 'accept: application/json' -o /tmp/oginstaller.zip - unzip /tmp/oginstaller.zip -d /tmp - mv /tmp/oginstaller /tmp/oginstaller-$BRANCH -} - -extract_installer() { - rm -rf /tmp/oginstall - mkdir -p /tmp/oginstall - cp -r /tmp/oginstaller-$BRANCH/non_graf_installer/python-installer/* /tmp/oginstall/ - chmod 755 /tmp/oginstall/*.py -} - -create_questions() { - echo "Creating questions..." - if [ $INSTALL_DEVEL ] ; then - python3 /tmp/oginstall/oginstaller-v3.py devel - elif [ $INSTALL_NIGHTLY ] ; then - python3 /tmp/oginstall/oginstaller-v3.py nightly - else - python3 /tmp/oginstall/oginstaller-v3.py - fi - deactivate -} - -clean_tmp() { - rm -rf /tmp/oginstall - rm -rf /tmp/oginstaller-$BRANCH - rm -f /tmp/oginstaller.zip -} - - -install_packages -download_installer -extract_installer -create_python_venv -create_questions -clean_tmp diff --git a/non_graf_installer/python-installer/opengnsys_installer.sh b/non_graf_installer/python-installer/opengnsys_installer.sh index b38aa94..1eb9aa4 100755 --- a/non_graf_installer/python-installer/opengnsys_installer.sh +++ b/non_graf_installer/python-installer/opengnsys_installer.sh @@ -7,8 +7,15 @@ BRANCH=${BRANCH:-main} GIT_SSL_NO_VERIFY=1 GIT_REPO="https://ognproject.evlt.uma.es/gitea/api/v1/repos/opengnsys/oginstaller/archive/$BRANCH.zip" export GIT_SSL_NO_VERIFY +DEVEL=$1 - +if [ "$DEVEL" == "devel" ]; then + INSTALL_DEVEL=1 +elif [ "$DEVEL" == "nightly" ]; then + INSTALL_NIGHTLY=1 +else + INSTALL_STABLE=1 +fi install_packages() { apt-get update @@ -38,22 +45,21 @@ extract_installer() { rm -rf /tmp/oginstall mkdir -p /tmp/oginstall cp -r /tmp/oginstaller-$BRANCH/non_graf_installer/python-installer/* /tmp/oginstall/ - cp -r /tmp/oginstaller-$BRANCH/non_graf_installer/component-installer/* /tmp/oginstall/ - chmod 755 /tmp/oginstall/*.sh chmod 755 /tmp/oginstall/*.py } create_questions() { echo "Creating questions..." - python3 /tmp/oginstall/oginstaller-v2.py + if [ $INSTALL_DEVEL ] ; then + python3 /tmp/oginstall/oginstaller-v3.py devel + elif [ $INSTALL_NIGHTLY ] ; then + python3 /tmp/oginstall/oginstaller-v3.py nightly + else + python3 /tmp/oginstall/oginstaller-v3.py + fi deactivate } -launch_component_installer() { - echo "Launching component installer..." - /tmp/oginstall/component-installer.sh -} - clean_tmp() { rm -rf /tmp/oginstall rm -rf /tmp/oginstaller-$BRANCH @@ -66,5 +72,4 @@ download_installer extract_installer create_python_venv create_questions -launch_component_installer clean_tmp