From a58023f89373a45385d857d376da71fe64d1a783 Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Mon, 2 Jun 2025 12:41:33 +0200 Subject: [PATCH 01/10] Fixed BT issue in sudoers file --- CHANGELOG.md | 5 +++++ etc/opengnsys-repository | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7505790..cf37820 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ # Changelog +## [0.8.2] - 2025-06-01 + +### Changed + +- Modified sudoersfile to start torrent ## [0.8.1] - 2025-04-01 diff --git a/etc/opengnsys-repository b/etc/opengnsys-repository index 6c196e5..6aa6b06 100644 --- a/etc/opengnsys-repository +++ b/etc/opengnsys-repository @@ -25,5 +25,7 @@ Cmnd_Alias KILL_BT = \ /usr/bin/pkill -9 bttrack, \ /usr/bin/kill -9 * +Cmnd_Alias PYTHON_OGREPO = /usr/bin/python3 /opt/opengnsys/ogrepository/bin/* + # Permitir al usuario opengnsys ejecutar estos comandos sin contraseña -opengnsys ALL=(root) NOPASSWD: MOUNT_RECOVERY, CHROOT_GRUB, LOOP_KPARTX, KILL_BT +opengnsys ALL=(root) NOPASSWD: MOUNT_RECOVERY, CHROOT_GRUB, LOOP_KPARTX, KILL_BT, PYTHON_OGREPO From ecbba3d45eca0e498eb9858fc9e9a37b068a8b74 Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Mon, 23 Jun 2025 09:57:10 +0200 Subject: [PATCH 02/10] refs #2282 Review errors in ogrepo update refs #2260 Change the way to install dependency refs #2260 Remove bittorrent dependency --- debian/control | 4 +-- debian/ogrepository.postinst | 49 ++++++++++++++++++++++++++++-------- debian/ogrepository.preinst | 31 +++++++++++++++++------ 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/debian/control b/debian/control index f10d4c4..071fadd 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,7 @@ Build-Depends: debhelper-compat (= 12) Package: ogrepository Architecture: all Pre-Depends: debian-archive-keyring , debconf (>= 1.5.0), -Depends: ${misc:Depends}, git, python3, python3-pip, python3-flask, python3-paramiko, python3-psutil, python3-flasgger, samba, gunicorn, wakeonlan , lzop , partclone , qemu-utils , udpcast, uftp +Depends: ${misc:Depends}, git, python3, python3-pip, python3-flask, python3-paramiko, python3-psutil, python3-flasgger, samba, gunicorn, wakeonlan , lzop , partclone , qemu-utils , udpcast, uftp, ctorrent, bittornado Description: Ogrepsoitory Package This package provides Ogrepository service. -X-OG-Release: opengnsys-1.6.0-beta, opengnsys-1.6.1-beta + diff --git a/debian/ogrepository.postinst b/debian/ogrepository.postinst index 0d4a658..a356423 100755 --- a/debian/ogrepository.postinst +++ b/debian/ogrepository.postinst @@ -5,6 +5,25 @@ set -x . /usr/share/debconf/confmodule +restore_config_if_modified() { + local new="$1" + local backup="$1.bak.upgrade_package" + + if [ -f "$backup" ]; then + if ! cmp -s "$new" "$backup"; then + echo ">>> Archivo modificado por el usuario detectado en $new" + echo " - Guardando archivo nuevo como ${new}.new" + mv -f "$new" "${new}.new" + echo " - Restaurando archivo anterior desde backup" + mv -f "$backup" "$new" + else + echo ">>> El archivo $new no ha cambiado desde la última versión, eliminando backup" + rm -f "$backup" + fi + fi +} + + # Cargar variables de configuración db_get opengnsys/ogrepository_ogrepoIp OGREPO_IP="$RET" @@ -23,17 +42,17 @@ USER="opengnsys" # Detectar si es una instalación nueva o una actualización +# if [ "$1" = "configure" ] && [ -z "$2" ]; then +# systemd-run --no-block /bin/bash -c " +# sleep 10; +# apt update -y; +# for pkg in bittorrent bittornado ctorrent; do +# if ! dpkg -l | grep -qw \"\$pkg\"; then +# apt install -y \"\$pkg\" +# fi +# done +# " if [ "$1" = "configure" ] && [ -z "$2" ]; then - systemd-run --no-block /bin/bash -c " -sleep 10; -apt update -y; -for pkg in bittorrent bittornado ctorrent; do - if ! dpkg -l | grep -qw \"\$pkg\"; then - apt install -y \"\$pkg\" - fi -done -" - sed -i "s/%%OGREPOSITORY_USER%%/$SAMBA_USER/g" /etc/systemd/system/ogrepo-api.service sed -i "s/%%OGREPOSITORY_USER%%/$SAMBA_USER/g" /etc/samba/ogrepo-smb.conf @@ -62,7 +81,7 @@ done fi (echo "$SAMBA_PASS"; echo "$SAMBA_PASS") | smbpasswd -a $SAMBA_USER fi - + systemctl enable ogrepo-api # Configure Repo cp /opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg.tmpl /opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg @@ -83,6 +102,14 @@ elif [ "$1" = "configure" ] && [ -n "$2" ]; then cp /opt/opengnsys/ogrepository/etc/opengnsys.pub $OPENGNSYS_HOME/.ssh/id_ed25519.pub cat $OPENGNSYS_HOME/.ssh/id_ed25519.pub >> $OPENGNSYS_HOME/.ssh/authorized_keys + restore_config_if_modified "/opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg" + restore_config_if_modified "/opt/opengnsys/ogrepository/etc/repoinfo.json" + restore_config_if_modified "/opt/opengnsys/ogrepository/etc/trashinfo.json" + restore_config_if_modified "/etc/samba/smb.conf" + restore_config_if_modified "/etc/samba/ogrepo-smb.conf" + restore_config_if_modified "/etc/sudoers.d/opengnsys-repository" + + fi # Cambiar la propiedad de los archivos al usuario especificado diff --git a/debian/ogrepository.preinst b/debian/ogrepository.preinst index 652cf8f..14be01b 100755 --- a/debian/ogrepository.preinst +++ b/debian/ogrepository.preinst @@ -2,8 +2,18 @@ set -e -KEY_FILE="/usr/share/keyrings/debian-archive-buster-stable.gpg" -REPO_FILE="/etc/apt/sources.list.d/buster.list" +backup_file_if_exists() { + local original="$1" + local backup="$1.bak.upgrade_package" + + if [ -e "$original" ]; then + echo " - Guardando backup de $original en $backup" + cp -a "$original" "$backup" + fi +} + +# KEY_FILE="/usr/share/keyrings/debian-archive-buster-stable.gpg" +# REPO_FILE="/etc/apt/sources.list.d/buster.list" # Asegurarse de que el usuario exista USER="opengnsys" @@ -20,10 +30,17 @@ echo "Añadiendo el repositorio de Debian Buster en $REPO_FILE..." mkdir -p "$(dirname "$REPO_FILE")" # Crear el archivo de repositorio si no existe -if [ ! -f "$REPO_FILE" ]; then - echo "deb [signed-by=$KEY_FILE] http://ftp.de.debian.org/debian buster main" > "$REPO_FILE" -else - echo "El repositorio ya está configurado en $REPO_FILE" -fi +# if [ ! -f "$REPO_FILE" ]; then +# echo "deb [signed-by=$KEY_FILE] http://ftp.de.debian.org/debian buster main" > "$REPO_FILE" +# else +# echo "El repositorio ya está configurado en $REPO_FILE" +# fi + +backup_file_if_exists "/opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg" +backup_file_if_exists "/opt/opengnsys/ogrepository/etc/repoinfo.json" +backup_file_if_exists "/opt/opengnsys/ogrepository/etc/trashinfo.json" +backup_file_if_exists "/etc/samba/smb.conf" +backup_file_if_exists "/etc/samba/ogrepo-smb.conf" +backup_file_if_exists "/etc/sudoers.d/ogrepository" exit 0 From dd60800c9788133c8bb284140f3ac72e2c25ed5f Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Mon, 23 Jun 2025 23:54:26 +0200 Subject: [PATCH 03/10] refs #2290: Replaces ctorrent by mktorrent to create torrent file for images --- bin/createTorrentSum.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/createTorrentSum.py b/bin/createTorrentSum.py index 15c2076..1f32690 100644 --- a/bin/createTorrentSum.py +++ b/bin/createTorrentSum.py @@ -134,8 +134,8 @@ def create_torrent(file_path, torrent_file, datafullsum): repo_ip = get_IPlocal() tracker_url = f"http://{repo_ip}:6969/announce" - # Creamos una lista con el comando para crear el torrrent, y lo imprimimos con espacios: - splitted_cmd = f"nice -n 0 ctorrent -t {file_path} -u {tracker_url} -s {torrent_file} -c {datafullsum} -l 4194304".split() + # Creamos una litas para ejecutar el comando mktorrent para crear el archivo torrent + splitted_cmd = f"nice -n 0 mktorrent -a {tracker_url} -c {datafullsum} -o {torrent_file} -l 4194304 {file_path}".split() print(f"Sending command: {' '.join(splitted_cmd)}") # Ejecutamos el comando en el sistema, e imprimimos el resultado: From a3b938e41ef5182d74f83a9a5a434fe7da75e488 Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Tue, 24 Jun 2025 05:20:39 +0000 Subject: [PATCH 04/10] refs #2290: Removes -l parameter in mktorrent refs #2294: Updates dependency with mktorrent --- bin/createTorrentSum.py | 2 +- debian/control | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/createTorrentSum.py b/bin/createTorrentSum.py index 1f32690..070d88b 100644 --- a/bin/createTorrentSum.py +++ b/bin/createTorrentSum.py @@ -135,7 +135,7 @@ def create_torrent(file_path, torrent_file, datafullsum): tracker_url = f"http://{repo_ip}:6969/announce" # Creamos una litas para ejecutar el comando mktorrent para crear el archivo torrent - splitted_cmd = f"nice -n 0 mktorrent -a {tracker_url} -c {datafullsum} -o {torrent_file} -l 4194304 {file_path}".split() + splitted_cmd = f"nice -n 0 mktorrent -a {tracker_url} -c {datafullsum} -o {torrent_file} {file_path}".split() print(f"Sending command: {' '.join(splitted_cmd)}") # Ejecutamos el comando en el sistema, e imprimimos el resultado: diff --git a/debian/control b/debian/control index 071fadd..1bcdd6b 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,7 @@ Build-Depends: debhelper-compat (= 12) Package: ogrepository Architecture: all Pre-Depends: debian-archive-keyring , debconf (>= 1.5.0), -Depends: ${misc:Depends}, git, python3, python3-pip, python3-flask, python3-paramiko, python3-psutil, python3-flasgger, samba, gunicorn, wakeonlan , lzop , partclone , qemu-utils , udpcast, uftp, ctorrent, bittornado +Depends: ${misc:Depends}, git, python3, python3-pip, python3-flask, python3-paramiko, python3-psutil, python3-flasgger, samba, gunicorn, wakeonlan , lzop , partclone , qemu-utils , udpcast, uftp, ctorrent, bittornado, mktorrent Description: Ogrepsoitory Package This package provides Ogrepository service. - + From bada82e88a31a3e491ca47b565ef546bae9f7dfa Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Tue, 24 Jun 2025 11:33:40 +0000 Subject: [PATCH 05/10] refs #2291 and #2293: Replace bittomany for aria2c refs #2293: changes way to kill aria2c process refs #2293: a aria2c is launched for each image to be served --- api/repo_api.py | 15 ++++---- bin/runTorrentSeeder.py | 83 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 15 deletions(-) diff --git a/api/repo_api.py b/api/repo_api.py index 0bc2c5f..335da4f 100644 --- a/api/repo_api.py +++ b/api/repo_api.py @@ -143,7 +143,7 @@ def search_process(process, string_to_search): """ Busca procesos que contengan el valor del parámetro "process" y el valor del parámetro "string_to_search" (la ruta de la imagen, normalmente). Si encuentra alguno retorna "True", y si no encuentra ninguno retorna "False". """ - journal.send("Running function 'search_process'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") + journal.send(f"Running function 'search_process' {process} wit string {string_to_search}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") try: # Obtenemos todos los procesos que están corriendo, y almacenamos la salida y los errores: @@ -155,11 +155,11 @@ def search_process(process, string_to_search): # Si hemos encontrado algún proceso que cumpla las condiciones, retornamos "True", y si no retornamos "False": if process_list != []: - journal.send("Process found", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") + journal.send(f"Process found: {process} with string {string_to_search} ", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") journal.send("{'component':'ogRepo', 'severity':'INFO', 'operation':'Run function search_process', 'desc':'Process found'}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api") return True else: - journal.send("Process not found", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") + journal.send(f"Process not found: {process} with string {string_to_search}", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") journal.send("{'component':'ogRepo', 'severity':'WARNING', 'operation':'Run function search_process', 'desc':'Process not found'}", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api") return False # Si se ha producido una excepción, imprimimos el error: @@ -1357,7 +1357,7 @@ def create_torrent_sum(): # --------------------------------------------------------- -# 12 - Endpoint "Enviar paquete Wake On Lan" (SINCRONO): +# 12 - Endoint "Enviar paquete Wake On Lan" (SINCRONO): @app.route("/ogrepository/v1/wol", methods=['POST']) def send_wakeonlan(): """ Este endpoint envía un paquete mágico Wake On Lan a la dirección MAC especificada, a través de la IP de broadcast especificadac. @@ -1567,8 +1567,9 @@ def send_p2p(): # Evaluamos los parámetros obtenidos, para construir las llamadas a los scripts, o para devolver un error si no se ha encontrado la imagen: if param_dict: - cmd_tracker = ['sudo', 'python3', f"{script_path}/runTorrentTracker.py"] # Este script si que requiere ser ejecutado con "sudo" - cmd_seeder = ['sudo', 'python3', f"{script_path}/runTorrentSeeder.py"] # Este script si que requiere ser ejecutado con "sudo" + + cmd_tracker = ['python3', f"{script_path}/runTorrentTracker.py"] # Este script si que requiere ser ejecutado con "sudo" + cmd_seeder = ['python3', f"{script_path}/runTorrentSeeder.py" , param_dict['name']] # Este script si que requiere ser ejecutado con "sudo" , Lanzamos el seeder con el nombre de la imagen como parámetro base_path = repo_path.rstrip('/') # Le quito la última barra para poder buscar correctamente en los procesos else: journal.send("Image not found", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") @@ -1591,7 +1592,7 @@ def send_p2p(): # (esperamos 10 segundos antes de hacerlo, porque los procesos no se inician inmediatamente): sleep(10) tracker_running = search_process('bttrack', base_path) - seeder_running = search_process('btlaunchmany', base_path) + seeder_running = search_process('aria2c', f"{param_dict['name']}.img.torrent") # El seeder se ejecuta con "aria2c" y el nombre de la imagen como parámetro # Evaluamos las comprobaciones anteriores, para devolver la respuesta que corresponda: if tracker_running and seeder_running: diff --git a/bin/runTorrentSeeder.py b/bin/runTorrentSeeder.py index ae17010..2496d76 100644 --- a/bin/runTorrentSeeder.py +++ b/bin/runTorrentSeeder.py @@ -16,6 +16,8 @@ No recibe ningún parámetro. import os import sys import subprocess +import psutil +import re from systemd import journal @@ -31,6 +33,7 @@ repo_path = '/opt/opengnsys/ogrepository/images' # En este caso, no lleva barra # -------------------------------------------------------------------------------------------- + def run_bittornado(repo_path): """ Ejecuta el comando "btlaunchmany.bittornado", con sus parámetros correspondientes. Además, captura el resultado y los posibles errores, y los imprime. @@ -55,6 +58,48 @@ def run_bittornado(repo_path): +def run_aria2c_seeder(image_name): + """Lanza aria2c como seeder puro para una imagen concreta ya existente.""" + + repo_path = '/opt/opengnsys/ogrepository/images' + torrent_file = os.path.join(repo_path, f"{image_name}.img.torrent") + image_file = os.path.join(repo_path, f"{image_name}.img") + + # Verificación básica + if not os.path.exists(torrent_file): + print(f"Torrent file not found: {torrent_file}") + journal.send(f"Seeder error: Torrent file not found: {torrent_file}", + PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api") + return + + if not os.path.exists(image_file): + print(f"Image file not found: {image_file}") + journal.send(f"Seeder error: Image file not found: {image_file}", + PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api") + return + + # Comando aria2c como seeder puro + cmd = [ + 'aria2c', + '--enable-peer-exchange=true', + '--bt-seed-unverified=true', + '--check-integrity=true', + '--seed-ratio=0.0', + '--dir=' + repo_path, + torrent_file + ] + + journal.send(f"Launching aria2c seeder for {image_name}", + PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api") + + print("Running command:", ' '.join(cmd)) + try: + subprocess.run(cmd, check=True) + except subprocess.CalledProcessError as e: + journal.send(f"aria2c seeder failed: {e}", + PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api") + print(f"Seeder process exited with code {e.returncode}") + # -------------------------------------------------------------------------------------------- # MAIN # -------------------------------------------------------------------------------------------- @@ -64,16 +109,38 @@ def main(): """ """ # Finalizamos el proceso "btlaunchmany.bittornado" (en caso de que estuviera corriendo): - try: - journal.send("runTorrentSeeder.py: Killing process 'btlaunchmany.bittornado'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") - subprocess.run(f"pkill btlaunchmany".split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - except Exception as error_description: - journal.send("runTorrentSeeder.py: No 'btlaunchmany.bittornado' process running", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") - print(f"No btlaunchmany.bittornado process running? Returned error: {error_description}") + if len(sys.argv) != 2: + print("Usage: runTorrentSeeder.py ") + journal.send("runTorrentSeeder.py: Invalid number of arguments. Expected 1 argument: ", + PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") + sys.exit(1) + + image_name = sys.argv[1] + torrent_file = os.path.join(repo_path, f"{image_name}.img.torrent") + found = False + # Matamos los procesos de aria2c que sirvan la imagen en concreto. Chequeamos todos los procesos - # Ejecutamos el comando "btlaunchmany.bittornado" (para hacer seed de los torrents): - run_bittornado(repo_path) + for proc in psutil.process_iter(['pid','name','cmdline']): + try: + if proc.info['name'] != 'aria2c': + continue + if any(arg.endswith(torrent_file) for arg in proc.info['cmdline']): + proc.kill() + found = True + print(f"Killed aria2c process with PID {proc.info['pid']} for {image_name}.torrent") + journal.send(f"runTorrentSeeder.py: Killed aria2c process with PID {proc.info['pid']} for {image_name}.torrent", + PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") + except (psutil.NoSuchProcess, psutil.AccessDenied): + continue + + if not found: + print(f"No aria2c process found for {image_name}.torrent") + journal.send(f"runTorrentSeeder.py: No aria2c process found for {image_name}.torrent", + PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") + + # Lanzamos aria2c como seeder para la imagen proporcionada + run_aria2c_seeder(image_name) # -------------------------------------------------------------------------------------------- From 0118ca53a5042c16a1e3e705998ee3b0c4a9896f Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Wed, 25 Jun 2025 11:48:25 +0200 Subject: [PATCH 06/10] refs #2293: Removes calls to runTorrentTracker --- api/repo_api.py | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/api/repo_api.py b/api/repo_api.py index 335da4f..22064e1 100644 --- a/api/repo_api.py +++ b/api/repo_api.py @@ -1567,8 +1567,6 @@ def send_p2p(): # Evaluamos los parámetros obtenidos, para construir las llamadas a los scripts, o para devolver un error si no se ha encontrado la imagen: if param_dict: - - cmd_tracker = ['python3', f"{script_path}/runTorrentTracker.py"] # Este script si que requiere ser ejecutado con "sudo" cmd_seeder = ['python3', f"{script_path}/runTorrentSeeder.py" , param_dict['name']] # Este script si que requiere ser ejecutado con "sudo" , Lanzamos el seeder con el nombre de la imagen como parámetro base_path = repo_path.rstrip('/') # Le quito la última barra para poder buscar correctamente en los procesos else: @@ -1579,11 +1577,18 @@ def send_p2p(): "error": "Image not found" }), 400 - # Ejecutamos los scripts "runTorrentSeeder.py" y "runTorrentSeeder.py", que no reciben parámetros. - # NOTA: No almacenamos la salida ni comprobamos los errores, porque los procesos quedarán corriendo hasta que se finalicen manualmente, - # por lo que no podemos comprobar el returncode (luego comprobaremos si los procesos se han iniciado correctamente). - journal.send("Running script 'runTorrentTracker.py'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") - subprocess.Popen(cmd_tracker) + # Comprobamos si el tracker esta ejecutandose, si no lo esta devolevemos un error y salimos del endpoint: + tracker_running = search_process('opentracker' , '/etc/opentracker/opentracker.conf') # El tracker se ececuta con "opentracker" y el fichero de configuración "/etc/opentracker/opentracker.conf" + if not tracker_running: + journal.send("Tracker not running", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") + journal.send("{'component':'ogRepo', 'severity':'ERROR', 'http_code':'500', 'operation':'Run opentrack', 'desc':'Tracker not running'}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api") + error_message = "Tracker not running. Check if the tracker is installed and configured correctly." + return jsonify({ + "success": False, + "error": error_message + }), 500 + + # Ejecutamos los scripts "runTorrentSeeder.py", que no reciben parámetros. journal.send("Running script 'runTorrentSeeder.py'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") subprocess.Popen(cmd_seeder) @@ -1591,26 +1596,29 @@ def send_p2p(): # Comprobamos si el tracker y el seeder están corriendo, y si apuntan al directorio que le hemos pasado # (esperamos 10 segundos antes de hacerlo, porque los procesos no se inician inmediatamente): sleep(10) - tracker_running = search_process('bttrack', base_path) seeder_running = search_process('aria2c', f"{param_dict['name']}.img.torrent") # El seeder se ejecuta con "aria2c" y el nombre de la imagen como parámetro + # Evaluamos las comprobaciones anteriores, para devolver la respuesta que corresponda: - if tracker_running and seeder_running: - journal.send("Scripts 'runTorrentTracker.py' and 'runTorrentSeeder.py' results OK (ReturnCodes: None), and processes running", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") - journal.send("{'component':'ogRepo', 'severity':'INFO', 'http_code':'200', 'operation':'Run scripts runTorrentTracker.py and runTorrentSeeder.py', 'desc':'Results OK (ReturnCodes: None), and processes running'}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api") + if seeder_running: + journal.send("'runTorrentSeeder.py' results OK (ReturnCodes: None), and processes running", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") + journal.send("{'component':'ogRepo', 'severity':'INFO', 'http_code':'200', 'operation':'Run script runTorrentSeeder.py', 'desc':'Results OK (ReturnCodes: None), and processes running'}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api") return jsonify({ "success": True, "output": "Tracker and Seeder serving image correctly" }), 200 else: - journal.send("Scripts 'runTorrentTracker.py' and 'runTorrentSeeder.py' results KO (Tracker or/and Seeder not runnig)", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") - journal.send("{'component':'ogRepo', 'severity':'ERROR', 'http_code':'500', 'operation':'Run scripts runTorrentTracker.py and runTorrentSeeder.py', 'desc':'Results KO (Tracker or/and Seeder not runnig)'}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api") + journal.send("Script 'runTorrentSeeder.py' results KO (Seeder not runnig)", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") + journal.send("{'component':'ogRepo', 'severity':'ERROR', 'http_code':'500', 'operation':'Run script runTorrentSeeder.py', 'desc': '" + error_message + "'}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api") + error_message = f"Seeder not running. Check if the image {param_dict['name']}.{param_dict['extension']} exists in the repository." + return jsonify({ "success": False, - "error": "Tracker or Seeder (or both) not running" + "error": error_message }), 500 + # --------------------------------------------------------- From 6236be85d84d91b9c4924e27768cc4fb3a3846fe Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Wed, 25 Jun 2025 11:53:43 +0200 Subject: [PATCH 07/10] refs 2293: Removes information for unwanted services --- bin/getRepoStatus.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/getRepoStatus.py b/bin/getRepoStatus.py index ffaaf79..f574de8 100644 --- a/bin/getRepoStatus.py +++ b/bin/getRepoStatus.py @@ -106,11 +106,11 @@ def main(): total_disk, used_disk, free_disk, percent_disk = get_disk_info() # Obtenemos el estado de los servicios listados, que almacenamos en un diccionario: - service_list = ['ssh', 'smbd', 'rsync'] + service_list = ['ssh', 'smbd', 'opentracker'] services_status = {service: get_service_status(service) for service in service_list} # Obtenemos el estado de los procesos listados, que almacenamos en un diccionario: - process_list = ['udp-sender', 'uftp', 'bttrack', 'btlaunchmany.bittornado'] + process_list = ['udp-sender', 'uftp', 'aria2c'] process_status = {process: get_process_status(process) for process in process_list} # Creamos un diccionario con toda la información obtenida: From 9f170c23c7d48e628728196e916f93ececea6e89 Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Wed, 25 Jun 2025 11:55:47 +0200 Subject: [PATCH 08/10] refs #2291 Commentout call to old utilities refs #2291 soft kill of aria2c process --- bin/runTorrentSeeder.py | 47 ++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 22 deletions(-) diff --git a/bin/runTorrentSeeder.py b/bin/runTorrentSeeder.py index 2496d76..e43f377 100644 --- a/bin/runTorrentSeeder.py +++ b/bin/runTorrentSeeder.py @@ -34,27 +34,27 @@ repo_path = '/opt/opengnsys/ogrepository/images' # En este caso, no lleva barra -def run_bittornado(repo_path): - """ Ejecuta el comando "btlaunchmany.bittornado", con sus parámetros correspondientes. - Además, captura el resultado y los posibles errores, y los imprime. - """ - # Creamos una lista con el comando "btlaunchmany.bittornado" y sus parámetros, y lo imprimimos con espacios: - splitted_cmd = f"btlaunchmany.bittornado {repo_path}".split() - print(f"Sending command: {' '.join(splitted_cmd)}") - journal.send(f"runTorrentSeeder.py: Running command: {' '.join(splitted_cmd)}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") +# def run_bittornado(repo_path): +# """ Ejecuta el comando "btlaunchmany.bittornado", con sus parámetros correspondientes. +# Además, captura el resultado y los posibles errores, y los imprime. +# """ +# # Creamos una lista con el comando "btlaunchmany.bittornado" y sus parámetros, y lo imprimimos con espacios: +# splitted_cmd = f"btlaunchmany.bittornado {repo_path}".split() +# print(f"Sending command: {' '.join(splitted_cmd)}") +# journal.send(f"runTorrentSeeder.py: Running command: {' '.join(splitted_cmd)}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") - # Ejecutamos el comando "btlaunchmany.bittornado" en el sistema, e imprimimos el resultado: - try: - result = subprocess.run(splitted_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - journal.send(f"runTorrentSeeder.py: Command ReturnCode: {result.returncode}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") - print(f"Bittornado ReturnCode: {result.returncode}") - except subprocess.CalledProcessError as error: - journal.send("runTorrentSeeder.py: Process finalized", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") - print(f"Bittornado ReturnCode: {error.returncode}") - print(f"Bittornado Error Output: {error.stderr.decode()}") - except Exception as error: - journal.send(f"runTorrentSeeder.py: Command exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") - print(f"Unexpected bittornado error: {error}") +# # Ejecutamos el comando "btlaunchmany.bittornado" en el sistema, e imprimimos el resultado: +# try: +# result = subprocess.run(splitted_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) +# journal.send(f"runTorrentSeeder.py: Command ReturnCode: {result.returncode}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") +# print(f"Bittornado ReturnCode: {result.returncode}") +# except subprocess.CalledProcessError as error: +# journal.send("runTorrentSeeder.py: Process finalized", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") +# print(f"Bittornado ReturnCode: {error.returncode}") +# print(f"Bittornado Error Output: {error.stderr.decode()}") +# except Exception as error: +# journal.send(f"runTorrentSeeder.py: Command exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") +# print(f"Unexpected bittornado error: {error}") @@ -91,7 +91,8 @@ def run_aria2c_seeder(image_name): journal.send(f"Launching aria2c seeder for {image_name}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api") - + journal.send(f"Command: {' '.join(cmd)}", + PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api") print("Running command:", ' '.join(cmd)) try: subprocess.run(cmd, check=True) @@ -120,13 +121,15 @@ def main(): found = False # Matamos los procesos de aria2c que sirvan la imagen en concreto. Chequeamos todos los procesos + journal.send(f"runTorrentSeeder.py: looking for aria2c processes for {image_name}.torrent", + PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG") for proc in psutil.process_iter(['pid','name','cmdline']): try: if proc.info['name'] != 'aria2c': continue if any(arg.endswith(torrent_file) for arg in proc.info['cmdline']): - proc.kill() + proc.terminate() found = True print(f"Killed aria2c process with PID {proc.info['pid']} for {image_name}.torrent") journal.send(f"runTorrentSeeder.py: Killed aria2c process with PID {proc.info['pid']} for {image_name}.torrent", From ccf04ba8fc84badf2da824264405b1ce440ae950 Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Wed, 25 Jun 2025 11:58:48 +0200 Subject: [PATCH 09/10] refs 2294: include opengnsys-opentracker as dependency --- debian/control | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 1bcdd6b..1ee440d 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,7 @@ Build-Depends: debhelper-compat (= 12) Package: ogrepository Architecture: all Pre-Depends: debian-archive-keyring , debconf (>= 1.5.0), -Depends: ${misc:Depends}, git, python3, python3-pip, python3-flask, python3-paramiko, python3-psutil, python3-flasgger, samba, gunicorn, wakeonlan , lzop , partclone , qemu-utils , udpcast, uftp, ctorrent, bittornado, mktorrent +Depends: ${misc:Depends}, git, python3, python3-pip, python3-flask, python3-paramiko, python3-psutil, python3-flasgger, samba, gunicorn, wakeonlan , lzop , partclone , qemu-utils , udpcast, uftp, mktorrent, aria2 , opengnsys-opentracker Description: Ogrepsoitory Package This package provides Ogrepository service. From 95524ac9cf83a367c864b364324089d08cdad62a Mon Sep 17 00:00:00 2001 From: Nicolas Arenas Date: Wed, 25 Jun 2025 12:40:55 +0200 Subject: [PATCH 10/10] Updated Changelog.md --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf37820..a40bbfc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,14 @@ # Changelog + +## [0.9.0] - 2025-06-25 + +## Added + +- Changed old tools for tools non dependant of Pyhton2 in repo +- mktorrent to handle creation of torrent files +- aria2c as torrent client for initial seeding +- opentracker as torrent tracker tool + ## [0.8.2] - 2025-06-01 ### Changed