From 4916d157365605665c51b79db512c925dd329fc5 Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Wed, 20 Nov 2024 13:44:11 +0100 Subject: [PATCH] Create version to use npyscreen module --- component-installer/component-installer.sh | 2 + python-installer/oginstaller-v2.py | 194 +++++++++++++++++++++ python-installer/opengnsys_installer.sh | 54 ++++++ 3 files changed, 250 insertions(+) create mode 100644 python-installer/oginstaller-v2.py create mode 100755 python-installer/opengnsys_installer.sh diff --git a/component-installer/component-installer.sh b/component-installer/component-installer.sh index e66f455..d0e104f 100644 --- a/component-installer/component-installer.sh +++ b/component-installer/component-installer.sh @@ -120,6 +120,8 @@ do OGCORE_BRANCH=$(jq -r '.container_version' /opt/opengnsys/ogCore/installer/config.json) container_version=$(jq -r '.container_version' /opt/opengnsys/ogCore/installer/config.json) git_checkout_release "$OGCORE_REPO" "$component_dir/repo" "$OGCORE_BRANCH" + cp $component_dir/repo/.env $component_dir/etc/ + cp $component_dir/repo/env.json $component_dir/etc/ mkdir -p $component_dir/etc/ mkdir -p $component_dir/bin/ cp $CONFIGS_DIR/provision_ogcore.sh $component_dir/bin/ diff --git a/python-installer/oginstaller-v2.py b/python-installer/oginstaller-v2.py new file mode 100644 index 0000000..8dc7d33 --- /dev/null +++ b/python-installer/oginstaller-v2.py @@ -0,0 +1,194 @@ +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] + 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=4, 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): + """Añade un campo de contraseña con metadatos.""" + widget = self.add(npyscreen.TitlePassword, name=name) + 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:") + self.add_password_field("confirm_password", "Confirmar Contraseña:", is_confirmation=True) + +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")} + +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["ogdhcpDir"] = {"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")} + + +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="ogLive-noble-6.8.0-31-generic-amd64-r20241024.8100be23_20241112")} + self.fields["ogBootSambaUser"] = {"widget": self.add(npyscreen.TitleText, name="ogBoot Samba User (opengnsys):", value="opengnsys")} + self.add_password_field("ogBootSambaPass", "ogBoot Samba Pass (og):") + self.add_password_field("confirm_ogBootSambaPass", "Confirmar ogBoot Samba Pass (og):", value="og" ,is_confirmation=True) + + +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:") + self.add_password_field("confirm_repository_password", "Confirmar Samba Password:", value="og" ,is_confirmation=True) + +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/python-installer/opengnsys_installer.sh b/python-installer/opengnsys_installer.sh new file mode 100755 index 0000000..174d499 --- /dev/null +++ b/python-installer/opengnsys_installer.sh @@ -0,0 +1,54 @@ +#!/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 + + + +install_packages() { + apt-get update + apt-get install -y curl jq unzip python3 python3-git +} + +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/python-installer/* /tmp/oginstall/ + cp -r /tmp/oginstaller-$BRANCH/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 +} + +launch_component_installer() { + echo "Launching component installer..." + /tmp/oginstall/component-installer.sh +} + + +install_packages +download_installer +extract_installer +create_questions +launch_component_installer +