Compare commits
No commits in common. "main" and "working-installer" have entirely different histories.
main
...
working-in
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
|
@ -21,10 +21,6 @@ OGREPOSITORY_REPO="$OPENGNSYS_BASE_URL/ogrepository.git"
|
||||||
export GIT_SSL_NO_VERIFY=1
|
export GIT_SSL_NO_VERIFY=1
|
||||||
|
|
||||||
|
|
||||||
# Creamos el usuario opengnsys
|
|
||||||
|
|
||||||
useradd -m -d /opt/opengnsys -r -s /bin/bash opengnsys
|
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
function install_docker() {
|
function install_docker() {
|
||||||
|
@ -127,7 +123,7 @@ do
|
||||||
mkdir -p $component_dir/etc
|
mkdir -p $component_dir/etc
|
||||||
cp $component_dir/repo/.env $component_dir/etc/
|
cp $component_dir/repo/.env $component_dir/etc/
|
||||||
cp $component_dir/repo/env.json $component_dir/etc/
|
cp $component_dir/repo/env.json $component_dir/etc/
|
||||||
chown 82:82 $component_dir/etc/env.json
|
mkdir -p $component_dir/etc/
|
||||||
mkdir -p $component_dir/bin/
|
mkdir -p $component_dir/bin/
|
||||||
cp $CONFIGS_DIR/provision_ogcore.sh $component_dir/bin/
|
cp $CONFIGS_DIR/provision_ogcore.sh $component_dir/bin/
|
||||||
chmod 755 $component_dir/bin/provision_ogcore.sh
|
chmod 755 $component_dir/bin/provision_ogcore.sh
|
|
@ -3,8 +3,14 @@
|
||||||
set -x
|
set -x
|
||||||
|
|
||||||
CONF_DIR=/opt/opengnsys/ogCore/etc/
|
CONF_DIR=/opt/opengnsys/ogCore/etc/
|
||||||
cd /opt/opengnsys/ogCore/repo/ || exit
|
cd /opt/opengnsys/ogCore/repo/
|
||||||
|
|
||||||
|
# Preparar el fichero .yaml
|
||||||
|
# CONF_DIR=/opt/opengnsys/ogCore/etc/
|
||||||
|
# mkdir -p $CONF_DIR
|
||||||
|
|
||||||
|
# Copiar el fichero de configuración a CONF_DIR
|
||||||
|
# cp docker-compose-deploy.yml $CONF_DIR/
|
||||||
|
|
||||||
if [ -f /opt/opengnsys/ogCore/installer/.deployed ]; then
|
if [ -f /opt/opengnsys/ogCore/installer/.deployed ]; then
|
||||||
echo "ogCore ya instalado"
|
echo "ogCore ya instalado"
|
||||||
|
@ -18,20 +24,11 @@ done
|
||||||
adminuser=$(jq -r '.username' /opt/opengnsys/ogCore/installer/config.json)
|
adminuser=$(jq -r '.username' /opt/opengnsys/ogCore/installer/config.json)
|
||||||
adminpass=$(jq -r '.password' /opt/opengnsys/ogCore/installer/config.json)
|
adminpass=$(jq -r '.password' /opt/opengnsys/ogCore/installer/config.json)
|
||||||
|
|
||||||
# Despliega la aplicación
|
|
||||||
docker compose -f $CONF_DIR/docker-compose-deploy.yml exec php composer install
|
docker compose -f $CONF_DIR/docker-compose-deploy.yml exec php composer install
|
||||||
# Genera las claves de JWT
|
|
||||||
docker compose -f $CONF_DIR/docker-compose-deploy.yml exec php php bin/console lexik:jwt:generate-keypair --overwrite
|
docker compose -f $CONF_DIR/docker-compose-deploy.yml exec php php bin/console lexik:jwt:generate-keypair --overwrite
|
||||||
# Crea/actualiza la base de datos
|
|
||||||
docker compose -f $CONF_DIR/docker-compose-deploy.yml exec php php bin/console doctrine:migrations:migrate --no-interaction
|
docker compose -f $CONF_DIR/docker-compose-deploy.yml exec php php bin/console doctrine:migrations:migrate --no-interaction
|
||||||
# Carga los datos por defecto: usuario
|
## TODO we need to feed $adminuser and $adminpass to doctrine:fixtures:load somehow
|
||||||
docker compose -f $CONF_DIR/docker-compose-deploy.yml exec php php bin/console doctrine:fixtures:load --no-interaction
|
docker compose -f $CONF_DIR/docker-compose-deploy.yml exec php php bin/console doctrine:fixtures:load --no-interaction
|
||||||
# Carga los datos por defecto: roles
|
|
||||||
docker compose -f $CONF_DIR/docker-compose-deploy.yml exec php bin/console app:load-default-user-groups
|
|
||||||
# Carga los datos por defecto: comandos
|
|
||||||
docker compose -f $CONF_DIR/docker-compose-deploy.yml exec php php bin/console app:load-default-commands
|
|
||||||
# Carga los datos por defecto: menú
|
|
||||||
docker compose -f $CONF_DIR/docker-compose-deploy.yml exec php php bin/console opengnsys:load-default-menu
|
|
||||||
|
|
||||||
|
|
||||||
# Provision user admin
|
# Provision user admin
|
||||||
|
@ -51,6 +48,5 @@ curl -k -L --location 'https://localhost:8443/users' \
|
||||||
--header "Authorization: Bearer $bearer" \
|
--header "Authorization: Bearer $bearer" \
|
||||||
--data "{ \"username\": \"$adminuser\", \"password\": \"$adminpass\", \"roles\": [\"ROLE_SUPER_ADMIN\"] }"
|
--data "{ \"username\": \"$adminuser\", \"password\": \"$adminpass\", \"roles\": [\"ROLE_SUPER_ADMIN\"] }"
|
||||||
|
|
||||||
|
|
||||||
touch /opt/opengnsys/ogCore/installer/.deployed
|
touch /opt/opengnsys/ogCore/installer/.deployed
|
||||||
exit 0
|
exit 0
|
|
@ -0,0 +1,42 @@
|
||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
set -x
|
||||||
|
|
||||||
|
# preparar el fichero .env
|
||||||
|
ENV_DIR=/opt/opengnsys/ogGui/etc/
|
||||||
|
ENV_FILE=$ENV_DIR/.env
|
||||||
|
mkdir -p $ENV_DIR
|
||||||
|
|
||||||
|
# Comprobar si ya se ha instalado ogCore
|
||||||
|
if [ -f /opt/opengnsys/ogGui/installer/.deployed ]; then
|
||||||
|
echo "ogCore ya instalado"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Sacar la IP del ogCore de la configuración
|
||||||
|
ogcore_ip=$(jq -r '.ogcore_ip' /opt/opengnsys/ogGui/installer/config.json)
|
||||||
|
export OGCORE_IP="$ogcore_ip"
|
||||||
|
|
||||||
|
# Si no se ha configurado la IP del ogCore, se intenta obtener de la interfaz de red
|
||||||
|
if [ -z "$ogcore_ip" ]; then
|
||||||
|
# Obtiene el nombre del interfaz asociado a la ruta por defecto
|
||||||
|
interface=$(ip route | grep default | awk '{print $5}')
|
||||||
|
|
||||||
|
# Si se encuentra el interfaz, obtiene su dirección IP
|
||||||
|
if [ -n "$interface" ]; then
|
||||||
|
ip_address=$(ip -o -4 addr show "$interface" | awk '{print $4}' | cut -d'/' -f1)
|
||||||
|
ogcore_ip=$ip_address
|
||||||
|
# Si no se ha configurado la IP del ogCore, se escribe en el fichero .env
|
||||||
|
echo "NG_APP_BASE_API_URL=https://$ogcore_ip:8443" > $ENV_FILE
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "No se pudo determinar el interfaz asociado a la ruta por defecto."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Si se ha configurado la IP del ogCore, se escribe en el fichero .env
|
||||||
|
echo "NG_APP_BASE_API_URL=$OGCORE_IP" > $ENV_FILE
|
||||||
|
|
||||||
|
touch /opt/opengnsys/ogGui/installer/.deployed
|
|
@ -10,7 +10,6 @@ OGPASS=${4:-"og"}
|
||||||
INSTALL_DIR=/opt/opengnsys/ogrepository
|
INSTALL_DIR=/opt/opengnsys/ogrepository
|
||||||
DOWNLOAD_DIR=${5:-"/tmp/ogrepository"}
|
DOWNLOAD_DIR=${5:-"/tmp/ogrepository"}
|
||||||
DEBIAN_FRONTEND=noninteractive
|
DEBIAN_FRONTEND=noninteractive
|
||||||
OGUSER_HOME=/opt/opengnsys
|
|
||||||
export DEBIAN_FRONTEND
|
export DEBIAN_FRONTEND
|
||||||
export GIT_SSL_NO_VERIFY
|
export GIT_SSL_NO_VERIFY
|
||||||
|
|
||||||
|
@ -35,33 +34,24 @@ install_updcast () {
|
||||||
add_user_ogrepository() {
|
add_user_ogrepository() {
|
||||||
if ! id "$OGUSER" &>/dev/null; then
|
if ! id "$OGUSER" &>/dev/null; then
|
||||||
echo "User ogrepository does not exist, creating it"
|
echo "User ogrepository does not exist, creating it"
|
||||||
useradd -m -d $OGUSER_HOME -r -s /bin/bash $OGUSER
|
useradd -r -s /bin/bash $OGUSER
|
||||||
fi
|
fi
|
||||||
if [ ! -d $OGUSER_HOME/.ssh ] ; then
|
|
||||||
mkdir -p $OGUSER_HOME/.ssh
|
|
||||||
cp /tmp/oginstall/ssh-keys/opengnsys $OGUSER_HOME/.ssh/id_ed25519
|
|
||||||
cp /tmp/oginstall/ssh-keys/opengnsys.pub $OGUSER_HOME/.ssh/id_ed25519.pub
|
|
||||||
cat /tmp/oginstall/ssh-keys/opengnsys.pub >> $OGUSER_HOME/.ssh/authorized_keys
|
|
||||||
chown -R $OGUSER:$OGUSER $OGUSER_HOME/.ssh
|
|
||||||
chmod 0600 $OGUSER_HOME/.ssh/*
|
|
||||||
fi
|
|
||||||
if [ ! -f /etc/sudoers.d/$OGUSER ]; then
|
if [ ! -f /etc/sudoers.d/$OGUSER ]; then
|
||||||
echo "User $OGUSER does not have sudo permissions, adding it"
|
echo "User $OGUSER does not have sudo permissions, adding it"
|
||||||
echo "$OGUSER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/"$OGUSER"
|
echo "$OGUSER ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/"$OGUSER"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
create_directories() {
|
create_directories() {
|
||||||
mkdir -p $INSTALL_DIR
|
mkdir -p $INSTALL_DIR
|
||||||
mkdir -p $INSTALL_DIR/images $INSTALL_DIR/images_trash/ $INSTALL_DIR/bin/ $INSTALL_DIR/etc/ $INSTALL_DIR/log/ $INSTALL_DIR/api/ $INSTALL_DIR/images_virtual
|
mkdir -p $INSTALL_DIR/images $INSTALL_DIR/images_trash/ $INSTALL_DIR/bin/ $INSTALL_DIR/etc/ $INSTALL_DIR/log/ $INSTALL_DIR/api/
|
||||||
chown -R $OGUSER:$OGUSER $INSTALL_DIR
|
chown -R $OGUSER:$OGUSER $INSTALL_DIR
|
||||||
}
|
}
|
||||||
|
|
||||||
install_dependencies() {
|
install_dependencies() {
|
||||||
apt update -y
|
apt update -y
|
||||||
apt install -y git python3 python3-pip python3-flask python3-paramiko python3-psutil python3-flasgger debian-archive-keyring samba gunicorn wakeonlan lzop partclone qemu-utils
|
apt install -y git python3 python3-pip python3-flask python3-paramiko python3-psutil python3-flasgger debian-archive-keyring samba gunicorn wakeonlan
|
||||||
}
|
}
|
||||||
|
|
||||||
install_ext_repo() {
|
install_ext_repo() {
|
||||||
|
@ -97,6 +87,7 @@ configure_samba() {
|
||||||
systemctl restart smbd
|
systemctl restart smbd
|
||||||
# Create default user ogrepository
|
# Create default user ogrepository
|
||||||
(echo $OGPASS; echo $OGPASS) | smbpasswd -s -a $OGUSER
|
(echo $OGPASS; echo $OGPASS) | smbpasswd -s -a $OGUSER
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
## Main program
|
## Main program
|
|
@ -1,27 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
set -x
|
|
||||||
|
|
||||||
# preparar el fichero .env
|
|
||||||
ENV_DIR=/opt/opengnsys/ogGui/etc/
|
|
||||||
ENV_FILE=$ENV_DIR/.env
|
|
||||||
mkdir -p $ENV_DIR
|
|
||||||
|
|
||||||
# Comprobar si ya se ha instalado ogCore
|
|
||||||
if [ -f /opt/opengnsys/ogGui/installer/.deployed ]; then
|
|
||||||
echo "ogCore ya instalado"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Sacar la IP del ogCore de la configuración
|
|
||||||
ogcore_url=$(jq -r '.ogcore_ip' /opt/opengnsys/ogGui/installer/config.json)
|
|
||||||
mercure_ip=$(jq -r '.mercure_ip' /opt/opengnsys/ogGui/installer/config.json)
|
|
||||||
export OGCORE_URL="$ogcore_url"
|
|
||||||
export MERCURE_URL="$mercure_url"
|
|
||||||
|
|
||||||
|
|
||||||
# Si se ha configurado la IP del ogCore, se escribe en el fichero .env
|
|
||||||
echo "NG_APP_BASE_API_URL=$OGCORE_URL" > $ENV_FILE
|
|
||||||
echo "NG_APP_OGCORE_MERCURE_BASE_URL=https://$mercure_ip:3000/.well-known/mercure" >> $ENV_FILE
|
|
||||||
|
|
||||||
touch /opt/opengnsys/ogGui/installer/.deployed
|
|
|
@ -1,7 +0,0 @@
|
||||||
-----BEGIN OPENSSH PRIVATE KEY-----
|
|
||||||
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
|
|
||||||
QyNTUxOQAAACBs7Wbqztq5ixPGFL+1DlTa0T6QUBMiLq6KxZnCJ5rofQAAAJD7Xj89+14/
|
|
||||||
PQAAAAtzc2gtZWQyNTUxOQAAACBs7Wbqztq5ixPGFL+1DlTa0T6QUBMiLq6KxZnCJ5rofQ
|
|
||||||
AAAEC4UmYDisgl5jNR6SUwRA80k6Qc06cBHg1mW3+2NU6SfmztZurO2rmLE8YUv7UOVNrR
|
|
||||||
PpBQEyIurorFmcInmuh9AAAABm5vbmFtZQECAwQFBgc=
|
|
||||||
-----END OPENSSH PRIVATE KEY-----
|
|
|
@ -1 +0,0 @@
|
||||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGztZurO2rmLE8YUv7UOVNrRPpBQEyIurorFmcInmuh9 noname
|
|
|
@ -1,54 +0,0 @@
|
||||||
import os
|
|
||||||
from git import Repo
|
|
||||||
from packaging.version import Version
|
|
||||||
|
|
||||||
def get_highest_remote_tag(repo_path):
|
|
||||||
try:
|
|
||||||
# Abre el repositorio local
|
|
||||||
repo = Repo(repo_path)
|
|
||||||
|
|
||||||
# Asegúrate de que el repositorio tiene un remoto
|
|
||||||
if not repo.remotes:
|
|
||||||
return None # No hay remotos configurados
|
|
||||||
|
|
||||||
# Obtén el remoto por defecto (origin o el primero disponible)
|
|
||||||
remote = repo.remotes.origin
|
|
||||||
|
|
||||||
# Recupera los tags remotos
|
|
||||||
remote.fetch(tags=True)
|
|
||||||
remote_tags = [ref.name.split('/')[-1] for ref in repo.references if ref.path.startswith('refs/tags/')]
|
|
||||||
if not remote_tags:
|
|
||||||
return None # No hay tags remotos
|
|
||||||
|
|
||||||
# Ordena los tags remotos por versión
|
|
||||||
tags_sorted = sorted(remote_tags, key=lambda t: Version(t) if t.replace('.', '').isdigit() else Version('0.0.0'), reverse=True)
|
|
||||||
return tags_sorted[0] if tags_sorted else None
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error al procesar el repositorio {repo_path}: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def process_selected_repositories(base_path, repo_names):
|
|
||||||
repo_highest_tags = {}
|
|
||||||
for repo_name in repo_names:
|
|
||||||
repo_path = os.path.join(base_path, repo_name)
|
|
||||||
if os.path.exists(repo_path) and os.path.isdir(os.path.join(repo_path, '.git')):
|
|
||||||
highest_tag = get_highest_remote_tag(repo_path)
|
|
||||||
repo_highest_tags[repo_name] = highest_tag
|
|
||||||
else:
|
|
||||||
repo_highest_tags[repo_name] = "No es un repositorio Git válido"
|
|
||||||
return repo_highest_tags
|
|
||||||
|
|
||||||
# Ruta base donde están los repositorios locales
|
|
||||||
base_path = "../"
|
|
||||||
|
|
||||||
# Lista de nombres de repositorios específicos
|
|
||||||
repo_names = [ "ogcore" , "oggui" , "ogboot" , "ogdhcp" , "ogrepository" ]
|
|
||||||
|
|
||||||
result = process_selected_repositories(base_path, repo_names)
|
|
||||||
|
|
||||||
# Muestra los resultados
|
|
||||||
for repo_name, tag in result.items():
|
|
||||||
print(f'{repo_name}:{tag}')
|
|
||||||
|
|
||||||
|
|
|
@ -1,311 +0,0 @@
|
||||||
#!/usr/bin/env python3
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
import requests
|
|
||||||
import sys
|
|
||||||
import npyscreen
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Configuración general
|
|
||||||
REPO_BASE_URL = "http://ognproject.evlt.uma.es/debian-opengnsys/opengnsys-devel"
|
|
||||||
RELEASES_URL = "https://ognproject.evlt.uma.es/debian-opengnsys/versions-dev.json"
|
|
||||||
APT_LIST_PATH = "/etc/apt/sources.list.d/opengnsys.list"
|
|
||||||
PACKAGES = ["ogrepository", "ogcore", "oggui", "ogclient", "ogboot", "ogdhcp"]
|
|
||||||
RELEASE_FILE = "/opt/opengnsys/release"
|
|
||||||
|
|
||||||
# === Sección npyscreen ===
|
|
||||||
|
|
||||||
class ServerURLForm(npyscreen.Form):
|
|
||||||
def create(self):
|
|
||||||
self.server_url = self.add(npyscreen.TitleText, name="Servidor de validación (URL completa):", value="http://localhost:5000/validar")
|
|
||||||
|
|
||||||
def afterEditing(self):
|
|
||||||
self.parentApp.server_url = self.server_url.value
|
|
||||||
self.parentApp.setNextForm("RELEASE")
|
|
||||||
|
|
||||||
class ReleaseSelectorForm(npyscreen.ActionForm):
|
|
||||||
def create(self):
|
|
||||||
self.releases = self.parentApp.releases
|
|
||||||
self.listbox = self.add(npyscreen.TitleSelectOne,
|
|
||||||
name="Releases disponibles",
|
|
||||||
values=self.releases,
|
|
||||||
scroll_exit=True,
|
|
||||||
max_height=len(self.releases)+4)
|
|
||||||
|
|
||||||
def on_ok(self):
|
|
||||||
selected_index = self.listbox.value[0] if self.listbox.value else None
|
|
||||||
if selected_index is None:
|
|
||||||
npyscreen.notify_confirm("Debes seleccionar una release antes de continuar.", title="Error")
|
|
||||||
else:
|
|
||||||
self.parentApp.selected = self.releases[selected_index]
|
|
||||||
self.parentApp.setNextForm(None)
|
|
||||||
|
|
||||||
def on_cancel(self):
|
|
||||||
npyscreen.notify_confirm("Operación cancelada. Saliendo del formulario.", title="Cancelado")
|
|
||||||
self.parentApp.setNextForm(None)
|
|
||||||
|
|
||||||
class ReleaseSelectorApp(npyscreen.NPSAppManaged):
|
|
||||||
def __init__(self, releases):
|
|
||||||
self.releases = releases
|
|
||||||
self.selected = None
|
|
||||||
self.server_url = None
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
def onStart(self):
|
|
||||||
self.addForm("MAIN", ServerURLForm, name="Configuración inicial")
|
|
||||||
self.addForm("RELEASE", ReleaseSelectorForm, name="Selecciona una release", releases=self.releases)
|
|
||||||
|
|
||||||
def choose_release_and_server(releases):
|
|
||||||
app = ReleaseSelectorApp(releases)
|
|
||||||
app.run()
|
|
||||||
return app.selected, app.server_url
|
|
||||||
|
|
||||||
# === Funciones principales ===
|
|
||||||
|
|
||||||
def backup_file(filepath):
|
|
||||||
"""Crea una copia de seguridad del archivo especificado."""
|
|
||||||
backup_path = f"{filepath}.bak"
|
|
||||||
if os.path.exists(filepath):
|
|
||||||
try:
|
|
||||||
os.replace(filepath, backup_path)
|
|
||||||
print(f"[INFO] Copia de seguridad creada: {backup_path}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[ERROR] No se pudo crear la copia de seguridad de {filepath}: {e}")
|
|
||||||
return backup_path
|
|
||||||
|
|
||||||
def restore_file(backup_path, original_path):
|
|
||||||
"""Restaura el archivo desde su copia de seguridad."""
|
|
||||||
if os.path.exists(backup_path):
|
|
||||||
try:
|
|
||||||
os.replace(backup_path, original_path)
|
|
||||||
print(f"[INFO] Archivo restaurado: {original_path}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[ERROR] No se pudo restaurar el archivo {original_path}: {e}")
|
|
||||||
|
|
||||||
def get_installed_packages():
|
|
||||||
installed = []
|
|
||||||
for pkg in PACKAGES:
|
|
||||||
try:
|
|
||||||
subprocess.run(
|
|
||||||
["dpkg-query", "-W", pkg],
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
text=True,
|
|
||||||
check=True
|
|
||||||
)
|
|
||||||
installed.append(pkg)
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
continue
|
|
||||||
return installed
|
|
||||||
|
|
||||||
def get_installed_release():
|
|
||||||
try:
|
|
||||||
with open(RELEASE_FILE, "r") as release_file:
|
|
||||||
line = release_file.readline().strip()
|
|
||||||
match = re.search(r".*:\s*(.+)", line)
|
|
||||||
if match:
|
|
||||||
return match.group(1).strip()
|
|
||||||
except FileNotFoundError:
|
|
||||||
print("El archivo de release no existe.")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error al leer el archivo de release: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
def fetch_available_releases():
|
|
||||||
try:
|
|
||||||
response = requests.get(RELEASES_URL)
|
|
||||||
response.raise_for_status()
|
|
||||||
data = response.json()
|
|
||||||
return data.get("versions", [])
|
|
||||||
except requests.RequestException as e:
|
|
||||||
print(f"[ERROR] No se pudo obtener la lista de releases: {e}")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def update_repo_file(selected_release):
|
|
||||||
backup_path = backup_file(APT_LIST_PATH)
|
|
||||||
line = f"deb {REPO_BASE_URL}/{selected_release} noble main\n"
|
|
||||||
print(f"[INFO] Escribiendo nueva línea en {APT_LIST_PATH}:\n{line.strip()}")
|
|
||||||
try:
|
|
||||||
with open(APT_LIST_PATH, "w") as f:
|
|
||||||
f.write(line)
|
|
||||||
except PermissionError:
|
|
||||||
print("[ERROR] No tienes permisos para escribir en el archivo del repositorio. Ejecuta el script como root.")
|
|
||||||
restore_file(backup_path, APT_LIST_PATH)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Ejecutar apt update para actualizar la información del repositorio
|
|
||||||
try:
|
|
||||||
print("[INFO] Actualizando la información del repositorio con 'apt update'...")
|
|
||||||
subprocess.run(["sudo", "apt", "update"], check=True)
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
print(f"[ERROR] Error al ejecutar 'apt update': {e}")
|
|
||||||
restore_file(backup_path, APT_LIST_PATH)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
def check_compatibility(server_url, installed_release, selected_release):
|
|
||||||
payload = {
|
|
||||||
"installed_release": installed_release,
|
|
||||||
"target_release": selected_release
|
|
||||||
}
|
|
||||||
try:
|
|
||||||
response = requests.post(server_url, json=payload, timeout=5)
|
|
||||||
response.raise_for_status()
|
|
||||||
result = response.json()
|
|
||||||
return result.get("compatible", False), result.get("message", "")
|
|
||||||
except requests.RequestException as e:
|
|
||||||
print(f"[ERROR] No se pudo contactar con el servidor de validación: {e}")
|
|
||||||
return False, str(e)
|
|
||||||
|
|
||||||
def summarize_updates(installed_packages, selected_release):
|
|
||||||
"""Genera un resumen de los paquetes que se van a actualizar y los que no."""
|
|
||||||
to_update = []
|
|
||||||
up_to_date = []
|
|
||||||
|
|
||||||
for pkg in installed_packages:
|
|
||||||
try:
|
|
||||||
result = subprocess.run(
|
|
||||||
["apt-cache", "policy", pkg],
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
text=True,
|
|
||||||
check=True,
|
|
||||||
env={"LANG": "C"} # Forzar el idioma a inglés
|
|
||||||
)
|
|
||||||
installed = None
|
|
||||||
candidate = None
|
|
||||||
for line in result.stdout.splitlines():
|
|
||||||
if "Installed:" in line: # Siempre estará en inglés
|
|
||||||
installed = line.split(":", 1)[1].strip()
|
|
||||||
elif "Candidate:" in line: # Siempre estará en inglés
|
|
||||||
candidate = line.split(":", 1)[1].strip()
|
|
||||||
|
|
||||||
if not installed or candidate == "(none)":
|
|
||||||
to_update.append(f"{pkg} (no instalado o sin versión candidata)")
|
|
||||||
elif installed != candidate:
|
|
||||||
to_update.append(f"{pkg} ({installed} → {candidate})")
|
|
||||||
else:
|
|
||||||
up_to_date.append(f"{pkg} ({installed})")
|
|
||||||
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
to_update.append(f"{pkg} (error obteniendo versión)")
|
|
||||||
|
|
||||||
summary = "\n--- Resumen de actualización ---\n"
|
|
||||||
summary += f"Release objetivo: {selected_release}\n\n"
|
|
||||||
summary += "Paquetes que se actualizarán:\n"
|
|
||||||
summary += "\n".join(f" - {line}" for line in to_update) if to_update else " - Ninguno\n"
|
|
||||||
summary += "\nPaquetes que ya están actualizados:\n"
|
|
||||||
summary += "\n".join(f" - {line}" for line in up_to_date) if up_to_date else " - Ninguno\n"
|
|
||||||
summary += "\n--------------------------------"
|
|
||||||
|
|
||||||
# Mostrar el resumen en una ventana emergente
|
|
||||||
npyscreen.notify_confirm(summary, title="Resumen de actualización", wide=True)
|
|
||||||
|
|
||||||
if not to_update:
|
|
||||||
npyscreen.notify_confirm("[INFO] Todos los paquetes están actualizados. No es necesario continuar.", title="Información")
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
if not npyscreen.notify_yes_no("¿Deseas continuar con la actualización?", title="Confirmación"):
|
|
||||||
npyscreen.notify_confirm("[INFO] Actualización cancelada por el usuario.", title="Cancelado")
|
|
||||||
restore_file(f"{APT_LIST_PATH}.bak", APT_LIST_PATH)
|
|
||||||
restore_file(f"{RELEASE_FILE}.bak", RELEASE_FILE)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
return [line.split()[0] for line in to_update]
|
|
||||||
|
|
||||||
def show_final_versions(packages):
|
|
||||||
print("\n✅ Resumen final de versiones instaladas:")
|
|
||||||
for pkg in packages:
|
|
||||||
try:
|
|
||||||
result = subprocess.run(
|
|
||||||
["dpkg-query", "-W", "-f=${Version}", pkg],
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.DEVNULL,
|
|
||||||
text=True
|
|
||||||
)
|
|
||||||
version = result.stdout.strip()
|
|
||||||
print(f" - {pkg}: {version}")
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
print(f" - {pkg}: no instalado")
|
|
||||||
|
|
||||||
def update_and_install(packages_to_update, selected_release):
|
|
||||||
backup_release = backup_file(RELEASE_FILE)
|
|
||||||
try:
|
|
||||||
subprocess.run(["sudo", "apt", "update"], check=True)
|
|
||||||
subprocess.run(["sudo", "apt", "install", "-y"] + packages_to_update, check=True)
|
|
||||||
print("[INFO] Paquetes actualizados correctamente.")
|
|
||||||
|
|
||||||
# Actualizar el archivo de release con la versión seleccionada
|
|
||||||
try:
|
|
||||||
os.makedirs(os.path.dirname(RELEASE_FILE), exist_ok=True)
|
|
||||||
with open(RELEASE_FILE, "w") as release_file:
|
|
||||||
release_file.write(f"Versión instalada: {selected_release}\n")
|
|
||||||
print(f"[INFO] Archivo de release actualizado: {selected_release}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[ERROR] No se pudo actualizar el archivo de release: {e}")
|
|
||||||
|
|
||||||
show_final_versions(packages_to_update)
|
|
||||||
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
print(f"[ERROR] Error al instalar paquetes: {e}")
|
|
||||||
restore_file(backup_release, RELEASE_FILE)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# === Entrada principal ===
|
|
||||||
|
|
||||||
def main():
|
|
||||||
print("[INFO] Iniciando actualización de paquetes de OpenGnSys...")
|
|
||||||
installed_release = get_installed_release()
|
|
||||||
if installed_release:
|
|
||||||
print(f"[INFO] Versión instalada: {installed_release}")
|
|
||||||
else:
|
|
||||||
print("[WARN] No se encontró la versión instalada.")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
installed = get_installed_packages()
|
|
||||||
if not installed:
|
|
||||||
print("[ERROR] No se detectaron paquetes OpenGnSys instalados.")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
releases = fetch_available_releases()
|
|
||||||
selected, server_url = choose_release_and_server(releases)
|
|
||||||
|
|
||||||
if not selected or not server_url:
|
|
||||||
print("[WARN] No se seleccionó release o URL del servidor. Restaurando archivos.")
|
|
||||||
restore_file(f"{APT_LIST_PATH}.bak", APT_LIST_PATH)
|
|
||||||
restore_file(f"{RELEASE_FILE}.bak", RELEASE_FILE)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
print(f"[INFO] Validando compatibilidad con {server_url}...")
|
|
||||||
compatible, message = check_compatibility(server_url, installed_release, selected)
|
|
||||||
|
|
||||||
if not compatible:
|
|
||||||
print(f"[ERROR] El servidor indica que la actualización no es compatible: {message}")
|
|
||||||
restore_file(f"{APT_LIST_PATH}.bak", APT_LIST_PATH)
|
|
||||||
restore_file(f"{RELEASE_FILE}.bak", RELEASE_FILE)
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
print(f"[INFO] Compatibilidad validada: {message}")
|
|
||||||
|
|
||||||
try:
|
|
||||||
update_repo_file(selected)
|
|
||||||
to_update = summarize_updates(installed, selected)
|
|
||||||
update_and_install(to_update, selected)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[ERROR] Error durante la actualización: {e}")
|
|
||||||
restore_file(f"{APT_LIST_PATH}.bak", APT_LIST_PATH)
|
|
||||||
restore_file(f"{RELEASE_FILE}.bak", RELEASE_FILE)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
try:
|
|
||||||
main()
|
|
||||||
except SystemExit as e:
|
|
||||||
# Manejar la excepción SystemExit para evitar interrupciones
|
|
||||||
if e.code != 0:
|
|
||||||
print(f"[INFO] El script terminó con código de salida: {e.code}")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"[ERROR] Ocurrió un error inesperado: {e}")
|
|
||||||
finally:
|
|
||||||
# Restaurar el terminal al estado normal
|
|
||||||
npyscreen.wrapper_basic(lambda stdscr: None)
|
|
|
@ -1,214 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Detect installed components.
|
|
||||||
|
|
||||||
|
|
||||||
INSTALLER_BRANCH=${INSTALLER_BRANCH:-main}
|
|
||||||
OPENGNSYS_BASE=/opt/opengnsys
|
|
||||||
OPENGNSYS_COMPONENTS=(ogCore ogGui ogDhcp ogBoot ogRepository)
|
|
||||||
GIT_SSL_NO_VERIFY=1
|
|
||||||
INSTALLED_COMPONENTS=()
|
|
||||||
|
|
||||||
GIT_REPO="https://ognproject.evlt.uma.es/gitea/api/v1/repos/opengnsys/oginstaller/archive/$INSTALLER_BRANCH.zip"
|
|
||||||
|
|
||||||
export GIT_SSL_NO_VERIFY
|
|
||||||
INSTALLED_COMPONENTS=()
|
|
||||||
|
|
||||||
check_os(){
|
|
||||||
if [ -f /etc/os-release ]; then
|
|
||||||
. /etc/os-release
|
|
||||||
# Just support Ubuntu 24.04 for now
|
|
||||||
if [ $ID == "ubuntu" ] && [ $VERSION_ID == "24.04" ]; then
|
|
||||||
echo "OS supported."
|
|
||||||
else
|
|
||||||
echo "OS not supported."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "OS not supported."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
detect_installed_components() {
|
|
||||||
local OGNODE=0
|
|
||||||
for component in "${OPENGNSYS_COMPONENTS[@]}"; do
|
|
||||||
if [ -f "${OPENGNSYS_BASE}/${component}/installer/config.json" ]; then
|
|
||||||
echo "Component $component is installed."
|
|
||||||
INSTALLED_COMPONENTS+=($component)
|
|
||||||
OGNODE=1
|
|
||||||
else
|
|
||||||
echo "Component $component is not installed."
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [ $OGNODE -eq 0 ]; then
|
|
||||||
echo "No OpenGnsys components installed."
|
|
||||||
else
|
|
||||||
echo "Installed components:" "${INSTALLED_COMPONENTS[@]}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Assume taht all components are at the same release version, get the first installed compoenent and return its version
|
|
||||||
get_og_installed_version() {
|
|
||||||
local component=$1
|
|
||||||
local version=$(jq -r '.release' ${OPENGNSYS_BASE}/${component}/installer/config.json)
|
|
||||||
echo $version
|
|
||||||
}
|
|
||||||
|
|
||||||
start_stop_component() {
|
|
||||||
local component=$1
|
|
||||||
local action=$2
|
|
||||||
case $component in
|
|
||||||
ogCore)
|
|
||||||
handle_ogcore $action
|
|
||||||
;;
|
|
||||||
ogGui)
|
|
||||||
handle_oggui $action
|
|
||||||
;;
|
|
||||||
ogDhcp)
|
|
||||||
handle_ogdhcp $action
|
|
||||||
;;
|
|
||||||
ogBoot)
|
|
||||||
handle_ogboot $action
|
|
||||||
;;
|
|
||||||
ogRepository)
|
|
||||||
handle_ogrepository $action
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Component $component not found."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
stop_installed_services() {
|
|
||||||
echo "Stopping services..."
|
|
||||||
for component in "${INSTALLED_COMPONENTS[@]}"; do
|
|
||||||
echo "Stopping component $component..."
|
|
||||||
start_stop_component $component stop
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
start_installed_services() {
|
|
||||||
echo "Starting services..."
|
|
||||||
for component in "${INSTALLED_COMPONENTS[@]}"; do
|
|
||||||
echo "Starting component $component..."
|
|
||||||
start_stop_component $component start
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
handle_ogboot() {
|
|
||||||
case $1 in
|
|
||||||
stop)
|
|
||||||
echo "Stopping ogBoot..."
|
|
||||||
systemctl stop nginx
|
|
||||||
systemctl stop tftpd-hpa
|
|
||||||
systemctl stop smbd
|
|
||||||
systemctl stop nmbd
|
|
||||||
;;
|
|
||||||
start)
|
|
||||||
echo "Starting ogBoot..."
|
|
||||||
systemctl start nginx
|
|
||||||
systemctl start tftpd-hpa
|
|
||||||
systemctl start smbd
|
|
||||||
systemctl start nmbd
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid action."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
handle_ogdhcp() {
|
|
||||||
case $1 in
|
|
||||||
stop)
|
|
||||||
echo "Stopping ogDhcp..."
|
|
||||||
systemctl stop kea-dhcp4-server
|
|
||||||
systemctl stop kea-ctrl-agent
|
|
||||||
;;
|
|
||||||
start)
|
|
||||||
echo "Starting ogDhcp..."
|
|
||||||
systemctl start kea-dhcp4-server
|
|
||||||
systemctl start kea-ctrl-agent
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid action."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
handle_ogrepository() {
|
|
||||||
case $1 in
|
|
||||||
stop)
|
|
||||||
echo "Stopping ogRepository..."
|
|
||||||
systemctl stop smbd
|
|
||||||
systemctl stop nmbd
|
|
||||||
systemctl stop ogrepo-api
|
|
||||||
;;
|
|
||||||
start)
|
|
||||||
echo "Starting ogRepository..."
|
|
||||||
systemctl start smbd
|
|
||||||
systemctl start nmbd
|
|
||||||
systemctl start ogrepo-api
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid action."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
handle_ogcore() {
|
|
||||||
case $1 in
|
|
||||||
stop)
|
|
||||||
echo "Stopping ogCore..."
|
|
||||||
systemctl stop ogcore
|
|
||||||
;;
|
|
||||||
start)
|
|
||||||
echo "Starting ogCore..."
|
|
||||||
systemctl start ogcore
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid action."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
handle_oggui() {
|
|
||||||
case $1 in
|
|
||||||
stop)
|
|
||||||
echo "Stopping ogGui..."
|
|
||||||
systemctl stop oggui-app
|
|
||||||
;;
|
|
||||||
start)
|
|
||||||
echo "Starting ogGui..."
|
|
||||||
systemctl start oggui-app
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo "Invalid action."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
update_installed_components() {
|
|
||||||
local version=$1
|
|
||||||
echo "Updating components to version $version..."
|
|
||||||
for component in "${INSTALLED_COMPONENTS[@]}"; do
|
|
||||||
echo "Updating component $component..."
|
|
||||||
update_component $component $version
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#### Main
|
|
||||||
|
|
||||||
check_os
|
|
||||||
detect_installed_components
|
|
||||||
installed_version=$(get_og_installed_version "${INSTALLED_COMPONENTS[0]}")
|
|
||||||
select_version_to_update
|
|
||||||
stop_installed_services
|
|
||||||
update_installed_components $installed_version
|
|
||||||
start_installed_services
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
|
||||||
|
CONFIGS_DIR=/tmp/opengnsys-installer-configs
|
||||||
|
rm -rf $CONFIGS_DIR
|
||||||
|
mkdir -p $CONFIGS_DIR
|
||||||
|
|
||||||
|
# Paso 1: Seleccionar los componentes
|
||||||
|
components=$(yad --list --title="Seleccionar componentes" \
|
||||||
|
--text="Selecciona los componentes que deseas configurar:" \
|
||||||
|
--checklist --multiple \
|
||||||
|
--column="Seleccionar" --column="Componente" \
|
||||||
|
FALSE "ogCore" \
|
||||||
|
FALSE "ogGui" \
|
||||||
|
FALSE "ogDhcp" \
|
||||||
|
FALSE "ogBoot" \
|
||||||
|
--width=400 --height=300 --center)
|
||||||
|
|
||||||
|
# Verificar si el usuario seleccionó algún componente
|
||||||
|
if [[ -z "$components" ]]; then
|
||||||
|
yad --info --text="No seleccionaste ningún componente. Saliendo..." --center
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for component in $components; do
|
||||||
|
selected_component=$(echo "$component" | cut -d '|' -f 2)
|
||||||
|
# Pedir la configuración específica para cada componente seleccionado
|
||||||
|
|
||||||
|
|
||||||
|
# Dividir la configuración en IP y ruta del fichero
|
||||||
|
config_file="config_${selected_component}.json"
|
||||||
|
case $selected_component in
|
||||||
|
"ogCore")
|
||||||
|
config=$(yad --form --title="Configuración para $selected_component" \
|
||||||
|
--field="Usuario administrador":TEXT \
|
||||||
|
--field="Contraseña":H \
|
||||||
|
--field="Tag del contenedor":TEXT \
|
||||||
|
"ogadmin" "" "latest" \
|
||||||
|
--width=400 --height=200 --center)
|
||||||
|
user=$(echo "$config" | cut -d '|' -f 1)
|
||||||
|
password=$(echo "$config" | cut -d '|' -f 2)
|
||||||
|
container_tag=$(echo "$config" | cut -d '|' -f 3)
|
||||||
|
echo "{\"username\": \"$user\", \"password\": \"$password\", \"container_version\": \"$container_tag\" }" > $CONFIGS_DIR/"$config_file"
|
||||||
|
;;
|
||||||
|
"ogGui")
|
||||||
|
config=$(yad --form --title="Configuración para $selected_component" \
|
||||||
|
--field="IP del servidor de ogCore" \
|
||||||
|
--field="Tag del contenedor":TEXT \
|
||||||
|
--width=400 --height=200 --center)
|
||||||
|
ogcore_ip=$(echo "$config" | cut -d '|' -f 1)
|
||||||
|
container_version=$(echo "$config" | cut -d '|' -f 2)
|
||||||
|
echo "{\"ogcore_ip\": \"$ogcore_ip\" , \"container_version\": \"$container_version\" }" > $CONFIGS_DIR/"$config_file"
|
||||||
|
;;
|
||||||
|
"ogDhcp")
|
||||||
|
config=$(yad --form --title="Configuración para $selected_component" \
|
||||||
|
--field="Configuración IP servidor de Boot" \
|
||||||
|
--field="Interfaces Boot" \
|
||||||
|
--width=400 --height=200 --center)
|
||||||
|
ogbootIP=$(echo "$config" | cut -d '|' -f 1)
|
||||||
|
interfaces=$(echo "$config" | cut -d '|' -f 2)
|
||||||
|
json_array_interfaces=$(echo "$interfaces" | jq -R 'split(",")')
|
||||||
|
echo "{\"ogbootIP\": \"$ogbootIP\", \"interfaces\": \"$json_array_interfaces\"}" > $CONFIGS_DIR/"$config_file"
|
||||||
|
;;
|
||||||
|
"ogBoot")
|
||||||
|
config=$(yad --form --title="Configuración para $selected_component" \
|
||||||
|
--field="ogCore Ip Server" \
|
||||||
|
--field="ogCore Server" \
|
||||||
|
--field="ogCore Dir" \
|
||||||
|
--field="ogBoot GitRepo" \
|
||||||
|
--field="ogBoot Samba User" \
|
||||||
|
--field="ogBoot Samba Pass" \
|
||||||
|
--width=400 --height=200 --center)
|
||||||
|
ogcore_ip=$(echo "$config" | cut -d '|' -f 1)
|
||||||
|
ogcore_server=$(echo "$config" | cut -d '|' -f 2)
|
||||||
|
ogcore_dir=$(echo "$config" | cut -d '|' -f 3)
|
||||||
|
ogboot_gitrepo=$(echo "$config" | cut -d '|' -f 4)
|
||||||
|
ogboot_samba_user=$(echo "$config" | cut -d '|' -f 5)
|
||||||
|
ogboot_samba_pass=$(echo "$config" | cut -d '|' -f 6)
|
||||||
|
echo "{\"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\"}" > $CONFIGS_DIR/"$config_file"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Verificar si los campos no están vacíos
|
||||||
|
# if [[ -z "$server_ip" || -z "$config_path" ]]; then
|
||||||
|
# yad --error --text="Debes proporcionar la IP del servidor y la ruta del fichero para $selected_component." --center
|
||||||
|
# exit 1
|
||||||
|
# fi
|
||||||
|
|
||||||
|
# Guardar la configuración en un archivo (cada componente tiene su archivo JSON)
|
||||||
|
config_file="./${selected_component}_config.json"
|
||||||
|
echo "{\"server_ip\": \"$server_ip\", \"config_path\": \"$config_path\"}" > "$config_file"
|
||||||
|
|
||||||
|
# Mostrar un mensaje de éxito
|
||||||
|
yad --info --text="Configuración guardada en $config_file para $selected_component." --center
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
|
||||||
|
# # Una vez se ha configurado todo, se puede proceder a la instalación de los componentes
|
||||||
|
# # Ejecutar la instalación con calamares y enviar el log a un archivo
|
||||||
|
|
||||||
|
# #calamares > installer.log 2>&1 & disown
|
||||||
|
sudo calamares > installer.log 2>&1
|
|
@ -0,0 +1,217 @@
|
||||||
|
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 if tag.name.startswith("opengnsys")]
|
||||||
|
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=10, 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, default_value=""):
|
||||||
|
"""Añade un campo de contraseña con metadatos."""
|
||||||
|
widget = self.add(npyscreen.TitlePassword, name=name, value=default_value)
|
||||||
|
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:" , default_value="12345678")
|
||||||
|
self.add_password_field("confirm_password", "Confirmar Contraseña:", is_confirmation=True, default_value="12345678")
|
||||||
|
|
||||||
|
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["ogDhcp_Dir"] = {"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")}
|
||||||
|
|
||||||
|
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():
|
||||||
|
if key == "interfaces":
|
||||||
|
config_data[key] = [iface.strip() for iface in field_data["widget"].value.split(",")]
|
||||||
|
else:
|
||||||
|
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)
|
||||||
|
|
||||||
|
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="https://ognproject.evlt.uma.es/oglive/ogLive-noble-6.8.0-31-generic-amd64-r20241128.62778c9_20241129.iso")}
|
||||||
|
self.fields["ogBootSambaUser"] = {"widget": self.add(npyscreen.TitleText, name="ogBoot Samba User (opengnsys):", value="opengnsys")}
|
||||||
|
self.add_password_field("ogBootSambaPass", "ogBoot Samba Pass (og):", default_value="og")
|
||||||
|
self.add_password_field("confirm_ogBootSambaPass", "Confirmar ogBoot Samba Pass (og):", is_confirmation=True, default_value="og")
|
||||||
|
|
||||||
|
|
||||||
|
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:", default_value="og")
|
||||||
|
self.add_password_field("confirm_repository_password", "Confirmar Samba Password:", is_confirmation=True, default_value="og")
|
||||||
|
|
||||||
|
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()
|
|
@ -0,0 +1,220 @@
|
||||||
|
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)
|
||||||
|
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 = ""
|
||||||
|
|
||||||
|
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=""):
|
||||||
|
max_y, max_x = stdscr.getmaxyx()
|
||||||
|
if x + len(prompt) >= max_x:
|
||||||
|
raise ValueError("El prompt es demasiado largo para caber en la pantalla.")
|
||||||
|
|
||||||
|
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
|
||||||
|
if prompt_end_x + len(input_text) < max_x - 1:
|
||||||
|
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, "URL Api OgCore (https://127.0.0.1:8443): " , "https://127.0.0.1:8443")
|
||||||
|
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/ogboot): ", "/opt/opengnsys/ogboot")
|
||||||
|
ogLive_default = get_input(stdscr, 6, 0, "ogLive por defecto (ogLive-noble-6.8.0-31-generic-amd64-r20241128.62778c9_20241129): ", "ogLive-noble-6.8.0-31-generic-amd64-r20241128.62778c9_20241129")
|
||||||
|
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)
|
|
@ -7,15 +7,8 @@ BRANCH=${BRANCH:-main}
|
||||||
GIT_SSL_NO_VERIFY=1
|
GIT_SSL_NO_VERIFY=1
|
||||||
GIT_REPO="https://ognproject.evlt.uma.es/gitea/api/v1/repos/opengnsys/oginstaller/archive/$BRANCH.zip"
|
GIT_REPO="https://ognproject.evlt.uma.es/gitea/api/v1/repos/opengnsys/oginstaller/archive/$BRANCH.zip"
|
||||||
export GIT_SSL_NO_VERIFY
|
export GIT_SSL_NO_VERIFY
|
||||||
DEVEL=$1
|
|
||||||
|
|
||||||
if [ "$DEVEL" == "devel" ]; then
|
|
||||||
INSTALL_DEVEL=1
|
|
||||||
elif [ "$DEVEL" == "nightly" ]; then
|
|
||||||
INSTALL_NIGHTLY=1
|
|
||||||
else
|
|
||||||
INSTALL_STABLE=1
|
|
||||||
fi
|
|
||||||
|
|
||||||
install_packages() {
|
install_packages() {
|
||||||
apt-get update
|
apt-get update
|
||||||
|
@ -44,22 +37,23 @@ download_installer() {
|
||||||
extract_installer() {
|
extract_installer() {
|
||||||
rm -rf /tmp/oginstall
|
rm -rf /tmp/oginstall
|
||||||
mkdir -p /tmp/oginstall
|
mkdir -p /tmp/oginstall
|
||||||
cp -r /tmp/oginstaller-$BRANCH/non_graf_installer/python-installer/* /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
|
chmod 755 /tmp/oginstall/*.py
|
||||||
}
|
}
|
||||||
|
|
||||||
create_questions() {
|
create_questions() {
|
||||||
echo "Creating questions..."
|
echo "Creating questions..."
|
||||||
if [ $INSTALL_DEVEL ] ; then
|
python3 /tmp/oginstall/oginstaller-v2.py
|
||||||
python3 /tmp/oginstall/oginstaller-v3.py devel
|
|
||||||
elif [ $INSTALL_NIGHTLY ] ; then
|
|
||||||
python3 /tmp/oginstall/oginstaller-v3.py nightly
|
|
||||||
else
|
|
||||||
python3 /tmp/oginstall/oginstaller-v3.py
|
|
||||||
fi
|
|
||||||
deactivate
|
deactivate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
launch_component_installer() {
|
||||||
|
echo "Launching component installer..."
|
||||||
|
/tmp/oginstall/component-installer.sh
|
||||||
|
}
|
||||||
|
|
||||||
clean_tmp() {
|
clean_tmp() {
|
||||||
rm -rf /tmp/oginstall
|
rm -rf /tmp/oginstall
|
||||||
rm -rf /tmp/oginstaller-$BRANCH
|
rm -rf /tmp/oginstaller-$BRANCH
|
||||||
|
@ -72,4 +66,5 @@ download_installer
|
||||||
extract_installer
|
extract_installer
|
||||||
create_python_venv
|
create_python_venv
|
||||||
create_questions
|
create_questions
|
||||||
|
launch_component_installer
|
||||||
clean_tmp
|
clean_tmp
|
|
@ -1,4 +1,2 @@
|
||||||
GitPython
|
GitPython
|
||||||
npyscreen
|
npyscreen
|
||||||
requests
|
|
||||||
bs4
|
|