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
update_torrent_repos
Nicolas Arenas 2025-06-24 11:33:40 +00:00
parent a3b938e41e
commit bada82e88a
2 changed files with 83 additions and 15 deletions

View File

@ -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:

View File

@ -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 <image_name>")
journal.send("runTorrentSeeder.py: Invalid number of arguments. Expected 1 argument: <image_name>",
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)
# --------------------------------------------------------------------------------------------