From 97f1f9c62e605e624f25fe9f626c359c49614c8f Mon Sep 17 00:00:00 2001 From: ggil Date: Fri, 30 Aug 2024 13:43:49 +0200 Subject: [PATCH] refs #631 - Add runTorrentTracker.py and runTorrentSeeder.py --- README.md | 78 +++++++++++-------- bin/torrent-tracker | 7 +- bin/torrent-tracker_OLD | 20 +++++ py_scripts/runTorrentSeeder.py | 130 ++++++++++++++++++++++++++++++++ py_scripts/runTorrentTracker.py | 89 ++++++++++++++++++++++ 5 files changed, 291 insertions(+), 33 deletions(-) create mode 100644 bin/torrent-tracker_OLD create mode 100644 py_scripts/runTorrentSeeder.py create mode 100644 py_scripts/runTorrentTracker.py diff --git a/README.md b/README.md index 725b867..dbd1c9f 100644 --- a/README.md +++ b/README.md @@ -27,15 +27,16 @@ El presente documento detalla los endpoints de la API, con sus respectivos pará 5. [Recuperar una Imagen](#recuperar-una-imagen) - `POST /ogrepository/v1/images/recover-image` 6. [Importar una Imagen](#importar-una-imagen) - `POST /ogrepository/v1/images/import-image` 7. [Crear archivos "sum" y "torrent"](#crear-archivos-sum-y-torrent) - `POST /ogrepository/v1/images/create-torrentsum` -8. [Enviar una Imagen mediante UDPcast](#enviar-una-imagen-mediante-udpcast) - `POST /ogrepository/v1/images/send-udpcast` -9. [Enviar una Imagen mediante UFTP](#enviar-una-imagen-mediante-uftp) - `POST /ogrepository/v1/images/send-uftp` -10. [Enviar una Imagen mediante P2P](#enviar-una-imagen-mediante-p2p) - `POST /ogrepository/v1/images/send-p2p` -11. [Chequear integridad de Imagen](#chequear-integridad-de-imagen) - `GET /ogrepository/v1/images/check-image` -12. [Ver Estado de Transmisiones Multicast-P2P](#ver-estado-de-transmisiones-multicast-p2p) - -13. [Cancelar Transmisión Multicast-P2P](#cancelar-transmisión-multicast-p2p) - +8. [Iniciar el Tracker P2P](#iniciar-el-tracker-p2p) - `POST /ogrepository/v1/images/run-tracker` +9. [Iniciar el Seeder P2P](#iniciar-el-seeder-p2p) - `POST /ogrepository/v1/images/run-seeder` +10. [Enviar una Imagen mediante UDPcast](#enviar-una-imagen-mediante-udpcast) - `POST /ogrepository/v1/images/send-udpcast` +11. [Enviar una Imagen mediante UFTP](#enviar-una-imagen-mediante-uftp) - `POST /ogrepository/v1/images/send-uftp` +12. [Chequear integridad de Imagen](#chequear-integridad-de-imagen) - `GET /ogrepository/v1/images/check-image` +13. [Ver Estado de Transmisiones Multicast-P2P](#ver-estado-de-transmisiones-multicast-p2p) - +14. [Cancelar Transmisión Multicast-P2P](#cancelar-transmisión-multicast-p2p) - --- -### Obtener Información de todas las Imágenes +### Obtener Información de todas las Imágenes Se devolverá la informacion contenida en el archivo "**/opt/opengnsys/etc/repoinfo.json**" (que corresponde a todas las imágenes almacenadas en el repositorio), y en el archivo "**/opt/opengnsys/etc/trashinfo.json**" (que corresponde a las imágenes que fueron eliminadas, que estarán en la papelera). Se puede utilizar el script "**getRepoInfo.py**, que hemos programado recientemente. @@ -290,6 +291,46 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d - **Código 400 Bad Request:** No se ha encontrado la imagen especificada. - **Código 200 OK:** Los archivos se han creado exitosamente. +--- +### Iniciar el Tracker P2P + +Se iniciará el tracker "bttrack" (o se reiniciará, en el caso de que ya estuviera iniciado), para hacer tracking de los torrents almacenados en el directorio de imágenes de ogRepository. +Se puede hacer con el script "**runTorrentTracker.py**", que hemos programado recientemente. +**NOTA**: Actualmente esto se hace automáticamente, al iniciar ogRepopository (desde el script "**/etc/init.d/opengnsys**"), pero creemos que solo debe hacerse cuando se solicite una descarga P2P. + +**URL:** `/ogrepository/v1/images/run-tracker` +**Método HTTP:** POST + +**Ejemplo de Solicitud:** + +```bash +curl -X POST -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/images/run-tracker +``` +**Respuestas:** +- **Código 500 Internal Server Error:** Ocurrió un error al iniciar el tracker. +- **Código 200 OK:** El tracker se ha iniciado exitosamente. + +--- +### Iniciar el Seeder P2P + +Se iniciará el seeder "bittornado" (o se reiniciará, en el caso de que ya estuviera iniciado), para hacer seed de los torrents almacenados en la raíz del directorio de imágenes de ogRepository (o en el subidrectorio de OU que se especifique). +Se puede hacer con el script "**runTorrentSeeder.py**", que hemos programado recientemente. +**NOTA**: Actualmente esto se hace automáticamente, al iniciar ogRepopository (desde el script "**/etc/init.d/opengnsys**"), pero creemos que solo debe hacerse cuando se solicite una descarga P2P. + +**URL:** `/ogrepository/v1/images/run-seeder` +**Método HTTP:** POST + +**Cuerpo de la Solicitud (JSON):** +- **ou_subdir**: Subdirectorio correspondiente a la OU (o "none" si no es el caso). + +**Ejemplo de Solicitud:** + +```bash +curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ou_subdir":"none"}' http://example.com/ogrepository/v1/images/run-seeder +``` +**Respuestas:** +- **Código 500 Internal Server Error:** Ocurrió un error al iniciar el seeder. +- **Código 200 OK:** El seeder se ha iniciado exitosamente. --- ### Enviar una Imagen mediante UDPcast @@ -346,29 +387,6 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d - **Código 400 Bad Request:** No se ha encontrado la imagen especificada. - **Código 200 OK:** La imagen se ha enviado exitosamente. ---- -### Enviar una Imagen mediante P2P - -Se debe hacer tracking de los torrents almacenados en ogRepository, e iniciar la transferencia de la imagen especificada (además, los clientes deben disponer del torrent asociado, y añadirlo a su cliente torrent). -No tengo claro cómo se haría con los scripts existentes (que utilizan "bttrack" y "ctorrent"), pero si usáramos "opentracker" y "transmission" (como se había propuesto), se debería crear nuevos scripts. - -**URL:** `/ogrepository/v1/images/send-p2p` -**Método HTTP:** POST - -**Cuerpo de la Solicitud (JSON):** -- **image**: Nombre de la imagen (con extensión). -- **ou_subdir**: Subdirectorio correspondiente a la OU (o "none" si no es el caso). - -**Ejemplo de Solicitud:** - -```bash -curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"image":"Windows10.img", "ou_subdir":"none"}' http://example.com/ogrepository/v1/images/send-p2p -``` -**Respuestas:** -- **Código 500 Internal Server Error:** Ocurrió un error al enviar la imagen. -- **Código 400 Bad Request:** No se ha encontrado la imagen especificada. -- **Código 200 OK:** La imagen se ha enviado exitosamente. - --- ### Chequear Integridad de Imagen diff --git a/bin/torrent-tracker b/bin/torrent-tracker index 55e3bef..36f8b19 100644 --- a/bin/torrent-tracker +++ b/bin/torrent-tracker @@ -3,18 +3,19 @@ BTTRACK=/usr/bin/bttrack.bittorrent BTSEEDER=/usr/bin/btlaunchmany.bittornado BTTRACKPORT=6969 BTTRACKDFILE=/tmp/dstate +BTTRACKLOG=/opt/opengnsys/log/bttrack.log BTINTERVAL=10 BTTORRENTSDIR=/opt/opengnsys/images # Desactivar descarga de torrents desde clientes no autorizados. BTALLOW_GET=0 # parametros basados en EAC 05-04-2009 antonio doblas viso. -BTTRACK_OPTIONS=" --save_dfile_interval $BTINTERVAL --timeout_downloaders_interval $BTINTERVAL --port $BTTRACKPORT --dfile $BTTRACKDFILE --reannounce_interval $BTINTERVAL --allowed_dir $BTTORRENTSDIR --allow_get $BTALLOW_GET " +BTTRACK_OPTIONS=" --save_dfile_interval $BTINTERVAL --timeout_downloaders_interval $BTINTERVAL --port $BTTRACKPORT --dfile $BTTRACKDFILE --reannounce_interval $BTINTERVAL --logfile $BTTRACKLOG --allowed_dir $BTTORRENTSDIR --allow_get $BTALLOW_GET " BTTRACKPID="/var/run/bttrack.pid" BTSEEDERPID="/var/run/btseeder.pid" ################### ####################################### -systemctl --user stop bttrack.service +pkill bttrack rm -f $BTTRACKDFILE sleep 2 -systemd-run --user --unit bttrack.service --wait bttrack $BTTRACK_OPTIONS +bttrack $BTTRACK_OPTIONS &>> $BTTRACKLOG & diff --git a/bin/torrent-tracker_OLD b/bin/torrent-tracker_OLD new file mode 100644 index 0000000..55e3bef --- /dev/null +++ b/bin/torrent-tracker_OLD @@ -0,0 +1,20 @@ +#!/bin/bash +BTTRACK=/usr/bin/bttrack.bittorrent +BTSEEDER=/usr/bin/btlaunchmany.bittornado +BTTRACKPORT=6969 +BTTRACKDFILE=/tmp/dstate +BTINTERVAL=10 +BTTORRENTSDIR=/opt/opengnsys/images +# Desactivar descarga de torrents desde clientes no autorizados. +BTALLOW_GET=0 +# parametros basados en EAC 05-04-2009 antonio doblas viso. +BTTRACK_OPTIONS=" --save_dfile_interval $BTINTERVAL --timeout_downloaders_interval $BTINTERVAL --port $BTTRACKPORT --dfile $BTTRACKDFILE --reannounce_interval $BTINTERVAL --allowed_dir $BTTORRENTSDIR --allow_get $BTALLOW_GET " +BTTRACKPID="/var/run/bttrack.pid" +BTSEEDERPID="/var/run/btseeder.pid" + +################### ####################################### + +systemctl --user stop bttrack.service +rm -f $BTTRACKDFILE +sleep 2 +systemd-run --user --unit bttrack.service --wait bttrack $BTTRACK_OPTIONS diff --git a/py_scripts/runTorrentSeeder.py b/py_scripts/runTorrentSeeder.py new file mode 100644 index 0000000..ad9b18c --- /dev/null +++ b/py_scripts/runTorrentSeeder.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Este script inicia el seeder "bittornado" (o lo reinicia, si ya estuviera iniciado), finalizando previamente cualquier proceso activo. +En principio, debería hacer lo mismo que la sección correspondiente del script "/etc/init.d/opengnsys", que se ejecuta al inicio (pero que debería dejar de hacerlo). +Creemos que debe ser llamado únicamente cuando se quiera hacer una descarga mediante P2P (junto al script "runTorrentTracker.py"). +NOTA: El paquete no hace una búsqueda recursiva, por lo que se debe especificar el subdirectorio correspondiente a la OU, si es el caso. + + Parámetros +------------ +sys.argv[1] - Subdirectorio correspondiente a la OU (o "none" si no es el caso). + - Ejemplo1: none + - Ejemplo2: ou_subdir + + Sintaxis +---------- +./runTorrentSeeder.py none|ou_subdir + + Ejemplos + --------- +./runTorrentSeeder.py none +./runTorrentSeeder.py ou_subdir +""" + +# -------------------------------------------------------------------------------------------- +# IMPORTS +# -------------------------------------------------------------------------------------------- + +import os +import sys +import subprocess + + +# -------------------------------------------------------------------------------------------- +# VARIABLES +# -------------------------------------------------------------------------------------------- + +script_name = os.path.basename(__file__) +repo_path = '/opt/opengnsys/images' + + +# -------------------------------------------------------------------------------------------- +# FUNCTIONS +# -------------------------------------------------------------------------------------------- + + +def show_help(): + """ Imprime la ayuda, cuando se ejecuta el script con el parámetro "help". + """ + help_text = f""" + Sintaxis: {script_name} none|ou_subdir + Ejemplo1: {script_name} none + Ejemplo2: {script_name} ou_subdir + """ + print(help_text) + + + +def check_params(): + """ Comprueba que se haya enviado la cantidad correcta de parámetros, y en el formato correcto. + Si no es así, muestra un mensaje de error, y sale del script. + LLama a la función "show_help" cuando se ejecuta el script con el parámetro "help". + """ + # Si se ejecuta el script con el parámetro "help", se muestra la ayuda, y se sale del script: + if len(sys.argv) == 2 and sys.argv[1] == "help": + show_help() + sys.exit(0) + # Si se ejecuta el script con más o menos de 1 parámetro, se muestra un error y la ayuda, y se sale del script: + elif len(sys.argv) != 2: + print(f"{script_name} Error: Formato incorrecto: Se debe especificar 1 parámetro") + show_help() + sys.exit(1) + + + +def run_bittornado(torrent_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 {torrent_path}".split() + print(f"Sending command: {' '.join(splitted_cmd)}") + + # 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) + print(f"Bittornado ReturnCode: {result.returncode}") + except subprocess.CalledProcessError as error: + print(f"Bittornado ReturnCode: {error.returncode}") + print(f"Bittornado Error Output: {error.stderr.decode()}") + except Exception as error: + print(f"Unexpected bittornado error: {error}") + + + +# -------------------------------------------------------------------------------------------- +# MAIN +# -------------------------------------------------------------------------------------------- + + +def main(): + """ + """ + # Evaluamos si se ha enviado la cantidad correcta de parámetros, y en el formato correcto: + check_params() + + # Finalizamos el proceso "btlaunchmany.bittornado" (en caso de que estuviera corriendo): + try: + subprocess.run(f"pkill btlaunchmany.bittornado".split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except Exception as error_description: + print(f"No bittornado process running? Returned error: {error_description}") + + # Construimos la ruta en la que buscar los torrents, en base al parámetro especificado: + if sys.argv[1] == 'none': + torrent_path = repo_path + else: + torrent_path = f"{repo_path}/{sys.argv[1]}" + + # Ejecutamos el comando "btlaunchmany.bittornado" (para hacer seed de los torrents): + run_bittornado(torrent_path) + + + +# -------------------------------------------------------------------------------------------- + +if __name__ == "__main__": + main() + +# -------------------------------------------------------------------------------------------- diff --git a/py_scripts/runTorrentTracker.py b/py_scripts/runTorrentTracker.py new file mode 100644 index 0000000..4e9cd38 --- /dev/null +++ b/py_scripts/runTorrentTracker.py @@ -0,0 +1,89 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Este script inicia el tracker "bttrack" (o lo reinicia, si ya estuviera iniciado), finalizando previamente cualquier proceso activo, y borrando el archivo "/tmp/dstate". +En principio, debería hacer lo mismo que el script bash original (cuyo nombre es "torrent-tracker"). + +No recibe ningún parámetro, y creemos que debe ser llamado únicamente cuando se quiera hacer una descarga mediante P2P (junto al script "runTorrentSeeder.py"). +""" + +# -------------------------------------------------------------------------------------------- +# IMPORTS +# -------------------------------------------------------------------------------------------- + +import os +import subprocess +import time + + +# -------------------------------------------------------------------------------------------- +# VARIABLES +# -------------------------------------------------------------------------------------------- + +repo_path = '/opt/opengnsys/images' + +bttrack_port = 6969 +bttrack_dfile = '/tmp/dstate' +bttrack_log = '/opt/opengnsys/log/bttrack.log' +bttrack_interval = 10 +bttrack_allow_get = 1 # Este es el valor que estaba en "etc/init.d/opengnsys" (en "torrent-tracker", que no se ejecutaba, el valor era "0") + + +# -------------------------------------------------------------------------------------------- +# FUNCTIONS +# -------------------------------------------------------------------------------------------- + + +def run_bttrack(): + """ Ejecuta el comando "bttrack", con sus parámetros correspondientes. + Además, captura el resultado y los posibles errores, y los imprime. + """ + # Creamos una lista con el comando "bttrack" y sus parámetros, y lo imprimimos con espacios: + splitted_cmd = f"bttrack --port {bttrack_port} --dfile {bttrack_dfile} --save_dfile_interval {bttrack_interval} --reannounce_interval {bttrack_interval} --logfile {bttrack_log} --allowed_dir {repo_path} --allow_get {bttrack_allow_get}".split() + print(f"Sending command: {' '.join(splitted_cmd)}") + + # Ejecutamos el comando "bttrack" en el sistema, e imprimimos el resultado: + try: + result = subprocess.run(splitted_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + print(f"Bttrack ReturnCode: {result.returncode}") + except subprocess.CalledProcessError as error: + print(f"Bttrack ReturnCode: {error.returncode}") + print(f"Bttrack Error Output: {error.stderr.decode()}") + except Exception as error: + print(f"Unexpected bttrack error: {error}") + + + +# -------------------------------------------------------------------------------------------- +# MAIN +# -------------------------------------------------------------------------------------------- + + +def main(): + """ + """ + # Finalizamos el proceso "bttrack" (en caso de que estuviera corriendo): + try: + subprocess.run(f"pkill bttrack".split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + except Exception as error_description: + print(f"No bttrack process running? Returned error: {error_description}") + + # Si existe el archivo "/tmp/dstate", lo eliminamos: + if os.path.exists(bttrack_dfile): + os.remove(bttrack_dfile) + + # Esperamos 2 segundos: + time.sleep(2) + + # Ejecutamos el comando "bttrack" (para hacer tracking de los torrents): + run_bttrack() + + + +# -------------------------------------------------------------------------------------------- + +if __name__ == "__main__": + main() + +# --------------------------------------------------------------------------------------------