refs #631 - Add 'getUFTPInfo.py', 'stopUFTP.py' and associated endpoints
parent
93a1b6c937
commit
126aa3cf8f
60
README.md
60
README.md
|
@ -37,8 +37,10 @@ El presente documento detalla los endpoints de la API, con sus respectivos pará
|
|||
14. [Enviar una Imagen mediante UFTP](#enviar-una-imagen-mediante-uftp) - `POST /ogrepository/v1/uftp`
|
||||
15. [Enviar una Imagen mediante P2P](#enviar-una-imagen-mediante-p2p) - `POST /ogrepository/v1/p2p`
|
||||
16. [Ver Estado de Transmisiones UDPcast](#ver-estado-de-transmisiones-udpcast) - `GET /ogrepository/v1/udpcast`
|
||||
17. [Cancelar Transmisión UDPcast](#cancelar-transmisión-udpcast) - `DELETE /ogrepository/v1/udpcast/images/{ID_img}`
|
||||
18. [Cancelar Transmisiones P2P](#cancelar-transmisiones-p2p) - `DELETE /ogrepository/v1/p2p`
|
||||
17. [Ver Estado de Transmisiones UFTP](#ver-estado-de-transmisiones-uftp) - `GET /ogrepository/v1/uftp`
|
||||
18. [Cancelar Transmisión UDPcast](#cancelar-transmisión-udpcast) - `DELETE /ogrepository/v1/udpcast/images/{ID_img}`
|
||||
19. [Cancelar Transmisión UFTP](#cancelar-transmisión-uftp) - `DELETE /ogrepository/v1/uftp/images/{ID_img}`
|
||||
20. [Cancelar Transmisiones P2P](#cancelar-transmisiones-p2p) - `DELETE /ogrepository/v1/p2p`
|
||||
|
||||
---
|
||||
### Obtener Información de Estado de ogRepository
|
||||
|
@ -562,6 +564,37 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/udpc
|
|||
}
|
||||
```
|
||||
---
|
||||
### Ver Estado de Transmisiones UFTP
|
||||
|
||||
Se devolverá el pid de los procesos de transferencias UFTP activas, y sus imágenes asociadas (con nombre e ID), en formato JSON, o un mensaje informativo si no hay procesos activos, o si se produce un error.
|
||||
Se puede hacer con el script "**getUFTPInfo.py**", que debe ser llamado por el endpoint.
|
||||
|
||||
**URL:** `/ogrepository/v1/uftp`
|
||||
**Método HTTP:** GET
|
||||
|
||||
**Ejemplo de Solicitud:**
|
||||
|
||||
```bash
|
||||
curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp
|
||||
```
|
||||
**Respuestas:**
|
||||
- **Código 500 Internal Server Error:** Ocurrió un error al comprobar las transmisiones UFTP.
|
||||
- **Código 400 Bad Request:** No se han encontrado transmisiones UFTP activas.
|
||||
- **Código 200 OK:** La información de las transmisiones UFTP activas se obtuvo exitosamente.
|
||||
- **Contenido:** Información de las transmisiones UFTP activas en formato JSON.
|
||||
```json
|
||||
{
|
||||
"3427": {
|
||||
"image_id": "22735b9070e4a8043371b8c6ae52b90d",
|
||||
"image_name": "Ubuntu20.img"
|
||||
},
|
||||
"4966": {
|
||||
"image_id": "9e7cd32c606ebe5bd39ba212ce7aeb02",
|
||||
"image_name": "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.
|
||||
|
@ -579,9 +612,30 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/u
|
|||
**Respuestas:**
|
||||
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UDPcast.
|
||||
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
|
||||
- **Código 400 Bad Request:** No hay transmisiones UCPcast activas para la imagen especificada.
|
||||
- **Código 400 Bad Request:** No hay transmisiones UDPcast activas para la imagen especificada.
|
||||
- **Código 200 OK:** La transmisión UDPcast se ha cancelado exitosamente.
|
||||
|
||||
---
|
||||
### Cancelar Transmisión UFTP
|
||||
|
||||
Se cancelará la transmisión por UFTP activa de la imagen especificada como parámetro, deteniendo el proceso "uftp" asociado a dicha imagen.
|
||||
Se puede hacer con el script "**stopUFTP.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. Este dato se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum").
|
||||
|
||||
**URL:** `/ogrepository/v1/uftp/images/{ID_img}`
|
||||
**Método HTTP:** DELETE
|
||||
|
||||
**Ejemplo de Solicitud:**
|
||||
|
||||
```bash
|
||||
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp/images/{ID_img}
|
||||
```
|
||||
**Respuestas:**
|
||||
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UFTP.
|
||||
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
|
||||
- **Código 400 Bad Request:** No hay transmisiones UFTP activas para la imagen especificada.
|
||||
- **Código 200 OK:** La transmisión UFTP se ha cancelado exitosamente.
|
||||
|
||||
---
|
||||
### Cancelar Transmisiones P2P
|
||||
|
||||
|
|
|
@ -24,8 +24,10 @@ El presente documento detalla los endpoints de la API, con sus respectivos pará
|
|||
14. [Enviar una Imagen mediante UFTP](#enviar-una-imagen-mediante-uftp) - `POST /ogrepository/v1/uftp`
|
||||
15. [Enviar una Imagen mediante P2P](#enviar-una-imagen-mediante-p2p) - `POST /ogrepository/v1/p2p`
|
||||
16. [Ver Estado de Transmisiones UDPcast](#ver-estado-de-transmisiones-udpcast) - `GET /ogrepository/v1/udpcast`
|
||||
17. [Cancelar Transmisión UDPcast](#cancelar-transmisión-udpcast) - `DELETE /ogrepository/v1/udpcast/images/{ID_img}`
|
||||
18. [Cancelar Transmisiones P2P](#cancelar-transmisiones-p2p) - `DELETE /ogrepository/v1/p2p`
|
||||
17. [Ver Estado de Transmisiones UFTP](#ver-estado-de-transmisiones-uftp) - `GET /ogrepository/v1/uftp`
|
||||
18. [Cancelar Transmisión UDPcast](#cancelar-transmisión-udpcast) - `DELETE /ogrepository/v1/udpcast/images/{ID_img}`
|
||||
19. [Cancelar Transmisión UFTP](#cancelar-transmisión-uftp) - `DELETE /ogrepository/v1/uftp/images/{ID_img}`
|
||||
20. [Cancelar Transmisiones P2P](#cancelar-transmisiones-p2p) - `DELETE /ogrepository/v1/p2p`
|
||||
|
||||
---
|
||||
### Obtener Información de Estado de ogRepository
|
||||
|
@ -549,6 +551,37 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/udpc
|
|||
}
|
||||
```
|
||||
---
|
||||
### Ver Estado de Transmisiones UFTP
|
||||
|
||||
Se devolverá el pid de los procesos de transferencias UFTP activas, y sus imágenes asociadas (con nombre e ID), en formato JSON, o un mensaje informativo si no hay procesos activos, o si se produce un error.
|
||||
Se puede hacer con el script "**getUFTPInfo.py**", que debe ser llamado por el endpoint.
|
||||
|
||||
**URL:** `/ogrepository/v1/uftp`
|
||||
**Método HTTP:** GET
|
||||
|
||||
**Ejemplo de Solicitud:**
|
||||
|
||||
```bash
|
||||
curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp
|
||||
```
|
||||
**Respuestas:**
|
||||
- **Código 500 Internal Server Error:** Ocurrió un error al comprobar las transmisiones UFTP.
|
||||
- **Código 400 Bad Request:** No se han encontrado transmisiones UFTP activas.
|
||||
- **Código 200 OK:** La información de las transmisiones UFTP activas se obtuvo exitosamente.
|
||||
- **Contenido:** Información de las transmisiones UFTP activas en formato JSON.
|
||||
```json
|
||||
{
|
||||
"3427": {
|
||||
"image_id": "22735b9070e4a8043371b8c6ae52b90d",
|
||||
"image_name": "Ubuntu20.img"
|
||||
},
|
||||
"4966": {
|
||||
"image_id": "9e7cd32c606ebe5bd39ba212ce7aeb02",
|
||||
"image_name": "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.
|
||||
|
@ -566,9 +599,30 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/u
|
|||
**Respuestas:**
|
||||
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UDPcast.
|
||||
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
|
||||
- **Código 400 Bad Request:** No hay transmisiones UCPcast activas para la imagen especificada.
|
||||
- **Código 400 Bad Request:** No hay transmisiones UDPcast activas para la imagen especificada.
|
||||
- **Código 200 OK:** La transmisión UDPcast se ha cancelado exitosamente.
|
||||
|
||||
---
|
||||
### Cancelar Transmisión UFTP
|
||||
|
||||
Se cancelará la transmisión por UFTP activa de la imagen especificada como parámetro, deteniendo el proceso "uftp" asociado a dicha imagen.
|
||||
Se puede hacer con el script "**stopUFTP.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. Este dato se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum").
|
||||
|
||||
**URL:** `/ogrepository/v1/uftp/images/{ID_img}`
|
||||
**Método HTTP:** DELETE
|
||||
|
||||
**Ejemplo de Solicitud:**
|
||||
|
||||
```bash
|
||||
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp/images/{ID_img}
|
||||
```
|
||||
**Respuestas:**
|
||||
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UFTP.
|
||||
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
|
||||
- **Código 400 Bad Request:** No hay transmisiones UFTP activas para la imagen especificada.
|
||||
- **Código 200 OK:** La transmisión UFTP se ha cancelado exitosamente.
|
||||
|
||||
---
|
||||
### Cancelar Transmisiones P2P
|
||||
|
||||
|
|
110
api/repo_api.py
110
api/repo_api.py
|
@ -31,6 +31,7 @@ repo_file = '/opt/opengnsys/etc/repoinfo.json'
|
|||
trash_file = '/opt/opengnsys/etc/trashinfo.json'
|
||||
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# FUNCTIONS
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
@ -906,7 +907,50 @@ def get_udpcast_info():
|
|||
# ---------------------------------------------------------
|
||||
|
||||
|
||||
# 17 - Endpoint "Cancelar Transmisión UDPcast":
|
||||
# 17 - Endpoint "Ver Estado de Transmisiones UFTP":
|
||||
@app.route("/ogrepository/v1/uftp", methods=['GET'])
|
||||
def get_uftp_info():
|
||||
""" Este endpoint devuelve información sobre los procesos de "uftp" activos, en formato json,
|
||||
lo que en la práctica permite comprobar las transferencias UFTP activas.
|
||||
Para ello, ejecuta el script "getUFTPInfo.py", que no recibe parámetros.
|
||||
"""
|
||||
try:
|
||||
# Ejecutamos el script "getUFTPInfo.py", y almacenamos el resultado:
|
||||
result = subprocess.run(['sudo', 'python3', f"{script_path}/getUFTPInfo.py"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='UTF8')
|
||||
|
||||
# Evaluamos el resultado de la ejecución, y devolvemos la respuesta:
|
||||
if result.returncode == 0:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"output": json.loads(result.stdout)
|
||||
}), 200
|
||||
else:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": result.stderr
|
||||
}), 500
|
||||
except Exception as error_description:
|
||||
if "exit status 1" in str(error_description):
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"exception": "No UFTP active transmissions"
|
||||
}), 400
|
||||
elif "exit status 2" in str(error_description):
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"exception": "Unexpected error checking UFTP transmissions"
|
||||
}), 500
|
||||
else:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"exception": str(error_description)
|
||||
}), 500
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
|
||||
# 18 - Endpoint "Cancelar Transmisión UDPcast":
|
||||
@app.route("/ogrepository/v1/udpcast/images/<string:imageId>", methods=['DELETE'])
|
||||
def stop_udpcast(imageId):
|
||||
""" Este endpoint cancela la transmisión UDPcast de la imagen que recibe como parámetro, finalizando el proceso "udp-sender" asociado.
|
||||
|
@ -968,7 +1012,69 @@ def stop_udpcast(imageId):
|
|||
# ---------------------------------------------------------
|
||||
|
||||
|
||||
# 18 - Endpoint "Cancelar Transmisiones P2P":
|
||||
# 19 - Endpoint "Cancelar Transmisión UFTP":
|
||||
@app.route("/ogrepository/v1/uftp/images/<string:imageId>", methods=['DELETE'])
|
||||
def stop_uftp(imageId):
|
||||
""" Este endpoint cancela la transmisión UFTP de la imagen que recibe como parámetro, finalizando el proceso "uftp" asociado.
|
||||
Para ello, ejecuta el script "stopUFTP.py", pasándole el nombre de la imagen (con subdirectorio de OU, si procede).
|
||||
"""
|
||||
# Obtenemos el nombre y la extensión de la imagen (y el subdirectorio de OU, si fuera el caso):
|
||||
param_dict = get_image_params(imageId, "repo")
|
||||
|
||||
# Evaluamos los parámetros obtenidos, para construir la llamada al script, o para devover un error si no se ha encontrado la imagen:
|
||||
if param_dict:
|
||||
if 'subdir' in param_dict:
|
||||
cmd = ['sudo', 'python3', f"{script_path}/stopUFTP.py", f"{param_dict['subdir']}/{param_dict['name']}.{param_dict['extension']}"]
|
||||
else:
|
||||
cmd = ['sudo', 'python3', f"{script_path}/stopUFTP.py", f"{param_dict['name']}.{param_dict['extension']}"]
|
||||
else:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": "Image not found"
|
||||
}), 400
|
||||
|
||||
try:
|
||||
# Ejecutamos el script "stopUFTP.py" (con los parámetros almacenados), y almacenamos el resultado:
|
||||
result = subprocess.run(cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='UTF8')
|
||||
|
||||
# Evaluamos el resultado de la ejecución, y devolvemos una respuesta:
|
||||
if result.returncode == 0:
|
||||
return jsonify({
|
||||
"success": True,
|
||||
"output": "Image transmission canceled successfully"
|
||||
}), 200
|
||||
else:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"error": result.stderr
|
||||
}), 500
|
||||
except Exception as error_description:
|
||||
if "exit status 3" in str(error_description):
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"exception": "No UFTP active transmissions for specified image"
|
||||
}), 400
|
||||
elif "exit status 4" in str(error_description):
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"exception": "Unexpected error checking UFTP transmissions"
|
||||
}), 500
|
||||
elif "exit status 5" in str(error_description):
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"exception": "Unexpected error finalizing UFTP transmission"
|
||||
}), 500
|
||||
else:
|
||||
return jsonify({
|
||||
"success": False,
|
||||
"exception": str(error_description)
|
||||
}), 500
|
||||
|
||||
|
||||
# ---------------------------------------------------------
|
||||
|
||||
|
||||
# 20 - Endpoint "Cancelar Transmisiones P2P":
|
||||
@app.route("/ogrepository/v1/p2p", methods=['DELETE'])
|
||||
def stop_p2p():
|
||||
""" Este endpoint cancela las transmisiones P2P activas, finalizando los procesos "btlaunchmany.bittornado" (seeder) y "bttrack" (tracker).
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
"""
|
||||
Este script busca procesos activos de "uftp", 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 UFTP activas, porque cuando finalizan también finaliza el proceso asociado.
|
||||
"""
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# IMPORTS
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# VARIABLES
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
repo_path = '/opt/opengnsys/images/'
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# FUNCTIONS
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def get_uftp_processes():
|
||||
""" Busca procesos de "uftp", y si los encuentra retorna el pid, el ID, 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 "uftp":
|
||||
process_list = [line for line in out.split('\n') if 'uftp' 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, el nombre de la imagen (con subdirectorio de OU, si es el caso), y la ruta de la imagen de cada uno:
|
||||
for process in process_list:
|
||||
pid = process.split()[1]
|
||||
image_name = process.split(repo_path)[1]
|
||||
image_path = process.split()[-1]
|
||||
# Obtenemos el ID de la imagen actual:
|
||||
with open(f"{image_path}.full.sum", 'r') as file:
|
||||
image_id = file.read().strip('\n')
|
||||
# Creamos una clave en el diccionario de resultados, correspondiente a la imagen actual:
|
||||
result_dict[pid] = {'image_id':image_id, 'image_name':image_name}
|
||||
# Retornamos el diccionario de resultados:
|
||||
return result_dict
|
||||
# Si no hemos encontrado procesos de uftp retornamos un mensaje:
|
||||
else:
|
||||
return "uftp 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 "uftp":
|
||||
results = get_uftp_processes()
|
||||
|
||||
# Si no hay procesos activos, o si se ha producido un error, imprimimos un mensaje explicativo, y salimos del script:
|
||||
if results == "uftp process not found":
|
||||
print("No UFTP active transmissions")
|
||||
sys.exit(1)
|
||||
elif results == "Unexpected error":
|
||||
print("Unexpected error checking UFTP transmissions")
|
||||
sys.exit(2)
|
||||
# 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()
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
|
@ -4,7 +4,8 @@
|
|||
"""
|
||||
Este script envía mediante UFTP la imagen recibida como primer parámetro, al puerto e IP (Multicast o Unicast) especificados en el segundo parámetro,
|
||||
a la velocidad de transferencia tambíén especificada en el segundo parámetro (la sintaxis de este parámetro es "Port:IP:Bitrate").
|
||||
Previamente, los clientes deben haberse puesto a escuchar en la IP Multicast correspondiente (tanto para envíos Multicast como para envíos Unicast).
|
||||
Previamente, los clientes deben haberse puesto a escuchar con un proceso "uftpd" en la IP Multicast correspondiente (tanto para envíos Multicast como para envíos Unicast).
|
||||
NOTA: La imagen se envía a la ruta de la caché de los clientes (que actualmente es "/opt/opengnsys/cache").
|
||||
|
||||
Paquetes APT requeridos: "uftp" (se puede instalar con "sudo apt install uftp").
|
||||
|
||||
|
@ -49,6 +50,7 @@ import subprocess
|
|||
|
||||
script_name = os.path.basename(__file__)
|
||||
repo_path = '/opt/opengnsys/images/'
|
||||
cache_path = '/opt/opengnsys/cache'
|
||||
log_file = '/opt/opengnsys/log/uftp.log'
|
||||
|
||||
|
||||
|
@ -137,11 +139,16 @@ def main():
|
|||
# Obtenemos la ruta completa al archivo a enviar:
|
||||
file_path = build_file_path()
|
||||
|
||||
# Si el fichero no es accesible, devolvermos un error, y salimos del script:
|
||||
if not os.path.isfile(file_path):
|
||||
print(f"{script_name} Error: Fichero \"{file_path}\" no accesible")
|
||||
# Si no existe el archivo de imagen, imprimimos un mensaje de error y salimos del script:
|
||||
if not os.path.exists(file_path):
|
||||
print("Image file doesn't exist")
|
||||
sys.exit(2)
|
||||
|
||||
# Si no existe el archivo de log, lo creamos:
|
||||
if not os.path.exists(log_file):
|
||||
print("Creating log file...")
|
||||
open(log_file, "w").close()
|
||||
|
||||
# Almacenamos los elementos del segundo parámetro en variables (su formato es "puerto:ip:bitrate"):
|
||||
param_list = sys.argv[2].split(':')
|
||||
port, ip, bitrate = param_list
|
||||
|
@ -150,7 +157,7 @@ def main():
|
|||
bitrate = calculate_bitrate(bitrate)
|
||||
|
||||
# Creamos una lista con el comando a enviar (esto es requerido por la función "subprocess.run"), e imprimimos el comando con espacios:
|
||||
splitted_cmd = f"uftp -M {ip} -p {port} -L {log_file} -Y aes256-cbc -h sha256 -e rsa -c -K 1024 -R {bitrate} {file_path}".split()
|
||||
splitted_cmd = f"uftp -M {ip} -p {port} -L {log_file} -o -D {cache_path} -Y aes256-cbc -h sha256 -e rsa -c -K 1024 -R {bitrate} {file_path}".split()
|
||||
|
||||
print(f"Sending command: {' '.join(splitted_cmd)}")
|
||||
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
"""
|
||||
Este script finaliza el proceso "uftp" asociado a la imagen que recibe como parámetro,
|
||||
lo que en la práctica hará que se cancele la transmisión existente de dicha imagen mediante UFTP.
|
||||
|
||||
Parámetros
|
||||
------------
|
||||
sys.argv[1] - Nombre completo de la imagen a cancelar su transmisión (con o sin ruta), pero incluyendo el subdirectorio correspondiente a la OU, si es el caso.
|
||||
- Ejemplo1: image1.img
|
||||
- Ejemplo2: /opt/opengnsys/images/image1.img
|
||||
- Ejemplo3: ou_subdir/image1.img
|
||||
- Ejemplo4: /ou_subdir/image1.img
|
||||
- Ejemplo5: /opt/opengnsys/images/ou_subdir/image1.img
|
||||
|
||||
Sintaxis
|
||||
----------
|
||||
./stopUDPcast.py [ou_subdir/]image_name|/image_path/image_name
|
||||
|
||||
Ejemplos
|
||||
---------
|
||||
./stopUDPcast.py image1.img
|
||||
./stopUDPcast.py /opt/opengnsys/images/image1.img
|
||||
./stopUDPcast.py ou_subdir/image1.img
|
||||
./stopUDPcast.py /ou_subdir/image1.img
|
||||
./stopUDPcast.py /opt/opengnsys/images/ou_subdir/image1.img
|
||||
"""
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# 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} [ou_subdir/]image_name|/image_path/image_name
|
||||
Ejemplo1: {script_name} image1.img
|
||||
Ejemplo2: {script_name} /opt/opengnsys/images/image1.img
|
||||
Ejemplo3: {script_name} ou_subdir/image1.img
|
||||
Ejemplo4: {script_name} /ou_subdir/image1.img
|
||||
Ejemplo5: {script_name} /opt/opengnsys/images/ou_subdir/image1.img
|
||||
"""
|
||||
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 build_file_path():
|
||||
""" Construye la ruta completa del archivo a chequear
|
||||
(agregando "/opt/opengnsys/images/" si no se ha especificado en el parámetro).
|
||||
"""
|
||||
param_path = sys.argv[1]
|
||||
# Si la ruta comienza con una barra, pero que no corresponde a "repo_path"
|
||||
# (porque corresponderá al subdirectorio de una OU), eliminamos la barra:
|
||||
if param_path.startswith('/') and not param_path.startswith(repo_path):
|
||||
param_path = param_path.lstrip('/')
|
||||
# Construimos la ruta completa:
|
||||
if not param_path.startswith(repo_path):
|
||||
file_path = os.path.join(repo_path, param_path)
|
||||
else:
|
||||
file_path = param_path
|
||||
return file_path
|
||||
|
||||
|
||||
def get_process_pid(file_path):
|
||||
""" Busca un proceso que contenga "uftp" y la ruta de la imagen que recibe como parámetro,
|
||||
y si lo encuentra almacena y retorna su pid asociado.
|
||||
Si no encuentra ningún proceso que cumpla las condiciones (o si se produce una excepción) sale del script.
|
||||
"""
|
||||
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 "uftp" y la imagen especificada como parámetro:
|
||||
filtered_lines = [line for line in out.split('\n') if 'uftp' in line and file_path in line]
|
||||
# Si hemos encontrado un proceso retornamos su pid, y si no imprimimos un mensaje de error y salimos del script:
|
||||
if filtered_lines != []:
|
||||
pid = filtered_lines[0].split()[1]
|
||||
return pid
|
||||
else:
|
||||
print("uftp process not found")
|
||||
sys.exit(3)
|
||||
# Si se ha producido una excepción, imprimimos el error y salimos del script:
|
||||
except Exception as error_description:
|
||||
print(f"Unexpected error: {error_description}")
|
||||
sys.exit(4)
|
||||
|
||||
|
||||
def kill_uftp(pid):
|
||||
""" Finaliza el proceso asociado al pid que recibe como parámetro, e imprime el return code.
|
||||
Si se produce una excepción, imprime el error y sale del script.
|
||||
"""
|
||||
try:
|
||||
# Finalizamos el proceso asociado al pid especificado como parámetro, e imprimimos el return code:
|
||||
result = subprocess.run(f"kill {pid}".split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
print(f"ReturnCode: {result.returncode}")
|
||||
# Si se ha producido una excepción, imprimimos el error y salimos del script:
|
||||
except Exception as error_description:
|
||||
print(f"Unexpected error: {error_description}")
|
||||
sys.exit(5)
|
||||
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
# MAIN
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
"""
|
||||
# Evaluamos si se ha enviado la cantidad correcta de parámetros, y en el formato correcto:
|
||||
check_params()
|
||||
|
||||
# Obtenemos la ruta completa al archivo de imagen:
|
||||
file_path = build_file_path()
|
||||
|
||||
# Si no existe el archivo de imagen, imprimimos un mensaje de error y salimos del script:
|
||||
if not os.path.exists(file_path):
|
||||
print("Image file doesn't exist")
|
||||
sys.exit(2)
|
||||
|
||||
# Obtenemos el pid del proceso "uftp" asociado a la imagen especificada:
|
||||
pid = get_process_pid(file_path)
|
||||
|
||||
# Finalizamos el proceso "uftp" encontrado:
|
||||
kill_uftp(pid)
|
||||
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
# --------------------------------------------------------------------------------------------
|
Loading…
Reference in New Issue