oginstaller/python-installer/oginstaller.py

220 lines
9.4 KiB
Python

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():
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 = ""
# 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)
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, "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":
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/ogcore): ", "/opt/opengnsys/ogcore")
ogLive_default = get_input(stdscr, 6, 0, "ogLive por defecto (ogLive-noble-6.8.0-31-generic-amd64-r20241024.8100be23_20241112): ", "ogLive-noble-6.8.0-31-generic-amd64-r20241024.8100be23_20241112")
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)