From 5bab3357331d4c604624c4e3c04390d54800f04c Mon Sep 17 00:00:00 2001 From: ggil Date: Fri, 4 Oct 2024 14:03:57 +0200 Subject: [PATCH] refs #631 - Add 'getUDPcastInfo.py' and modify API proposal --- README.md | 67 ++++++++++++++++++++----------- bin/getUDPcastInfo.py | 91 +++++++++++++++++++++++++++++++++++++++++++ bin/sendFileMcast.py | 4 +- 3 files changed, 138 insertions(+), 24 deletions(-) create mode 100644 bin/getUDPcastInfo.py diff --git a/README.md b/README.md index 9355cfa..398525a 100644 --- a/README.md +++ b/README.md @@ -34,16 +34,16 @@ El presente documento detalla los endpoints de la API, con sus respectivos pará 12. [Enviar una Imagen mediante UDPcast](#enviar-una-imagen-mediante-udpcast) - `POST /ogrepository/v1/udpcast/images/{ID_img}` 13. [Enviar una Imagen mediante UFTP](#enviar-una-imagen-mediante-uftp) - `POST /ogrepository/v1/uftp/images/{ID_img}` 14. [Enviar una Imagen mediante P2P](#enviar-una-imagen-mediante-p2p) - `POST /ogrepository/v1/p2p/images/{ID_img}` -15. [Cancelar Transmisión UDPcast](#cancelar-transmisión-udpcast) - `DELETE /ogrepository/v1/udpcast/images/{ID_img}` -16. [Cancelar Transmisiones P2P](#cancelar-transmisiones-p2p) - `DELETE /ogrepository/v1/p2p` -17. [Ver Estado de Transmisiones Multicast-P2P](#ver-estado-de-transmisiones-multicast-p2p) - +15. [Ver Estado de Transmisiones UDPcast](#ver-estado-de-transmisiones-udpcast) - `GET /ogrepository/v1/udpcast` +16. [Cancelar Transmisión UDPcast](#cancelar-transmisión-udpcast) - `DELETE /ogrepository/v1/udpcast/images/{ID_img}` +17. [Cancelar Transmisiones P2P](#cancelar-transmisiones-p2p) - `DELETE /ogrepository/v1/p2p` --- ### Obtener Información de Estado de ogRepository Se devolverá informacion de CPU, memoria RAM, disco duro y el estado de ciertos servicios y procesos de ogRepository, en formato JSON. -Se puede utilizar el script "**getRepoStatus.py**, que hemos programado recientemente. -**NOTA**: En los apartados "services" y "processes" he especificado los servicios y procesos que me han parecido interesantes, pero se puede añadir o eliminar los que se desee. +Se puede utilizar el script "**getRepoStatus.py**, que debe ser llamado por el endpoint. +**NOTA**: En los apartados "services" y "processes" he especificado los servicios y procesos que me han parecido interesantes, pero se puede añadir o eliminar los que se desee. **URL:** `/ogrepository/v1/status` **Método HTTP:** GET @@ -92,7 +92,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/stat ### 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. +Se puede utilizar el script "**getRepoInfo.py**, que debe ser llamado por el endpoint. **NOTA**: La versión actual de este script requiere que se le pase "all" como primer parámetro (que correspondería al nombre de la imagen) y "none" como segundo parámetro (que corresponderia al nombre del subdirectorio correspondiente a la OU). Esta transformación de parámetros se puede realizar en el controlador PHP. **URL:** `/ogrepository/v1/images` @@ -198,7 +198,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag ### Obtener Información de una Imagen concreta Se devolverá la informacion de la imagen especificada, que puede estar en el archivo "**/opt/opengnsys/etc/repoinfo.json**" o en el archivo "**/opt/opengnsys/etc/trashinfo.json**" (en este último caso, si la imagen está en la papelera). -Se puede utilizar el script "**getRepoInfo.py**, que hemos programado recientemente. +Se puede utilizar el script "**getRepoInfo.py**, que debe ser llamado por el endpoint. **NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, y el subdirectorio correspondiente a la OU (o "none" si no es el caso) como segundo parámetro. En principio, ogCore puede acceder a estos datos a partir del ID de la imagen (que hemos quedado que será el contenido del archivo "full.sum"), y la transformación de parámetros puede realizarse en el controlador PHP. **URL:** `/ogrepository/v1/images/{ID_img}` @@ -249,7 +249,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag ### Actualizar Información del Repositorio Se actualizará la información de las imágenes almacenadas en el repositorio, reflejándola en el archivo "**/opt/opengnsys/etc/repoinfo.json**". -Se puede hacer con el script "**updateRepoInfo.py**", que hemos programado recientemente (y que es similar al script bash original "**checkrepo**"). +Se puede hacer con el script "**updateRepoInfo.py**", que debe ser llamado por el endpoint (y que es similar al script bash original "**checkrepo**"). Este endpoint es llamado por el script "**deleteImage.py**" (para actualizar la información cada vez que se elimine una imagen), y creemos que también debe ser llamado por ogCore u ogLive cada vez que se haya creado una imagen. **URL:** `/ogrepository/v1/images` @@ -289,7 +289,7 @@ curl -X POST -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/sta ### Eliminar una Imagen Se eliminará la imagen especificada como parámetro, pudiendo eliminarla permanentemente o enviarla a la papelera. -Se puede hacer con el script "**deleteimage.py**", que hemos programado recientemente (y que incluye la funcionalidad "papelera"), y que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio. +Se puede hacer con el script "**deleteimage.py**", que debe ser llamado por el endpoint (y que incluye la funcionalidad "papelera"), y que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio. **NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión, e incluyendo el nombre del directorio correspondiente a la OU, si fuera el caso) como primer parámetro, y el parámetro opcional "-p" (para que la eliminación sea permanente). En principio, ogCore puede acceder a estos datos a partir del ID de la imagen (que hemos quedado que será el contenido del archivo "full.sum"), y la transformación de parámetros puede realizarse en el controlador PHP, pero en principio habrá que especificar el método de eliminación en un json (en la URL). **URL:** `/ogrepository/v1/images/{ID_img}` @@ -312,7 +312,7 @@ curl -X DELETE -H "Authorization: $API_KEY" -H "Content-Type: application/json" ### Recuperar una Imagen Se recuperará la imagen especificada como parámetro, desde la papelera. -Se puede hacer con el script "**recoverImage.py**", que hemos programado recientemente, y que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio. +Se puede hacer con el script "**recoverImage.py**", que debe ser llamado por el endpoint, y que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio. **NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión, e incluyendo el nombre del directorio correspondiente a la OU, si fuera el caso) como único parámetro. En principio, ogCore puede acceder a estos datos a partir del ID de la imagen (que hemos quedado que será el contenido del archivo "full.sum"), y la transformación de parámetros puede realizarse en el controlador PHP. **URL:** `/ogrepository/v1/trash/images/{ID_img}` @@ -332,7 +332,7 @@ curl -X POST -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/tra ### Eliminar una Imagen de la Papelera Se eliminará permanentemente la imagen especificada como parámetro, desde la papelera. -Se puede hacer con el script "**deleteTrashImage.py**", que hemos programado recientemente, y que a su vez llama al script "**updateTrashInfo.py**", para actualizar la información de la papelera. +Se puede hacer con el script "**deleteTrashImage.py**", que debe ser llamado por el endpoint, y que a su vez llama al script "**updateTrashInfo.py**", para actualizar la información de la papelera. **NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión, e incluyendo el nombre del directorio correspondiente a la OU, si fuera el caso) como único parámetro. En principio, ogCore puede acceder a estos datos a partir del ID de la imagen (que hemos quedado que será el contenido del archivo "full.sum"), y la transformación de parámetros puede realizarse en el controlador PHP. **URL:** `/ogrepository/v1/trash/images/{ID_img}` @@ -352,7 +352,7 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/t ### Importar una Imagen Se importará una imagen de un repositorio remoto al repositorio local. -Se puede hacer con el script "**importImage.py**", que hemos programado recientemente. +Se puede hacer con el script "**importImage.py**", que debe ser llamado por el endpoint. **NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión, e incluyendo el nombre del directorio correspondiente a la OU, si fuera el caso) como primer parámetro, la IP o hostname del repositorio remoto como segundo parámetro, y el usuario remoto como tercer parámetro. En principio, ogCore puede acceder a estos datos a partir del ID del repositorio y del ID de la imagen (que hemos quedado que será el contenido del archivo "full.sum"), y la transformación de parámetros puede realizarse en el controlador PHP, pero en principio habrá que especificar el usuario remoto en un json (en la URL). **URL:** `/ogrepository/v1/repo/{ID_repo}/images/{ID_img}` @@ -375,7 +375,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d ### Crear archivos auxiliares Se crearán los archivos ".sum", ".full.sum", ".size" y ".torrent", para la imagen especificada como parámetro. -Se puede hacer con el script "**createTorrentSum.py**", que hemos programado recientemente. +Se puede hacer con el script "**createTorrentSum.py**", que debe ser llamado por el endpoint. **URL:** `/ogrepository/v1/images/torrentsum` **Método HTTP:** POST @@ -398,7 +398,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d ### Enviar paquete Wake On Lan Se enviará un paquete Wake On Lan a la dirección MAC especificada, a través de la IP de broadcast especificada. -Se puede hacer con el script "**sendWakeOnLan.py**", que hemos programado recientemente. +Se puede hacer con el script "**sendWakeOnLan.py**", que debe ser llamado por el endpoint. **URL:** `/ogrepository/v1/wol` **Método HTTP:** POST @@ -494,11 +494,40 @@ curl -X POST -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/p2p - **Código 400 Bad Request:** No se ha encontrado la imagen especificada. - **Código 200 OK:** La imagen se ha enviado exitosamente. +--- +### Ver Estado de Transmisiones UDPcast + +Se devolverá el pid de los procesos de transferencias UDPcast activas, y sus imágenes asociadas, en formato JSON, o un mensaje informativo si no hay procesos activos, o si se produce un error. +Se puede hacer con el script "**getUDPcastInfo.py**", que debe ser llamado por el endpoint. + +**URL:** `/ogrepository/v1/udpcast` +**Método HTTP:** GET + +**Ejemplo de Solicitud:** + +```bash +curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/udpcast +``` +**Respuestas:** +- **Código 500 Internal Server Error:** Ocurrió un error al comprobar las transmisiones UDPcast. +- **Código 400 Bad Request:** No se han encontrado transmisiones UDPcast activas. +- **Código 200 OK:** La información de las transmisiones UDPcast activas se obtuvo exitosamente. + - **Contenido:** Información de las transmisiones UDPcast activas en formato JSON. + ```json + { + "6720": { + "image": "Ubuntu20.img" + }, + "6721": { + "image": "Windows10.img" + } + } + ``` --- ### Cancelar Transmisión UDPcast Se cancelará la transmisión por UDPcast activa de la imagen especificada como parámetro, deteniendo el proceso "udp-sender" asociado a dicha imagen. -Se puede hacer con el script "**stopUDPcast.py**", que hemos programado recientemente. +Se puede hacer con el script "**stopUDPcast.py**", que debe ser llamado por el endpoint. **NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión, e incluyendo el nombre del directorio correspondiente a la OU, si fuera el caso) como único parámetro. En principio, ogCore puede acceder a estos datos a partir del ID de la imagen (que hemos quedado que será el contenido del archivo "full.sum"), y la transformación de parámetros puede realizarse en el controlador PHP. **URL:** `/ogrepository/v1/udpcast/images/{ID_img}` @@ -518,7 +547,7 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/u ### Cancelar Transmisiones P2P Se cancelarán las transmisiones P2P activas en el ogRepository al que se envíe la orden, deteniendo los procesos "bttrack" y "btlaunchmany.bittornado". -Se puede hacer con el script "**stopP2P.py**", que hemos programado recientemente. +Se puede hacer con el script "**stopP2P.py**", que debe ser llamado por el endpoint. **NOTA**: No he encontrado la forma de detener la transmisión de una imagen concreta, ya que "bttrack" y "btlaunchmany.bittornado" hacen tracking y seed (respectivamente) de todos los torrents existentes en la raíz del directorio especificado. **URL:** `/ogrepository/v1/p2p` @@ -533,10 +562,4 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/p - **Código 500 Internal Server Error:** Ocurrió un error al cancelar las transmisiones. - **Código 200 OK:** Las transmisiones se han cancelado exitosamente. ---- -### Ver Estado de Transmisiones Multicast-P2P - -Se debe estudiar como realizar esta tarea para cada uno de los protocolos de transmisión, ya que cada uno tiene sus particularidades, y habitualmente no tienen comandos asociados para comprobar el estado de las transmisiones. Es posible que sea neceario parsear los logs de ogRepo y/o de los clientes. -**NOTA**: Seguramente deba crearse un endpoint específico para cada uno de los protocolos que se utilicen. - --- \ No newline at end of file diff --git a/bin/getUDPcastInfo.py b/bin/getUDPcastInfo.py new file mode 100644 index 0000000..72dc4a9 --- /dev/null +++ b/bin/getUDPcastInfo.py @@ -0,0 +1,91 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + + +""" +Este script busca procesos activos de "udp-sender", y si encuentra alguno devuelve el pid y la imagen asociada de cada uno de ellos, en una estructura JSON. +Si no encuentra ninguno, o si se produce un error, imprime un mensaje informativo. +No recibe ningún parámetro. + +En la práctica, permite comprobar las transminisones UDPcast activas, porque cuando finalizan también finaliza el proceso asociado. +""" + +# -------------------------------------------------------------------------------------------- +# IMPORTS +# -------------------------------------------------------------------------------------------- + +import subprocess +import json + + +# -------------------------------------------------------------------------------------------- +# VARIABLES +# -------------------------------------------------------------------------------------------- + +repo_path = '/opt/opengnsys/images/' + + +# -------------------------------------------------------------------------------------------- +# FUNCTIONS +# -------------------------------------------------------------------------------------------- + + +def get_udpsender_processes(): + """ Busca procesos de "udp-sender", y si los encuentra retorna el pid y la imagen asociada de cada uno de ellos, en un diccionario. + Si no encuentra ningun proceso, o si se produce un error, retorna un mensaje. + """ + try: + # Obtenemos todos los procesos, y almacenamos la salida y los errores: + result = subprocess.Popen(['ps', '-aux'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='UTF8') + out, error = result.communicate() + + # Almacenamos en una lista los procesos que contengan "udp-sender": + process_list = [line for line in out.split('\n') if 'udp-sender' in line] + # Si hemos encontrado procesos de udp-sender creamos un diccionario para almacenarlos: + if process_list != []: + result_dict = {} + # Iteramos los procesos y extraemos el pid y el nombre de la imagen de cada uno, + # los almacenamos en el diccionario, y retornamos este: + for process in process_list: + pid = process.split()[1] + image = process.split(repo_path)[1] + result_dict[pid] = {'image':image} + return result_dict + # Si no hemos encontrado procesos de udp-sender retrornamos un mensaje: + else: + return "udp-sender process not found" + # Si se ha producido una excepción, retornamos un mensaje: + except Exception: + return "Unexpected error" + + + +# -------------------------------------------------------------------------------------------- +# MAIN +# -------------------------------------------------------------------------------------------- + + +def main(): + """ + """ + # Obtenemos información sobre los procesos de udp-sender: + results = get_udpsender_processes() + + # Si no hay procesos activos, o si se ha producido un error, imprimimos un mensaje explicativo: + if results == "udp-sender process not found": + print("No UDPcast active transmissions") + elif results == "Unexpected error": + print("Unexpected error checking UDPcast transmissions") + # Si hay procesos activos, convertimos el diccionario de resultados a JSON, e imprimimos este: + else: + json_data = json.dumps(results, indent=4) + print(json_data) + + + +# -------------------------------------------------------------------------------------------- + +if __name__ == "__main__": + main() + +# -------------------------------------------------------------------------------------------- diff --git a/bin/sendFileMcast.py b/bin/sendFileMcast.py index ae7d1eb..81fa35b 100644 --- a/bin/sendFileMcast.py +++ b/bin/sendFileMcast.py @@ -171,8 +171,8 @@ def main(): '--min-clients', nclients, '--max-wait', maxtime, # Esto hace que espere 120 segundos desde la conexión del primer cliente para empezar la transmisión. #'--autostart', '20', # Esto hace que empiece la transmisión automáticamente después de enviar 20 paquetes "hello". - '--file', file_path, - '--log', log_file + '--log', log_file, + '--file', file_path ] # Imprimimos el comando con espacios (como realmente se enviará):