From b2305740b28b0d6e0dc8dbd4a01caee9d768ef66 Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Thu, 14 Nov 2024 07:26:50 +0100 Subject: [PATCH] Improving input methods --- python-installer/oginstaller.py | 373 ++++++++++++++++++++++++++------ 1 file changed, 308 insertions(+), 65 deletions(-) diff --git a/python-installer/oginstaller.py b/python-installer/oginstaller.py index da4bcc0..10c9730 100755 --- a/python-installer/oginstaller.py +++ b/python-installer/oginstaller.py @@ -1,12 +1,222 @@ +# 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) # Clona el repositorio si no existe +# else: +# print("Usando repositorio existente en", repo_path) + +# repo = Repo(repo_path) +# # pattern = "opengnsys" +# # tags = [tag.name for tag in repo.tags if tag.name.startswith(pattern)] +# tags = [tag.name for tag in repo.tags] +# # Comprobar si se han obtenido tags correctamente +# 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): +# stdscr.addstr(y, x, prompt, curses.color_pair(1)) +# password = "" +# while True: +# key = stdscr.getch() +# if key == curses.KEY_BACKSPACE or key == 127: # Manejar borrado +# if len(password) > 0: +# password = password[:-1] +# y, x = stdscr.getyx() +# stdscr.delch(y, x - 1) # Borra el último asterisco +# elif key == ord("\n"): # Confirmar con Enter +# break +# elif 32 <= key <= 126: # Rango de caracteres imprimibles +# password += chr(key) +# stdscr.addch("*") # Muestra un asterisco por cada carácter ingresado +# return password + + +# def main(stdscr): +# # Inicializar colores +# curses.start_color() +# curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE) # Texto blanco sobre fondo azul +# stdscr.bkgd(' ', curses.color_pair(1)) # Aplicar fondo azul a la pantalla + +# curses.curs_set(0) # Ocultar el cursor en el menú de selección +# stdscr.clear() + +# # Paso 1: Seleccionar componentes +# components = ["ogCore", "ogGui", "ogDhcp", "ogBoot", "ogRepository"] +# selected_components = [] +# current_index = 0 # Índice para saber en qué componente está el cursor + +# # 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: +# # Mostrar el estado actual de selección de cada componente +# 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)) + +# # Mueve el cursor visualmente para resaltar la selección actual +# 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: # Navegar hacia arriba +# current_index -= 1 +# elif key == curses.KEY_DOWN and current_index < len(components) - 1: # Navegar hacia abajo +# current_index += 1 +# elif key == ord(" "): # Marcar/desmarcar con espacio +# component = components[current_index] +# if component in selected_components: +# selected_components.remove(component) +# else: +# selected_components.append(component) +# elif key == ord("\n"): # Confirma la selección con Enter +# 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: # Navegar hacia arriba +# tag_index -= 1 +# elif key == curses.KEY_DOWN and tag_index < len(tags) - 1: # Navegar hacia abajo +# tag_index += 1 +# elif key == ord("\n"): # Confirma la selección con Enter +# break + +# stdscr.refresh() + + + +# # Ahora pasamos a la configuración específica de cada componente seleccionado +# curses.echo() # Activar eco para mostrar la entrada +# 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) # Mostrar el cursor para las entradas de configuración + +# config_data = {} +# if component == "ogCore": +# stdscr.addstr(3, 4, "Usuario administrador (ogadmin): ", curses.color_pair(1)) +# user = stdscr.getstr(3, 26, 20).decode("utf-8") or "ogadmin" +# stdscr.addstr(4, 4, "Contraseña (12345678): ", curses.color_pair(1)) +# password = get_password(stdscr, 4, 4, "Contraseña (por defecto 'password'): ") or "password" +# config_data = {"username": user, "password": password, "container_version": tags[tag_index]} + +# elif component == "ogGui": +# stdscr.addstr(3, 4, "IP del servidor de ogCore: ", curses.color_pair(1)) +# ogcore_ip = stdscr.getstr(3, 32, 20).decode("utf-8") +# config_data = {"ogcore_ip": ogcore_ip, "container_version": tags[tag_index]} + +# elif component == "ogDhcp": +# stdscr.addstr(3, 4, "Configuración IP servidor de Boot: ", curses.color_pair(1)) +# ogbootIP = stdscr.getstr(3, 37, 20).decode("utf-8") +# stdscr.addstr(3, 4, "Configuración IP servidor de DHCP: ", curses.color_pair(1)) +# ogdhcpIP = stdscr.getstr(3, 37, 20).decode("utf-8") +# stdscr.addstr(4, 4, "Interfaces Boot (eth0,eth1): ", curses.color_pair(1)) +# interfaces = stdscr.getstr(4, 40, 20).decode("utf-8") or "eth0,eth1" +# json_array_interfaces = interfaces.split(",") +# stdscr.addstr(4, 4, "Directorio de ogdhcp (/opt/opengnsys/ogdhcp): ", curses.color_pair(1)) +# ogdhcp_dir = stdscr.getstr(5, 4, 20).decode("utf-8") or "/opt/opengnsys/ogdhcp" +# config_data = {"ogbootIP": ogbootIP, "ogDhcpIP": ogdhcpIP, "ogDhcp_Dir": ogdhcp_dir , "interfaces": json_array_interfaces , "relase": tags[tag_index]} + +# elif component == "ogBoot": +# stdscr.addstr(3, 4, "ogCore Ip Server: ", curses.color_pair(1)) +# ogcore_ip = stdscr.getstr(3, 28, 20).decode("utf-8") +# stdscr.addstr(4, 4, "ogBoot Server IP: ", curses.color_pair(1)) +# ogboot_server_ip = stdscr.getstr(4, 28, 20).decode("utf-8") +# stdscr.addstr(5, 4, "ogCore Dir (/opt/opengnsys/ogcore): ", curses.color_pair(1)) +# ogcore_dir = stdscr.getstr(5, 28, 20).decode("utf-8") or "/opt/opengnsys/ogcore" +# stdscr.addstr(6, 4, "ogLive por defecto (https://ognproject.evlt.uma.es/oglive//ogLive-noble-6.8.0-31-generic-amd64-r20241024.8100be23_20241112.iso): ", curses.color_pair(1)) +# ogLive_default = stdscr.getstr(6, 28, 20).decode("utf-8") or "https://ognproject.evlt.uma.es/oglive//ogLive-noble-6.8.0-31-generic-amd64-r20241024.8100be23_20241112.iso" +# stdscr.addstr(7, 4, "ogBoot Samba User (opengnsys):", curses.color_pair(1)) +# ogboot_samba_user = stdscr.getstr(7, 28, 20).decode("utf-8") or "opengnsys" +# stdscr.addstr(8, 4, "ogBoot Samba Pass (og):", curses.color_pair(1)) +# ogboot_samba_pass = get_password(stdscr, 4, 4, "Contraseña (por defecto 'password'): ") or "og" + +# config_data = { +# "ogCore_ServerIP": ogcore_ip, +# "ogBoot_ServerIP": ogboot_server_ip, +# "ogBoot_Dir": ogcore_dir, +# "ogLive_Default": ogLive_default, +# "ogBootSambaUser": ogboot_samba_user, +# "ogBootSambaPass": ogboot_samba_pass, +# "release": tags[tag_index] +# } + +# elif component == "ogRepository": +# stdscr.addstr(3, 4, "ogRepository IP Server: ", curses.color_pair(1)) +# ogrepository_ip = stdscr.getstr(3, 28, 20).decode("utf-8") +# stdscr.addstr(4, 4, "ogRepository Sambauser (opengnsys): ", curses.color_pair(1)) +# ogrepository_samba_user = stdscr.getstr(4, 28, 20).decode("utf-8") or "opengnsys" +# stdscr.addstr(5, 4, "ogRepository Sambapass (og): ", curses.color_pair(1)) +# ogrepository_samba_pass = get_password(stdscr, 5, 4, "Contraseña (por defecto 'password'): ") or "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) + + import curses import json import os from git import Repo - CONFIGS_DIR = "/tmp/oginstall" os.makedirs(CONFIGS_DIR, exist_ok=True) + +# Uso ogCore para obtener ellistado de tags REPO_URL = "https://ognproject.evlt.uma.es/gitea/opengnsys/ogcore.git" def get_git_tags(): @@ -14,15 +224,12 @@ def get_git_tags(): 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) # Clona el repositorio si no existe + Repo.clone_from(REPO_URL, repo_path) else: print("Usando repositorio existente en", repo_path) repo = Repo(repo_path) - # pattern = "opengnsys" - # tags = [tag.name for tag in repo.tags if tag.name.startswith(pattern)] tags = [tag.name for tag in repo.tags] - # Comprobar si se han obtenido tags correctamente if tags: print("Tags encontrados:", tags) else: @@ -33,49 +240,99 @@ def get_git_tags(): 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 = "" + + # Mostrar prompt sin enmascarar el valor predeterminado hasta que el usuario comience a escribir + 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=""): + 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 + 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) # Texto blanco sobre fondo azul - stdscr.bkgd(' ', curses.color_pair(1)) # Aplicar fondo azul a la pantalla + curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLUE) + stdscr.bkgd(' ', curses.color_pair(1)) - curses.curs_set(0) # Ocultar el cursor en el menú de selección + curses.curs_set(0) stdscr.clear() # Paso 1: Seleccionar componentes components = ["ogCore", "ogGui", "ogDhcp", "ogBoot", "ogRepository"] selected_components = [] - current_index = 0 # Índice para saber en qué componente está el cursor + 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: - # Mostrar el estado actual de selección de cada componente 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)) - - # Mueve el cursor visualmente para resaltar la selección actual 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: # Navegar hacia arriba + if key == curses.KEY_UP and current_index > 0: current_index -= 1 - elif key == curses.KEY_DOWN and current_index < len(components) - 1: # Navegar hacia abajo + elif key == curses.KEY_DOWN and current_index < len(components) - 1: current_index += 1 - elif key == ord(" "): # Marcar/desmarcar con espacio + 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"): # Confirma la selección con Enter + elif key == ord("\n"): break stdscr.refresh() @@ -83,9 +340,9 @@ def main(stdscr): # 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: @@ -95,82 +352,68 @@ def main(stdscr): key = stdscr.getch() - if key == curses.KEY_UP and tag_index > 0: # Navegar hacia arriba + if key == curses.KEY_UP and tag_index > 0: tag_index -= 1 - elif key == curses.KEY_DOWN and tag_index < len(tags) - 1: # Navegar hacia abajo + elif key == curses.KEY_DOWN and tag_index < len(tags) - 1: tag_index += 1 - elif key == ord("\n"): # Confirma la selección con Enter + elif key == ord("\n"): break - stdscr.refresh() - - + stdscr.refresh() - # Ahora pasamos a la configuración específica de cada componente seleccionado - curses.echo() # Activar eco para mostrar la entrada + # 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) # Mostrar el cursor para las entradas de configuración + curses.curs_set(1) config_data = {} if component == "ogCore": - stdscr.addstr(3, 4, "Usuario administrador:", curses.color_pair(1)) - user = stdscr.getstr(3, 26, 20).decode("utf-8") - stdscr.addstr(4, 4, "Contraseña:", curses.color_pair(1)) - password = stdscr.getstr(4, 26, 20).decode("utf-8") + 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": - stdscr.addstr(3, 4, "IP del servidor de ogCore:", curses.color_pair(1)) - ogcore_ip = stdscr.getstr(3, 32, 20).decode("utf-8") + ogcore_ip = get_input(stdscr, 3, 0, "IP del servidor de ogCore (127.0.0.1): " , "127.0.0.1") config_data = {"ogcore_ip": ogcore_ip, "container_version": tags[tag_index]} elif component == "ogDhcp": - stdscr.addstr(3, 4, "Configuración IP servidor de Boot:", curses.color_pair(1)) - ogbootIP = stdscr.getstr(3, 37, 20).decode("utf-8") - stdscr.addstr(4, 4, "Interfaces Boot (separadas por coma):", curses.color_pair(1)) - interfaces = stdscr.getstr(4, 40, 20).decode("utf-8") + 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, "interfaces": json_array_interfaces , "relase": tags[tag_index]} + config_data = {"ogbootIP": ogbootIP, "ogDhcpIP": ogdhcpIP , "ogDhcp_Dir" : ogdhcpDir , "interfaces": json_array_interfaces, "release": tags[tag_index]} elif component == "ogBoot": - stdscr.addstr(3, 4, "ogCore Ip Server:", curses.color_pair(1)) - ogcore_ip = stdscr.getstr(3, 28, 20).decode("utf-8") - stdscr.addstr(4, 4, "ogCore Server:", curses.color_pair(1)) - ogcore_server = stdscr.getstr(4, 28, 20).decode("utf-8") - stdscr.addstr(5, 4, "ogCore Dir:", curses.color_pair(1)) - ogcore_dir = stdscr.getstr(5, 28, 20).decode("utf-8") - stdscr.addstr(6, 4, "ogBoot GitRepo:", curses.color_pair(1)) - ogboot_gitrepo = stdscr.getstr(6, 28, 20).decode("utf-8") - stdscr.addstr(7, 4, "ogBoot Samba User:", curses.color_pair(1)) - ogboot_samba_user = stdscr.getstr(7, 28, 20).decode("utf-8") - stdscr.addstr(8, 4, "ogBoot Samba Pass:", curses.color_pair(1)) - ogboot_samba_pass = stdscr.getstr(8, 28, 20).decode("utf-8") - + 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/ogcore): ", "/opt/opengnsys/ogcore") + ogLive_default = get_input(stdscr, 6, 0, "ogLive por defecto (https://ognproject.evlt.uma.es/oglive//ogLive-noble-6.8.0-31-generic-amd64-r20241024.8100be23_20241112.iso): ", "https://ognproject.evlt.uma.es/oglive//ogLive-noble-6.8.0-31-generic-amd64-r20241024.8100be23_20241112.iso") + 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_ip": ogcore_ip, - "ogcore_server": ogcore_server, - "ogcore_dir": ogcore_dir, - "ogboot_gitrepo": ogboot_gitrepo, - "ogboot_samba_user": ogboot_samba_user, - "ogboot_samba_pass": ogboot_samba_pass, + "ogCore_ServerIP": ogcore_ip, + "ogBoot_ServerIP": ogboot_server_ip, + "ogBoot_Dir": ogcore_dir, + "ogLive_Default": ogLive_default, + "ogBootSambaUser": ogboot_samba_user, + "ogBootSambaPass": ogboot_samba_pass, "release": tags[tag_index] } + elif component == "ogRepository": - stdscr.addstr(3, 4, "ogRepository IP Server: ", curses.color_pair(1)) - ogrepository_ip = stdscr.getstr(3, 28, 20).decode("utf-8") - stdscr.addstr(4, 4, "ogRepository Sambauser: ", curses.color_pair(1)) - ogrepository_samba_user = stdscr.getstr(4, 28, 20).decode("utf-8") - stdscr.addstr(5, 4, "ogRepository Sambapass: ", curses.color_pair(1)) - ogrepository_samba_pass = stdscr.getstr(5, 28, 20).decode("utf-8") - + 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: