refs #910 - Modify scripts, API and documentation (to supress OU subdir)

pull/5/head
Gerardo GIl Elizeire 2024-11-12 17:01:31 +01:00
parent f98d290ea3
commit 35b2066c1e
20 changed files with 303 additions and 1036 deletions

105
README.md
View File

@ -8,7 +8,7 @@ Este repositorio GIT contiene la estructura de datos del repositorio de imágene
- **api** ------ API de ogRepository.
- **bin** ------ Scripts en Python 3 y binarios de gestión de ogRepository.
- **etc** ------ Ficheros y plantillas de configuración de ogRepository.
- **packets** - Paquetes cuya instalación es requerida.
- **packets** - Paquetes cuya instalación es requerida.
---
@ -124,7 +124,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/stat
Se devolverá la informacion contenida en el archivo "**/opt/opengnsys/ogrepository/etc/repoinfo.json**" (que corresponde a todas las imágenes almacenadas en el repositorio), y en el archivo "**/opt/opengnsys/ogrepository/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 debe ser llamado por el endpoint, que a su vez llama al script "**updateRepoInfo.py**", para actualizar previamente la información del repositorio.
**NOTA**: El 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 realiza en la API.
**NOTA**: El script requiere que en este caso se le pase "all" como parámetro, pero el endpoint se ejecuta sin parámetros.
**URL:** `/ogrepository/v1/images`
**Método HTTP:** GET
@ -147,7 +147,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
{
"name": "Ubuntu24",
"type": "img",
"clientname": "Ubuntu_24",
"clientname": "Ubuntu24_clientname",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "EXTFS",
@ -159,7 +159,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
{
"name": "Windows10",
"type": "img",
"clientname": "Windows_10",
"clientname": "Windows10_clientname",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "NTFS",
@ -168,51 +168,26 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
"sum": "8874d5ab84314f44841c36c69bb5aa82",
"fullsum": "9e7cd32c606ebe5bd39ba212ce7aeb02"
}
],
"ous": [
{
"subdir": "OU_subdir",
"images": [
{
"name": "Ubuntu20",
"type": "img",
"clientname": "Ubuntu_20",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "EXTFS",
"datasize": 8912896000000,
"size": 3803794535,
"sum": "081a933c780ab1aaa044435ad5d4bf56",
"fullsum": "22735b9070e4a8043371b8c6ae52b90d"
}
]
}
]
}
},
},
"TRASH": {
"directory": "/opt/opengnsys/ogrepository/images_trash",
"images": [],
"ous": [
"images": [
{
"subdir": "CentroVirtual",
"images": [
{
"name": "Ubuntu20OLD",
"type": "img",
"clientname": "Ubuntu_20",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "EXTFS",
"datasize": 8912896000000,
"size": 3803794535,
"sum": "081a933c780ab1aaa044435ad5d4bf56",
"fullsum": "22735b9070e4a8043371b8c6ae52b90d"
}
]
"name": "Ubuntu20",
"type": "img",
"clientname": "Ubuntu20_clientname",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "EXTFS",
"datasize": 8912896000000,
"size": 3803794535,
"sum": "081a933c780ab1aaa044435ad5d4bf56",
"fullsum": "22735b9070e4a8043371b8c6ae52b90d"
}
]
}
}
```
- **name**: Nombre de la imagen, sin extensión.
- **type**: Extensión de la imagen.
@ -230,7 +205,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
Se devolverá la informacion de la imagen especificada, que puede estar en el archivo "**/opt/opengnsys/ogrepository/etc/repoinfo.json**" o en el archivo "**/opt/opengnsys/ogrepository/etc/trashinfo.json**" (en este último caso, si la imagen está en la papelera).
Se puede utilizar el script "**getRepoInfo.py**, que debe ser llamado por el endpoint, que a su vez llama al script "**updateRepoInfo.py**", para actualizar previamente la información del repositorio.
**NOTA**: El 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. Estos datos se obtienen en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), y alli se realiza la transformación de parámetros.
**NOTA**: El script requiere que en este caso se le pase el nombre de la imagen (con extensión) como 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/images/{ID_img}`
**Método HTTP:** GET
@ -253,7 +228,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
{
"name": "Windows10",
"type": "img",
"clientname": "Windows_10",
"clientname": "Windows10_clientname",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "NTFS",
@ -300,7 +275,7 @@ curl -X PUT -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
Se comprobará la integridad del fichero de imagen especificado como parámetro.
Se puede hacer con el script "**checkImage.py**", que compara el tamaño actual del archivo con el almacenado en el archivo "**.size**", y el hash MD5 del último MB del archivo con el almacenado en el archivo "**.sum**".
**NOTA**: El 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. Estos datos se obtienen en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), y alli se realiza la transformación de parámetros.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como 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/status/images/{ID_img}`
**Método HTTP:** GET
@ -321,7 +296,7 @@ curl -X POST -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/sta
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 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**: El 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). Estos datos se obtienen en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), y alli se realiza la transformación de parámetros, pero también hay que especificar el método de eliminación en la URL, como parámetro adicional.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, y el parámetro opcional "-p" (para que la eliminación sea permanente). El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero también hay que especificar el método de eliminación en la URL, para enviar o no el parámetro opcional.
**URL:** `/ogrepository/v1/images/{ID_img}?method={method}`
**Método HTTP:** DELETE
@ -344,7 +319,7 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/i
Se recuperará la imagen especificada como parámetro, desde la papelera.
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**: El 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. Estos datos se obtienen en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), y alli se realiza la transformación de parámetros.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como 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/trash/images`
**Método HTTP:** POST
@ -367,7 +342,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
Se eliminará permanentemente la imagen especificada como parámetro, desde 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**: El 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. Estos datos se obtienen en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), y alli se realiza la transformación de parámetros.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como 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/trash/images/{ID_img}`
**Método HTTP:** DELETE
@ -387,22 +362,21 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/t
Se importará una imagen de un repositorio remoto al repositorio local.
Se puede hacer con el script "**importImage.py**", que debe ser llamado por el endpoint.
**NOTA**: El 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. Estos parámetros deben enviarse desde ogCore (en el JSON), porque el repositorio local no puede extraer la información de la imagen de un ID almacenado en un repositorio remoto.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, la IP o hostname del repositorio remoto como segundo parámetro, y el usuario remoto como tercer parámetro. Estos parámetros deben enviarse desde ogCore (en el JSON), porque el repositorio local no puede extraer la información de la imagen de un ID almacenado en un repositorio remoto.
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está importando, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/repo/images`
**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).
- **repo_ip**: Dirección IP del repositorio remoto (desde el que se importará la imagen).
- **image**: Nombre de la imagen (con extensión).
- **repo_ip**: Dirección IP del repositorio remoto (desde el que se importará la imagen).
- **user**: Usuario con el que acceder al repositorio remoto.
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"image":"Windows10.img", "ou_subdir":"none", "repo_ip":"192.168.56.100", "user":"opengnsys"}' http://example.com/ogrepository/v1/repo/images
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"image":"Windows10.img", "repo_ip":"192.168.56.100", "user":"opengnsys"}' http://example.com/ogrepository/v1/repo/images
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al importar la imagen.
@ -414,7 +388,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
Se exportará una imagen del repositorio local a un repositorio remoto.
Se puede hacer con el script "**exportImage.py**", que debe ser llamado por el endpoint.
**NOTA**: El 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. El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero la IP del repositorio remoto y el usuario remoto deben enviarse desde ogCore (en el JSON).
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, la IP o hostname del repositorio remoto como segundo parámetro, y el usuario remoto como tercer parámetro. El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero la IP del repositorio remoto y el usuario remoto deben enviarse desde ogCore (en el JSON).
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está exportando, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/repo/images`
@ -440,20 +414,19 @@ curl -X PUT -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
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 debe ser llamado por el endpoint.
**NOTA**: El 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 unico parámetro. Este parámetro no puede obtenerse en la API, a partir del ID de imagen (como en otros casos), porque el ID corresponde al contenido del archivo "full.sum" asociado (que no estará creado hasta que no se ejecute este script).
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como parámetro. Este parámetro no puede obtenerse en la API, a partir del ID de imagen (como en otros casos), porque el ID corresponde al contenido del archivo "full.sum" asociado (que no estará creado hasta que no se ejecute este script).
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar cierto tiempo, por lo que solo informa de que los archivos auxiliares se están creando, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/images/torrentsum`
**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).
- **image**: Nombre de la imagen (con extensión).
**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/torrentsum
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"image":"Windows10.img"}' http://example.com/ogrepository/v1/images/torrentsum
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al crear los archivos auxiliares.
@ -465,7 +438,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
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 debe ser llamado por el endpoint.
**NOTA**: La versión actual de este script requiere que se le pase la dirección IP de broadcast como primer parámetro, y la dirección MAC destino como segundo parámetro. Estos datos deben enviarse desde ogCore (en el JSON).
**NOTA**: Este script requiere que se le pase la dirección IP de broadcast como primer parámetro, y la dirección MAC destino como segundo parámetro. Estos datos deben enviarse desde ogCore (en el JSON).
**URL:** `/ogrepository/v1/wol`
**Método HTTP:** POST
@ -488,7 +461,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
Se enviará la imagen especificada por Multicast, mediante la aplicación UDPcast.
Se puede hacer con el script "**sendFileMcast.py**", que a su vez llama al binario "**udp-sender**", que es quien realmente realiza el envío.
**NOTA**: El 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 los datos de transferencia como segundo parámetro (en una cadena, con los datos separados por dos puntos). El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero los datos de transferencia deben enviarse desde ogCore (y luego son tratados en la API, para construir la cadena correspondiente al parámetro).
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, y los datos de transferencia como segundo parámetro (en una cadena, con los datos separados por dos puntos). El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero los datos de transferencia deben enviarse desde ogCore (y luego son tratados en la API, para construir la cadena correspondiente al parámetro).
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está enviando, y abre un proceso paralelo (pero no avisa a ogCore de su finalización, porque no puede comprobar cuando acaba la tarea de restauración de la imagen).
**URL:** `/ogrepository/v1/udpcast`
@ -518,7 +491,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
Se enviará la imagen especificada por Unicast o Multicast, mediante el protocolo "UFTP".
Se puede hacer con el script "**sendFileUFTP.py**", que requiere que previamente los clientes ogLive destino se pongan en escucha con un daemon "UFTPD" (ejecutando el script "**listenUFTPD.py**"). Esto funciona al revés que "UDPcast", ya que primero se debe ejecutar un comando en los clientes, y luego en el servidor.
**NOTA**: El 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 los datos de transferencia como segundo parámetro (en una cadena, con los datos separados por dos puntos). El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero los datos de transferencia deben enviarse desde ogCore (y luego son tratados en la API, para construir la cadena correspondiente al parámetro).
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, y los datos de transferencia como segundo parámetro (en una cadena, con los datos separados por dos puntos). El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero los datos de transferencia deben enviarse desde ogCore (y luego son tratados en la API, para construir la cadena correspondiente al parámetro).
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está enviando, y abre un proceso paralelo (pero no avisa a ogCore de su finalización, porque no puede comprobar cuando acaba la tarea de restauración de la imagen).
**URL:** `/ogrepository/v1/uftp`
@ -543,9 +516,9 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
---
### Enviar una Imagen mediante P2P
Se enviará la imagen especificada mediante "P2P", iniciando el tracker y el seeder (que harán tracking y seed de los torrents contenidos en la raiz del directorio especificado).
Se enviará la imagen especificada mediante "P2P", iniciando el tracker y el seeder (que harán tracking y seed de los torrents contenidos en el directorio de imágenes).
Se puede hacer con los scripts "**runTorrentTracker.py**" y "**runTorrentSeeder.py**", que deben ser llamados por el endpoint.
**NOTA**: Estos scripts requieren que se les pase el directorio en el que está situada la imagen a enviar 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").
**NOTA**: Estos scripts no reciben parámetros, pero es necesario que el endpoint compruebe si la imagen a enviar existe antes de llamarlos, por lo que se le debe enviar el ID de la imagen (que corresponde al contenido del archivo "full.sum") desde ogCore (en el JSON).
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está enviando, y abre un proceso paralelo (pero no avisa a ogCore de su finalización, porque no puede comprobar cuando acaba la tarea de restauración de la imagen).
@ -632,7 +605,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp
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 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").
**NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión) como 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/udpcast/images/{ID_img}`
**Método HTTP:** DELETE
@ -653,7 +626,7 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/u
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").
**NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión) como 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

View File

@ -84,7 +84,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/stat
Se devolverá la informacion contenida en el archivo "**/opt/opengnsys/ogrepository/etc/repoinfo.json**" (que corresponde a todas las imágenes almacenadas en el repositorio), y en el archivo "**/opt/opengnsys/ogrepository/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 debe ser llamado por el endpoint, que a su vez llama al script "**updateRepoInfo.py**", para actualizar previamente la información del repositorio.
**NOTA**: El 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 realiza en la API.
**NOTA**: El script requiere que en este caso se le pase "all" como parámetro, pero el endpoint se ejecuta sin parámetros.
**URL:** `/ogrepository/v1/images`
**Método HTTP:** GET
@ -107,7 +107,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
{
"name": "Ubuntu24",
"type": "img",
"clientname": "Ubuntu_24",
"clientname": "Ubuntu24_clientname",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "EXTFS",
@ -119,7 +119,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
{
"name": "Windows10",
"type": "img",
"clientname": "Windows_10",
"clientname": "Windows10_clientname",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "NTFS",
@ -128,51 +128,26 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
"sum": "8874d5ab84314f44841c36c69bb5aa82",
"fullsum": "9e7cd32c606ebe5bd39ba212ce7aeb02"
}
],
"ous": [
{
"subdir": "OU_subdir",
"images": [
{
"name": "Ubuntu20",
"type": "img",
"clientname": "Ubuntu_20",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "EXTFS",
"datasize": 8912896000000,
"size": 3803794535,
"sum": "081a933c780ab1aaa044435ad5d4bf56",
"fullsum": "22735b9070e4a8043371b8c6ae52b90d"
}
]
}
]
}
},
},
"TRASH": {
"directory": "/opt/opengnsys/ogrepository/images_trash",
"images": [],
"ous": [
"images": [
{
"subdir": "CentroVirtual",
"images": [
{
"name": "Ubuntu20OLD",
"type": "img",
"clientname": "Ubuntu_20",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "EXTFS",
"datasize": 8912896000000,
"size": 3803794535,
"sum": "081a933c780ab1aaa044435ad5d4bf56",
"fullsum": "22735b9070e4a8043371b8c6ae52b90d"
}
]
"name": "Ubuntu20",
"type": "img",
"clientname": "Ubuntu20_clientname",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "EXTFS",
"datasize": 8912896000000,
"size": 3803794535,
"sum": "081a933c780ab1aaa044435ad5d4bf56",
"fullsum": "22735b9070e4a8043371b8c6ae52b90d"
}
]
}
}
```
- **name**: Nombre de la imagen, sin extensión.
- **type**: Extensión de la imagen.
@ -190,7 +165,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
Se devolverá la informacion de la imagen especificada, que puede estar en el archivo "**/opt/opengnsys/ogrepository/etc/repoinfo.json**" o en el archivo "**/opt/opengnsys/ogrepository/etc/trashinfo.json**" (en este último caso, si la imagen está en la papelera).
Se puede utilizar el script "**getRepoInfo.py**, que debe ser llamado por el endpoint, que a su vez llama al script "**updateRepoInfo.py**", para actualizar previamente la información del repositorio.
**NOTA**: El 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. Estos datos se obtienen en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), y alli se realiza la transformación de parámetros.
**NOTA**: El script requiere que en este caso se le pase el nombre de la imagen (con extensión) como 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/images/{ID_img}`
**Método HTTP:** GET
@ -213,7 +188,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
{
"name": "Windows10",
"type": "img",
"clientname": "Windows_10",
"clientname": "Windows10_clientname",
"clonator": "partclone",
"compressor": "lzop",
"filesystem": "NTFS",
@ -260,7 +235,7 @@ curl -X PUT -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/imag
Se comprobará la integridad del fichero de imagen especificado como parámetro.
Se puede hacer con el script "**checkImage.py**", que compara el tamaño actual del archivo con el almacenado en el archivo "**.size**", y el hash MD5 del último MB del archivo con el almacenado en el archivo "**.sum**".
**NOTA**: El 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. Estos datos se obtienen en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), y alli se realiza la transformación de parámetros.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como 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/status/images/{ID_img}`
**Método HTTP:** GET
@ -281,7 +256,7 @@ curl -X POST -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/sta
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 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**: El 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). Estos datos se obtienen en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), y alli se realiza la transformación de parámetros, pero también hay que especificar el método de eliminación en la URL, como parámetro adicional.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, y el parámetro opcional "-p" (para que la eliminación sea permanente). El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero también hay que especificar el método de eliminación en la URL, para enviar o no el parámetro opcional.
**URL:** `/ogrepository/v1/images/{ID_img}?method={method}`
**Método HTTP:** DELETE
@ -304,7 +279,7 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/i
Se recuperará la imagen especificada como parámetro, desde la papelera.
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**: El 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. Estos datos se obtienen en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), y alli se realiza la transformación de parámetros.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como 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/trash/images`
**Método HTTP:** POST
@ -327,7 +302,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
Se eliminará permanentemente la imagen especificada como parámetro, desde 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**: El 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. Estos datos se obtienen en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), y alli se realiza la transformación de parámetros.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como 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/trash/images/{ID_img}`
**Método HTTP:** DELETE
@ -347,22 +322,21 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/t
Se importará una imagen de un repositorio remoto al repositorio local.
Se puede hacer con el script "**importImage.py**", que debe ser llamado por el endpoint.
**NOTA**: El 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. Estos parámetros deben enviarse desde ogCore (en el JSON), porque el repositorio local no puede extraer la información de la imagen de un ID almacenado en un repositorio remoto.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, la IP o hostname del repositorio remoto como segundo parámetro, y el usuario remoto como tercer parámetro. Estos parámetros deben enviarse desde ogCore (en el JSON), porque el repositorio local no puede extraer la información de la imagen de un ID almacenado en un repositorio remoto.
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está importando, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/repo/images`
**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).
- **repo_ip**: Dirección IP del repositorio remoto (desde el que se importará la imagen).
- **image**: Nombre de la imagen (con extensión).
- **repo_ip**: Dirección IP del repositorio remoto (desde el que se importará la imagen).
- **user**: Usuario con el que acceder al repositorio remoto.
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"image":"Windows10.img", "ou_subdir":"none", "repo_ip":"192.168.56.100", "user":"opengnsys"}' http://example.com/ogrepository/v1/repo/images
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"image":"Windows10.img", "repo_ip":"192.168.56.100", "user":"opengnsys"}' http://example.com/ogrepository/v1/repo/images
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al importar la imagen.
@ -374,7 +348,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
Se exportará una imagen del repositorio local a un repositorio remoto.
Se puede hacer con el script "**exportImage.py**", que debe ser llamado por el endpoint.
**NOTA**: El 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. El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero la IP del repositorio remoto y el usuario remoto deben enviarse desde ogCore (en el JSON).
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, la IP o hostname del repositorio remoto como segundo parámetro, y el usuario remoto como tercer parámetro. El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero la IP del repositorio remoto y el usuario remoto deben enviarse desde ogCore (en el JSON).
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está exportando, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/repo/images`
@ -400,20 +374,19 @@ curl -X PUT -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
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 debe ser llamado por el endpoint.
**NOTA**: El 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 unico parámetro. Este parámetro no puede obtenerse en la API, a partir del ID de imagen (como en otros casos), porque el ID corresponde al contenido del archivo "full.sum" asociado (que no estará creado hasta que no se ejecute este script).
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como parámetro. Este parámetro no puede obtenerse en la API, a partir del ID de imagen (como en otros casos), porque el ID corresponde al contenido del archivo "full.sum" asociado (que no estará creado hasta que no se ejecute este script).
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar cierto tiempo, por lo que solo informa de que los archivos auxiliares se están creando, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/images/torrentsum`
**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).
- **image**: Nombre de la imagen (con extensión).
**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/torrentsum
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"image":"Windows10.img"}' http://example.com/ogrepository/v1/images/torrentsum
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al crear los archivos auxiliares.
@ -425,7 +398,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
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 debe ser llamado por el endpoint.
**NOTA**: La versión actual de este script requiere que se le pase la dirección IP de broadcast como primer parámetro, y la dirección MAC destino como segundo parámetro. Estos datos deben enviarse desde ogCore (en el JSON).
**NOTA**: Este script requiere que se le pase la dirección IP de broadcast como primer parámetro, y la dirección MAC destino como segundo parámetro. Estos datos deben enviarse desde ogCore (en el JSON).
**URL:** `/ogrepository/v1/wol`
**Método HTTP:** POST
@ -448,7 +421,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
Se enviará la imagen especificada por Multicast, mediante la aplicación UDPcast.
Se puede hacer con el script "**sendFileMcast.py**", que a su vez llama al binario "**udp-sender**", que es quien realmente realiza el envío.
**NOTA**: El 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 los datos de transferencia como segundo parámetro (en una cadena, con los datos separados por dos puntos). El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero los datos de transferencia deben enviarse desde ogCore (y luego son tratados en la API, para construir la cadena correspondiente al parámetro).
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, y los datos de transferencia como segundo parámetro (en una cadena, con los datos separados por dos puntos). El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero los datos de transferencia deben enviarse desde ogCore (y luego son tratados en la API, para construir la cadena correspondiente al parámetro).
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está enviando, y abre un proceso paralelo (pero no avisa a ogCore de su finalización, porque no puede comprobar cuando acaba la tarea de restauración de la imagen).
**URL:** `/ogrepository/v1/udpcast`
@ -478,7 +451,7 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
Se enviará la imagen especificada por Unicast o Multicast, mediante el protocolo "UFTP".
Se puede hacer con el script "**sendFileUFTP.py**", que requiere que previamente los clientes ogLive destino se pongan en escucha con un daemon "UFTPD" (ejecutando el script "**listenUFTPD.py**"). Esto funciona al revés que "UDPcast", ya que primero se debe ejecutar un comando en los clientes, y luego en el servidor.
**NOTA**: El 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 los datos de transferencia como segundo parámetro (en una cadena, con los datos separados por dos puntos). El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero los datos de transferencia deben enviarse desde ogCore (y luego son tratados en la API, para construir la cadena correspondiente al parámetro).
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, y los datos de transferencia como segundo parámetro (en una cadena, con los datos separados por dos puntos). El primer parámetro se obtiene en la API, a partir del ID de la imagen (que corresponde al contenido del archivo "full.sum"), pero los datos de transferencia deben enviarse desde ogCore (y luego son tratados en la API, para construir la cadena correspondiente al parámetro).
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está enviando, y abre un proceso paralelo (pero no avisa a ogCore de su finalización, porque no puede comprobar cuando acaba la tarea de restauración de la imagen).
**URL:** `/ogrepository/v1/uftp`
@ -503,9 +476,9 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
---
### Enviar una Imagen mediante P2P
Se enviará la imagen especificada mediante "P2P", iniciando el tracker y el seeder (que harán tracking y seed de los torrents contenidos en la raiz del directorio especificado).
Se enviará la imagen especificada mediante "P2P", iniciando el tracker y el seeder (que harán tracking y seed de los torrents contenidos en el directorio de imágenes).
Se puede hacer con los scripts "**runTorrentTracker.py**" y "**runTorrentSeeder.py**", que deben ser llamados por el endpoint.
**NOTA**: Estos scripts requieren que se les pase el directorio en el que está situada la imagen a enviar 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").
**NOTA**: Estos scripts no reciben parámetros, pero es necesario que el endpoint compruebe si la imagen a enviar existe antes de llamarlos, por lo que se le debe enviar el ID de la imagen (que corresponde al contenido del archivo "full.sum") desde ogCore (en el JSON).
**NOTA2**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está enviando, y abre un proceso paralelo (pero no avisa a ogCore de su finalización, porque no puede comprobar cuando acaba la tarea de restauración de la imagen).
@ -592,7 +565,7 @@ curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp
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 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").
**NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión) como 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/udpcast/images/{ID_img}`
**Método HTTP:** DELETE
@ -613,7 +586,7 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/u
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").
**NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión) como 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

View File

@ -6,7 +6,7 @@
Responde a peticiones HTTP (en principio, enviadas desde ogCore) mediante endpoints, que a su vez ejecutan los scripts Python almacenados en ogRepository.
En ciertos casos, transforma los parámetros recibidos desde el portal, para adaptarlos a los que es necesario enviar a los scripts
(por ejemplo, a partir del ID de una imagen obtiene su nombre, su extensión y el subdirectorio de OU).
(por ejemplo, a partir del ID de una imagen obtiene su nombre y su extensión).
Librerías Python requeridas: - flask (se puede instalar con "sudo apt install python3-flask")
- paramiko (se puede instalar con "sudo apt install python3-paramiko")
@ -72,8 +72,7 @@ swagger = Swagger(app, template=swagger_template)
def get_image_params(image_id, search='all'):
""" A partir de un ID de imagen (que corresponde al "fullsum"), busca la imagen en el repositorio y/o en la papelera (dependiendo del parámetro "search").
Si encuentra la imagen devuelve su nombre, su extensión y el subdirectorio de OU (si fuera el caso) en un diccionario,
y si no encuentra la imagen especificada retorna "None".
Si encuentra la imagen devuelve su nombre y su extensión en un diccionario, y si no encuentra la imagen especificada retorna "None".
El parámtro "search" tiene el valor predeterminado "all" (que hará que busque tanto en el repo como en la papelera),
pero se le puede pasar el valor "repo" (para que busque solo en el repo) o "trash" (para que busque solo en la papelera).
"""
@ -90,14 +89,6 @@ def get_image_params(image_id, search='all'):
result['name'] = image.get('name')
result['extension'] = image.get('type')
return result
# Iteramos la clave "ous" y su sublclave "images" y buscamos la imagen (y si la encontramos almacenamos el nombre y la extension):
for ou in repo_data.get('ous', []):
for image in ou.get('images', []):
if image.get('fullsum') == image_id:
result['name'] = image.get('name')
result['extension'] = image.get('type')
result['subdir'] = ou.get('subdir')
return result
# Abrimos y almacenamos el archivo "trashinfo.json" (solo si se ha de buscar en la papelera, y si el archivo tiene contenido):
if (search == 'all' or search == 'trash') and os.path.getsize(trash_file) > 0:
@ -109,14 +100,6 @@ def get_image_params(image_id, search='all'):
result['name'] = image.get('name')
result['extension'] = image.get('type')
return result
# Iteramos la clave "ous" y su sublclave "images" y buscamos la imagen (y si la encontramos almacenamos el nombre y la extension):
for ou in trash_data.get('ous', []):
for image in ou.get('images', []):
if image.get('fullsum') == image_id:
result['name'] = image.get('name')
result['extension'] = image.get('type')
result['subdir'] = ou.get('subdir')
return result
# Si no encontramos la imagen, retornamos "None":
return None
@ -170,7 +153,7 @@ def check_lock_local(image_file_path, job_id):
data = {
'job_id': job_id
}
# Llamamos al endpoint de ogCore, enviando los datos (de momento comento la llamada, porque la función llama a un endpoint inexistente):
# Llamamos al endpoint de ogCore, enviando los datos del diccionario:
#recall_ogcore(data)
break
# Si aun existe el archivo ".lock", imprimimos un mensaje en la API:
@ -218,7 +201,7 @@ def check_lock_remote(image_file_path, remote_host, remote_user, job_id):
data = {
'job_id': job_id
}
# Llamamos al endpoint de ogCore, enviando los datos (de momento comento la llamada, porque la función llama a un endpoint inexistente):
# Llamamos al endpoint de ogCore, enviando los datos del diccionario:
#recall_ogcore(data)
break
# Esperamos 1 minuto para volver a realizar la comprobación:
@ -256,7 +239,7 @@ def check_aux_files(image_file_path, job_id):
'job_id': job_id,
'image_id': image_id
}
# Llamamos al endpoint de ogCore, enviando los datos (de momento comento la llamada, porque la función llama a un endpoint inexistente):
# Llamamos al endpoint de ogCore, enviando los datos del diccionario:
#recall_ogcore(data)
break
# Esperamos 10 segundos para volver a realizar la comprobación:
@ -272,7 +255,8 @@ def recall_ogcore(data):
que estaba corriendo en un proceso independiente (no controlado por los endpoints).
"""
# Almacenamos la URL del endpoint de ogCore (prueba):
endpoint_url = f"http://{ogcore_ip}:8006/ogcore/v1/test"
#endpoint_url = f"http://{ogcore_ip}:8006/ogcore/v1/test"
endpoint_url = f"https://{ogcore_ip}:8443/og-repository/webhook" # Es HTTPS?
# Almacenamos los headers, y convertiomos "data" a JSON:
headers = {'content-type': 'application/json'}
@ -327,11 +311,11 @@ def get_repo_status():
@app.route("/ogrepository/v1/images", methods=['GET'])
def get_repo_info():
""" Este endpoint devuelve información de todas las imágenes contenidas en el repositorio (incluída la papelera), en formato json.
Para ello, ejecuta el script "getRepoInfo.py", con los parámetros "all" y "none".
Para ello, ejecuta el script "getRepoInfo.py", con el parámetro "all".
"""
try:
# Ejecutamos el script "getRepoInfo.py" (con los parámetros "all" y "none"), y almacenamos el resultado:
result = subprocess.run(['sudo', 'python3', f"{script_path}/getRepoInfo.py", 'all', 'none'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='UTF8')
# Ejecutamos el script "getRepoInfo.py" (con el parámetro "all"), y almacenamos el resultado:
result = subprocess.run(['sudo', 'python3', f"{script_path}/getRepoInfo.py", 'all'], 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:
@ -358,18 +342,14 @@ def get_repo_info():
@app.route("/ogrepository/v1/images/<string:imageId>", methods=['GET'])
def get_repo_image_info(imageId):
""" Este endpoint devuelve información de la imagen especificada como parámetro, en formato json.
Para ello, ejecuta el script "getRepoInfo.py", con el nombre de la imagen como primer parámetro,
y el subdirectorio correspondiente a la OU (o "none") como segundo parámetro.
Para ello, ejecuta el script "getRepoInfo.py", con el nombre de la imagen como parámetro.
"""
# Obtenemos el nombre y la extensión de la imagen (y el subdirectorio de OU, si fuera el caso):
# Obtenemos el nombre y la extensión de la imagen:
param_dict = get_image_params(imageId)
# 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}/getRepoInfo.py", f"{param_dict['name']}.{param_dict['extension']}", param_dict['subdir']]
else:
cmd = ['sudo', 'python3', f"{script_path}/getRepoInfo.py", f"{param_dict['name']}.{param_dict['extension']}", 'none']
cmd = ['sudo', 'python3', f"{script_path}/getRepoInfo.py", f"{param_dict['name']}.{param_dict['extension']}"]
else:
return jsonify({
"success": False,
@ -437,18 +417,14 @@ def update_repo_info():
def check_image(imageId):
""" Este endpoint comprueba la integridad de la imagen especificada como parámetro,
comparando el tamaño y el hash MD5 del último MB con los valores almacenados en los archivos "size" y "sum".
Para ello, ejecuta el script "checkImage.py", con el nombre de la imagen como único parámetro,
incluyendo el subdirectorio correspondiente a la OU (si fuera el caso).
Para ello, ejecuta el script "checkImage.py", con el nombre de la imagen como único parámetro.
"""
# Obtenemos el nombre y la extensión de la imagen (y el subdirectorio de OU, si fuera el caso):
# Obtenemos el nombre y la extensión de la imagen:
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}/checkImage.py", f"{param_dict['subdir']}/{param_dict['name']}.{param_dict['extension']}"]
else:
cmd = ['sudo', 'python3', f"{script_path}/checkImage.py", f"{param_dict['name']}.{param_dict['extension']}"]
cmd = ['sudo', 'python3', f"{script_path}/checkImage.py", f"{param_dict['name']}.{param_dict['extension']}"]
else:
return jsonify({
"success": False,
@ -491,36 +467,24 @@ def check_image(imageId):
def delete_image(imageId):
""" Este endpoint elimina la imagen especificada como parámetro (y todos sus archivos asociados),
moviéndolos a la papelera o eliminándolos permanentemente (dependiendo del parámetro "method").
Para ello, ejecuta el script "deleteImage.py", con el nombre de la imagen como primer parámetro,
incluyendo el subdirectorio correspondiente a la OU (si fuera el caso), y el parámetro opcional "-p".
Para ello, ejecuta el script "deleteImage.py", con el nombre de la imagen como primer parámetro, y el parámetro opcional "-p".
"""
# Obtenemos el nombre y la extensión de la imagen (y el subdirectorio de OU, si fuera el caso):
# Obtenemos el nombre y la extensión de la imagen:
param_dict = get_image_params(imageId, "repo")
# Almacenams el método de eliminación ("trash" o "permanent")
method = request.values.get('method')
# 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:
if method == "permanent":
cmd = ['sudo', 'python3', f"{script_path}/deleteImage.py", f"{param_dict['subdir']}/{param_dict['name']}.{param_dict['extension']}", '-p']
elif method == "trash":
cmd = ['sudo', 'python3', f"{script_path}/deleteImage.py", f"{param_dict['subdir']}/{param_dict['name']}.{param_dict['extension']}"]
else:
return jsonify({
"success": False,
"error": "Incorrect method (must be 'permanent' or 'trash')"
}), 400
if method == "permanent":
cmd = ['sudo', 'python3', f"{script_path}/deleteImage.py", f"{param_dict['name']}.{param_dict['extension']}", '-p']
elif method == "trash":
cmd = ['sudo', 'python3', f"{script_path}/deleteImage.py", f"{param_dict['name']}.{param_dict['extension']}"]
else:
if method == "permanent":
cmd = ['sudo', 'python3', f"{script_path}/deleteImage.py", f"{param_dict['name']}.{param_dict['extension']}", '-p']
elif method == "trash":
cmd = ['sudo', 'python3', f"{script_path}/deleteImage.py", f"{param_dict['name']}.{param_dict['extension']}"]
else:
return jsonify({
"success": False,
"error": "Incorrect method (must be 'permanent' or 'trash')"
}), 400
return jsonify({
"success": False,
"error": "Incorrect method (must be 'permanent' or 'trash')"
}), 400
else:
return jsonify({
"success": False,
@ -557,22 +521,18 @@ def delete_image(imageId):
def recover_image():
""" Este endpoint recupera la imagen especificada como parámetro (y todos sus archivos asociados),
moviéndolos nuevamente al repositorio de imágenes, desde la papelera.
Para ello, ejecuta el script "recoverImage.py", con el nombre de la imagen como único parámetro,
incluyendo el subdirectorio correspondiente a la OU (si fuera el caso).
Para ello, ejecuta el script "recoverImage.py", con el nombre de la imagen como único parámetro.
"""
# Almacenamos el parámetro "ID_img" (enviado por JSON):
json_data = json.loads(request.data)
image_id = json_data.get("ID_img")
# Obtenemos el nombre y la extensión de la imagen (y el subdirectorio de OU, si fuera el caso):
# Obtenemos el nombre y la extensión de la imagen:
param_dict = get_image_params(image_id, "trash")
# 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}/recoverImage.py", f"{param_dict['subdir']}/{param_dict['name']}.{param_dict['extension']}"]
else:
cmd = ['sudo', 'python3', f"{script_path}/recoverImage.py", f"{param_dict['name']}.{param_dict['extension']}"]
cmd = ['sudo', 'python3', f"{script_path}/recoverImage.py", f"{param_dict['name']}.{param_dict['extension']}"]
else:
return jsonify({
"success": False,
@ -608,18 +568,14 @@ def recover_image():
@app.route("/ogrepository/v1/trash/images/<string:imageId>", methods=['DELETE'])
def delete_trash_image(imageId):
""" Este endpoint elimina permanentemente la imagen especificada como parámetro (y todos sus archivos asociados), desde la papelera.
Para ello, ejecuta el script "deleteTrashImage.py", con el nombre de la imagen como único parámetro,
incluyendo el subdirectorio correspondiente a la OU (si fuera el caso).
Para ello, ejecuta el script "deleteTrashImage.py", con el nombre de la imagen como único parámetro.
"""
# Obtenemos el nombre y la extensión de la imagen (y el subdirectorio de OU, si fuera el caso):
# Obtenemos el nombre y la extensión de la imagen:
param_dict = get_image_params(imageId, "trash")
# 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}/deleteTrashImage.py", f"{param_dict['subdir']}/{param_dict['name']}.{param_dict['extension']}"]
else:
cmd = ['sudo', 'python3', f"{script_path}/deleteTrashImage.py", f"{param_dict['name']}.{param_dict['extension']}"]
cmd = ['sudo', 'python3', f"{script_path}/deleteTrashImage.py", f"{param_dict['name']}.{param_dict['extension']}"]
else:
return jsonify({
"success": False,
@ -654,23 +610,18 @@ def delete_trash_image(imageId):
# 9 - Endpoint "Importar una Imagen" (ASINCRONO):
@app.route("/ogrepository/v1/repo/images", methods=['POST'])
def import_image():
""" Este endpoint importa la imagen especificada como primer parámetro (y todos sus archivos asociados),
desde un servidor remoto al servidor local.
Para ello, ejecuta el script "importImage.py", con el nombre de la imagen como primer parámetro (con subdirectorio de OU, si es el caso),
""" Este endpoint importa la imagen especificada como primer parámetro (y todos sus archivos asociados), desde un servidor remoto al servidor local.
Para ello, ejecuta el script "importImage.py", con el nombre de la imagen como primer parámetro,
la IP o hostname del servidor remoto como segundo parámetro, y el usuario con el que conectar al servidor como tercer parámetro.
"""
# Almacenamos los parámetros enviados en el JSON:
json_data = json.loads(request.data)
image_name = json_data.get("image")
ou_subdir = json_data.get("ou_subdir")
remote_ip = json_data.get("repo_ip")
remote_user = json_data.get("user")
# Evaluamos los parámetros obtenidos, para construir la ruta de la imagen:
if ou_subdir == "none":
image_file_path = f"{repo_path}{image_name}"
else:
image_file_path = f"{repo_path}{ou_subdir}/{image_name}"
# Construimos la ruta de la imagen:
image_file_path = f"{repo_path}{image_name}"
# Construimos la llamada al script:
cmd = ['sudo', 'python3', f"{script_path}/importImage.py", image_file_path, remote_ip, remote_user]
@ -733,9 +684,8 @@ def import_image():
# 10 - Endpoint "Exportar una Imagen" (ASINCRONO):
@app.route("/ogrepository/v1/repo/images", methods=['PUT'])
def export_image():
""" Este endpoint exporta la imagen especificada como primer parámetro (y todos sus archivos asociados),
desde el servidor local a un servidor remoto.
Para ello, ejecuta el script "exportImage.py", con el nombre de la imagen como primer parámetro (con subdirectorio de OU, si es el caso),
""" Este endpoint exporta la imagen especificada como primer parámetro (y todos sus archivos asociados), desde el servidor local a un servidor remoto.
Para ello, ejecuta el script "exportImage.py", con el nombre de la imagen como primer parámetro,
la IP o hostname del servidor remoto como segundo parámetro, y el usuario con el que conectar al servidor como tercer parámetro.
"""
# Almacenamos los parámetros enviados en el JSON:
@ -749,10 +699,7 @@ def export_image():
# Evaluamos los parámetros obtenidos, para construir la ruta de la imagen, o para devover un error si no se ha encontrado la imagen:
if param_dict:
if 'subdir' in param_dict:
image_file_path = f"{param_dict['subdir']}/{param_dict['name']}.{param_dict['extension']}"
else:
image_file_path = f"{param_dict['name']}.{param_dict['extension']}"
image_file_path = f"{param_dict['name']}.{param_dict['extension']}"
else:
return jsonify({
"success": False,
@ -821,18 +768,14 @@ def export_image():
@app.route("/ogrepository/v1/images/torrentsum", methods=['POST'])
def create_torrent_sum():
""" Este endpoint crea los archivos ".size", ".sum", ".full.sum" y ".torrent" para la imagen que recibe como parámetro.
Para ello, ejecuta el script "createTorrentSum.py", con el nombre de la imagen como único parámetro (con subdirectorio de OU, si es el caso).
Para ello, ejecuta el script "createTorrentSum.py", con el nombre de la imagen como único parámetro.
"""
# Almacenamos los parámetros enviados en el JSON:
json_data = json.loads(request.data)
image_name = json_data.get("image")
ou_subdir = json_data.get("ou_subdir")
# Evaluamos los parámetros obtenidos, para construir la ruta de la imagen (relativa a "repo_path"):
if ou_subdir == "none":
image_file_path = image_name
else:
image_file_path = f"{ou_subdir}/{image_name}"
# Construimos la ruta de la imagen (relativa a "repo_path"):
image_file_path = image_name
# Construimos la llamada al script:
cmd = ['sudo', 'python3', f"{script_path}/createTorrentSum.py", image_file_path]
@ -939,10 +882,7 @@ def send_udpcast():
# 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}/sendFileMcast.py", f"{param_dict['subdir']}/{param_dict['name']}.{param_dict['extension']}", f"{port}:{method}:{ip}:{bitrate}:{nclients}:{maxtime}"]
else:
cmd = ['sudo', 'python3', f"{script_path}/sendFileMcast.py", f"{param_dict['name']}.{param_dict['extension']}", f"{port}:{method}:{ip}:{bitrate}:{nclients}:{maxtime}"]
cmd = ['sudo', 'python3', f"{script_path}/sendFileMcast.py", f"{param_dict['name']}.{param_dict['extension']}", f"{port}:{method}:{ip}:{bitrate}:{nclients}:{maxtime}"]
else:
return jsonify({
"success": False,
@ -1002,10 +942,7 @@ def send_uftp():
# 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}/sendFileUFTP.py", f"{param_dict['subdir']}/{param_dict['name']}.{param_dict['extension']}", f"{port}:{ip}:{bitrate}"]
else:
cmd = ['sudo', 'python3', f"{script_path}/sendFileUFTP.py", f"{param_dict['name']}.{param_dict['extension']}", f"{port}:{ip}:{bitrate}"]
cmd = ['sudo', 'python3', f"{script_path}/sendFileUFTP.py", f"{param_dict['name']}.{param_dict['extension']}", f"{port}:{ip}:{bitrate}"]
else:
return jsonify({
"success": False,
@ -1049,8 +986,8 @@ def send_uftp():
# 15 - Endpoint "Enviar una Imagen mediante P2P" (ASINCRONO):
@app.route("/ogrepository/v1/p2p", methods=['POST'])
def send_p2p():
""" Este endpoint inicia el tracker "bttrack" y el seeder "bittornado", en el directorio en el que esté situada la imagen que recibe como parámetro.
Para ello, ejecuta los scripts "runTorrentTracker.py" y "runTorrentSeeder.py", pasándoles el subdirectorio de OU de la imagen (o "none" si no es el caso).
""" Este endpoint inicia el tracker "bttrack" y el seeder "bittornado", en el directorio de imágenes (sirviendo todas las imágenes).
Para ello, ejecuta los scripts "runTorrentTracker.py" y "runTorrentSeeder.py", que no reciben parámetros.
"""
# Almacenamos los parámetros enviados en el JSON:
json_data = json.loads(request.data)
@ -1059,23 +996,18 @@ def send_p2p():
# Obtenemos el nombre y la extensión de la imagen (y el subdirectorio de OU, si fuera el caso):
param_dict = get_image_params(image_id, "repo")
# Evaluamos los parámetros obtenidos, para construir la llamada al script, o para devover un error si no se ha encontrado la imagen:
# Evaluamos los parámetros obtenidos, para construir las llamadas a los scripts, o para devover un error si no se ha encontrado la imagen:
if param_dict:
if 'subdir' in param_dict:
cmd_tracker = ['sudo', 'python3', f"{script_path}/runTorrentTracker.py", param_dict['subdir']]
cmd_seeder = ['sudo', 'python3', f"{script_path}/runTorrentSeeder.py", param_dict['subdir']]
base_path = f"{repo_path}{param_dict['subdir']}"
else:
cmd_tracker = ['sudo', 'python3', f"{script_path}/runTorrentTracker.py", 'none']
cmd_seeder = ['sudo', 'python3', f"{script_path}/runTorrentSeeder.py", 'none']
base_path = repo_path.rstrip('/') # Le quito la última barra para poder buscar correctamente en los procesos
cmd_tracker = ['sudo', 'python3', f"{script_path}/runTorrentTracker.py"]
cmd_seeder = ['sudo', 'python3', f"{script_path}/runTorrentSeeder.py"]
base_path = repo_path.rstrip('/') # Le quito la última barra para poder buscar correctamente en los procesos
else:
return jsonify({
"success": False,
"error": "Image not found"
}), 400
# Ejecutamos los scripts "runTorrentSeeder.py" y "runTorrentSeeder.py" (con los parámetros almacenados).
# Ejecutamos los scripts "runTorrentSeeder.py" y "runTorrentSeeder.py", que no reciben parámetros.
# NOTA: No almacenamos la salida ni comprobamos los errores, porque los procesos quedarán corriendo hasta que se finalicen manualmente,
# por lo que no podemos comprobar el returncode (luego comprobaremos si los procesos se han iniciado correctamente).
subprocess.Popen(cmd_tracker)
@ -1183,17 +1115,14 @@ def get_uftp_info():
@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.
Para ello, ejecuta el script "stopUDPcast.py", pasándole el nombre de la imagen (con subdirectorio de OU, si procede).
Para ello, ejecuta el script "stopUDPcast.py", pasándole el nombre de la imagen.
"""
# Obtenemos el nombre y la extensión de la imagen (y el subdirectorio de OU, si fuera el caso):
# Obtenemos el nombre y la extensión de la imagen:
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}/stopUDPcast.py", f"{param_dict['subdir']}/{param_dict['name']}.{param_dict['extension']}"]
else:
cmd = ['sudo', 'python3', f"{script_path}/stopUDPcast.py", f"{param_dict['name']}.{param_dict['extension']}"]
cmd = ['sudo', 'python3', f"{script_path}/stopUDPcast.py", f"{param_dict['name']}.{param_dict['extension']}"]
else:
return jsonify({
"success": False,
@ -1245,17 +1174,14 @@ def stop_udpcast(imageId):
@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).
Para ello, ejecuta el script "stopUFTP.py", pasándole el nombre de la imagen.
"""
# 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']}"]
cmd = ['sudo', 'python3', f"{script_path}/stopUFTP.py", f"{param_dict['name']}.{param_dict['extension']}"]
else:
return jsonify({
"success": False,

View File

@ -8,13 +8,13 @@ info:
**API de ogRepository, programada en Flask**.
Responde a peticiones HTTP mediante endpoints, que a su vez ejecutan los scripts de Python 3 almacenados en ogRepository. En el entorno real, estas peticiones HTTP se enviarán desde ogCore.
En la mayoría de los casos, transforma los parámetros recibidos para adaptarlos a los que es necesario enviar a los scripts (por ejemplo, a partir del ID de una imagen obtiene su nombre, su extensión y el subdirectorio de OU).
En la mayoría de los casos, transforma los parámetros recibidos para adaptarlos a los que es necesario enviar a los scripts (por ejemplo, a partir del ID de una imagen obtiene su nombre y su extensión).
---
Paquetes APT requeridos:
- **uftp** (se puede instalar con "sudo DEBIAN_FRONTEND=noninteractive apt install uftp -y", para que no pida la ruta predeterminada)
- **udpcast** (se puede instalar con "sudo apt install ./udpcast_20230924_amd64.deb", apuntando al paquete)
- **udpcast** (se puede instalar con "sudo apt install ./udpcast_20230924_amd64.deb", apuntando al paquete)
- **ctorrent** (se puede instalar con "sudo apt install ctorrent")
- **bittorrent** (se puede instalar con "sudo apt install bittorrent", pero previamente hay que añadir un repositorio de Debian)
- **bittornado** (se puede instalar con "sudo apt install bittornado", pero previamente hay que añadir un repositorio de Debian)
@ -217,7 +217,7 @@ paths:
get:
summary: "Obtener Información de todas las Imágenes"
description: |
Este endpoint ejecuta el script "**getRepoInfo.py**" con los parámetros "**all**" y "**none**" para devolver información de todas las imágenes almacenadas en el repositorio y en la papelera, que a su vez llama al script "**updateRepoInfo.py**", para actualizar previamente la información del repositorio.
Este endpoint ejecuta el script "**getRepoInfo.py**" con el parámetro "**all**", para devolver información de todas las imágenes almacenadas en el repositorio y en la papelera, que a su vez llama al script "**updateRepoInfo.py**", para actualizar previamente la información del repositorio.
Devuelve detalles como el nombre de la imagen, tipo, nombre del cliente, clonador, compresor, sistema de archivos, tamaño de los datos, tamaño de la imagen, y hashes MD5.
tags:
- "Información de Imágenes"
@ -252,7 +252,7 @@ paths:
example: "img"
clientname:
type: string
example: "Ubuntu_24"
example: "Ubuntu24_clientname"
clonator:
type: string
example: "partclone"
@ -274,49 +274,6 @@ paths:
fullsum:
type: string
example: "33575b9070e4a8043371b8c6ae52b80e"
ous:
type: array
items:
type: object
properties:
subdir:
type: string
example: "OU_subdir"
images:
type: array
items:
type: object
properties:
name:
type: string
example: "Ubuntu20"
type:
type: string
example: "img"
clientname:
type: string
example: "Ubuntu_20"
clonator:
type: string
example: "partclone"
compressor:
type: string
example: "lzop"
filesystem:
type: string
example: "EXTFS"
datasize:
type: integer
example: 8912896000000
size:
type: integer
example: 3803794535
sum:
type: string
example: "081a933c780ab1aaa044435ad5d4bf56"
fullsum:
type: string
example: "22735b9070e4a8043371b8c6ae52b90d"
TRASH:
type: object
properties:
@ -324,52 +281,40 @@ paths:
type: string
example: "/opt/opengnsys/ogrepository/images_trash"
images:
type: array
items:
type: object
ous:
type: array
items:
type: object
properties:
subdir:
name:
type: string
example: "CentroVirtual"
images:
type: array
items:
type: object
properties:
name:
type: string
example: "Ubuntu20OLD"
type:
type: string
example: "img"
clientname:
type: string
example: "Ubuntu_20"
clonator:
type: string
example: "partclone"
compressor:
type: string
example: "lzop"
filesystem:
type: string
example: "EXTFS"
datasize:
type: integer
example: 8912896000000
size:
type: integer
example: 3803794535
sum:
type: string
example: "081a933c780ab1aaa044435ad5d4bf56"
fullsum:
type: string
example: "22735b9070e4a8043371b8c6ae52b90d"
example: "Windows10"
type:
type: string
example: "img"
clientname:
type: string
example: "Windows10_clientname"
clonator:
type: string
example: "partclone"
compressor:
type: string
example: "lzop"
filesystem:
type: string
example: "NTFS"
datasize:
type: integer
example: 8912896000000
size:
type: integer
example: 3803794535
sum:
type: string
example: "081a933c780ab1aaa044435ad5d4bf56"
fullsum:
type: string
example: "22735b9070e4a8043371b8c6ae52b90d"
"500 (Error)":
description: "Error al consultar y/o devolver la información de las imágenes."
schema:
@ -400,7 +345,7 @@ paths:
summary: "Obtener Información de una Imagen concreta"
description: |
Este endpoint devuelve información de la imagen especificada mediante su ID, en formato JSON.
Utiliza el script "**getRepoInfo.py**" que recibe como parámetros el nombre de la imagen con extensión y el subdirectorio correspondiente a la OU (o "none" si no es el caso), que a su vez llama al script "**updateRepoInfo.py**", para actualizar previamente la información del repositorio.
Utiliza el script "**getRepoInfo.py**" que recibe como parámetro el nombre de la imagen (con extensión), que a su vez llama al script "**updateRepoInfo.py**", para actualizar previamente la información del repositorio.
La imagen puede estar en el archivo "**repoinfo.json**" (si está almacenada en el repositorio) o en "**trashinfo.json**" (si está en la papelera).
tags:
- "Información de Imágenes"
@ -432,13 +377,13 @@ paths:
properties:
name:
type: string
example: "Windows10"
example: "Ubuntu24"
type:
type: string
example: "img"
clientname:
type: string
example: "Windows_10"
example: "Ubuntu24_clientname"
clonator:
type: string
example: "partclone"
@ -447,7 +392,7 @@ paths:
example: "lzop"
filesystem:
type: string
example: "NTFS"
example: "EXTFS"
datasize:
type: integer
example: 9859634200000
@ -501,7 +446,7 @@ paths:
summary: "Chequear Integridad de Imagen"
description: |
Este endpoint comprueba la integridad de la imagen especificada como parámetro, comparando el tamaño y el hash MD5 del último MB con los valores almacenados en los archivos ".size" y ".sum".
Utiliza el script "**checkImage.py**", que recibe el nombre de la imagen (con extensión) y el subdirectorio correspondiente a la OU, si aplica.
Utiliza el script "**checkImage.py**", que recibe el nombre de la imagen (con extensión) como parámetro.
tags:
- "Información de Imágenes"
parameters:
@ -576,7 +521,7 @@ paths:
summary: "Eliminar una Imagen"
description: |
Este endpoint elimina la imagen especificada como parámetro (y todos sus archivos asociados), moviéndolos a la papelera o eliminándolos permanentemente (dependiendo del parámetro "method").
Utiliza el script "**deleteImage.py**" que recibe el nombre de la imagen (con extensión y subdirectorio correspondiente a la OU, si aplica) como primer parámetro, y opcionalmente el parámetro "-p" (para eliminación permanente), que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio.
Utiliza el script "**deleteImage.py**" que recibe el nombre de la imagen (con extensión) como primer parámetro, y opcionalmente el parámetro "-p" (para eliminación permanente), que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio.
tags:
- "Eliminar y Recuperar Imágenes"
parameters:
@ -643,7 +588,7 @@ paths:
summary: "Recuperar una Imagen"
description: |
Este endpoint recupera la imagen especificada, moviéndola desde la papelera al repositorio de imágenes.
Utiliza el script "**recoverImage.py**", que recibe el nombre de la imagen (con extensión y subdirectorio correspondiente a la OU, si aplica), que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio.
Utiliza el script "**recoverImage.py**", que recibe el nombre de la imagen (con extensión), que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio.
tags:
- "Eliminar y Recuperar Imágenes"
parameters:
@ -711,7 +656,7 @@ paths:
summary: "Eliminar una Imagen de la Papelera"
description: |
Este endpoint elimina permanentemente la imagen especificada, desde la papelera.
Utiliza el script "**deleteTrashImage.py**", que recibe el nombre de la imagen (con extensión y subdirectorio correspondiente a la OU, si aplica), que a su vez llama al script "**updateTrashInfo.py**", para actualizar la información de la papelera.
Utiliza el script "**deleteTrashImage.py**", que recibe el nombre de la imagen (con extensión), que a su vez llama al script "**updateTrashInfo.py**", para actualizar la información de la papelera.
tags:
- "Eliminar y Recuperar Imágenes"
parameters:
@ -1283,7 +1228,7 @@ paths:
summary: "Enviar una Imagen mediante P2P"
description: |
Este endpoint inicia el tracker y el seeder de torrents para enviar una imagen especificada mediante P2P.
Utiliza los scripts "**runTorrentTracker.py**" y "**runTorrentSeeder.py**" para iniciar el tracker y el seeder en el directorio de la imagen.
Utiliza los scripts "**runTorrentTracker.py**" y "**runTorrentSeeder.py**" para iniciar el tracker y el seeder en el directorio de imágenes.
**NOTA**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está enviando, y abre un proceso paralelo (pero no avisa a ogCore de su finalización, porque no puede comprobar cuando acaba la tarea de restauración de la imagen).
tags:
@ -1389,7 +1334,7 @@ paths:
summary: "Importar una Imagen"
description: |
Este endpoint importa la imagen especificada desde un servidor remoto al servidor local.
Utiliza el script "**importImage.py**", que recibe como parámetros el nombre de la imagen, la IP o hostname del servidor remoto, el usuario para la conexión, y el subdirectorio correspondiente a la OU (si aplica),
Utiliza el script "**importImage.py**", que recibe como parámetros el nombre de la imagen, la IP o hostname del servidor remoto, y el usuario con el que conectar al servidor remoto.
que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio.
**NOTA**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está importando, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
@ -1401,7 +1346,6 @@ paths:
required: true
description: |
* **image** - Nombre de la imagen, con extensión
* **ou_subdir** - Subdirectorio correspondiente a la OU, o 'none' si no procede
* **repo_ip** - Dirección IP del servidor remoto
* **user** - Usuario con el que conectar al servidor remoto
schema:
@ -1410,10 +1354,6 @@ paths:
image:
type: string
example: "Windows10.img"
ou_subdir:
type: string
description: "Subdirectorio correspondiente a la OU (o 'none' si no es el caso)"
example: "none"
repo_ip:
type: string
description: "Dirección IP del repositorio remoto"
@ -1508,7 +1448,7 @@ paths:
summary: "Exportar una Imagen"
description: |
Este endpoint exporta la imagen especificada desde el servidor local a un servidor remoto.
Utiliza el script "**exportImage.py**", que recibe como parámetros el nombre de la imagen, la IP o hostname del servidor remoto, el usuario para la conexión, y el subdirectorio correspondiente a la OU (si aplica).
Utiliza el script "**exportImage.py**", que recibe como parámetros el nombre de la imagen, la IP o hostname del servidor remoto, y el usuario con el que conectar al servidor remoto.
Una vez que acabe, debe llamarse al endpoint "**Actualizar Información del Repositorio**" en el ogRepository destino de la exportación, para actualizar la información del repositorio.
@ -1636,7 +1576,7 @@ paths:
summary: "Crear archivos auxiliares"
description: |
Este endpoint crea los archivos "**size**", "**sum**", "**full.sum**" y "**torrent**" para la imagen especificada.
Utiliza el script "**createTorrentSum.py**", que recibe como parámetro el nombre de la imagen (con subdirectorio de OU, si aplica), que a su vez llama al script "**updateRepoInfo.py**, para actualizar la información del repositorio".
Utiliza el script "**createTorrentSum.py**", que recibe como parámetro el nombre de la imagen (con extensión), que a su vez llama al script "**updateRepoInfo.py**, para actualizar la información del repositorio".
Debe ser llamado cada vez que se cree una imagen desde un ogLive, y cada vez que se llame al endpoint "**Exportar una Imagen**" (en este último caso, debe ejecutarse en el ogRepository destino de la exportación).
@ -1649,16 +1589,12 @@ paths:
required: true
description: |
* **image** - Nombre de la imagen, con extensión
* **ou_subdir** - Subdirectorio correspondiente a la OU, o 'none' si no procede
schema:
type: object
properties:
image:
type: string
example: "Windows10.img"
ou_subdir:
type: string
example: "none"
responses:
"200":
description: "Los archivos auxiliares se están creando."

View File

@ -7,24 +7,18 @@ Este script comprueba la integridad de la imagen que recibe como parámetro, vol
Parámetros
------------
sys.argv[1] - Nombre completo de la imagen a chequear (con o sin ruta), pero incluyendo el subdirectorio correspondiente a la OU, si es el caso.
sys.argv[1] - Nombre completo de la imagen a chequear (con o sin ruta).
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/ogrepository/images/image1.img
- Ejemplo3: ou_subdir/image1.img
- Ejemplo4: /ou_subdir/image1.img
- Ejemplo5: /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
Sintaxis
----------
./checkImage.py [ou_subdir/]image_name|/image_path/image_name
./checkImage.py image_name|/image_path/image_name
Ejemplos
---------
./checkImage.py image1.img
./checkImage.py /opt/opengnsys/ogrepository/images/image1.img
./checkImage.py ou_subdir/image1.img
./checkImage.py /ou_subdir/image1.img
./checkImage.py /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
"""
# --------------------------------------------------------------------------------------------
@ -53,12 +47,9 @@ 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
Sintaxis: {script_name} image_name|/image_path/image_name
Ejemplo1: {script_name} image1.img
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images/image1.img
Ejemplo3: {script_name} ou_subdir/image1.img
Ejemplo4: {script_name} /ou_subdir/image1.img
Ejemplo5: {script_name} /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
"""
print(help_text)
@ -81,13 +72,9 @@ def check_params():
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).
(agregando "/opt/opengnsys/ogrepository/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)

View File

@ -10,24 +10,18 @@ Debería ser llamado por ogCore u ogLive cada vez que se cree una imagen.
Parámetros
------------
sys.argv[1] - Nombre completo de la imagen (con o sin ruta), pero incluyendo el subdirectorio correspondiente a la OU, si es el caso.
sys.argv[1] - Nombre completo de la imagen.
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/ogrepository/images/image1.img
- Ejemplo3: ou_subdir/image1.img
- Ejemplo4: /ou_subdir/image1.img
- Ejemplo5: /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
Sintaxis
----------
./createTorrentSum.py [ou_subdir/]image_name|/image_path/image_name
./createTorrentSum.py image_name|/image_path/image_name
Ejemplos
---------
./createTorrentSum.py image1.img
./createTorrentSum.py /opt/opengnsys/ogrepository/images/image1.img
./createTorrentSum.py ou_subdir/image1.img
./createTorrentSum.py /ou_subdir/image1.img
./createTorrentSum.py /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
"""
# --------------------------------------------------------------------------------------------
@ -60,12 +54,9 @@ 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
Sintaxis: {script_name} image_name|/image_path/image_name
Ejemplo1: {script_name} image1.img
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images/image1.img
Ejemplo3: {script_name} ou_subdir/image1.img
Ejemplo4: {script_name} /ou_subdir/image1.img
Ejemplo5: {script_name} /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
"""
print(help_text)
@ -88,13 +79,9 @@ def check_params():
def build_file_path():
""" Construye la ruta completa al archivo de imagen
(agregando "/opt/opengnsys/images/" si no se ha especificado en el parámetro).
(agregando "/opt/opengnsys/ogrepository/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)
@ -127,7 +114,7 @@ def get_md5_fullsum(file_path):
def get_IPlocal():
""" Retorna la IP asociada a la variable "IPlocal", del archivo '/opt/opengnsys/etc/ogAdmRepo.cfg'
""" Retorna la IP asociada a la variable "IPlocal", del archivo '/opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg'
(que corresponde a la IP del repositorio).
"""
with open(config_file, 'r') as file:
@ -140,7 +127,7 @@ def get_IPlocal():
def create_torrent(file_path, torrent_file, datafullsum):
""" Crea un archivo ".torrent" para la imagen que recibe como primer parámetro.
Obtiene la IP del repositorio llamando a la función "get_IPlocal",
que a su vez la obtiene del archivo '/opt/opengnsys/etc/ogAdmRepo.cfg'.
que a su vez la obtiene del archivo '/opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg'.
"""
# Almacenamos la IP del repositorio, y construimos la URL del tracker:
repo_ip = get_IPlocal()

View File

@ -2,34 +2,28 @@
# -*- coding: utf-8 -*-
"""
Este script elimina la imagen que recibe como parámetro (y todos sus archivos asociados), moviendo los archivos a la papelera
(respetando el subdirectorio correspondiente a la OU, si fuera el caso), o eliminándolos permanentemente si se especifica el parámetro "-p".
Este script elimina la imagen que recibe como parámetro (y todos sus archivos asociados), moviendo los archivos a la papelera,
o eliminándolos permanentemente si se especifica el parámetro "-p".
Es similar al script bash original (cuyo nombre es "deleteimage", a secas), pero este no incluía la funcionalidad papelera.
Llama al script "updateRepoInfo.py", para actualizar la información del repositorio.
Parámetros
------------
sys.argv[1] - Nombre completo de la imagen a eliminar (con o sin ruta), pero incluyendo el subdirectorio correspondiente a la OU, si es el caso.
sys.argv[1] - Nombre completo de la imagen a eliminar (con o sin ruta).
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/ogrepository/images/image1.img
- Ejemplo3: ou_subdir/image1.img
- Ejemplo4: /ou_subdir/image1.img
- Ejemplo5: /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
sys.argv[2] - Parámetro opcional para especificar que la eliminación sea permanente (sin papelera).
- Ejemplo: -p
Sintaxis
----------
./deleteImage.py [ou_subdir/]image_name|/image_path/image_name [-p]
./deleteImage.py image_name|/image_path/image_name [-p]
Ejemplos
---------
./deleteImage.py image1.img -p
./deleteImage.py /opt/opengnsys/ogrepository/images/image1.img -p
./deleteImage.py ou_subdir/image1.img -p
./deleteImage.py /ou_subdir/image1.img
./deleteImage.py /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
"""
# --------------------------------------------------------------------------------------------
@ -64,12 +58,9 @@ 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 [-p]
Sintaxis: {script_name} image_name|/image_path/image_name [-p]
Ejemplo1: {script_name} image1.img -p
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images/image1.img -p
Ejemplo3: {script_name} ou_subdir/image1.img -p
Ejemplo4: {script_name} /ou_subdir/image1.img
Ejemplo5: {script_name} /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images/image1.img
"""
print(help_text)
@ -107,13 +98,9 @@ def check_params():
def build_file_path():
""" Construye la ruta completa al archivo a eliminar
(agregando "/opt/opengnsys/images/" si no se ha especificado en el parámetro).
(agregando "/opt/opengnsys/ogrepository/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)
@ -137,8 +124,8 @@ def create_trash_folder():
os.chmod(trash_path, 0o775)
def delete_normal_image(file_path, method, extensions):
""" Elimina la imagen "normal" que recibe en el parámetro "file_path", y todos sus archivos asociados,
def delete_image(file_path, method, extensions):
""" Elimina la imagen que recibe en el parámetro "file_path", y todos sus archivos asociados,
moviéndolos a la papelera o eliminándolos permanentemente (en función del parámetro "method").
"""
# Iteramos las extensiones de los archivos, y construimos la ruta completa de cada uno de ellos:
@ -153,26 +140,6 @@ def delete_normal_image(file_path, method, extensions):
os.remove(file_to_remove)
def delete_ou_image(file_path, method, extensions):
""" Elimina la imagen basada en OU que recibe en el parámetro "file_path", y todos sus archivos asociados,
moviéndolos a la papelera o eliminándolos permanentemente (en función del parámetro "method").
"""
# Iteramos las extensiones de los archivos, y construimos la ruta completa de cada uno de ellos:
for ext in extensions:
file_to_remove = f"{file_path}{ext}"
# Si el archivo actual existe, lo eliminamos o lo movemos a la papelera (dependiendo del valor del parámetro "method"),
# y en el último caso lo situamos en un subdirectorio correspondiente a la OU:
if os.path.exists(file_to_remove):
if method == 'trash':
ou_subdir = file_to_remove.split('/')[4]
# Comprobamos si en la papelera existe un subdirectorio correspondiente a la OU (y si no existe lo creamos):
if not os.path.exists(f"{trash_path}{ou_subdir}"):
os.mkdir(f"{trash_path}{ou_subdir}")
shutil.move(file_to_remove, f"{trash_path}{ou_subdir}")
elif method == 'permanent':
os.remove(file_to_remove)
def update_repo_info():
""" Actualiza la información del repositorio, ejecutando el script "updateRepoInfo.py".
Como se ve, es necesario que el script se ejecute como sudo, o dará error.
@ -222,14 +189,9 @@ def main():
# (incluyendo ninguna extensión, que corresponde a la propia imagen):
extensions = ['', '.size', '.sum', '.full.sum', '.torrent', '.info', '.info.checked']
# Evaluamos la cantidad de barras que hay en la ruta de la imagen, para diferenciar entre imágenes "normales" y basadas en OU
# (y llamamos a la función correspondiente para eliminarla):
if file_path.count('/') == 5:
print("Deleting normal image...")
delete_normal_image(file_path, method, extensions)
elif file_path.count('/') == 6:
print("Deleting OU based image...")
delete_ou_image(file_path, method, extensions)
# Llamamos a la función que elimina la imagen:
print("Deleting image...")
delete_image(file_path, method, extensions)
# Actualizamos la información del repositorio, ejecutando el script "updateRepoInfo.py":
print("Updating Repository Info...")

View File

@ -7,24 +7,18 @@ Llama al script "updateTrashInfo.py", para actualizar la información de las im
Parámetros
------------
sys.argv[1] - Nombre completo de la imagen a eliminar (con o sin ruta), pero incluyendo el subdirectorio correspondiente a la OU, si es el caso.
sys.argv[1] - Nombre completo de la imagen a eliminar (con o sin ruta).
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/ogrepository/images_trash/image1.img
- Ejemplo3: ou_subdir/image1.img
- Ejemplo4: /ou_subdir/image1.img
- Ejemplo5: /opt/opengnsys/ogrepository/images_trash/ou_subdir/image1.img
Sintaxis
----------
./deleteTrashImage.py [ou_subdir/]image_name|/image_path/image_name
./deleteTrashImage.py image_name|/image_path/image_name
Ejemplos
---------
./deleteTrashImage.py image1.img
./deleteTrashImage.py /opt/opengnsys/ogrepository/images_trash/image1.img
./deleteTrashImage.py ou_subdir/image1.img
./deleteTrashImage.py /ou_subdir/image1.img
./deleteTrashImage.py /opt/opengnsys/ogrepository/images_trash/ou_subdir/image1.img
"""
# --------------------------------------------------------------------------------------------
@ -55,12 +49,9 @@ 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
Sintaxis: {script_name} image_name|/image_path/image_name
Ejemplo1: {script_name} image1.img
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images_trash/image1.img
Ejemplo3: {script_name} ou_subdir/image1.img
Ejemplo4: {script_name} /ou_subdir/image1.img
Ejemplo5: {script_name} /opt/opengnsys/ogrepository/images_trash/ou_subdir/image1.img
"""
print(help_text)
@ -83,13 +74,9 @@ def check_params():
def build_file_path():
""" Construye la ruta completa al archivo a eliminar
(agregando "/opt/opengnsys/images_trash/" si no se ha especificado en el parámetro).
(agregando "/opt/opengnsys/ogrepository/images_trash/" 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 "trash_path"
# (porque corresponderá al subdirectorio de una OU), eliminamos la barra:
if param_path.startswith('/') and not param_path.startswith(trash_path):
param_path = param_path.lstrip('/')
# Construimos la ruta completa:
if not param_path.startswith(trash_path):
file_path = os.path.join(trash_path, param_path)

View File

@ -11,12 +11,9 @@ Librerías Python requeridas: "paramiko" (se puede instalar con "sudo apt instal
Parámetros
------------
sys.argv[1] - Nombre completo de la imagen a exportar (con o sin ruta), pero incluyendo el subdirectorio correspondiente a la OU, si es el caso.
sys.argv[1] - Nombre completo de la imagen a exportar (con o sin ruta).
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/ogrepository/images/image1.img
- Ejemplo3: ou_subdir/image1.img
- Ejemplo4: /ou_subdir/image1.img
- Ejemplo5: /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
sys.argv[2] - IP o hostname del repositorio remoto.
- Ejemplo1: 192.168.56.100
@ -28,15 +25,12 @@ sys.argv[3] - Usuario con el que conectar al repositorio remoto.
Sintaxis
----------
./exportImage.py [ou_subdir/]image_name|/image_path/image_name remote_host remote_user
./exportImage.py image_name|/image_path/image_name remote_host remote_user
Ejemplos
---------
./exportImage.py image1.img 192.168.56.100 user
./exportImage.py /opt/opengnsys/ogrepository/images/image1.img 192.168.56.100 user
./exportImage.py ou_subdir/image1.img remote_hostname user
./exportImage.py /ou_subdir/image1.img remote_hostname root
./exportImage.py /opt/opengnsys/ogrepository/images/ou_subdir/image1.img remote_hostname root
./exportImage.py /opt/opengnsys/ogrepository/images/image1.img remote_hostname user
"""
# --------------------------------------------------------------------------------------------
@ -69,12 +63,9 @@ 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 remote_host remote_user
Sintaxis: {script_name} image_name|/image_path/image_name remote_host remote_user
Ejemplo1: {script_name} image1.img 192.168.56.100 user
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images/image1.img 192.168.56.100 user
Ejemplo3: {script_name} ou_subdir/image1.img remote_hostname user
Ejemplo4: {script_name} /ou_subdir/image1.img remote_hostname root
Ejemplo5: {script_name} /opt/opengnsys/ogrepository/images/ou_subdir/image1.img remote_hostname root
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images/image1.img remote_hostname user
"""
print(help_text)
@ -99,13 +90,9 @@ def check_params():
def build_file_path():
""" Construye la ruta completa al archivo a exportar
(agregando "/opt/opengnsys/images/" si no se ha especificado en el parámetro).
(agregando "/opt/opengnsys/ogrepository/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)
@ -145,16 +132,6 @@ def export_image(file_path, remote_host, remote_user):
except IOError:
print("As expected, image doesn't exist on remote repository.")
# Evaluamos si la ruta de la imagen tiene 6 barras, en cuyo caso corresponderá a una imagen basada en OU,
# y almacenamos el nombre del directorio correspondiente a la OU:
if file_path.count('/') == 6:
ou_subdir = file_path.split('/')[5]
# Comprobamos si el directorio de OU existe en el equipo remoto, y en caso contrario lo creamos:
try:
sftp_client.stat(f"{repo_path}{ou_subdir}")
except IOError:
sftp_client.mkdir(f"{repo_path}{ou_subdir}", mode=755)
# Creamos un archivo de bloqueo en el servidor remoto:
sftp_client.open(f"{file_path}.lock", 'w')

View File

@ -2,8 +2,7 @@
# -*- coding: utf-8 -*-
"""
Este script devuelve información (en formato json) de todas las imágenes contenidas en el repositorio (incluída la papelera),
o de la imagen que se especifique como primer parámetro (debiendo especificar también el subdirectorio de OU como segundo parámetro, si procede).
Este script devuelve información (en formato json) de todas las imágenes contenidas en el repositorio (incluída la papelera), o de la imagen que se especifique como parámetro.
Previamente, llama al script "updateRepoInfo.py", para actualizar la información del repositorio (para evitar que error si no hay ninguna, por ejemplo).
Parámetros
@ -12,19 +11,14 @@ sys.argv[1] - Nombre completo de la imagen a consultar (con extensión y sin rut
- Ejemplo1: all
- Ejemplo2: image1.img
sys.argv[2] - Subdirectorio correspondiente a la OU, o "none" si no procede..
- Ejemplo1: none
- Ejemplo2: OU_subdirectory
Sintaxis
----------
./getRepoInfo.py image_name|all ou_subdir|none
./getRepoInfo.py image_name|all
Ejemplos
---------
./getRepoInfo.py all none
./getRepoInfo.py image1.img none
./getRepoInfo.py image1.img OU_subdirectory
./getRepoInfo.py all
./getRepoInfo.py image1.img
"""
# --------------------------------------------------------------------------------------------
@ -56,10 +50,9 @@ def show_help():
""" Imprime la ayuda, cuando se ejecuta el script con el parámetro "help".
"""
help_text = f"""
Sintaxis: {script_name} image_name|all ou_subdir|none
Ejemplo1: {script_name} all none
Ejemplo2: {script_name} image1.img none
Ejemplo3: {script_name} image1.img OU_subdirectory
Sintaxis: {script_name} image_name|all
Ejemplo1: {script_name} all
Ejemplo2: {script_name} image1.img
"""
print(help_text)
@ -74,9 +67,9 @@ def check_params():
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 2 parámetros, se muestra un error y la ayuda, y se sale del script:
elif len(sys.argv) != 3:
print(f"{script_name} Error: Formato incorrecto: Se debe especificar 2 parámetros")
# 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)
@ -138,38 +131,6 @@ def get_image_info(repo_data, trash_data, image_name, image_ext):
def get_ou_image_info(repo_data, trash_data, image_name, image_ext, ou_subdir):
""" Busca la imagen basada en OU en el repositorio y en la papelera, devolviendo la información asociada si la encuentra,
(o devolviendo un mensaje de error y saliendo del script si no la encuentra).
"""
dictionary = ""
# Buscamos la OU y la imagen en el repositorio, y si los encontramos creamos un diccionario con los datos:
if repo_data != "":
for ou in repo_data['ous']:
if ou['subdir'] == ou_subdir:
for image in ou['images']:
if image['name'] == image_name and image['type'] == image_ext:
dictionary = {"directory": repo_data['directory'],
"ous": [{"subdir": ou_subdir, "images": [image]}]}
# Buscamos la OU y la imagen en la papelera, y si los encontramos creamos un diccionario con los datos:
if trash_data != "":
for ou in trash_data['ous']:
if ou['subdir'] == ou_subdir:
for image in ou['images']:
if image['name'] == image_name:
dictionary = {"directory": trash_data['directory'],
"ous": [{"subdir": ou_subdir, "images": [image]}]}
# Si hemos obtenido datos de la imagen, los pasamos a json y los imprmimos,
# y si no, imprimimos un mensaje de error y salimos del script:
if dictionary != "":
final_json = json.dumps(dictionary, indent=2)
print(final_json)
else:
print("No se ha encontrado la imagen especificada en el repositorio")
sys.exit(3)
# --------------------------------------------------------------------------------------------
# MAIN
# --------------------------------------------------------------------------------------------
@ -201,18 +162,13 @@ def main():
trash_data = ""
# Dependiendo del valor de los parámetros, llamamos a la función correspondiente, para imprimir la información
# (extrayendo el nombre, la extensión de la imagen, y/o la OU cuando se necesite):
# (extrayendo el nombre y la extensión de la imagen):
if sys.argv[1] == 'all':
get_all_info(repo_data, trash_data)
elif sys.argv[2] == 'none':
image_name = sys.argv[1].split('.')[0]
image_ext = sys.argv[1].split('.')[1]
get_image_info(repo_data, trash_data, image_name, image_ext)
else:
image_name = sys.argv[1].split('.')[0]
image_ext = sys.argv[1].split('.')[1]
ou_subdir = sys.argv[2]
get_ou_image_info(repo_data, trash_data, image_name, image_ext, ou_subdir)
get_image_info(repo_data, trash_data, image_name, image_ext)

View File

@ -11,12 +11,9 @@ Librerías Python requeridas: "paramiko" (se puede instalar con "sudo apt instal
Parámetros
------------
sys.argv[1] - Nombre completo de la imagen a importar (con o sin ruta), pero incluyendo el subdirectorio correspondiente a la OU, si es el caso.
sys.argv[1] - Nombre completo de la imagen a importar (con o sin ruta).
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/ogrepository/images/image1.img
- Ejemplo3: ou_subdir/image1.img
- Ejemplo4: /ou_subdir/image1.img
- Ejemplo5: /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
sys.argv[2] - IP o hostname del repositorio remoto.
- Ejemplo1: 192.168.56.100
@ -28,15 +25,12 @@ sys.argv[3] - Usuario con el que conectar al repositorio remoto.
Sintaxis
----------
./importImage.py [ou_subdir/]image_name|/image_path/image_name remote_host remote_user
./importImage.py image_name|/image_path/image_name remote_host remote_user
Ejemplos
---------
./importImage.py image1.img 192.168.56.100 user
./importImage.py /opt/opengnsys/ogrepository/images/image1.img 192.168.56.100 user
./importImage.py ou_subdir/image1.img remote_hostname user
./importImage.py /ou_subdir/image1.img remote_hostname root
./importImage.py /opt/opengnsys/ogrepository/images/ou_subdir/image1.img remote_hostname root
./importImage.py /opt/opengnsys/ogrepository/images/image1.img remote_hostname user
"""
# --------------------------------------------------------------------------------------------
@ -70,12 +64,9 @@ 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 remote_host remote_user
Sintaxis: {script_name} image_name|/image_path/image_name remote_host remote_user
Ejemplo1: {script_name} image1.img 192.168.56.100 user
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images/image1.img 192.168.56.100 user
Ejemplo3: {script_name} ou_subdir/image1.img remote_hostname user
Ejemplo4: {script_name} /ou_subdir/image1.img remote_hostname root
Ejemplo5: {script_name} /opt/opengnsys/ogrepository/images/ou_subdir/image1.img remote_hostname root
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images/image1.img remote_hostname user
"""
print(help_text)
@ -100,13 +91,9 @@ def check_params():
def build_file_path():
""" Construye la ruta completa al archivo a importar
(agregando "/opt/opengnsys/images/" si no se ha especificado en el parámetro).
(agregando "/opt/opengnsys/ogrepository/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)
@ -195,14 +182,6 @@ def main():
remote_host = sys.argv[2]
remote_user = sys.argv[3]
# Evaluamos si la ruta de la imagen tiene 6 barras, en cuyo caso corresponderá a una imagen basada en OU,
# y almacenamos el nombre del directorio correspondiente a la OU:
if file_path.count('/') == 6:
ou_subdir = file_path.split('/')[5]
# Si no existe un directorio correspondiente a la OU en el repo local, lo creamos:
if not os.path.exists(f"{repo_path}{ou_subdir}"):
os.mkdir(f"{repo_path}{ou_subdir}", 0o755)
# Importamos la imagen del repositorio remoto:
import_image(file_path, remote_host, remote_user)

View File

@ -2,30 +2,23 @@
# -*- coding: utf-8 -*-
"""
Este script recupera la imagen que recibe como parámetro (y todos sus archivos asociados), moviendo los archivos a "/opt/opengnsys/ogrepository/images", desde la papelera
(respetando el subdirectorio correspondiente a la OU, si fuera el caso).
Este script recupera la imagen que recibe como parámetro (y todos sus archivos asociados), moviendo los archivos a "/opt/opengnsys/ogrepository/images", desde la papelera.
Llama al script "updateRepoInfo.py", para actualizar la información del repositorio.
Parámetros
------------
sys.argv[1] - Nombre completo de la imagen a recuperar (con o sin ruta), pero incluyendo el subdirectorio correspondiente a la OU, si es el caso.
sys.argv[1] - Nombre completo de la imagen a recuperar (con o sin ruta).
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/ogrepository/images_trash/image1.img
- Ejemplo3: ou_subdir/image1.img
- Ejemplo4: /ou_subdir/image1.img
- Ejemplo5: /opt/opengnsys/ogrepository/images_trash/ou_subdir/image1.img
Sintaxis
----------
./recoverImage.py [ou_subdir/]image_name|/image_path/image_name
./recoverImage.py image_name|/image_path/image_name
Ejemplos
---------
./recoverImage.py image1.img
./recoverImage.py /opt/opengnsys/ogrepository/images_trash/image1.img
./recoverImage.py ou_subdir/image1.img
./recoverImage.py /ou_subdir/image1.img
./recoverImage.py /opt/opengnsys/ogrepository/images_trash/ou_subdir/image1.img
"""
# --------------------------------------------------------------------------------------------
@ -57,12 +50,9 @@ 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
Sintaxis: {script_name} image_name|/image_path/image_name
Ejemplo1: {script_name} image1.img
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images_trash/image1.img
Ejemplo3: {script_name} ou_subdir/image1.img
Ejemplo4: {script_name} /ou_subdir/image1.img
Ejemplo5: {script_name} /opt/opengnsys/ogrepository/images_trash/ou_subdir/image1.img
"""
print(help_text)
@ -90,13 +80,9 @@ def check_params():
def build_file_path():
""" Construye la ruta completa al archivo a recuperar
(agregando "/opt/opengnsys/images_trash/" si no se ha especificado en el parámetro).
(agregando "/opt/opengnsys/ogrepository/images_trash/" 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 "trash_path"
# (porque corresponderá al subdirectorio de una OU), eliminamos la barra:
if param_path.startswith('/') and not param_path.startswith(trash_path):
param_path = param_path.lstrip('/')
# Construimos la ruta completa:
if not param_path.startswith(trash_path):
file_path = os.path.join(trash_path, param_path)
@ -105,14 +91,14 @@ def build_file_path():
return file_path
def recover_normal_image(file_path, extensions):
""" Recupera la imagen "normal" que recibe en el parámetro "file_path", y todos sus archivos asociados,
moviéndolos a "/opt/opengnsys/images" (desde la papelera).
def recover_image(file_path, extensions):
""" Recupera la imagen que recibe en el parámetro "file_path", y todos sus archivos asociados,
moviéndolos a "/opt/opengnsys/ogrepository/images" (desde la papelera).
"""
# Iteramos las extensiones de los archivos, y construimos la ruta completa de cada uno de ellos:
for ext in extensions:
file_to_recover = f"{file_path}{ext}"
# Si el archivo actual existe, lo movemos a "/opt/opengnsys/images" (recuperándolo desde la papelera):
# Si el archivo actual existe, lo movemos a "/opt/opengnsys/ogrepository/images" (recuperándolo desde la papelera):
if os.path.exists(file_to_recover):
# Si la extensión del archivo actual es ".info.checked" la renombramos a ".info" (para que lo pille "updateRepoInfo"):
if ext == '.info.checked':
@ -121,26 +107,6 @@ def recover_normal_image(file_path, extensions):
shutil.move(file_to_recover, repo_path)
def recover_ou_image(file_path, extensions):
""" Recupera la imagen basada en OU que recibe en el parámetro "file_path", y todos sus archivos asociados,
moviéndolos a "/opt/opengnsys/images" (desde la papelera), respetando el subdirectorio correspondiente a la OU.
"""
# Iteramos las extensiones de los archivos, y construimos la ruta completa de cada uno de ellos:
for ext in extensions:
file_to_recover = f"{file_path}{ext}"
# Si el archivo actual existe, lo movemos a "/opt/opengnsys/images/ou_subdir":
if os.path.exists(file_to_recover):
# Si la extensión del archivo actual es ".info.checked" la renombramos a ".info" (para que lo pille "updateRepoInfo"):
if ext == '.info.checked':
os.rename(file_to_recover, file_to_recover.strip('.checked'))
file_to_recover = file_to_recover.strip('.checked')
ou_subdir = file_to_recover.split('/')[4]
# Comprobamos si en "repo_path" existe un subdirectorio correspondiente a la OU (y si no existe lo creamos):
if not os.path.exists(f"{repo_path}{ou_subdir}"):
os.mkdir(f"{repo_path}{ou_subdir}")
shutil.move(file_to_recover, f"{repo_path}{ou_subdir}")
def update_repo_info():
""" Actualiza la información del repositorio, ejecutando el script "updateRepoInfo.py".
Como se ve, es necesario que el script se ejecute como sudo, o dará error.
@ -174,14 +140,9 @@ def main():
# (incluyendo ninguna extensión, que corresponde a la propia imagen):
extensions = ['', '.size', '.sum', '.full.sum', '.torrent', '.info', '.info.checked']
# Evaluamos la cantidad de barras que hay en la ruta de la imagen, para diferenciar entre imágenes "normales" y basadas en OU
# (y llamamos a la función correspondiente para recuperarla):
if file_path.count('/') == 5:
print("Recovering normal image...")
recover_normal_image(file_path, extensions)
elif file_path.count('/') == 6:
print("Recovering OU based image...")
recover_ou_image(file_path, extensions)
# Llamamos a la función que recupera la imagen:
print("Recovering image...")
recover_image(file_path, extensions)
# Actualizamos la información del repositorio, ejecutando el script "updateRepoInfo.py":
print("Updating Repository Info...")

View File

@ -5,22 +5,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
No recibe ningún parámetro.
"""
# --------------------------------------------------------------------------------------------
@ -36,7 +22,6 @@ import subprocess
# VARIABLES
# --------------------------------------------------------------------------------------------
script_name = os.path.basename(__file__)
repo_path = '/opt/opengnsys/ogrepository/images' # En este caso, no lleva barra final
@ -45,41 +30,12 @@ repo_path = '/opt/opengnsys/ogrepository/images' # En este caso, no lleva barra
# --------------------------------------------------------------------------------------------
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):
def run_bittornado(repo_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()
splitted_cmd = f"btlaunchmany.bittornado {repo_path}".split()
print(f"Sending command: {' '.join(splitted_cmd)}")
# Ejecutamos el comando "btlaunchmany.bittornado" en el sistema, e imprimimos el resultado:
@ -102,23 +58,14 @@ def run_bittornado(torrent_path):
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".split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except Exception as error_description:
print(f"No btlaunchmany.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)
run_bittornado(repo_path)

View File

@ -7,20 +7,7 @@ En principio, debería hacer lo mismo que el script bash original (cuyo nombre e
Creemos que debe ser llamado únicamente cuando se quiera hacer una descarga mediante P2P (junto al script "runTorrentSeeder.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
----------
./runTorrentTracker.py none|ou_subdir
Ejemplos
---------
./runTorrentTracker.py none
./runTorrentTracker.py ou_subdir
No recibe ningún parámetro.
"""
# --------------------------------------------------------------------------------------------
@ -37,7 +24,6 @@ import time
# VARIABLES
# --------------------------------------------------------------------------------------------
script_name = os.path.basename(__file__)
repo_path = '/opt/opengnsys/ogrepository/images' # En este caso, no lleva barra final
bttrack_port = 6969
@ -52,41 +38,12 @@ bttrack_allow_get = 0 # Este valor impide la descarga desde clientes no autoriza
# --------------------------------------------------------------------------------------------
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_bttrack(torrent_path):
def run_bttrack(repo_path):
""" 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 {torrent_path} --allow_get {bttrack_allow_get}".split()
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:
@ -109,9 +66,6 @@ def run_bttrack(torrent_path):
def main():
"""
"""
# Evaluamos si se ha enviado la cantidad correcta de parámetros, y en el formato correcto:
check_params()
# 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)
@ -125,14 +79,8 @@ def main():
# Esperamos 2 segundos:
time.sleep(2)
# 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 "bttrack" (para hacer tracking de los torrents):
run_bttrack(torrent_path)
run_bttrack(repo_path)

View File

@ -7,27 +7,21 @@ En principio, debería hacer lo mismo que el script bash original (cuyo nombre e
Parámetros
------------
sys.argv[1] - Nombre completo de la imagen a enviar (con o sin ruta), pero incluyendo el subdirectorio correspondiente a la OU, si es el caso.
sys.argv[1] - Nombre completo de la imagen a enviar (con o sin ruta).
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/ogrepository/images/image1.img
- Ejemplo3: ou_subdir/image1.img
- Ejemplo4: /ou_subdir/image1.img
- Ejemplo5: /opt/opengnsys/ogrepository/images/ou_subdir/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 [ou_subdir/]image_name|/image_path/image_name Port:Duplex:IP:Mpbs:Nclients:Timeout
./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/ogrepository/images/image1.img 9000:full:239.194.17.2:70M:20:120
./sendFileMcast.py ou_subdir/image1.img 9000:full:239.194.17.2:70M:20:120
./sendFileMcast.py /ou_subdir/image1.img 9000:full:239.194.17.2:70M:20:120
./sendFileMcast.py /opt/opengnsys/ogrepository/images/ou_subdir/image1.img 9000:full:239.194.17.2:70M:20:120
"""
# --------------------------------------------------------------------------------------------
@ -59,12 +53,9 @@ 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 Port:Duplex:IP:Mpbs:Nclients:Timeout
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/ogrepository/images/image1.img 9000:full-duplex:239.194.17.2:70M:20:120
Ejemplo3: {script_name} ou_subdir/image1.img 9000:full-duplex:239.194.17.2:70M:20:120
Ejemplo4: {script_name} /ou_subdir/image1.img 9000:full-duplex:239.194.17.2:70M:20:120
Ejemplo5: {script_name} /opt/opengnsys/ogrepository/images/ou_subdir/image1.img 9000:full-duplex:239.194.17.2:70M:20:120
"""
print(help_text)
@ -91,13 +82,9 @@ def check_params():
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).
(agregando "/opt/opengnsys/ogrepository/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)

View File

@ -11,12 +11,9 @@ Paquetes APT requeridos: "uftp" (se puede instalar con "sudo apt install uftp").
Parámetros
------------
sys.argv[1] - Nombre completo de la imagen a enviar (con o sin ruta), pero incluyendo el subdirectorio correspondiente a la OU, si es el caso.
sys.argv[1] - Nombre completo de la imagen a enviar (con o sin ruta).
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/ogrepository/images/image1.img
- Ejemplo3: ou_subdir/image1.img
- Ejemplo4: /ou_subdir/image1.img
- Ejemplo5: /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
sys.argv[2] - Parámetros Multicast/Unicast (en formato "Port:IP:Bitrate")
- Ejemplo1: 9000:239.194.17.2:100M
@ -24,15 +21,12 @@ sys.argv[2] - Parámetros Multicast/Unicast (en formato "Port:IP:Bitrate")
Sintaxis
----------
./sendFileUFTP.py [ou_subdir/]image_name|/image_path/image_name Port:IP:Bitrate
./sendFileUFTP.py image_name|/image_path/image_name Port:IP:Bitrate
Ejemplos
---------
./sendFileUFTP.py image1.img 9000:239.194.17.2:100M
./sendFileUFTP.py /opt/opengnsys/ogrepository/images/image1.img 9000:239.194.17.2:100M
./sendFileUFTP.py ou_subdir/image1.img 9000:192.168.56.101:1G
./sendFileUFTP.py /ou_subdir/image1.img 9000:192.168.56.101:1G
./sendFileUFTP.py /opt/opengnsys/ogrepository/images/ou_subdir/image1.img 9000:192.168.56.101:1G
./sendFileUFTP.py /opt/opengnsys/ogrepository/images/image1.img 9000:192.168.56.101:1G
"""
# --------------------------------------------------------------------------------------------
@ -63,12 +57,9 @@ 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 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/ogrepository/images/image1.img 9000:239.194.17.2:100M
Ejemplo3: {script_name} ou_subdir/image1.img 9000:192.168.56.101:1G
Ejemplo4: {script_name} /ou_subdir/image1.img 9000:192.168.56.101:1G
Ejemplo5: {script_name} /opt/opengnsys/ogrepository/images/ou_subdir/image1.img 9000:192.168.56.101:1G
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images/image1.img 9000:239.194.17.2:1G
"""
print(help_text)
@ -95,13 +86,9 @@ def check_params():
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).
(agregando "/opt/opengnsys/ogrepository/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)

View File

@ -8,24 +8,18 @@ Este script finaliza el proceso "udp-sender" asociado a la imagen que recibe com
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.
sys.argv[1] - Nombre completo de la imagen a cancelar su transmisión (con o sin ruta).
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/ogrepository/images/image1.img
- Ejemplo3: ou_subdir/image1.img
- Ejemplo4: /ou_subdir/image1.img
- Ejemplo5: /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
Sintaxis
----------
./stopUDPcast.py [ou_subdir/]image_name|/image_path/image_name
./stopUDPcast.py image_name|/image_path/image_name
Ejemplos
---------
./stopUDPcast.py image1.img
./stopUDPcast.py /opt/opengnsys/ogrepository/images/image1.img
./stopUDPcast.py ou_subdir/image1.img
./stopUDPcast.py /ou_subdir/image1.img
./stopUDPcast.py /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
"""
# --------------------------------------------------------------------------------------------
@ -54,12 +48,9 @@ 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
Sintaxis: {script_name} image_name|/image_path/image_name
Ejemplo1: {script_name} image1.img
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images/image1.img
Ejemplo3: {script_name} ou_subdir/image1.img
Ejemplo4: {script_name} /ou_subdir/image1.img
Ejemplo5: {script_name} /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
"""
print(help_text)
@ -82,13 +73,9 @@ def check_params():
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).
(agregando "/opt/opengnsys/ogrepository/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)

View File

@ -8,24 +8,18 @@ Este script finaliza el proceso "uftp" asociado a la imagen que recibe como par
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.
sys.argv[1] - Nombre completo de la imagen a cancelar su transmisión (con o sin ruta).
- Ejemplo1: image1.img
- Ejemplo2: /opt/opengnsys/ogrepository/images/image1.img
- Ejemplo3: ou_subdir/image1.img
- Ejemplo4: /ou_subdir/image1.img
- Ejemplo5: /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
Sintaxis
----------
./stopUDPcast.py [ou_subdir/]image_name|/image_path/image_name
./stopUDPcast.py image_name|/image_path/image_name
Ejemplos
---------
./stopUDPcast.py image1.img
./stopUDPcast.py /opt/opengnsys/ogrepository/images/image1.img
./stopUDPcast.py ou_subdir/image1.img
./stopUDPcast.py /ou_subdir/image1.img
./stopUDPcast.py /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
"""
# --------------------------------------------------------------------------------------------
@ -54,12 +48,9 @@ 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
Sintaxis: {script_name} image_name|/image_path/image_name
Ejemplo1: {script_name} image1.img
Ejemplo2: {script_name} /opt/opengnsys/ogrepository/images/image1.img
Ejemplo3: {script_name} ou_subdir/image1.img
Ejemplo4: {script_name} /ou_subdir/image1.img
Ejemplo5: {script_name} /opt/opengnsys/ogrepository/images/ou_subdir/image1.img
"""
print(help_text)
@ -82,13 +73,9 @@ def check_params():
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).
(agregando "/opt/opengnsys/ogrepository/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)

View File

@ -42,7 +42,7 @@ def create_empty_json():
Evidentemente, solo es llamada cuando no existe el archivo.
"""
# Creamos un diccionario con la estructura básica que debe tener el archivo json:
json_data = {"directory": repo_path, "images": [], "ous": []}
json_data = {"directory": repo_path, "images": []}
# Abrimos el archivo json en modo escritura (creándolo si no existe, como es el caso),
# y le añadimos la estructura almacenada en el diccionario "json_data":
@ -52,17 +52,17 @@ def create_empty_json():
def check_files():
""" Esta función recorre el directorio de imágenes, para buscar archivos con extensiones ".img" o ".dsk".
""" Esta función recorre el directorio de imágenes, para buscar archivos con extensión ".img".
Llama a la función "add_to_json" para que esta añada información de las imágenes no bloqueadas (sin archivo ".lock"),
que además tengan un archivo ".info" asociado (siempre que este no se haya modificado antes que la propia imagen).
Originalmente eliminaba los archivos ".info" después de extraer la información, pero ahora los renombra (agrega ".checked").
"""
# Iteramos recursivamente todos los archivos y directorios de "/opt/opengnsys/images",
# Iteramos recursivamente todos los archivos y directorios de "/opt/opengnsys/ogrepository/images",
# y luego iteramos todos los archivos encontrados (en una iteración anidada):
for root, dirs, files in os.walk(repo_path):
for file in files:
# Si la imagen actual tiene extensión ".img" o ".dsk", construimos la ruta completa ("img_path"):
if file.endswith((".img", ".dsk")):
# Si la imagen actual tiene extensión ".img", construimos la ruta completa ("img_path"):
if file.endswith(".img"):
img_path = os.path.join(root, file)
# Si existe un archivo ".lock" asociado a la imagen actual, pasamos a la siguiente:
if os.path.exists(f"{img_path}.lock"):
@ -96,60 +96,12 @@ def check_files():
def check_dirs():
""" Esta función recorre el directorio de imágenes, para buscar archivos con nombre "ogimg.info".
Llama a la función "add_to_json" para que esta añada información de las imágenes no bloqueadas (sin archivo ".lock"),
que además tengan un archivo "ogimg.info" asociado (pero no que tipo de imágenes son esas).
"""
# Iteramos recursivamente todos los archivos y directorios de "/opt/opengnsys/images",
# y luego iteramos todos los archivos encontrados (en una iteración anidada):
for root, dirs, files in os.walk(repo_path):
for file in files:
# Si el nombre del archivo actual es "ogimg.info", construimos su ruta completa ("info_path"), y la ruta del directorio ("img_path"):
if file == "ogimg.info":
info_path = os.path.join(root, file)
img_path = os.path.dirname(info_path)
# Si existe un archivo ".lock" asociado a la imagen actual, o si la ruta coincide con "repo_path", pasamos a la siguiente:
if img_path == repo_path or os.path.exists(f"{img_path}.lock"):
continue
# Almacenamos el contenido del archivo "ogimg.info", en la variable "lines":
with open(info_path, 'r') as file:
lines = file.readlines()
# Iteramos las lineas obtenidas, para extraer el tipo de sistema de archivos ("fstype") y el tamaño de los datos ("sizedata"),
# y con ello construimos una cadena "rsync::{fstype}:{sizedata}:" (que almacenamos en "data"):
for line in lines:
if line.startswith("# fstype"):
fstype = line.split("=")[1].strip()
elif line.startswith("# sizedata"):
sizedata = line.split("=")[1].strip()
info_data = f"rsync::{fstype}:{sizedata}:"
# Almacenamos el contenido de los archivos ".size", ".sum" y ".full.sum":
with open(f"{img_path}.size", 'r') as file:
size = file.read().strip('\n')
with open(f"{img_path}.sum", 'r') as file:
_sum = file.read().strip('\n')
with open(f"{img_path}.full.sum", 'r') as file:
fullsum = file.read().strip('\n')
# Llamamos a la función "add_to_json", para que inserte la información de la imagen en el archivo json
# (pasándole el nombre de la imagen, el tipo "dir"", y los datos extraídos del archivo "ogimg.info"):
img_name = os.path.relpath(img_path, repo_path)
add_to_json(img_name, "dir", info_data, size, _sum, fullsum)
def add_to_json(image_name, image_type, data, size, _sum, fullsum):
""" Esta función añade al archivo "repoinfo.json" la información de las imágenes que aun no ha sido introducida en él (imágenes nuevas, básicamente).
El procedimiento es diferente para las imágenes "normales" y para las imágenes basadas en OU.
"""
# Almacenamos el contenido de la variable "data" (del tipo "PARTCLONE:LZOP:EXTFS:8500000:Ubuntu_20") en variables separadas:
clonator, compressor, fstype, datasize, client = data.split(":")
# Si la imagen está dentro de una OU (directorio), extraemos el nombre de la OU y de la imagen:
ou_name = None
if '/' in image_name:
ou_name = os.path.dirname(image_name)
image_name = os.path.basename(image_name)
# Creamos un diccionario con los datos de la imagen, que luego insertaremos en el json:
json_data = {
"name": image_name,
@ -169,44 +121,24 @@ def add_to_json(image_name, image_type, data, size, _sum, fullsum):
with open(info_file, 'r') as file:
info_data = json.load(file)
else:
info_data = {"directory": repo_path, "images": [], "ous": []}
info_data = {"directory": repo_path, "images": []}
# Comprobamos si las claves "info_data" (o sea, del archivo json) son las correctas:
if set(info_data.keys()) == {"directory", "images", "ous"}:
if set(info_data.keys()) == {"directory", "images"}:
# Actualizamos la información de las imágenes "normales" (no basadas en OU):
if ou_name is None:
img_index = next((i for i, img in enumerate(info_data["images"]) if img["name"] == image_name), None)
if img_index is not None:
# Update if image data changes
if info_data["images"][img_index] != json_data:
info_data["images"][img_index] = json_data
else:
# Append a new entry
info_data["images"].append(json_data)
# Actualizamos la información de las imágenes basadas en OU:
# Actualizamos la información de las imágenes:
img_index = next((i for i, img in enumerate(info_data["images"]) if img["name"] == image_name), None)
if img_index is not None:
# Update if image data changes
if info_data["images"][img_index] != json_data:
info_data["images"][img_index] = json_data
else:
ou_index = next((i for i, ou in enumerate(info_data["ous"]) if ou["subdir"] == ou_name), None)
if ou_index is None:
# Append a new OU entry
info_data["ous"].append({"subdir": ou_name, "images": [json_data]})
else:
img_index = next((i for i, img in enumerate(info_data["ous"][ou_index]["images"]) if img["name"] == image_name), None)
if img_index is not None:
# Update if image data changes
if info_data["ous"][ou_index]["images"][img_index] != json_data:
info_data["ous"][ou_index]["images"][img_index] = json_data
else:
# Append a new entry
info_data["ous"][ou_index]["images"].append(json_data)
# Append a new entry
info_data["images"].append(json_data)
# Si las claves de "info_data" no son las correctas, creamos toda la estructura:
else:
if ou_name is None:
info_data = {"directory": repo_path, "images": [json_data], "ous": []}
else:
info_data = {"directory": repo_path, "images": [], "ous": [{"subdir": ou_name, "images": [json_data]}]}
info_data = {"directory": repo_path, "images": [json_data]}
# Sobreescribimos el archivo "repoinfo.json", con el contenido de "info_data" (que estará actualizado):
with open(info_file, 'w') as file:
@ -233,23 +165,6 @@ def remove_from_json():
if not os.path.exists(img_path) and not os.path.exists(f"{img_path}.lock"):
json_data["images"].pop(i)
# Iteramos las imágenes de la clave "ous" de "json_data", construimos sus rutas y comprobamos su existencia
# (si no existen, las eliminamos de "json_data"):
for j, ou in enumerate(json_data.get("ous", [])):
ou_name = ou["subdir"]
ou_path = os.path.join(repo_path, ou_name)
if not os.path.exists(ou_path):
json_data["ous"].pop(j)
else:
for i, image in enumerate(ou.get("images", [])):
img_name = image["name"]
img_type = image["type"]
if img_type != "dir":
img_name = f"{img_name}.{img_type}"
img_path = os.path.join(ou_path, img_name)
if not os.path.exists(img_path) and not os.path.exists(f"{img_path}.lock"):
ou["images"].pop(i)
# Sobreescribimos el archivo "repoinfo.json", con el contenido de "json_data"
# (una vez eliminadas las imágenes inexistentes):
with open(info_file, 'w') as file:
@ -294,23 +209,18 @@ def main():
if not os.access(info_file, os.W_OK):
raise PermissionError(f"Cannot access {info_file}")
# Llamamos a la función "check_files", para añadir al archivo json las imágenes ".img" o ".dsk" aun no añadidas
# Llamamos a la función "check_files", para añadir al archivo json las imágenes aun no añadidas
# (que son las que tienen asociado un archivo ".info", aun no renombrado o eliminado):
print("Checking file images...")
check_files()
# Llamamos a la función "check_dirs", para añadir al archivo json las imágenes aun no añadidas que tienen asociado un archivo "ogimg.info"
# (no sé qué imágenes son estas, pero de alguna forma están basadas en directorios):
print("Checking dir images...")
check_dirs()
# Llamamos a la función "remove_from_json", para eliminar del archivo json las imágenes que fueron eliminadas del repositorio:
# Llamamos a la función "remove_from_json", para eliminar del archivo json las imágenes que fueron eliminadas del repositorio
# (solo si el archivo tiene contenido, o dará error):
if os.path.getsize(info_file) > 0:
print("Removing deleted images...")
remove_from_json()
# Actualizamos la información de la papelera, ejecutando el script "updateTrashInfo.py"
# (solo si el archivo tiene contenido, o dará error):
# Actualizamos la información de la papelera, ejecutando el script "updateTrashInfo.py":
print("Updating Trash Info...")
update_trash_info()

View File

@ -58,7 +58,7 @@ def create_empty_json():
Evidentemente, solo es llamada cuando no existe el archivo.
"""
# Creamos un diccionario con la estructura básica que debe tener el archivo json:
json_data = {"directory": trash_path, "images": [], "ous": []}
json_data = {"directory": trash_path, "images": []}
# Abrimos el archivo json en modo escritura (creándolo si no existe, como es el caso),
# y le añadimos la estructura almacenada en el diccionario "json_data":
@ -68,16 +68,16 @@ def create_empty_json():
def check_files():
""" Esta función recorre el directorio de imágenes, para buscar archivos con extensiones ".img" o ".dsk".
""" Esta función recorre el directorio de papelera de imágenes, para buscar archivos con extensión ".img".
Llama a la función "add_to_json" para que esta añada información de las imágenes no bloqueadas (sin archivo ".lock"),
que además tengan un archivo ".info.checked" asociado (siempre que este no se haya modificado antes que la propia imagen).
"""
# Iteramos recursivamente todos los archivos y directorios de "/opt/opengnsys/images_trash",
# Iteramos recursivamente todos los archivos y directorios de "/opt/opengnsys/ogrepository/images_trash",
# y luego iteramos todos los archivos encontrados (en una iteración anidada):
for root, dirs, files in os.walk(trash_path):
for file in files:
# Si la imagen actual tiene extensión ".img" o ".dsk", construimos la ruta completa ("img_path"):
if file.endswith((".img", ".dsk")):
# Si la imagen actual tiene extensión ".img", construimos la ruta completa ("img_path"):
if file.endswith(".img"):
img_path = os.path.join(root, file)
# Si existe un archivo ".lock" asociado a la imagen actual, pasamos a la siguiente:
if os.path.exists(f"{img_path}.lock"):
@ -107,60 +107,12 @@ def check_files():
def check_dirs():
""" Esta función recorre el directorio de imágenes, para buscar archivos con nombre "ogimg.info".
Llama a la función "add_to_json" para que esta añada información de las imágenes no bloqueadas (sin archivo ".lock"),
que además tengan un archivo "ogimg.info" asociado (pero no que tipo de imágenes son esas).
"""
# Iteramos recursivamente todos los archivos y directorios de "/opt/opengnsys/images_trash",
# y luego iteramos todos los archivos encontrados (en una iteración anidada):
for root, dirs, files in os.walk(trash_path):
for file in files:
# Si el nombre del archivo actual es "ogimg.info", construimos su ruta completa ("info_path"), y la ruta del directorio ("img_path"):
if file == "ogimg.info":
info_path = os.path.join(root, file)
img_path = os.path.dirname(info_path)
# Si existe un archivo ".lock" asociado a la imagen actual, o si la ruta coincide con "trash_path", pasamos a la siguiente:
if img_path == trash_path or os.path.exists(f"{img_path}.lock"):
continue
# Almacenamos el contenido del archivo "ogimg.info", en la variable "lines":
with open(info_path, 'r') as file:
lines = file.readlines()
# Iteramos las lineas obtenidas, para extraer el tipo de sistema de archivos ("fstype") y el tamaño de los datos ("sizedata"),
# y con ello construimos una cadena "rsync::{fstype}:{sizedata}:" (que almacenamos en "data"):
for line in lines:
if line.startswith("# fstype"):
fstype = line.split("=")[1].strip()
elif line.startswith("# sizedata"):
sizedata = line.split("=")[1].strip()
info_data = f"rsync::{fstype}:{sizedata}:"
# Almacenamos el contenido de los archivos ".size", ".sum" y ".full.sum":
with open(f"{img_path}.size", 'r') as file:
size = file.read().strip('\n')
with open(f"{img_path}.sum", 'r') as file:
_sum = file.read().strip('\n')
with open(f"{img_path}.full.sum", 'r') as file:
fullsum = file.read().strip('\n')
# Llamamos a la función "add_to_json", para que inserte la información de la imagen en el archivo json
# (pasándole el nombre de la imagen, el tipo "dir"", y los datos extraídos del archivo "ogimg.info"):
img_name = os.path.relpath(img_path, trash_path)
add_to_json(img_name, "dir", info_data, size, _sum, fullsum)
def add_to_json(image_name, image_type, data, size, _sum, fullsum):
""" Esta función añade al archivo "trashinfo.json" la información de las imágenes que aun no ha sido introducida en él (imágenes eliminadas recientemente, básicamente).
El procedimiento es diferente para las imágenes "normales" y para las imágenes basadas en OU.
"""
# Almacenamos el contenido de la variable "data" (del tipo "PARTCLONE:LZOP:EXTFS:8500000:Ubuntu_20") en variables separadas:
clonator, compressor, fstype, datasize, client = data.split(":")
# Si la imagen está dentro de una OU (directorio), extraemos el nombre de la OU y de la imagen:
ou_name = None
if '/' in image_name:
ou_name = os.path.dirname(image_name)
image_name = os.path.basename(image_name)
# Creamos un diccionario con los datos de la imagen, que luego insertaremos en el json:
json_data = {
"name": image_name,
@ -180,44 +132,24 @@ def add_to_json(image_name, image_type, data, size, _sum, fullsum):
with open(info_file, 'r') as file:
info_data = json.load(file)
else:
info_data = {"directory": trash_path, "images": [], "ous": []}
info_data = {"directory": trash_path, "images": []}
# Comprobamos si las claves "info_data" (o sea, del archivo json) son las correctas:
if set(info_data.keys()) == {"directory", "images", "ous"}:
if set(info_data.keys()) == {"directory", "images"}:
# Actualizamos la información de las imágenes "normales" (no basadas en OU):
if ou_name is None:
img_index = next((i for i, img in enumerate(info_data["images"]) if img["name"] == image_name), None)
if img_index is not None:
# Update if image data changes
if info_data["images"][img_index] != json_data:
info_data["images"][img_index] = json_data
else:
# Append a new entry
info_data["images"].append(json_data)
# Actualizamos la información de las imágenes basadas en OU:
# Actualizamos la información de las imágenes:
img_index = next((i for i, img in enumerate(info_data["images"]) if img["name"] == image_name), None)
if img_index is not None:
# Update if image data changes
if info_data["images"][img_index] != json_data:
info_data["images"][img_index] = json_data
else:
ou_index = next((i for i, ou in enumerate(info_data["ous"]) if ou["subdir"] == ou_name), None)
if ou_index is None:
# Append a new OU entry
info_data["ous"].append({"subdir": ou_name, "images": [json_data]})
else:
img_index = next((i for i, img in enumerate(info_data["ous"][ou_index]["images"]) if img["name"] == image_name), None)
if img_index is not None:
# Update if image data changes
if info_data["ous"][ou_index]["images"][img_index] != json_data:
info_data["ous"][ou_index]["images"][img_index] = json_data
else:
# Append a new entry
info_data["ous"][ou_index]["images"].append(json_data)
# Append a new entry
info_data["images"].append(json_data)
# Si las claves de "info_data" no son las correctas, creamos toda la estructura:
else:
if ou_name is None:
info_data = {"directory": trash_path, "images": [json_data], "ous": []}
else:
info_data = {"directory": trash_path, "images": [], "ous": [{"subdir": ou_name, "images": [json_data]}]}
info_data = {"directory": trash_path, "images": [json_data], "ous": []}
# Sobreescribimos el archivo "trashinfo.json", con el contenido de "info_data" (que estará actualizado):
with open(info_file, 'w') as file:
@ -244,23 +176,6 @@ def remove_from_json():
if not os.path.exists(img_path) and not os.path.exists(f"{img_path}.lock"):
json_data["images"].pop(i)
# Iteramos las imágenes de la clave "ous" de "json_data", construimos sus rutas y comprobamos su existencia
# (si no existen, las eliminamos de "json_data"):
for j, ou in enumerate(json_data.get("ous", [])):
ou_name = ou["subdir"]
ou_path = os.path.join(trash_path, ou_name)
if not os.path.exists(ou_path):
json_data["ous"].pop(j)
else:
for i, image in enumerate(ou.get("images", [])):
img_name = image["name"]
img_type = image["type"]
if img_type != "dir":
img_name = f"{img_name}.{img_type}"
img_path = os.path.join(ou_path, img_name)
if not os.path.exists(img_path) and not os.path.exists(f"{img_path}.lock"):
ou["images"].pop(i)
# Sobreescribimos el archivo "trashinfo.json", con el contenido de "json_data"
# (una vez eliminadas las imágenes inexistentes):
with open(info_file, 'w') as file:
@ -295,16 +210,11 @@ def main():
if not os.access(info_file, os.W_OK):
raise PermissionError(f"Cannot access {info_file}")
# Llamamos a la función "check_files", para añadir al archivo json las imágenes ".img" o ".dsk" aun no añadidas
# Llamamos a la función "check_files", para añadir al archivo json las imágenes aun no añadidas
# (que son las que tienen asociado un archivo ".info.checked"):
print("Checking file images...")
check_files()
# Llamamos a la función "check_dirs", para añadir al archivo json las imágenes aun no añadidas que tienen asociado un archivo "ogimg.info"
# (no sé qué imágenes son estas, pero de alguna forma están basadas en directorios):
print("Checking dir images...")
check_dirs()
# Llamamos a la función "remove_from_json", para eliminar del archivo json las imágenes que ya no están en la papelera
# (solo si el archivo tiene contenido, o dará error):
if os.path.getsize(info_file) > 0: