refs #583 - Añadido sendFileMcast.py, y reestructurados los directorios

pull/1/head
Gerardo GIl Elizeire 2024-08-07 16:01:40 +02:00
parent 98742f31a6
commit 66f51cc1e2
3 changed files with 174 additions and 10 deletions

View File

@ -4,5 +4,6 @@ OpenGnsys Repository Manager README
Este repositorio GIT contiene la estructura de datos del repositorio de datos de OpenGnsys.
- bin: binarios y scripts de gestión del repositorio.
- etc: ficheros o plantillas de configuración del repositorio.
- bin: Binarios y scripts de gestión del repositorio.
- etc: Ficheros o plantillas de configuración del repositorio.
- py_scripts: Scripts en Python 3, algunos de los cuales son traducciones de los scripts bash situados en "bin".

View File

@ -0,0 +1,164 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Este script envía mediante UDPCast la imagen recibida como primer parámetro, con los datos Multicast especificados en el segundo parámetro.
En principio, debería hacer lo mismo que el script bash original (cuyo nombre es "sendFileMcast", a secas).
Parámetros
------------
sys.argv[1] - Nombre completo de la imagen a enviar (con o sin ruta)
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/images/image1.img
sys.argv[2] - Parámetros Multicast (en formato "Port:Duplex:IP:Mpbs:Nclients:Timeout")
- Ejemplo: 9000:full:239.194.17.2:70M:20:120
Sintaxis
----------
./sendFileMcast.py image_name|/image_path/image_name Port:Duplex:IP:Mpbs:Nclients:Timeout
Ejemplos
---------
./sendFileMcast.py image1.img 9000:full:239.194.17.2:70M:20:120
./sendFileMcast.py /opt/opengnsys/images/image1.img 9000:full:239.194.17.2:70M:20:120
"""
# --------------------------------------------------------------------------------------------
# IMPORTS
# --------------------------------------------------------------------------------------------
import os
import sys
import subprocess
# --------------------------------------------------------------------------------------------
# VARIABLES
# --------------------------------------------------------------------------------------------
script_name = os.path.basename(__file__)
repo_path = '/opt/opengnsys/images/'
bin_path = '/opt/opengnsys/bin/'
repo_iface = subprocess.getoutput('/opt/opengnsys/bin/getRepoIface')
# --------------------------------------------------------------------------------------------
# FUNCTIONS
# --------------------------------------------------------------------------------------------
def show_help():
""" Imprime la ayuda, cuando se ejecuta el script con el parámetro "help".
"""
help_text = f"""
Sintaxis: {script_name} image_name|/image_path/image_name Port:Duplex:IP:Mpbs:Nclients:Timeout
Ejemplo1: {script_name} image1.img 9000:full-duplex:239.194.17.2:70M:20:120
Ejemplo2: {script_name} /opt/opengnsys/images/image1.img 9000:full-duplex:239.194.17.2:70M:20:120
"""
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 la función con más o menos de 2 parámetros, se muestra un mensaje de error, y se sale del script:
elif len(sys.argv) != 3:
print(f"{script_name} Error: Formato incorrecto: Se debe especificar 2 parámetros (image_name|/image_path/image_name Port:Duplex:IP:Mpbs:Nclients:Timeout)")
sys.exit(1)
# Si en el segundo parámetro no hay 6 elementos (separados por ":"), se muestra un mensaje de error, y se sale del script:
param_list = sys.argv[2].split(':')
if len(param_list) != 6:
print(f"{script_name} Error: Datos Multicast incorrectos: \"{sys.argv[2]}\" (se debe especificar \"Port:Duplex:IP:Mpbs:Nclients:Timeout\")")
sys.exit(3)
def build_file_path():
""" Construye la ruta completa al archivo a enviar
(agregando "/opt/opengnsys/images/" si no se ha especificado en el parámetro).
"""
param_path = sys.argv[1]
if not param_path.startswith(repo_path):
file_path = os.path.join(repo_path, param_path)
else:
file_path = param_path
return file_path
# --------------------------------------------------------------------------------------------
# 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 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")
sys.exit(2)
# Almacenamos los elementos del segundo parámetro en variables (su formato es "Port:Duplex:IP:Mpbs:Nclients:Timeout"):
param_list = sys.argv[2].split(':')
port, method, ip, bitrate, nclients, maxtime = param_list
# Retocamos las variables "method" y "bitrate":
method = '--half-duplex' if 'half' in method.lower() else '--full-duplex'
bitrate = bitrate.lower()
# Creamos la variable "cerror" (no sé que hace, pero estaba en el script original):
cerror = "8x8/128"
# Creamos una lista con el comando a enviar (esto es requerido por la función "subprocess.run").
# NOTA: Se desabilita el uso de mbuffer, ya que esta versión del upd-sender no la admite (ya estaba así en el script original).
mbuffer = "" # which mbuffer &> /dev/null && MBUFFER="--pipe 'mbuffer -m 20M'"
splitted_cmd = [
os.path.join(bin_path, 'udp-sender'),
mbuffer,
'--nokbd',
'--retries-until-drop', '65',
'--portbase', port,
method,
'--interface', repo_iface,
'--mcast-data-address', ip,
'--fec', cerror,
'--max-bitrate', bitrate,
'--ttl', '16',
'--min-clients', nclients,
'--max-wait', maxtime,
'--file', file_path
]
# Imprimimos el comando con espacios (como realmente se enviará):
print(f"Sending command: {' '.join(splitted_cmd)}")
# Ejecutamos el comando en el sistema, e imprimimos el resultado:
try:
result = subprocess.run(splitted_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print(f"ReturnCode: {result.returncode}")
except subprocess.CalledProcessError as error:
print(f"ReturnCode: {error.returncode}")
print(f"Error Output: {error.stderr.decode()}")
except Exception as error:
print(f"Se ha producido un error inesperado: {error}")
# --------------------------------------------------------------------------------------------
if __name__ == "__main__":
main()
# --------------------------------------------------------------------------------------------

View File

@ -3,7 +3,7 @@
"""
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 "puerto:ip:bitrate").
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).
Paquetes APT requeridos: "uftp"
@ -14,13 +14,13 @@ sys.argv[1] - Nombre completo de la imagen a enviar (con o sin ruta)
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/images/image1.img
sys.argv[2] - Parámetros Multicast/Unicast (en formato "puerto:ip:bitrate")
sys.argv[2] - Parámetros Multicast/Unicast (en formato "Port:IP:Bitrate")
- Ejemplo1: 9000:239.194.17.2:100M
- Ejemplo2: 9000:192.168.56.101:1G
Sintaxis
----------
./sendFileUFTP.py image_name|/image_path/image_name port:ip:bitrate
./sendFileUFTP.py image_name|/image_path/image_name Port:IP:Bitrate
Ejemplos
---------
@ -46,7 +46,6 @@ repo_path = '/opt/opengnsys/images/'
log_file = '/opt/opengnsys/images/uftp.log'
# --------------------------------------------------------------------------------------------
# FUNCTIONS
# --------------------------------------------------------------------------------------------
@ -56,7 +55,7 @@ def show_help():
""" Imprime la ayuda, cuando se ejecuta el script con el parámetro "help".
"""
help_text = f"""
Sintaxis: {script_name} image_name|/image_path/image_name port:ip:bitrate
Sintaxis: {script_name} image_name|/image_path/image_name Port:IP:Bitrate
Ejemplo1: {script_name} image1.img 9000:239.194.17.2:100M
Ejemplo2: {script_name} /opt/opengnsys/images/image1.img 9000:192.168.56.101:1G
"""
@ -73,10 +72,10 @@ def check_params():
show_help()
sys.exit(0)
# Si se ejecuta la función con más o menos de 2 parámetros, se muestra un mensaje de error, y se sale del script:
if len(sys.argv) != 3:
elif len(sys.argv) != 3:
print(f"{script_name} Error: Formato incorrecto: Se debe especificar 2 parámetros (image_name|/image_path/image_name port:ip:bitrate)")
sys.exit(1)
# Si en el segundo parámetro no hay 3 elementos (separados por ":"), devolvermos un error, y salimos del script:
# Si en el segundo parámetro no hay 3 elementos (separados por ":"), se muestra un mensaje de error, y se sale del script:
param_list = sys.argv[2].split(':')
if len(param_list) != 3:
print(f"{script_name} Error: Datos Multicast incorrectos: \"{sys.argv[2]}\" (se debe especificar \"puerto:ip:bitrate\")")
@ -129,7 +128,7 @@ def main():
print(f"{script_name} Error: Fichero \"{file_path}\" no accesible")
sys.exit(2)
# Almacenamos los elementos del segundo parámetro en variables:
# 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