Updted installer
parent
561232ee9f
commit
6983bba294
|
@ -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}")
|
||||
|
|
Loading…
Reference in New Issue