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) # --------------------------------------------------------------------------------------------