refs #631 - Add 'getUFTPInfo.py', 'stopUFTP.py' and associated endpoints

pull/1/head
Gerardo GIl Elizeire 2024-10-21 17:27:46 +02:00
parent 93a1b6c937
commit 126aa3cf8f
6 changed files with 509 additions and 17 deletions

View File

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

View File

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

View File

@ -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).

99
bin/getUFTPInfo.py 100644
View File

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

View File

@ -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)}")

172
bin/stopUFTP.py 100644
View File

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