From 6983bba2947a810f824e06ce6eddb5ddba1f4398 Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Wed, 14 May 2025 07:00:27 +0200 Subject: [PATCH] Updted installer --- .../python-installer/oginstaller-v3.py | 121 ++++++++++-------- 1 file changed, 66 insertions(+), 55 deletions(-) diff --git a/non_graf_installer/python-installer/oginstaller-v3.py b/non_graf_installer/python-installer/oginstaller-v3.py index 07e1e03..7dc0079 100644 --- a/non_graf_installer/python-installer/oginstaller-v3.py +++ b/non_graf_installer/python-installer/oginstaller-v3.py @@ -95,6 +95,7 @@ def get_available_versions(): def get_default_ip(): """Obtiene la IP asociada a la interfaz por defecto del servidor.""" + logging.debug("Obteniendo la IP por defecto del servidor.") try: # Obtener la interfaz asociada a la ruta por defecto result = subprocess.run( @@ -106,7 +107,9 @@ def get_default_ip(): # Extraer la interfaz de la salida interface = next((line.split()[-1] for line in result.stdout.splitlines() if "dev" in line), None) if not interface: + logging.error("No se pudo determinar la interfaz por defecto.") raise ValueError("No se pudo determinar la interfaz por defecto.") + logging.debug(f"Interfaz por defecto: {interface}") # Obtener la IP de la interfaz with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s: @@ -114,7 +117,7 @@ def get_default_ip(): ip_address = s.getsockname()[0] return ip_address except Exception as e: - print(f"Error al obtener la IP por defecto: {e}") + logging.error(f"Error al obtener la IP por defecto: {e}") return "192.168.2.2" # Valor por defecto def get_oglive_list(): @@ -123,6 +126,7 @@ def get_oglive_list(): # Realizar la solicitud HTTP response = requests.get("https://ognproject.evlt.uma.es/oglive/", timeout=10) response.raise_for_status() # Lanza una excepción si la respuesta no es 200 OK + # Registrar el contenido de la respuesta para depuración # Extraer los enlaces del contenido HTML from bs4 import BeautifulSoup @@ -133,7 +137,7 @@ def get_oglive_list(): sorted_links = sorted(links, key=lambda x: x.split("_")[1] if "_" in x else x, reverse=True) return sorted_links except Exception as e: - print(f"Error al obtener la lista de oglives: {e}") + logging.error(f"Error al obtener la lista de oglives: {e}") return [] # Devolver una lista vacía en caso de error # Variable global para la IP por defecto @@ -151,17 +155,20 @@ class InstallationTypeForm(npyscreen.ActionForm): def on_ok(self): """Guardar la selección y pasar al formulario correspondiente.""" + logging.debug(f"Entrando en InstallationTypeForm") if self.installation_type.value is None: npyscreen.notify_confirm("Debes seleccionar un tipo de instalación.", title="Error") return if self.installation_type.value == [0]: # Mononodo + logging.debug("Instalación mononodo seleccionada.") self.parentApp.installation_type = "mononodo" self.parentApp.setNextForm("MONONODO_CONFIG") elif self.installation_type.value == [1]: # Multinodo + logging.debug("Instalación multinodo seleccionada.") self.parentApp.installation_type = "multinodo" self.parentApp.setNextForm("MULTINODO_CONFIG") - + def on_cancel(self): """Salir de la aplicación.""" if npyscreen.notify_yes_no("¿Estás seguro de que deseas salir?", title="Confirmación"): @@ -179,6 +186,7 @@ class MononodoConfigForm(npyscreen.ActionForm): 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.setNextForm("MAIN") @@ -707,22 +715,24 @@ class OgRepositoryForm(ComponentForm): ) } -class InstallationProgressForm(npyscreen.FormBaseNew): +class InstallationProgressForm(npyscreen.Form): """Formulario para mostrar el progreso de instalación y el log en tiempo real.""" - # Crear la parte superior para el progreso de instalación def create(self): - # Usa tamaños fijos razonables que funcionen incluso en terminales pequeños + # Ajustar alturas para evitar problemas de espacio self.progress_box = self.add( npyscreen.BoxTitle, name="Progreso de instalación", - max_height=10, + max_height=6, + rely=1, + relx=2, scroll_exit=True ) - self.log_box = self.add( npyscreen.BoxTitle, name="Log de instalación", - max_height=10, + max_height=8, + rely=8, + relx=2, scroll_exit=True ) @@ -748,67 +758,54 @@ class InstallationProgressForm(npyscreen.FormBaseNew): def install_components_with_ui(form, components, selected_tag): """Instala los componentes seleccionados mostrando el progreso y el log en tiempo real.""" log_file_path = os.path.join(LOGS_DIR, "installation.log") - installed_packages = [] # Lista de paquetes instalados correctamente - failed_packages = [] # Lista de paquetes que fallaron - - # Registrar el tiempo de inicio + installed_packages = [] + failed_packages = [] start_time = time.time() try: - # Abrir el archivo de log en modo sin buffer - with open(log_file_path, "w", buffering=1) as log_file: # Line-buffered mode + with open(log_file_path, "w", buffering=1) as log_file: total_packages = len(components) - - # Hilo para leer el log en tiempo real def tail_log(): - with open(log_file_path, "r") as log_reader: - log_reader.seek(0, os.SEEK_END) # Ir al final del archivo - while True: - line = log_reader.readline() # Leer una nueva línea - if line: - form.update_log(line) # Actualizar el log en la interfaz - #time.sleep(0.1) # Pequeña pausa para evitar uso excesivo de CPU + try: + with open(log_file_path, "r") as log_reader: + log_reader.seek(0, os.SEEK_END) + while True: + line = log_reader.readline() + if line: + form.update_log(line) + except Exception as e: + # Mostrar error en log si ocurre + try: + form.update_log(f"[ERROR] {e}") + except Exception: + pass log_thread = threading.Thread(target=tail_log, daemon=True) log_thread.start() for index, package in enumerate(components, start=1): - # Actualizar el progreso en la parte superior con barra de progreso form.update_progress(f"Instalando paquete {index}/{total_packages}: {package}", current=index, total=total_packages) - - # Crear una barra de progreso para el paquete install_command = f"DEBIAN_FRONTEND=noninteractive apt-get install -y {package}" process = subprocess.Popen( - install_command, shell=True, text=True, stdout=log_file, stderr=log_file, bufsize=1 # Line-buffered + install_command, shell=True, text=True, stdout=log_file, stderr=log_file, bufsize=1 ) - - # Esperar a que el proceso de instalación termine process.wait() - - # Forzar el vaciado del buffer del archivo de log log_file.flush() - - # Registrar errores en el archivo de registro if process.returncode != 0: error_message = f"Error al instalar el paquete {package}. Consulta el archivo de registro: {log_file_path}" form.update_progress(error_message) - failed_packages.append(package) # Agregar a la lista de fallos + failed_packages.append(package) else: form.update_progress(f"Paquete {package} instalado correctamente.") - installed_packages.append(package) # Agregar a la lista de éxitos - - # Instalar ogclient si se está instalando ogboot + installed_packages.append(package) if package == "ogboot": form.update_progress("Instalando paquete adicional: ogclient") install_command = "DEBIAN_FRONTEND=noninteractive apt-get install -y ogclient" process = subprocess.Popen( - install_command, shell=True, text=True, stdout=log_file, stderr=log_file, bufsize=1 # Line-buffered + install_command, shell=True, text=True, stdout=log_file, stderr=log_file, bufsize=1 ) process.wait() - - # Forzar el vaciado del buffer del archivo de log log_file.flush() - if process.returncode != 0: error_message = f"Error al instalar el paquete ogclient. Consulta el archivo de registro: {log_file_path}" form.update_progress(error_message) @@ -817,14 +814,14 @@ def install_components_with_ui(form, components, selected_tag): form.update_progress("Paquete ogclient instalado correctamente.") installed_packages.append("ogclient") except Exception as e: - form.update_progress(f"Error durante la instalación: {e}") + try: + form.update_progress(f"Error durante la instalación: {e}") + except Exception: + print(f"[ERROR] {e}") failed_packages.append("Error general durante la instalación") - # Registrar el tiempo de finalización end_time = time.time() - duration = end_time - start_time # Calcular la duración en segundos - - # Generar el resumen + duration = end_time - start_time summary = "\n--- Resumen de la instalación ---\n" summary += f"Tiempo total de instalación: {duration:.2f} segundos\n" summary += f"Paquetes instalados correctamente: {len(installed_packages)}\n" @@ -838,11 +835,16 @@ def install_components_with_ui(form, components, selected_tag): summary += "\nTodos los paquetes se instalaron correctamente.\n" summary += f"\nConsulta el archivo de registro para más detalles: {log_file_path}" - # Mostrar el resumen en una ventana emergente - npyscreen.notify_confirm(summary, title="Resumen de la instalación", wide=True) + # Mostrar el resumen y salir del formulario + try: + npyscreen.notify_confirm(summary, title="Resumen de la instalación", wide=True) + except Exception as e: + print(summary) + print(f"[ERROR] {e}") - # Mostrar el resumen en la parte superior (opcional, si quieres mantenerlo en el formulario) - form.update_progress(summary) + # Forzar la salida de la aplicación después del resumen + import sys + sys.exit(0) class MyApp(npyscreen.NPSAppManaged): def onStart(self): @@ -852,7 +854,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 Boot + self.boot_ip = None # IP del servidor Bootdpkg self.selected_components = [] # Componentes seleccionados self.selected_tag = None # Versión seleccionada self.configurations = {} # Configuraciones de los componentes @@ -874,6 +876,7 @@ class MyApp(npyscreen.NPSAppManaged): def generate_debconf(self): # Comprobar si la clave pública ya existe + logging.debug("Entrando en generate_debconf") key_path = "/etc/apt/trusted.gpg.d/opengnsys.gpg" if os.path.exists(key_path): # Silenciar este mensaje @@ -881,16 +884,19 @@ class MyApp(npyscreen.NPSAppManaged): else: # Añadir la clave pública try: + logging.debug("Añadiendo la clave pública") subprocess.run( 'curl -k -L https://ognproject.evlt.uma.es/debian-opengnsys/public.key | gpg --dearmour -o /etc/apt/trusted.gpg.d/opengnsys.gpg', shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True ) except subprocess.CalledProcessError: - # Silenciar errores + logging.error("Error al añadir la clave pública") + return # Añadir el repositorio try: + logging.debug("Añadiendo el repositorio") selected_tag = self.selected_tag # Obtener el tag seleccionado # Determinar el valor de repo_line según el argumento recibido if len(sys.argv) > 1 and sys.argv[1].lower() == "devel": @@ -902,11 +908,13 @@ class MyApp(npyscreen.NPSAppManaged): with open('/etc/apt/sources.list.d/opengnsys.list', 'w') as repo_file: repo_file.write(repo_line + '\n') except Exception: - # Silenciar errores + logging.error("Error al añadir el repositorio") + print("Error al añadir el repositorio") return # Crear el archivo de versión instalada try: + logging.debug("Creando el archivo de versión instalada") os.makedirs("/opt/opengnsys", exist_ok=True) with open("/opt/opengnsys/release", "w") as release_file: release_file.write(f"Versión instalada: {selected_tag}\n") @@ -915,6 +923,7 @@ class MyApp(npyscreen.NPSAppManaged): # Actualizar los repositorios try: + logging.debug("Actualizando los repositorios") subprocess.run('apt-get update', shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=True) except subprocess.CalledProcessError: # Silenciar errores @@ -935,9 +944,11 @@ class MyApp(npyscreen.NPSAppManaged): subprocess.run( line, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL ) + logging.debug(f"Configuraciones guardadas en: {output_file}") except Exception: # Silenciar errores - pass + logging.error(f"Error al guardar configuraciones en {output_file}") + print(f"Error al guardar configuraciones en {output_file}") # Silenciar el mensaje de configuraciones guardadas # print(f"\nConfiguraciones guardadas en: {output_file}")