Compare commits

..

3 Commits

Author SHA1 Message Date
Nicolas Arenas 1e601c2dc3 Updates CHANAGELOG.md 2025-03-18 08:36:17 +01:00
Nicolas Arenas 3ae1a3a592 Add changelog 2025-03-18 07:39:38 +01:00
Nicolas Arenas 5a8fed3c79 Add Jenkinsfile for deb package
ogrepository/pipeline/head This commit looks good Details
2025-03-18 01:49:54 +01:00
23 changed files with 956 additions and 4047 deletions

View File

@ -1,266 +1,156 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.10.4] - 2025-09-30
### Fixed
- Set safe.directory just once
## [0.10.3] - 2025-09-18
### Changed
- Create tags via a query to the forgejo API
## [0.10.2] - 2025-09-01
### Fixed
- Corregida la logica en el endpoint create torrent sum
- Mejoras en los mensajes de logs
- Mejoras en la validación de los archivos info e info.checked
## [0.10.1] - 2025-08-25
### Fixed
- Import images problems when there is not info.checked file (#2723, #2726)
- Improves logging (#2727)
## [0.10.0] - 2025-07-07
### Added
- OgGit functionality (#2371, #2363, #2363, #2317)
### Removed
- Removed unused BitTorrent-related packages and logic
## [0.9.0] - 2025-06-25
### Added
- Changed old tools for tools non dependant of Pyhton2 in repo
- mktorrent to handle creation of torrent files
- aria2c as torrent client for initial seeding
- opentracker as torrent tracker tool
## [0.8.2] - 2025-06-01
### Changed
- Modified sudoersfile to start torrent
## [0.8.1] - 2025-04-01
### Changed
- Add sudo to cancel transfers endpoints (#1796)
## [0.8.0] - 2025-03-25
### Added
- Rename Image functionality (#1733)
## [0.7.3] - 2025-03-19
### Changed
- Fix permissions problem and authorized_keys file in debian package
## [0.7.2] - 2025-03-19
### Changed
- Update CHANGELOG.md
## [0.7.1] - 2025-03-19
### Changed
- Updated Jenkinsfile for publishing packages (#1313)
## [0.7.0] - 2025-03-18
### Added
- Image to Virtual Disk conversion (#1689)
## [0.6.4] - 2025-03-13
### Changed
### Added
- Virtual Disk to Image conversion improvement (#1701)
- Merge pull request 'refs #1701 - 'convertVMtoIMG.py' improvement' (#27) from add_python_scripts into main
## [0.6.3] - 2025-03-12
### Fixed
### Added
- Virtual Disk to Image conversion fix (#1701)
- Merge pull request 'refs #1701 - Fix script convertVMtoIMG.py' (#26) from add_python_scripts into main
## [0.6.2] - 2025-03-10
### Added
- ogGit Install Status info (#1681)
- Merge pull request 'refs #1681 - Add ogGit install status' (#25) from add_python_scripts into main
## [0.6.1] - 2025-03-05
### Changed
### Added
- Cancel Transfers scripts improvement (#1642)
- Merge pull request 'refs #1642 - Modify Cancel Transfers scripts' (#24) from add_python_scripts into main
## [0.6.0] - 2025-03-03
### Added
- Virtual Disk to Image conversion (#1525)
- Merge pull request 'refs #1525 - Add Convert VM to IMG' (#23) from add_python_scripts into main
## [0.5.23] - 2025-02-20
### Changed
### Added
- Backup Image improvement (#1530)
- Merge pull request 'refs #1530 - Add 'backupImage.py' and related endpoint' (#22) from add_python_scripts into main
## [0.5.22] - 2025-02-20
### Added
- Backup Image (#1530)
- Merge pull request 'refs #1530 - Add 'backupImage.py' and related endpoint' (#22) from add_python_scripts into main
## [0.5.20] - 2025-02-11
### Changed
### Added
- Paramiko SSH Client parameters improvement (#1482)
- Merge pull request 'refs #1482 - Modify Paramiko SSH Client parameters' (#21) from add_python_scripts into main
## [0.5.19] - 2025-02-06
### Fixed
### Added
- Script corrections (#1437)
- Merge pull request 'add_python_scripts' (#20) from add_python_scripts into main
## [0.5.18] - 2025-02-03
### Fixed
### Added
- Script corrections (#1437)
- Merge pull request 'refs #1437 - Scripts corrections' (#19) from add_python_scripts into main
## [0.5.17] - 2025-02-03
### Removed
### Added
- Remove unnecessary sudo calls (#1437)
- Merge pull request 'refs #1437 - Remove unnecessary sudo calls' (#18) from add_python_scripts into main
## [0.5.16] - 2025-01-31
### Added
- API tests (#1378)
### Changed
- API improvement (#1378)
- Merge pull request 'refs #1378 - Add API tests and modify API' (#17) from add_python_scripts into main
## [0.5.15] - 2025-01-28
### Fixed
### Added
- API tests errors fixes (#1378)
- Merge pull request 'refs #1378 - Fix API tests errors' (#16) from add_python_scripts into main
## [0.5.14] - 2025-01-24
### Added
- API tests (#1346)
- Merge pull request 'refs #1346 - Add API tests' (#15) from add_python_scripts into main
## [0.5.13] - 2025-01-10
### Removed
### Added
- Remove recursive image search (#1335)
- Merge pull request 'refs #1335 - Supress recursive image search' (#14) from add_python_scripts into main
## [0.5.12] - 2024-12-17
### Changed
### Added
- Modify logs format (#1294)
- Merge pull request 'refs #1294 - Modify logs format' (#13) from add_python_scripts into main
## [0.5.11] - 2024-12-12
### Changed
### Added
- API logs improvement (#1242)
- Merge pull request 'refs #1242 - API logs improvement' (#12) from add_python_scripts into main
## [0.5.10] - 2024-12-02
### Changed
### Added
- API and Script logs improvement (#631)
- Merge pull request 'refs #631 - Modify logs in API and some scripts' (#11) from add_python_scripts into main
## [0.5.9] - 2024-11-29
### Added
- Script journalctl logs (#631)
- Merge pull request 'refs #631 - Add journalctl logs to scripts' (#10) from add_python_scripts into main
## [0.5.8] - 2024-11-28
### Added
- API journalctl logs (#631)
- Merge pull request 'refs #631 - Add journalctl logs to API' (#9) from add_python_scripts into main
## [0.5.7] - 2024-11-26
### Added
- 'python3-request' packet
## [0.5.6] - 2024-11-22
### Changed
### Added
- API improvements (#631)
- Merge pull request 'refs #631 - More API improvements' (#8) from add_python_scripts into main
## [0.5.5] - 2024-11-21
### Changed
### Added
- API improvements (#631)
- Merge pull request 'refs #631 - API improvement' (#7) from add_python_scripts into main
## [0.5.4] - 2024-11-20
### Changed
### Added
- API and Script improvements (#631)
- Merge pull request 'add_python_scripts' (#6) from add_python_scripts into main
## [0.5.3] - 2024-11-18
### Changed
- Update Documentation (#631)
## [0.5.2] - 2024-11-18
### Changed
- API improvements (#631)
## [0.5.1] - 2024-11-15
### Changed
- API improvements (#610)
## [0.5.0] - 2024-11-15
### Changed
- Update Documentation (#1084)

View File

@ -49,72 +49,29 @@ pipeline {
}
}
stage('Generate Changelog (Nightly)'){
when {
branch 'main'
}
steps {
script {
def devName = params.DEV_NAME ? params.DEV_NAME : env.DEFAULT_DEV_NAME
def devEmail = params.DEV_EMAIL ? params.DEV_EMAIL : env.DEFAULT_DEV_EMAIL
generateDebianChangelog(env.BUILD_DIR, devName, devEmail,"nightly")
}
}
}
stage('Build') {
steps {
script {
construirPaquete(env.BUILD_DIR, "../artifacts", "172.17.8.68", "/var/tmp/opengnsys/debian-repo/ogrepository")
}
}
}
stage ('Publish to Debian Repository') {
when {
expression {
return env.TAG_NAME != null
}
}
agent { label 'debian-repo' }
steps {
script {
// Construir el patrón de versión esperado en el nombre del paquete
def versionPattern = "${env.TAG_NAME}-${env.BUILD_NUMBER}"
publicarEnAptly('/var/tmp/opengnsys/debian-repo/ogrepository', 'opengnsys-devel', versionPattern)
}
}
}
stage ('Publish to Debian Repository (Nightly)') {
when {
branch 'main'
}
agent { label 'debian-repo' }
steps {
script {
// Construir el patrón de versión esperado en el nombre del paquete
def versionPattern = "-${env.BUILD_NUMBER}~nightly"
publicarEnAptly('/var/tmp/opengnsys/debian-repo/ogrepository', 'nightly', versionPattern)
dir("${env.BUILD_DIR}") {
sh '''
dpkg-buildpackage -us -uc
mkdir -p ../artifacts && mv ../*.deb ../*.changes ../*.buildinfo ../artifacts/
ssh aptly@172.17.8.68 "rm -rf /var/tmp/opengnsys/debian-repo && mkdir -p /var/tmp/opengnsys/debian-repo"
scp -r ../artifacts/* aptly@172.17.8.68:/var/tmp/opengnsys/debian-repo/
'''
}
}
}
}
post {
success {
script {
// Solo lanzar cuando el build sea exitoso y en la rama main
if (env.BRANCH_NAME == 'main') {
build job: 'Aptly publish nightly repository',
wait: false,
parameters: [
string(name: 'TRIGGERED_BY', value: "${env.JOB_NAME}-${env.BUILD_NUMBER}")
]
}
}
}
always {
notifyBuildStatus('opengnsys@qindel.com')
notifyBuildStatus('narenas@qindel.com')
}
}
}
// stage ('Publish to Debian Repository') {
// agent { label 'debian-repo' }
// steps {
// sh "aptly repo add opengnsys-devel /var/tmp/opengnsys/debian-repo/*.deb"
// }
// }

536
README.md
View File

@ -62,21 +62,19 @@ El presente documento detalla los endpoints de la API, con sus respectivos pará
6. [Eliminar una Imagen](#eliminar-una-imagen) - `DELETE /ogrepository/v1/images/{ID_img}?method={method}`
7. [Recuperar una Imagen](#recuperar-una-imagen) - `POST /ogrepository/v1/trash/images`
8. [Eliminar una Imagen de la Papelera](#eliminar-una-imagen-de-la-papelera) - `DELETE /ogrepository/v1/trash/images/{ID_img}`
9. [Enviar una Imagen mediante UDPcast](#enviar-una-imagen-mediante-udpcast) - `POST /ogrepository/v1/udpcast`
10. [Ver Estado de Transmisiones UDPcast](#ver-estado-de-transmisiones-udpcast) - `GET /ogrepository/v1/udpcast`
11. [Cancelar Transmisión UDPcast](#cancelar-transmisión-udpcast) - `DELETE /ogrepository/v1/udpcast/images/{ID_img}`
12. [Enviar una Imagen mediante UFTP](#enviar-una-imagen-mediante-uftp) - `POST /ogrepository/v1/uftp`
13. [Ver Estado de Transmisiones UFTP](#ver-estado-de-transmisiones-uftp) - `GET /ogrepository/v1/uftp`
14. [Cancelar Transmisión UFTP](#cancelar-transmisión-uftp) - `DELETE /ogrepository/v1/uftp/images/{ID_img}`
15. [Enviar una Imagen mediante P2P](#enviar-una-imagen-mediante-p2p) - `POST /ogrepository/v1/p2p`
16. [Cancelar Transmisiones P2P](#cancelar-transmisiones-p2p) - `DELETE /ogrepository/v1/p2p`
17. [Transferir una Imagen entre Repositorios](#transferir-una-imagen-entre-repositorios) - `POST /ogrepository/v1/repo/images`
18. [Hacer Backup de una Imagen](#hacer-backup-de-una-imagen) - `PUT /ogrepository/v1/repo/images`
19. [Convertir Imagen Virtual a Imagen OpenGnsys](#convertir-imagen-virtual-a-imagen-opengnsys) - `POST /ogrepository/v1/images/virtual`
20. [Convertir Imagen OpenGnsys a Imagen Virtual](#convertir-imagen-opengnsys-a-imagen-virtual) - `PUT /ogrepository/v1/images/virtual`
21. [Renombrar una Imagen](#renombrar-una-imagen) - `POST /ogrepository/v1/images/rename`
22. [Crear archivos auxiliares](#crear-archivos-auxiliares) - `POST /ogrepository/v1/images/torrentsum`
23. [Enviar paquete Wake On Lan](#enviar-paquete-wake-on-lan) - `POST /ogrepository/v1/wol`
9. [Transferir una Imagen entre Repositorios](#transferir-una-imagen-entre-repositorios) - `POST /ogrepository/v1/repo/images`
10. [Hacer Backup de una Imagen](#hacer-backup-de-una-imagen) - `PUT /ogrepository/v1/repo/images`
11. [Crear archivos auxiliares](#crear-archivos-auxiliares) - `POST /ogrepository/v1/images/torrentsum`
12. [Convertir Imagen Virtual](#convertir-imagen-virtual) - `POST /ogrepository/v1/images/virtual`
13. [Enviar paquete Wake On Lan](#enviar-paquete-wake-on-lan) - `POST /ogrepository/v1/wol`
14. [Enviar una Imagen mediante UDPcast](#enviar-una-imagen-mediante-udpcast) - `POST /ogrepository/v1/udpcast`
15. [Enviar una Imagen mediante UFTP](#enviar-una-imagen-mediante-uftp) - `POST /ogrepository/v1/uftp`
16. [Enviar una Imagen mediante P2P](#enviar-una-imagen-mediante-p2p) - `POST /ogrepository/v1/p2p`
17. [Ver Estado de Transmisiones UDPcast](#ver-estado-de-transmisiones-udpcast) - `GET /ogrepository/v1/udpcast`
18. [Ver Estado de Transmisiones UFTP](#ver-estado-de-transmisiones-uftp) - `GET /ogrepository/v1/uftp`
19. [Cancelar Transmisión UDPcast](#cancelar-transmisión-udpcast) - `DELETE /ogrepository/v1/udpcast/images/{ID_img}`
20. [Cancelar Transmisión UFTP](#cancelar-transmisión-uftp) - `DELETE /ogrepository/v1/uftp/images/{ID_img}`
21. [Cancelar Transmisiones P2P](#cancelar-transmisiones-p2p) - `DELETE /ogrepository/v1/p2p`
---
### Obtener Información de Estado de ogRepository
@ -369,210 +367,6 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/t
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se eliminó exitosamente.
---
### Enviar una Imagen mediante UDPcast
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) 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`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **port**: Puerto Multicast.
- **method**: Modalidad half-duplex o full-duplex ("half" o "full").
- **ip**: IP Multicast.
- **bitrate**: Velocidad de transmisión (en Mbps).
- **nclients**: Número mínimo de clientes.
- **maxtime**: Tiempo máximo de espera.
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "port":"9000", "method":"full", "ip":"239.194.17.2", "bitrate":"70M", "nclients":"20", "maxtime":"120"}' http://example.com/ogrepository/v1/udpcast
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante UDPcast.
---
### Ver Estado de Transmisiones UDPcast
Se devolverá el pid de los procesos de transferencias UDPcast activas, y sus imágenes asociadas (con nombre e ID), en formato JSON, o un mensaje informativo si no hay procesos activos, o si se produce un error.
Se puede hacer con el script "**getUDPcastInfo.py**", que debe ser llamado por el endpoint.
**URL:** `/ogrepository/v1/udpcast`
**Método HTTP:** GET
**Ejemplo de Solicitud:**
```bash
curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/udpcast
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al comprobar las transmisiones UDPcast.
- **Código 400 Bad Request:** No se han encontrado transmisiones UDPcast activas.
- **Código 200 OK:** La información de las transmisiones UDPcast activas se obtuvo exitosamente.
- **Contenido:** Información de las transmisiones UDPcast activas en formato JSON.
```json
{
"6720": {
"image_id": "22735b9070e4a8043371b8c6ae52b90d",
"image_name": "Ubuntu20.img"
},
"6721": {
"image_id": "9e7cd32c606ebe5bd39ba212ce7aeb02",
"image_name": "Windows10.img"
}
}
```
---
### Cancelar Transmisión UDPcast
Se cancelará la transmisión por UDPcast activa de la imagen especificada como parámetro, deteniendo el proceso "udp-sender" asociado a dicha imagen.
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) 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
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/udpcast/images/22735b9070e4a8043371b8c6ae52b90d
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UDPcast.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 400 Bad Request:** No hay transmisiones UDPcast activas para la imagen especificada.
- **Código 200 OK:** La transmisión UDPcast se ha cancelado exitosamente.
---
### Enviar una Imagen mediante UFTP
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) 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`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **port**: Puerto Multicast.
- **ip**: IP Unicast/Multicast.
- **bitrate**: Velocidad de transmisión (con "K" para Kbps, "M" para Mbps o "G" para Gbps).
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "port":"9000", "ip":"239.194.17.2", "bitrate":"1G"}' http://example.com/ogrepository/v1/uftp
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante UFTP.
---
### Ver Estado de Transmisiones UFTP
Se devolverá el pid de los procesos de transferencias UFTP activas, y sus imágenes asociadas (con nombre e ID), en formato JSON, o un mensaje informativo si no hay procesos activos, o si se produce un error.
Se puede hacer con el script "**getUFTPInfo.py**", que debe ser llamado por el endpoint.
**URL:** `/ogrepository/v1/uftp`
**Método HTTP:** GET
**Ejemplo de Solicitud:**
```bash
curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al comprobar las transmisiones UFTP.
- **Código 400 Bad Request:** No se han encontrado transmisiones UFTP activas.
- **Código 200 OK:** La información de las transmisiones UFTP activas se obtuvo exitosamente.
- **Contenido:** Información de las transmisiones UFTP activas en formato JSON.
```json
{
"3427": {
"image_id": "22735b9070e4a8043371b8c6ae52b90d",
"image_name": "Ubuntu20.img"
},
"4966": {
"image_id": "9e7cd32c606ebe5bd39ba212ce7aeb02",
"image_name": "Windows10.img"
}
}
```
---
### Cancelar Transmisión UFTP
Se cancelará la transmisión por UFTP activa de la imagen especificada como parámetro, deteniendo el proceso "uftp" asociado a dicha imagen.
Se puede hacer con el script "**stopUFTP.py**", que debe ser llamado por el endpoint.
**NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión) 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
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp/images/22735b9070e4a8043371b8c6ae52b90d
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UFTP.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 400 Bad Request:** No hay transmisiones UFTP activas para la imagen especificada.
- **Código 200 OK:** La transmisión UFTP se ha cancelado exitosamente.
---
### 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 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 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).
**URL:** `/ogrepository/v1/p2p`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d"}' http://example.com/ogrepository/v1/p2p
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al intentar enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante P2P.
---
### Cancelar Transmisiones P2P
Se cancelarán las transmisiones P2P activas en el ogRepository al que se envíe la orden, deteniendo los procesos "bttrack" y "btlaunchmany.bittornado".
Se puede hacer con el script "**stopP2P.py**", que debe ser llamado por el endpoint.
**NOTA**: No he encontrado la forma de detener la transmisión de una imagen concreta, ya que "bttrack" y "btlaunchmany.bittornado" hacen tracking y seed (respectivamente) de todos los torrents existentes en la raíz del directorio especificado.
**URL:** `/ogrepository/v1/p2p`
**Método HTTP:** DELETE
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/p2p
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar las transmisiones P2P.
- **Código 200 OK:** Las transmisiones P2P se han cancelado exitosamente.
---
### Transferir una Imagen entre Repositorios
@ -628,80 +422,6 @@ curl -X PUT -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
- **Código 400 Bad Request:** No se ha encontrado la imagen y/o el equipo remoto especificados.
- **Código 200 OK:** Se está haciendo backup de la imagen.
---
### Convertir Imagen Virtual a Imagen OpenGnsys
Se convertirá la imagen virtual especificada (que debe haberse copiado previamente en la ruta "opt/opengnsys/ogrepository/images_virtual") en una imagen "img" como las que se generan desde OpenGnsys (con "partclone" y "lzop").
Se puede hacer con el script "**convertVMtoIMG.py**", que debe ser llamado por el endpoint.
**NOTA**: El script requiere que se le pase el nombre de la imagen virtual (con extensión) como primer parámetro, y el sistema de archivos de la partición a clonar como segundo parámetro (en formato "blkid"). Estos parámetros 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 virtual se está convirtiendo, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/images/virtual`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **virtual_image**: Nombre de la imagen virtual (con extensión).
- **filesystem**: Sistema de archivos de la partición a clonar, en formato "blkid".
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"virtual_image":"UbuntuVM.vdi", "filesystem":"ext4"}' http://example.com/ogrepository/v1/images/virtual
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al convertir la imagen virtual.
- **Código 400 Bad Request:** No se ha encontrado la imagen virtual especificada.
- **Código 200 OK:** La imagen virtual se está convirtiendo.
---
### Convertir Imagen OpenGnsys a Imagen Virtual
Se convertirá la imagen "img" especificada en una imagen virtual con la extensión especificada ("vdi", "vmdk", etc), guardándola en la ruta "opt/opengnsys/ogrepository/images_virtual/export".
Se puede hacer con el script "**convertIMGtoVM.py**", que debe ser llamado por el endpoint.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, y la extensión del disco virtual destino ("vdi", "vmdk", etc) como segundo 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 extensión del disco virtual debe enviarse 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á convirtiendo a virtual, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/images/virtual`
**Método HTTP:** PUT
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **vm_extension**: Extensión del disco virtual destino ("vdi", "vmdk", etc).
**Ejemplo de Solicitud:**
```bash
curl -X PUT -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "vm_extension":"vdi"}' http://example.com/ogrepository/v1/images/virtual
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al convertir la imagen a virtual.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está convirtiendo a virtual.
---
### Renombrar una Imagen
Se renombrará la imagen especificada como primer parámetro (y todos sus archivos asociados), asignando el nombre especificado como segundo parámetro.
Se puede hacer con el script "**renameImage.py**", que debe ser llamado por el endpoint.
**NOTA**: El script requiere que se le pase el nombre de la imagen (sin extensión) como primer parámetro, y el nuevo nombre a asignar como segundo 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 el nuevo nombre a asignar debe enviarse en el JSON.
**URL:** `/ogrepository/v1/images/rename`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **image_new_name**: Nuevo nombre a asignar a la imagen.
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "image_new_name":"Ubuntu_BKP"}' http://example.com/ogrepository/v1/images/rename
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al renombrar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se ha renombrado exitosamente.
---
### Crear archivos auxiliares
@ -726,6 +446,31 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** Los archivos auxiliares se están creando.
---
### Convertir Imagen Virtual
Se convertirá la imagen virtual especificada (que debe haberse copiado previamente en la ruta "opt/opengnsys/ogrepository/images_virtual") en una imagen "img" como las que se generan desde OpenGnsys (con "partclone" y "lzop").
Se puede hacer con el script "**convertVMtoIMG.py**", que debe ser llamado por el endpoint.
**NOTA**: El script requiere que se le pase el nombre de la imagen virtual (con extensión) como primer parámetro, y el sistema de archivos de la partición a clonar como segundo parámetro (en formato "blkid"). Estos parámetros 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 virtual se está convirtiendo, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/images/virtual`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **virtual_image**: Nombre de la imagen virtual (con extensión).
- **filesystem**: Sistema de archivos de la partición a clonar, en formato "blkid".
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"virtual_image":"UbuntuVM.vdi", "filesystem":"ext4"}' http://example.com/ogrepository/v1/images/virtual
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al convertir la imagen virtual.
- **Código 400 Bad Request:** No se ha encontrado la imagen virtual especificada.
- **Código 200 OK:** La imagen virtual se está convirtiendo.
---
### Enviar paquete Wake On Lan
@ -749,4 +494,209 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
- **Código 500 Internal Server Error:** Ocurrió un error al enviar el paquete Wake On Lan.
- **Código 200 OK:** El paquete Wake On Lan se ha enviado exitosamente.
---
### Enviar una Imagen mediante UDPcast
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) 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`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **port**: Puerto Multicast.
- **method**: Modalidad half-duplex o full-duplex ("half" o "full").
- **ip**: IP Multicast.
- **bitrate**: Velocidad de transmisión (en Mbps).
- **nclients**: Número mínimo de clientes.
- **maxtime**: Tiempo máximo de espera.
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "port":"9000", "method":"full", "ip":"239.194.17.2", "bitrate":"70M", "nclients":"20", "maxtime":"120"}' http://example.com/ogrepository/v1/udpcast
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante UDPcast.
---
### Enviar una Imagen mediante UFTP
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) 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`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **port**: Puerto Multicast.
- **ip**: IP Unicast/Multicast.
- **bitrate**: Velocidad de transmisión (con "K" para Kbps, "M" para Mbps o "G" para Gbps).
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "port":"9000", "ip":"239.194.17.2", "bitrate":"1G"}' http://example.com/ogrepository/v1/uftp
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante UFTP.
---
### 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 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 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).
**URL:** `/ogrepository/v1/p2p`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d"}' http://example.com/ogrepository/v1/p2p
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al intentar enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante P2P.
---
### Ver Estado de Transmisiones UDPcast
Se devolverá el pid de los procesos de transferencias UDPcast activas, y sus imágenes asociadas (con nombre e ID), en formato JSON, o un mensaje informativo si no hay procesos activos, o si se produce un error.
Se puede hacer con el script "**getUDPcastInfo.py**", que debe ser llamado por el endpoint.
**URL:** `/ogrepository/v1/udpcast`
**Método HTTP:** GET
**Ejemplo de Solicitud:**
```bash
curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/udpcast
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al comprobar las transmisiones UDPcast.
- **Código 400 Bad Request:** No se han encontrado transmisiones UDPcast activas.
- **Código 200 OK:** La información de las transmisiones UDPcast activas se obtuvo exitosamente.
- **Contenido:** Información de las transmisiones UDPcast activas en formato JSON.
```json
{
"6720": {
"image_id": "22735b9070e4a8043371b8c6ae52b90d",
"image_name": "Ubuntu20.img"
},
"6721": {
"image_id": "9e7cd32c606ebe5bd39ba212ce7aeb02",
"image_name": "Windows10.img"
}
}
```
---
### Ver Estado de Transmisiones UFTP
Se devolverá el pid de los procesos de transferencias UFTP activas, y sus imágenes asociadas (con nombre e ID), en formato JSON, o un mensaje informativo si no hay procesos activos, o si se produce un error.
Se puede hacer con el script "**getUFTPInfo.py**", que debe ser llamado por el endpoint.
**URL:** `/ogrepository/v1/uftp`
**Método HTTP:** GET
**Ejemplo de Solicitud:**
```bash
curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al comprobar las transmisiones UFTP.
- **Código 400 Bad Request:** No se han encontrado transmisiones UFTP activas.
- **Código 200 OK:** La información de las transmisiones UFTP activas se obtuvo exitosamente.
- **Contenido:** Información de las transmisiones UFTP activas en formato JSON.
```json
{
"3427": {
"image_id": "22735b9070e4a8043371b8c6ae52b90d",
"image_name": "Ubuntu20.img"
},
"4966": {
"image_id": "9e7cd32c606ebe5bd39ba212ce7aeb02",
"image_name": "Windows10.img"
}
}
```
---
### Cancelar Transmisión UDPcast
Se cancelará la transmisión por UDPcast activa de la imagen especificada como parámetro, deteniendo el proceso "udp-sender" asociado a dicha imagen.
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) 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
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/udpcast/images/22735b9070e4a8043371b8c6ae52b90d
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UDPcast.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 400 Bad Request:** No hay transmisiones UDPcast activas para la imagen especificada.
- **Código 200 OK:** La transmisión UDPcast se ha cancelado exitosamente.
---
### Cancelar Transmisión UFTP
Se cancelará la transmisión por UFTP activa de la imagen especificada como parámetro, deteniendo el proceso "uftp" asociado a dicha imagen.
Se puede hacer con el script "**stopUFTP.py**", que debe ser llamado por el endpoint.
**NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión) 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
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp/images/22735b9070e4a8043371b8c6ae52b90d
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UFTP.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 400 Bad Request:** No hay transmisiones UFTP activas para la imagen especificada.
- **Código 200 OK:** La transmisión UFTP se ha cancelado exitosamente.
---
### Cancelar Transmisiones P2P
Se cancelarán las transmisiones P2P activas en el ogRepository al que se envíe la orden, deteniendo los procesos "bttrack" y "btlaunchmany.bittornado".
Se puede hacer con el script "**stopP2P.py**", que debe ser llamado por el endpoint.
**NOTA**: No he encontrado la forma de detener la transmisión de una imagen concreta, ya que "bttrack" y "btlaunchmany.bittornado" hacen tracking y seed (respectivamente) de todos los torrents existentes en la raíz del directorio especificado.
**URL:** `/ogrepository/v1/p2p`
**Método HTTP:** DELETE
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/p2p
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar las transmisiones P2P.
- **Código 200 OK:** Las transmisiones P2P se han cancelado exitosamente.
---

View File

@ -16,21 +16,19 @@ El presente documento detalla los endpoints de la API, con sus respectivos pará
6. [Eliminar una Imagen](#eliminar-una-imagen) - `DELETE /ogrepository/v1/images/{ID_img}?method={method}`
7. [Recuperar una Imagen](#recuperar-una-imagen) - `POST /ogrepository/v1/trash/images`
8. [Eliminar una Imagen de la Papelera](#eliminar-una-imagen-de-la-papelera) - `DELETE /ogrepository/v1/trash/images/{ID_img}`
9. [Enviar una Imagen mediante UDPcast](#enviar-una-imagen-mediante-udpcast) - `POST /ogrepository/v1/udpcast`
10. [Ver Estado de Transmisiones UDPcast](#ver-estado-de-transmisiones-udpcast) - `GET /ogrepository/v1/udpcast`
11. [Cancelar Transmisión UDPcast](#cancelar-transmisión-udpcast) - `DELETE /ogrepository/v1/udpcast/images/{ID_img}`
12. [Enviar una Imagen mediante UFTP](#enviar-una-imagen-mediante-uftp) - `POST /ogrepository/v1/uftp`
13. [Ver Estado de Transmisiones UFTP](#ver-estado-de-transmisiones-uftp) - `GET /ogrepository/v1/uftp`
14. [Cancelar Transmisión UFTP](#cancelar-transmisión-uftp) - `DELETE /ogrepository/v1/uftp/images/{ID_img}`
15. [Enviar una Imagen mediante P2P](#enviar-una-imagen-mediante-p2p) - `POST /ogrepository/v1/p2p`
16. [Cancelar Transmisiones P2P](#cancelar-transmisiones-p2p) - `DELETE /ogrepository/v1/p2p`
17. [Transferir una Imagen entre Repositorios](#transferir-una-imagen-entre-repositorios) - `POST /ogrepository/v1/repo/images`
18. [Hacer Backup de una Imagen](#hacer-backup-de-una-imagen) - `PUT /ogrepository/v1/repo/images`
19. [Convertir Imagen Virtual a Imagen OpenGnsys](#convertir-imagen-virtual-a-imagen-opengnsys) - `POST /ogrepository/v1/images/virtual`
20. [Convertir Imagen OpenGnsys a Imagen Virtual](#convertir-imagen-opengnsys-a-imagen-virtual) - `PUT /ogrepository/v1/images/virtual`
21. [Renombrar una Imagen](#renombrar-una-imagen) - `POST /ogrepository/v1/images/rename`
22. [Crear archivos auxiliares](#crear-archivos-auxiliares) - `POST /ogrepository/v1/images/torrentsum`
23. [Enviar paquete Wake On Lan](#enviar-paquete-wake-on-lan) - `POST /ogrepository/v1/wol`
9. [Transferir una Imagen entre Repositorios](#transferir-una-imagen-entre-repositorios) - `POST /ogrepository/v1/repo/images`
10. [Hacer Backup de una Imagen](#hacer-backup-de-una-imagen) - `PUT /ogrepository/v1/repo/images`
11. [Crear archivos auxiliares](#crear-archivos-auxiliares) - `POST /ogrepository/v1/images/torrentsum`
12. [Convertir Imagen Virtual](#convertir-imagen-virtual) - `POST /ogrepository/v1/images/virtual`
13. [Enviar paquete Wake On Lan](#enviar-paquete-wake-on-lan) - `POST /ogrepository/v1/wol`
14. [Enviar una Imagen mediante UDPcast](#enviar-una-imagen-mediante-udpcast) - `POST /ogrepository/v1/udpcast`
15. [Enviar una Imagen mediante UFTP](#enviar-una-imagen-mediante-uftp) - `POST /ogrepository/v1/uftp`
16. [Enviar una Imagen mediante P2P](#enviar-una-imagen-mediante-p2p) - `POST /ogrepository/v1/p2p`
17. [Ver Estado de Transmisiones UDPcast](#ver-estado-de-transmisiones-udpcast) - `GET /ogrepository/v1/udpcast`
18. [Ver Estado de Transmisiones UFTP](#ver-estado-de-transmisiones-uftp) - `GET /ogrepository/v1/uftp`
19. [Cancelar Transmisión UDPcast](#cancelar-transmisión-udpcast) - `DELETE /ogrepository/v1/udpcast/images/{ID_img}`
20. [Cancelar Transmisión UFTP](#cancelar-transmisión-uftp) - `DELETE /ogrepository/v1/uftp/images/{ID_img}`
21. [Cancelar Transmisiones P2P](#cancelar-transmisiones-p2p) - `DELETE /ogrepository/v1/p2p`
---
### Obtener Información de Estado de ogRepository
@ -323,210 +321,6 @@ curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/t
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se eliminó exitosamente.
---
### Enviar una Imagen mediante UDPcast
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) 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`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **port**: Puerto Multicast.
- **method**: Modalidad half-duplex o full-duplex ("half" o "full").
- **ip**: IP Multicast.
- **bitrate**: Velocidad de transmisión (en Mbps).
- **nclients**: Número mínimo de clientes.
- **maxtime**: Tiempo máximo de espera.
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "port":"9000", "method":"full", "ip":"239.194.17.2", "bitrate":"70M", "nclients":"20", "maxtime":"120"}' http://example.com/ogrepository/v1/udpcast
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante UDPcast.
---
### Ver Estado de Transmisiones UDPcast
Se devolverá el pid de los procesos de transferencias UDPcast activas, y sus imágenes asociadas (con nombre e ID), en formato JSON, o un mensaje informativo si no hay procesos activos, o si se produce un error.
Se puede hacer con el script "**getUDPcastInfo.py**", que debe ser llamado por el endpoint.
**URL:** `/ogrepository/v1/udpcast`
**Método HTTP:** GET
**Ejemplo de Solicitud:**
```bash
curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/udpcast
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al comprobar las transmisiones UDPcast.
- **Código 400 Bad Request:** No se han encontrado transmisiones UDPcast activas.
- **Código 200 OK:** La información de las transmisiones UDPcast activas se obtuvo exitosamente.
- **Contenido:** Información de las transmisiones UDPcast activas en formato JSON.
```json
{
"6720": {
"image_id": "22735b9070e4a8043371b8c6ae52b90d",
"image_name": "Ubuntu20.img"
},
"6721": {
"image_id": "9e7cd32c606ebe5bd39ba212ce7aeb02",
"image_name": "Windows10.img"
}
}
```
---
### Cancelar Transmisión UDPcast
Se cancelará la transmisión por UDPcast activa de la imagen especificada como parámetro, deteniendo el proceso "udp-sender" asociado a dicha imagen.
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) 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
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/udpcast/images/22735b9070e4a8043371b8c6ae52b90d
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UDPcast.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 400 Bad Request:** No hay transmisiones UDPcast activas para la imagen especificada.
- **Código 200 OK:** La transmisión UDPcast se ha cancelado exitosamente.
---
### Enviar una Imagen mediante UFTP
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) 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`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **port**: Puerto Multicast.
- **ip**: IP Unicast/Multicast.
- **bitrate**: Velocidad de transmisión (con "K" para Kbps, "M" para Mbps o "G" para Gbps).
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "port":"9000", "ip":"239.194.17.2", "bitrate":"1G"}' http://example.com/ogrepository/v1/uftp
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante UFTP.
---
### Ver Estado de Transmisiones UFTP
Se devolverá el pid de los procesos de transferencias UFTP activas, y sus imágenes asociadas (con nombre e ID), en formato JSON, o un mensaje informativo si no hay procesos activos, o si se produce un error.
Se puede hacer con el script "**getUFTPInfo.py**", que debe ser llamado por el endpoint.
**URL:** `/ogrepository/v1/uftp`
**Método HTTP:** GET
**Ejemplo de Solicitud:**
```bash
curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al comprobar las transmisiones UFTP.
- **Código 400 Bad Request:** No se han encontrado transmisiones UFTP activas.
- **Código 200 OK:** La información de las transmisiones UFTP activas se obtuvo exitosamente.
- **Contenido:** Información de las transmisiones UFTP activas en formato JSON.
```json
{
"3427": {
"image_id": "22735b9070e4a8043371b8c6ae52b90d",
"image_name": "Ubuntu20.img"
},
"4966": {
"image_id": "9e7cd32c606ebe5bd39ba212ce7aeb02",
"image_name": "Windows10.img"
}
}
```
---
### Cancelar Transmisión UFTP
Se cancelará la transmisión por UFTP activa de la imagen especificada como parámetro, deteniendo el proceso "uftp" asociado a dicha imagen.
Se puede hacer con el script "**stopUFTP.py**", que debe ser llamado por el endpoint.
**NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión) 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
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp/images/22735b9070e4a8043371b8c6ae52b90d
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UFTP.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 400 Bad Request:** No hay transmisiones UFTP activas para la imagen especificada.
- **Código 200 OK:** La transmisión UFTP se ha cancelado exitosamente.
---
### 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 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 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).
**URL:** `/ogrepository/v1/p2p`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d"}' http://example.com/ogrepository/v1/p2p
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al intentar enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante P2P.
---
### Cancelar Transmisiones P2P
Se cancelarán las transmisiones P2P activas en el ogRepository al que se envíe la orden, deteniendo los procesos "bttrack" y "btlaunchmany.bittornado".
Se puede hacer con el script "**stopP2P.py**", que debe ser llamado por el endpoint.
**NOTA**: No he encontrado la forma de detener la transmisión de una imagen concreta, ya que "bttrack" y "btlaunchmany.bittornado" hacen tracking y seed (respectivamente) de todos los torrents existentes en la raíz del directorio especificado.
**URL:** `/ogrepository/v1/p2p`
**Método HTTP:** DELETE
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/p2p
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar las transmisiones P2P.
- **Código 200 OK:** Las transmisiones P2P se han cancelado exitosamente.
---
### Transferir una Imagen entre Repositorios
@ -582,80 +376,6 @@ curl -X PUT -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
- **Código 400 Bad Request:** No se ha encontrado la imagen y/o el equipo remoto especificados.
- **Código 200 OK:** Se está haciendo backup de la imagen.
---
### Convertir Imagen Virtual a Imagen OpenGnsys
Se convertirá la imagen virtual especificada (que debe haberse copiado previamente en la ruta "opt/opengnsys/ogrepository/images_virtual") en una imagen "img" como las que se generan desde OpenGnsys (con "partclone" y "lzop").
Se puede hacer con el script "**convertVMtoIMG.py**", que debe ser llamado por el endpoint.
**NOTA**: El script requiere que se le pase el nombre de la imagen virtual (con extensión) como primer parámetro, y el sistema de archivos de la partición a clonar como segundo parámetro (en formato "blkid"). Estos parámetros 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 virtual se está convirtiendo, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/images/virtual`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **virtual_image**: Nombre de la imagen virtual (con extensión).
- **filesystem**: Sistema de archivos de la partición a clonar, en formato "blkid".
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"virtual_image":"UbuntuVM.vdi", "filesystem":"ext4"}' http://example.com/ogrepository/v1/images/virtual
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al convertir la imagen virtual.
- **Código 400 Bad Request:** No se ha encontrado la imagen virtual especificada.
- **Código 200 OK:** La imagen virtual se está convirtiendo.
---
### Convertir Imagen OpenGnsys a Imagen Virtual
Se convertirá la imagen "img" especificada en una imagen virtual con la extensión especificada ("vdi", "vmdk", etc), guardándola en la ruta "opt/opengnsys/ogrepository/images_virtual/export".
Se puede hacer con el script "**convertIMGtoVM.py**", que debe ser llamado por el endpoint.
**NOTA**: El script requiere que se le pase el nombre de la imagen (con extensión) como primer parámetro, y la extensión del disco virtual destino ("vdi", "vmdk", etc) como segundo 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 extensión del disco virtual debe enviarse 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á convirtiendo a virtual, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/images/virtual`
**Método HTTP:** PUT
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **vm_extension**: Extensión del disco virtual destino ("vdi", "vmdk", etc).
**Ejemplo de Solicitud:**
```bash
curl -X PUT -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "vm_extension":"vdi"}' http://example.com/ogrepository/v1/images/virtual
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al convertir la imagen a virtual.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está convirtiendo a virtual.
---
### Renombrar una Imagen
Se renombrará la imagen especificada como primer parámetro (y todos sus archivos asociados), asignando el nombre especificado como segundo parámetro.
Se puede hacer con el script "**renameImage.py**", que debe ser llamado por el endpoint.
**NOTA**: El script requiere que se le pase el nombre de la imagen (sin extensión) como primer parámetro, y el nuevo nombre a asignar como segundo 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 el nuevo nombre a asignar debe enviarse en el JSON.
**URL:** `/ogrepository/v1/images/rename`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **image_new_name**: Nuevo nombre a asignar a la imagen.
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "image_new_name":"Ubuntu_BKP"}' http://example.com/ogrepository/v1/images/rename
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al renombrar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se ha renombrado exitosamente.
---
### Crear archivos auxiliares
@ -680,6 +400,31 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** Los archivos auxiliares se están creando.
---
### Convertir Imagen Virtual
Se convertirá la imagen virtual especificada (que debe haberse copiado previamente en la ruta "opt/opengnsys/ogrepository/images_virtual") en una imagen "img" como las que se generan desde OpenGnsys (con "partclone" y "lzop").
Se puede hacer con el script "**convertVMtoIMG.py**", que debe ser llamado por el endpoint.
**NOTA**: El script requiere que se le pase el nombre de la imagen virtual (con extensión) como primer parámetro, y el sistema de archivos de la partición a clonar como segundo parámetro (en formato "blkid"). Estos parámetros 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 virtual se está convirtiendo, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
**URL:** `/ogrepository/v1/images/virtual`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **virtual_image**: Nombre de la imagen virtual (con extensión).
- **filesystem**: Sistema de archivos de la partición a clonar, en formato "blkid".
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"virtual_image":"UbuntuVM.vdi", "filesystem":"ext4"}' http://example.com/ogrepository/v1/images/virtual
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al convertir la imagen virtual.
- **Código 400 Bad Request:** No se ha encontrado la imagen virtual especificada.
- **Código 200 OK:** La imagen virtual se está convirtiendo.
---
### Enviar paquete Wake On Lan
@ -703,4 +448,209 @@ curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d
- **Código 500 Internal Server Error:** Ocurrió un error al enviar el paquete Wake On Lan.
- **Código 200 OK:** El paquete Wake On Lan se ha enviado exitosamente.
---
### Enviar una Imagen mediante UDPcast
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) 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`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **port**: Puerto Multicast.
- **method**: Modalidad half-duplex o full-duplex ("half" o "full").
- **ip**: IP Multicast.
- **bitrate**: Velocidad de transmisión (en Mbps).
- **nclients**: Número mínimo de clientes.
- **maxtime**: Tiempo máximo de espera.
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "port":"9000", "method":"full", "ip":"239.194.17.2", "bitrate":"70M", "nclients":"20", "maxtime":"120"}' http://example.com/ogrepository/v1/udpcast
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante UDPcast.
---
### Enviar una Imagen mediante UFTP
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) 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`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
- **port**: Puerto Multicast.
- **ip**: IP Unicast/Multicast.
- **bitrate**: Velocidad de transmisión (con "K" para Kbps, "M" para Mbps o "G" para Gbps).
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d", "port":"9000", "ip":"239.194.17.2", "bitrate":"1G"}' http://example.com/ogrepository/v1/uftp
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante UFTP.
---
### 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 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 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).
**URL:** `/ogrepository/v1/p2p`
**Método HTTP:** POST
**Cuerpo de la Solicitud (JSON):**
- **ID_img**: Identificador de la imagen (correspondiente al contenido del archivo "full.sum" asociado).
**Ejemplo de Solicitud:**
```bash
curl -X POST -H "Authorization: $API_KEY" -H "Content-Type: application/json" -d '{"ID_img":"22735b9070e4a8043371b8c6ae52b90d"}' http://example.com/ogrepository/v1/p2p
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al intentar enviar la imagen.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 200 OK:** La imagen se está enviando mediante P2P.
---
### Ver Estado de Transmisiones UDPcast
Se devolverá el pid de los procesos de transferencias UDPcast activas, y sus imágenes asociadas (con nombre e ID), en formato JSON, o un mensaje informativo si no hay procesos activos, o si se produce un error.
Se puede hacer con el script "**getUDPcastInfo.py**", que debe ser llamado por el endpoint.
**URL:** `/ogrepository/v1/udpcast`
**Método HTTP:** GET
**Ejemplo de Solicitud:**
```bash
curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/udpcast
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al comprobar las transmisiones UDPcast.
- **Código 400 Bad Request:** No se han encontrado transmisiones UDPcast activas.
- **Código 200 OK:** La información de las transmisiones UDPcast activas se obtuvo exitosamente.
- **Contenido:** Información de las transmisiones UDPcast activas en formato JSON.
```json
{
"6720": {
"image_id": "22735b9070e4a8043371b8c6ae52b90d",
"image_name": "Ubuntu20.img"
},
"6721": {
"image_id": "9e7cd32c606ebe5bd39ba212ce7aeb02",
"image_name": "Windows10.img"
}
}
```
---
### Ver Estado de Transmisiones UFTP
Se devolverá el pid de los procesos de transferencias UFTP activas, y sus imágenes asociadas (con nombre e ID), en formato JSON, o un mensaje informativo si no hay procesos activos, o si se produce un error.
Se puede hacer con el script "**getUFTPInfo.py**", que debe ser llamado por el endpoint.
**URL:** `/ogrepository/v1/uftp`
**Método HTTP:** GET
**Ejemplo de Solicitud:**
```bash
curl -X GET -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al comprobar las transmisiones UFTP.
- **Código 400 Bad Request:** No se han encontrado transmisiones UFTP activas.
- **Código 200 OK:** La información de las transmisiones UFTP activas se obtuvo exitosamente.
- **Contenido:** Información de las transmisiones UFTP activas en formato JSON.
```json
{
"3427": {
"image_id": "22735b9070e4a8043371b8c6ae52b90d",
"image_name": "Ubuntu20.img"
},
"4966": {
"image_id": "9e7cd32c606ebe5bd39ba212ce7aeb02",
"image_name": "Windows10.img"
}
}
```
---
### Cancelar Transmisión UDPcast
Se cancelará la transmisión por UDPcast activa de la imagen especificada como parámetro, deteniendo el proceso "udp-sender" asociado a dicha imagen.
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) 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
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/udpcast/images/22735b9070e4a8043371b8c6ae52b90d
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UDPcast.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 400 Bad Request:** No hay transmisiones UDPcast activas para la imagen especificada.
- **Código 200 OK:** La transmisión UDPcast se ha cancelado exitosamente.
---
### Cancelar Transmisión UFTP
Se cancelará la transmisión por UFTP activa de la imagen especificada como parámetro, deteniendo el proceso "uftp" asociado a dicha imagen.
Se puede hacer con el script "**stopUFTP.py**", que debe ser llamado por el endpoint.
**NOTA**: La versión actual de este script requiere que se le pase el nombre de la imagen (con extensión) 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
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/uftp/images/22735b9070e4a8043371b8c6ae52b90d
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar la transmisión UFTP.
- **Código 400 Bad Request:** No se ha encontrado la imagen especificada.
- **Código 400 Bad Request:** No hay transmisiones UFTP activas para la imagen especificada.
- **Código 200 OK:** La transmisión UFTP se ha cancelado exitosamente.
---
### Cancelar Transmisiones P2P
Se cancelarán las transmisiones P2P activas en el ogRepository al que se envíe la orden, deteniendo los procesos "bttrack" y "btlaunchmany.bittornado".
Se puede hacer con el script "**stopP2P.py**", que debe ser llamado por el endpoint.
**NOTA**: No he encontrado la forma de detener la transmisión de una imagen concreta, ya que "bttrack" y "btlaunchmany.bittornado" hacen tracking y seed (respectivamente) de todos los torrents existentes en la raíz del directorio especificado.
**URL:** `/ogrepository/v1/p2p`
**Método HTTP:** DELETE
**Ejemplo de Solicitud:**
```bash
curl -X DELETE -H "Authorization: $API_KEY" http://example.com/ogrepository/v1/p2p
```
**Respuestas:**
- **Código 500 Internal Server Error:** Ocurrió un error al cancelar las transmisiones P2P.
- **Código 200 OK:** Las transmisiones P2P se han cancelado exitosamente.
---

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@ import unittest
from unittest.mock import patch, mock_open, MagicMock, AsyncMock
from flask import json
import os
from repo_api import app, get_image_params, search_process, check_remote_connection, check_remote_image, check_lock_local, check_aux_files, check_file_exists, check_remote_backup, check_virtual_image_conversion, check_free_space, check_virtual_image_reconversion
from repo_api import app, get_image_params, search_process, check_remote_connection, check_remote_image, check_lock_local, check_aux_files, check_file_exists, check_remote_backup, check_virtual_image_conversion, check_free_space
# --------------------------------------------------------------------------------------------
@ -591,15 +591,15 @@ class RepoApiTestCase(unittest.TestCase):
self.assertIn('Image not found', json.loads(response.data)['exception'])
# ------------------------------------------------------------------- Tests "Convertir imagen virtual a imagen OpenGnsys"
# ------------------------------------------------------------------- Tests "Convertir imagen virtual"
@patch('repo_api.subprocess.Popen')
@patch('repo_api.check_virtual_image_conversion')
def test_convert_virtual_image(self, mock_popen, mock_check_virtual_image_conversion):
""" Método de prueba del endpoint "Convertir imagen virtual a imagen OpenGnsys".
""" Método de prueba del endpoint "Convertir imagen virtual".
"""
print("Testing endpoint 'Convertir imagen virtual a imagen OpenGnsys'...")
print("Testing endpoint 'Convertir imagen virtual'...")
mock_popen.return_value = MagicMock(returncode=None)
mock_check_virtual_image_conversion.return_value = AsyncMock(returncode=None)
response = self.app.post('/ogrepository/v1/images/virtual', data=json.dumps({"virtual_image":"test4unittestvm.vdi", "filesystem":"ext4"}), content_type='application/json')
@ -611,10 +611,10 @@ class RepoApiTestCase(unittest.TestCase):
@patch('repo_api.check_file_exists')
@patch('repo_api.subprocess.Popen')
def test_convert_virtual_image_error500(self, mock_popen, mock_check_virtual_image_conversion, mock_check_file_exists):
""" Método de prueba del endpoint "Convertir imagen virtual a imagen OpenGnsys"
""" Método de prueba del endpoint "Convertir imagen virtual"
(en caso de error "500").
"""
print("Testing endpoint 'Convertir imagen virtual a imagen OpenGnsys' (error 500)...")
print("Testing endpoint 'Convertir imagen virtual' (error 500)...")
mock_check_file_exists.return_value = True
mock_popen.side_effect = Exception("Error al convertir la imagen virtual")
mock_check_virtual_image_conversion.return_value = AsyncMock(returncode=None)
@ -625,10 +625,10 @@ class RepoApiTestCase(unittest.TestCase):
@patch('repo_api.check_file_exists')
def test_convert_virtual_image_error400_no_virtual_image(self, mock_check_file_exists):
""" Método de prueba del endpoint "Convertir imagen virtual a imagen OpenGnsys"
""" Método de prueba del endpoint "Convertir imagen virtual"
(en caso de error "400", por imagen virtual inexistente).
"""
print("Testing endpoint 'Convertir imagen virtual a imagen OpenGnsys' (error 400, no virtual image)...")
print("Testing endpoint 'Convertir imagen virtual' (error 400, no virtual image)...")
mock_check_file_exists.return_value = False
response = self.app.post('/ogrepository/v1/images/virtual', data=json.dumps({"virtual_image":"test4unittestvm.vdi", "filesystem":"ext4"}), content_type='application/json')
self.assertEqual(response.status_code, 400)
@ -637,10 +637,10 @@ class RepoApiTestCase(unittest.TestCase):
@patch('repo_api.check_file_exists')
def test_convert_virtual_image_error400_name_incorrect(self, mock_check_file_exists):
""" Método de prueba del endpoint "Convertir imagen virtual a imagen OpenGnsys"
""" Método de prueba del endpoint "Convertir imagen virtual"
(en caso de error "400", por nombre incorrecto).
"""
print("Testing endpoint 'Convertir imagen virtual a imagen OpenGnsys' (error 400, name incorrect)...")
print("Testing endpoint 'Convertir imagen virtual' (error 400, name incorrect)...")
mock_check_file_exists.return_value = True
response = self.app.post('/ogrepository/v1/images/virtual', data=json.dumps({"virtual_image":"test4unittestvm.vdi", "filesystem":"ext4"}), content_type='application/json')
self.assertEqual(response.status_code, 400)
@ -649,90 +649,16 @@ class RepoApiTestCase(unittest.TestCase):
@patch('repo_api.check_free_space')
def test_convert_virtual_image_error400_not_enough_space(self, mock_check_free_space):
""" Método de prueba del endpoint "Convertir imagen virtual a imagen OpenGnsys"
""" Método de prueba del endpoint "Convertir imagen virtual"
(en caso de error "400", por falta de espacio en disco).
"""
print("Testing endpoint 'Convertir imagen virtual a imagen OpenGnsys' (error 400, not enough space)...")
print("Testing endpoint 'Convertir imagen virtual' (error 400, not enough space)...")
mock_check_free_space.return_value = False
response = self.app.post('/ogrepository/v1/images/virtual', data=json.dumps({"virtual_image":"test4unittestvm.vdi", "filesystem":"ext4"}), content_type='application/json')
self.assertEqual(response.status_code, 400)
self.assertIn('There is not enough free disk space', json.loads(response.data)['exception'])
# ------------------------------------------------------------------- Tests "Convertir imagen OpenGnsys a imagen virtual"
@patch('repo_api.subprocess.Popen')
@patch('repo_api.get_image_params')
@patch('repo_api.check_virtual_image_reconversion')
def test_convert_image_to_virtual(self, mock_popen, mock_get_image_params, mock_check_virtual_image_reconversion):
""" Método de prueba del endpoint "Convertir imagen OpenGnsys a imagen virtual".
"""
print("Testing endpoint 'Convertir imagen OpenGnsys a imagen virtual'...")
mock_get_image_params.return_value = {'name': 'test4unittest', 'extension': 'img'}
mock_popen.return_value = MagicMock(returncode=None)
mock_check_virtual_image_reconversion.return_value = AsyncMock(returncode=None)
response = self.app.put('/ogrepository/v1/images/virtual', data=json.dumps({"ID_img": "test_image_id", "vm_extension":"vdi"}), content_type='application/json')
self.assertEqual(response.status_code, 200)
self.assertIn('Converting image to virtual...', json.loads(response.data)['output'])
@patch('repo_api.check_virtual_image_reconversion')
@patch('repo_api.get_image_params')
@patch('repo_api.subprocess.Popen')
def test_convert_image_to_virtual_error500(self, mock_popen, mock_get_image_params, mock_check_virtual_image_reconversion):
""" Método de prueba del endpoint "Convertir imagen OpenGnsys a imagen virtual"
(en caso de error "500").
"""
print("Testing endpoint 'Convertir imagen OpenGnsys a imagen virtual' (error 500)...")
mock_get_image_params.return_value = {'name': 'test4unittest', 'extension': 'img'}
mock_popen.side_effect = Exception("Error al convertir la imagen a virtual")
mock_check_virtual_image_reconversion.return_value = AsyncMock(returncode=None)
response = self.app.put('/ogrepository/v1/images/virtual', data=json.dumps({"ID_img": "test_image_id", "vm_extension":"vdi"}), content_type='application/json')
self.assertEqual(response.status_code, 500)
self.assertIn('Error al convertir la imagen a virtual', response.data.decode())
@patch('repo_api.get_image_params')
def test_convert_image_to_virtual_error400_no_image(self, mock_get_image_params):
""" Método de prueba del endpoint "Convertir imagen OpenGnsys a imagen virtual"
(en caso de error "400", por imagen virtual inexistente).
"""
print("Testing endpoint 'Convertir imagen OpenGnsys a imagen virtual' (error 400, no image)...")
mock_get_image_params.return_value = None
response = self.app.put('/ogrepository/v1/images/virtual', data=json.dumps({"ID_img": "test_image_id", "vm_extension":"vdi"}), content_type='application/json')
self.assertEqual(response.status_code, 400)
self.assertIn("Image not found", json.loads(response.data)['error'])
@patch('repo_api.check_file_exists')
@patch('repo_api.get_image_params')
def test_convert_image_to_virtual_error400_name_incorrect(self, mock_get_image_params, mock_check_file_exists):
""" Método de prueba del endpoint "Convertir imagen OpenGnsys a imagen virtual"
(en caso de error "400", por nombre incorrecto).
"""
print("Testing endpoint 'Convertir imagen OpenGnsys a imagen virtual' (error 400, name incorrect)...")
mock_get_image_params.return_value = {'name': 'test4unittest', 'extension': 'img'}
mock_check_file_exists.return_value = True
response = self.app.put('/ogrepository/v1/images/virtual', data=json.dumps({"ID_img": "test_image_id", "vm_extension":"vdi"}), content_type='application/json')
self.assertEqual(response.status_code, 400)
self.assertIn('There is an exported virtual image with the same name as the image', json.loads(response.data)['exception'])
@patch('repo_api.check_free_space')
@patch('repo_api.get_image_params')
def test_convert_image_to_virtual_error400_not_enough_space(self, mock_get_image_params, mock_check_free_space):
""" Método de prueba del endpoint "Convertir imagen OpenGnsys a imagen virtual"
(en caso de error "400", por falta de espacio en disco).
"""
print("Testing endpoint 'Convertir imagen OpenGnsys a imagen virtual' (error 400, not enough space)...")
mock_get_image_params.return_value = {'name': 'test4unittest', 'extension': 'img'}
mock_check_free_space.return_value = False
response = self.app.put('/ogrepository/v1/images/virtual', data=json.dumps({"ID_img": "test_image_id", "vm_extension":"vdi"}), content_type='application/json')
self.assertEqual(response.status_code, 400)
self.assertIn('There is not enough free disk space', json.loads(response.data)['exception'])
# ------------------------------------------------------------------- Tests "Enviar paquete Wake On Lan"
@ -1109,62 +1035,6 @@ class RepoApiTestCase(unittest.TestCase):
self.assertIn('Error al cancelar las transmisiones P2P', response.data.decode())
# ------------------------------------------------------------------- Tests "Renombrar una Imagen"
@patch('repo_api.get_image_params')
@patch('repo_api.subprocess.run')
def test_rename_image(self, mock_subprocess, mock_get_image_params):
""" Método de prueba del endpoint "Renombrar una Imagen".
"""
print("Testing endpoint 'Renombrar una Imagen'...")
mock_get_image_params.return_value = {'name': 'test4unittest', 'extension': 'img'}
mock_subprocess.return_value = MagicMock(returncode=0)
response = self.app.put('/ogrepository/v1/images/rename', data=json.dumps({"ID_img":"test_image_id", "image_new_name":"new_name"}), content_type='application/json')
self.assertEqual(response.status_code, 200)
self.assertIn('Image renamed successfully', json.loads(response.data)['output'])
@patch('repo_api.get_image_params')
@patch('repo_api.subprocess.run')
def test_rename_image_error500(self, mock_subprocess, mock_get_image_params):
""" Método de prueba del endpoint "Renombrar una Imagen"
(en caso de error "500").
"""
print("Testing endpoint 'Renombrar una Imagen' (error 500)...")
mock_get_image_params.return_value = {'name': 'test4unittest', 'extension': 'img'}
mock_subprocess.side_effect = Exception("Error al renombrar la imagen")
response = self.app.put('/ogrepository/v1/images/rename', data=json.dumps({"ID_img":"test_image_id", "image_new_name":"new_name"}), content_type='application/json')
self.assertEqual(response.status_code, 500)
self.assertIn('Error al renombrar la imagen', response.data.decode())
@patch('repo_api.get_image_params')
def test_rename_image_error400_no_image(self, mock_get_image_params):
""" Método de prueba del endpoint "Renombrar una Imagen"
(en caso de error "400", por imagen inexistente).
"""
print("Testing endpoint 'Renombrar una Imagen' (error 400, no image)...")
mock_get_image_params.return_value = None
response = self.app.put('/ogrepository/v1/images/rename', data=json.dumps({"ID_img":"test_image_id", "image_new_name":"new_name"}), content_type='application/json')
self.assertEqual(response.status_code, 400)
self.assertIn('Image not found', json.loads(response.data)['error'])
@patch('repo_api.check_file_exists')
@patch('repo_api.get_image_params')
def test_rename_image_error400_name_incorrect(self, mock_get_image_params, mock_check_file_exists):
""" Método de prueba del endpoint "Renombrar una Imagen"
(en caso de error "400", por nombre incorrecto).
"""
print("Testing endpoint 'Renombrar una Imagen' (error 400, name incorrect)...")
mock_get_image_params.return_value = {'name': 'test4unittest', 'extension': 'img'}
mock_check_file_exists.return_value = True
response = self.app.put('/ogrepository/v1/images/rename', data=json.dumps({"ID_img":"test_image_id", "image_new_name":"new_name"}), content_type='application/json')
self.assertEqual(response.status_code, 400)
self.assertIn('There is an image with the name to assign', json.loads(response.data)['exception'])
# --------------------------------------------------------------------------------------------

View File

@ -1,452 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Este script convierte la imagen de OpengGnsys especificada como primer parámetro en una imagen virtual con la extensión especificada como segundo parámetro ("vdi", "vmdk", etc).
La imagen virtual se exporta a la ruta "/opt/opengnsys/ogrepository/images_virtual/export/", desde donde puede ser descargada para importarla en VirtualBox, VMware, etc.
Paquetes APT requeridos: "qemu" (se puede instalar con "sudo apt install qemu-utils").
"partclone" (se puede instalar con "sudo apt install partclone").
"lzop" (se puede instalar con "sudo apt install lzop").
Parámetros
------------
sys.argv[1] - Nombre completo de la imagen a convertir (sin ruta).
- Ejemplo1: Ubuntu.img
- Ejemplo2: Windows.img
sys.argv[2] - Extensión del disco virtual destino (sin punto).
- Ejemplo1: vdi
- Ejemplo2: vmdk
Sintaxis
----------
./comvertIMGtoVM.py image_name virtual_extension
Ejemplos
---------
./comvertIMGtoVM.py Ubuntu.img vdi
./comvertIMGtoVM.py Windows.img vmdk
"""
# --------------------------------------------------------------------------------------------
# IMPORTS
# --------------------------------------------------------------------------------------------
import sys
import os
import pwd
import grp
import subprocess
from systemd import journal
# --------------------------------------------------------------------------------------------
# VARIABLES
# --------------------------------------------------------------------------------------------
script_name = os.path.basename(__file__)
repo_path = '/opt/opengnsys/ogrepository/images/' # No borrar la barra final
vm_export_path = '/opt/opengnsys/ogrepository/images_virtual/export/' # No borrar la barra final
partclone_logfile = '/opt/opengnsys/ogrepository/log/partclone.log'
raw_img = '/opt/opengnsys/ogrepository/images_virtual/export/disk.raw'
mount_point = "/mnt/recovery"
# --------------------------------------------------------------------------------------------
# FUNCTIONS
# --------------------------------------------------------------------------------------------
def show_help():
""" Imprime la ayuda, cuando se ejecuta el script con el parámetro "help".
"""
help_text = f"""
Sintaxis: {script_name} image_name virtual_extension
Ejemplo1: {script_name} Ubuntu.img vdi
Ejemplo2: {script_name} Windows.img vmdk
"""
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 2 parámetroa, 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")
show_help()
sys.exit(1)
def create_export_folder():
""" Crea el directorio '/opt/opengnsys/ogrepository/images_virtual/export/', y le asigna propietarios y permisos.
Evidentemente, esta función solo es llamada cuando no existe el directorio.
"""
# Obtenemos el UID del usuario "opengnsys" y el GID del grupo "opengnsys":
uid = pwd.getpwnam('opengnsys').pw_uid
gid = grp.getgrnam('opengnsys').gr_gid
# Creamos el directorio '/opt/opengnsys/ogrepository/images_virtual/export/':
os.mkdir(vm_export_path)
# Asignamos el usuario y el grupo propietarios del directorio:
os.chown(vm_export_path, uid, gid)
# Asignamos permisos "755" al directorio :
os.chmod(vm_export_path, 0o755)
def create_raw_disk(raw_size):
""" Crea un disco "RAW", sobre el que luego se creará una tabla de particiones, mediante "qemu-img create".
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
"""
try:
journal.send("convertIMGtoVM.py: Running command 'qemu-img create'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
result = subprocess.run(['qemu-img', 'create', '-f', 'raw', raw_img, raw_size], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
if result.returncode == 0:
return True
else:
return False
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
except subprocess.CalledProcessError as error:
journal.send(f"convertIMGtoVM.py: 'qemu-img create' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
except Exception as error:
journal.send(f"convertIMGtoVM.py: 'qemu-img create' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
def create_partition_table(partition_size):
""" Crea una tabla de particiones en el disco "RAW", mediante "fdisk".
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
"""
try:
journal.send("convertIMGtoVM.py: Running command 'fdisk'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Construimos el parámetro "input", que debe codificarse en bytes (con "encode"):
input_data = f"o\nn\np\n1\n\n+{partition_size}\nw".encode()
result = subprocess.run(['fdisk', raw_img], input=input_data, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
if result.returncode == 0:
return True
else:
return False
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
except subprocess.CalledProcessError as error:
journal.send(f"convertIMGtoVM.py: 'fdisk' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
except Exception as error:
journal.send(f"convertIMGtoVM.py: 'fdisk' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
def associate_loop_device():
""" Asocia el disco "RAW" a un dispositivo loopback, mediante "losetup".
Si se ejecuta correctamente retorna "True", el dispositivo loopback y la partición de destino, y si da error retorna "False", "None" y "None".
"""
try:
journal.send("convertIMGtoVM.py: Running command 'losetup'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
result = subprocess.run(['losetup', '-P', '--find', '--show', raw_img], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding='UTF8')
# Si el resultado de la ejecución es correcto, obtenemos el dispositivo loopback y la partición de destino, y los retornamos:
if result.returncode == 0:
# Obtenemos la partición de destino, y la imprimimos en el log, junto con el dispositivo loopback:
loop_device = result.stdout.strip()
dest_partition = f"{loop_device}p1"
journal.send(f"convertIMGtoVM.py: Loopback device obtained: {loop_device}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
journal.send(f"convertIMGtoVM.py: Destination partition obtained: {dest_partition}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return True, loop_device, dest_partition
else:
return False, None, None
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False", "None" y "None" (entrará aquí si el return code no es "0"):
except subprocess.CalledProcessError as error:
journal.send(f"convertIMGtoVM.py: 'losetup' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False, None, None
except Exception as error:
journal.send(f"convertIMGtoVM.py: 'losetup' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False, None, None
def decompress_image(image_name_full):
""" Descomprime la imagen "IMG" origen, con "lzop".
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
"""
try:
journal.send("convertIMGtoVM.py: Running command 'lzop'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
result = subprocess.run(['lzop', '-d', f"{repo_path}{image_name_full}", '-o', f"{vm_export_path}{image_name_full}"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
if result.returncode == 0:
return True
else:
return False
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
except subprocess.CalledProcessError as error:
journal.send(f"convertIMGtoVM.py: 'lzop' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
except Exception as error:
journal.send(f"convertIMGtoVM.py: 'lzop' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
def restore_image(image_name_full, dest_partition):
""" Restaura la imagen descomprimida en la partición de destino (que hemos obtenido con "losetup").
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
"""
try:
journal.send("convertIMGtoVM.py: Running command 'partclone.restore'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
result = subprocess.run(['partclone.restore', '-s', f"{vm_export_path}{image_name_full}", '-o', dest_partition, '-L', partclone_logfile], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
if result.returncode == 0:
return True
else:
return False
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
except subprocess.CalledProcessError as error:
journal.send(f"convertIMGtoVM.py: 'partclone.restore' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
except Exception as error:
journal.send(f"convertIMGtoVM.py: 'partclone.restore' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
def mount_partition(dest_partition):
""" Crea un directorio de montaje, y monta allí la partición de destino (que hemos obtenido con "losetup").
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
NOTA: Los comandos "mkdir" y "mount" deben ejecutarse con "sudo", o darán error.
"""
try:
# Creamos el directorio de montaje:
subprocess.run(['sudo', 'mkdir', '-p', mount_point], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except Exception as error:
journal.send(f"convertIMGtoVM.py: 'mkdir' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
try:
# Montamos la partición en el directorio de montaje:
journal.send("convertIMGtoVM.py: Running command 'mount'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
result = subprocess.run(['sudo', 'mount', dest_partition, mount_point], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
if result.returncode == 0:
return True
else:
return False
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
except subprocess.CalledProcessError as error:
journal.send(f"convertIMGtoVM.py: 'mount' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
except Exception as error:
journal.send(f"convertIMGtoVM.py: 'mount' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
def install_grub(loop_device):
""" Instala GRUB en el dispositivo loopback.
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
NOTA: Los comandos deben ejecutarse con "sudo", o darán error.
"""
try:
journal.send("convertIMGtoVM.py: Installing GRUB...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Ejecutamos los comandos necesarios para instalar GRUB:
subprocess.run(['sudo', 'mount', '--bind', '/dev', f"{mount_point}/dev"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.run(['sudo', 'mount', '--bind', '/proc', f"{mount_point}/proc"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.run(['sudo', 'mount', '--bind', '/sys', f"{mount_point}/sys"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.run(['sudo', 'chroot', mount_point, 'grub-install', '--target=i386-pc', loop_device], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.run(['sudo', 'chroot', mount_point, 'grub-mkconfig', '-o', '/boot/grub/grub.cfg'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Como no ha habido errores, retornamos "True":
return True
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
except subprocess.CalledProcessError as error:
journal.send(f"convertIMGtoVM.py: GRUB install error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
except Exception as error:
journal.send(f"convertIMGtoVM.py: GRUB install exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
def umount_partitions(loop_device):
""" Desmonta todas las particiones montadas previamente, con "umount" y "losetup".
No retorna "True" o "False", porque este paso no afecta a la conversión de la imagen.
NOTA: Los comandos deben ejecutarse con "sudo", o darán error.
"""
try:
journal.send("convertIMGtoVM.py: Umounting partitions...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Desmontamos las particiones, con "umount" y "losetup":
subprocess.run(['sudo', 'umount', f"{mount_point}/dev"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.run(['sudo', 'umount', f"{mount_point}/proc"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.run(['sudo', 'umount', f"{mount_point}/sys"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.run(['sudo', 'umount', '-l', mount_point], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.run(['sudo', 'losetup', '-d', loop_device], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Como no ha habido errores, imprimimos un mensaje en el log:
journal.send("convertIMGtoVM.py: Umount partitions OK", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Si se produce un error o una excepción lo imprimimos en el log:
except subprocess.CalledProcessError as error:
journal.send(f"convertIMGtoVM.py: 'umount' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
except Exception as error:
journal.send(f"convertIMGtoVM.py: 'umount' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
def convert_image(image_name, vm_extension):
""" Convierte el disco "RAW" en un disco virtual, con la extensión especificada como parámetro.
Si se ejecuta correctamente retorna "True", y si da error retorna "False".
"""
try:
journal.send("convertIMGtoVM.py: Running command 'qemu-img convert'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
result = subprocess.run(['qemu-img', 'convert', '-f', 'raw', '-O', vm_extension, raw_img, f"{vm_export_path}{image_name}.{vm_extension}"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Evaluamos el resultado de la ejecución, retornando "True" si es correcta y "False" si no lo es:
if result.returncode == 0:
return True
else:
return False
# Si se produce un error o una excepción lo imprimimos en el log, y retornamos "False":
except subprocess.CalledProcessError as error:
journal.send(f"convertIMGtoVM.py: 'qemu-img convert' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
except Exception as error:
journal.send(f"convertIMGtoVM.py: 'qemu-img convert' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
return False
def erase_image_file(file2del):
""" Borra el archivo correspondiente a la ruta "file2del".
No retorna "True" o "False", porque este paso no afecta a la conversión de la imagen.
"""
journal.send(f"convertIMGtoVM.py: Erasing file {file2del}...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Si existe el archivo "file2del", lo borramos:
if os.path.exists(file2del):
os.remove(file2del)
# --------------------------------------------------------------------------------------------
# MAIN
# --------------------------------------------------------------------------------------------
def main():
"""
"""
# Evaluamos si se ha enviado la cantidad correcta de parámetros, y en el formato correcto:
check_params()
# Almacenamos el nombre completo de la imagen y la extensión del disco virtual de destino (desde los parámetros), y extraemos el nombre sin extensión:
image_name_full = sys.argv[1]
image_name = image_name_full.split('.')[0]
vm_extension = sys.argv[2].lower()
# Obtenemos el tamaño de la imagen, y calculamos el tamaño a asignar al disco "RAW" y a la partición:
image_size = os.path.getsize(f"{repo_path}{image_name_full}")
raw_size = image_size * 6.5 # El disco "RAW" debe ser "6,5" veces más grande que la imagen
partition_size = (90 * raw_size) / 100 # La partición debe tener el 90% del tamaño del disco "RAW"
# Si no existe el directorio '/opt/opengnsys/ogrepository/images_virtual/export/', lo creamos:
if not os.path.exists(vm_export_path):
journal.send("convertIMGtoVM.py: Creating export folder...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
create_export_folder()
# Creamos el disco "RAW" (con "qemu-img create"):
create_raw = create_raw_disk(f"{raw_size / 1024 / 1024 / 1024}G")
if create_raw == False:
journal.send("convertIMGtoVM.py: RAW disk creation failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
sys.exit(2)
else:
journal.send("convertIMGtoVM.py: RAW disk creation OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Creamos una tabla de particiones en el disco "RAW" (con "fdisk"):
create_table = create_partition_table(f"{int(partition_size / 1024 / 1024 / 1024)}G")
if create_table == False:
journal.send("convertIMGtoVM.py: Partition table creation failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
sys.exit(3)
else:
journal.send("convertIMGtoVM.py: Partition table creation OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Asociamos el disco "RAW" a un dispositivo loopback, y almacenamos este y la partición de destino
assoc_loop_result, loop_device, dest_partition = associate_loop_device()
if assoc_loop_result == False:
journal.send("convertIMGtoVM.py: Loop device association failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
sys.exit(4)
else:
journal.send("convertIMGtoVM.py: Loop device association OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Descomprimimos la imagen original (con "lzop"):
image_decompressed = decompress_image(image_name_full)
if image_decompressed == False:
journal.send("convertIMGtoVM.py: Image decompression failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
erase_image_file(f"{vm_export_path}{image_name_full}") # Como ha fallado, borramos la imagen descomprimida
sys.exit(5)
else:
journal.send("convertIMGtoVM.py: Image decompression OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Restauramos la imagen descomprimida en la partición de destino (con "partclone.restore"):
image_restored = restore_image(image_name_full, dest_partition)
if image_restored == False:
journal.send("convertIMGtoVM.py: Image restoration failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
erase_image_file(f"{vm_export_path}{image_name_full}") # Como ha fallado, borramos la imagen descomprimida
sys.exit(6)
else:
journal.send("convertIMGtoVM.py: Image restoration OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
erase_image_file(f"{vm_export_path}{image_name_full}") # Si ha ido OK también borramos la imagen descomprimida, porque ya no la necesitamos.
# Montamos la partición de destino (con "mount"):
partition_mounted = mount_partition(dest_partition)
if partition_mounted == False:
journal.send("convertIMGtoVM.py: Partition mount failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
sys.exit(7)
else:
journal.send("convertIMGtoVM.py: Partition mount OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Instalamos GRUB en el dispositivo loopback (con "mount" y "chroot"):
grub_installed = install_grub(loop_device)
if grub_installed == False:
journal.send("convertIMGtoVM.py: GRUB install failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
umount_partitions(loop_device) # Como ha fallado, desmontamos todas las particiones
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
sys.exit(8)
else:
journal.send("convertIMGtoVM.py: GRUB install OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Desmontamos las particiones montadas previamente (con "umount" y "losetup"):
umount_partitions(loop_device)
# Convertimos el disco "RAW" en un disco virtual (con "qemu-img convert"):
image_conversion = convert_image(image_name, vm_extension)
if image_conversion == False:
journal.send("convertIMGtoVM.py: Image conversion failed", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
erase_image_file(raw_img) # Como ha fallado, borramos el disco "RAW"
erase_image_file(f"{vm_export_path}{image_name}.{vm_extension}") # Como ha fallado, borramos la imagen virtual (por si ha creado algo)
sys.exit(9)
else:
erase_image_file(raw_img) # Si ha funcionado OK, también borramos el disco "RAW"
journal.send("convertIMGtoVM.py: Image conversion OK (ReturnCode: 0)", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# --------------------------------------------------------------------------------------------
if __name__ == "__main__":
main()
# --------------------------------------------------------------------------------------------

View File

@ -134,8 +134,8 @@ def create_torrent(file_path, torrent_file, datafullsum):
repo_ip = get_IPlocal()
tracker_url = f"http://{repo_ip}:6969/announce"
# Creamos una litas para ejecutar el comando mktorrent para crear el archivo torrent
splitted_cmd = f"nice -n 0 mktorrent -a {tracker_url} -c {datafullsum} -o {torrent_file} {file_path}".split()
# Creamos una lista con el comando para crear el torrrent, y lo imprimimos con espacios:
splitted_cmd = f"nice -n 0 ctorrent -t {file_path} -u {tracker_url} -s {torrent_file} -c {datafullsum} -l 4194304".split()
print(f"Sending command: {' '.join(splitted_cmd)}")
# Ejecutamos el comando en el sistema, e imprimimos el resultado:
@ -184,16 +184,11 @@ def main():
# Obtenemos la ruta completa de la imagen:
file_path = build_file_path()
# Si no existe el archivo de imagen o el .info, imprimimos un mensaje de error y salimos del script:
if not os.path.exists(file_path) or not (os.path.exists(f"{file_path}.info.checked") or os.path.exists(f"{file_path}.info")):
if not os.path.exists(file_path):
journal.send(f"createTorrentSum.py: Image file '{file_path}' not found", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"Image file '{file_path}' doesn't exist")
if not os.path.exists(f"{file_path}.info.checked") and not os.path.exists(f"{file_path}.info"):
journal.send(f"createTorrentSum.py: Neither '{file_path}.info.checked' nor '{file_path}.info' found", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"Neither info file '{file_path}.info.checked' nor '{file_path}.info' exists")
# Si no existe el archivo de imagen, imprimimos un mensaje de error y salimos del script:
if not os.path.exists(file_path):
journal.send("createTorrentSum.py: Image not found", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print("Image file doesn't exist")
sys.exit(2)
# Si la imagen está bloqueada, imprimimos un mensaje de error y salimos del script:
if os.path.exists(f"{file_path}.lock"):
@ -262,8 +257,7 @@ def main():
# Actualizamos la información del repositorio, ejecutando el script "updateRepoInfo.py":
journal.send("createTorrentSum.py: Updating repository info...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print("Updating Repository Info...")
if os.path.exists(f"{file_path}.info"):
update_repo_info()
update_repo_info()

View File

@ -106,11 +106,11 @@ def main():
total_disk, used_disk, free_disk, percent_disk = get_disk_info()
# Obtenemos el estado de los servicios listados, que almacenamos en un diccionario:
service_list = ['ssh', 'smbd', 'opentracker']
service_list = ['ssh', 'smbd', 'rsync']
services_status = {service: get_service_status(service) for service in service_list}
# Obtenemos el estado de los procesos listados, que almacenamos en un diccionario:
process_list = ['udp-sender', 'uftp', 'aria2c']
process_list = ['udp-sender', 'uftp', 'bttrack', 'btlaunchmany.bittornado']
process_status = {process: get_process_status(process) for process in process_list}
# Creamos un diccionario con toda la información obtenida:

View File

@ -1,149 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Este script renombra la imagen especificada como primer parámetro (y todos sus archivos asociados), asignando el nombre especificado como segundo parámetro.
Una vez renombrados los archivos, llama al script "updateRepoInfo.py", para actualizar la información del repositorio.
Parámetros
------------
sys.argv[1] - Nombre de la imagen a renombrar (sin extensión y sin ruta).
- Ejemplo1: Ubuntu24
- Ejemplo2: Windows10
sys.argv[2] - Nuevo nombre a asignar a la imagen (sin extensión y sin ruta).
- Ejemplo1: Ubuntu24_BKP
- Ejemplo2: Windows10_BKP
Sintaxis
----------
./renameImage.py image_to_rename image_new_name
Ejemplos
---------
./renameImage.py Ubuntu24 Ubuntu24_BKP
./renameImage.py Windows10 Windows10_BKP
"""
# --------------------------------------------------------------------------------------------
# IMPORTS
# --------------------------------------------------------------------------------------------
import os
import sys
import subprocess
from systemd import journal
# --------------------------------------------------------------------------------------------
# VARIABLES
# --------------------------------------------------------------------------------------------
script_name = os.path.basename(__file__)
repo_path = '/opt/opengnsys/ogrepository/images/' # No borrar la barra final
update_repo_script = '/opt/opengnsys/ogrepository/bin/updateRepoInfo.py'
# --------------------------------------------------------------------------------------------
# FUNCTIONS
# --------------------------------------------------------------------------------------------
def show_help():
""" Imprime la ayuda, cuando se ejecuta el script con el parámetro "help".
"""
help_text = f"""
Sintaxis: {script_name} image_to_rename image_new_name
Ejemplo1: {script_name} Ubuntu24 Ubuntu24_BKP
Ejemplo2: {script_name} Windows10 Windows10_BKP
"""
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 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")
show_help()
sys.exit(1)
def rename_image(image_original_name, image_new_name):
""" Asigna el nuevo nombre especificado a la imagen y a todos los archivos asociados.
Al archivo ".info.checked" también le cambia la extensión a ".info",
para poder actualizar la información del repositorio posteriormente.
"""
try:
journal.send("renameImage.py: Renaming image files...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Creamos una lista con las extensiones de los archivos de la imagen (menos "info.checked"):
extensions = ['.img', '.img.full.sum', '.img.size', '.img.sum', '.img.torrent']
# Renombramos cada uno de los archivos (menos "info.checked"):
for ext in extensions:
os.rename(f"{repo_path}{image_original_name}{ext}", f"{repo_path}{image_new_name}{ext}")
# Renombramos separadamente el archivo "info.checked" (porque también le cambiamos la extensión a "info"):
os.rename(f"{repo_path}{image_original_name}.img.info.checked", f"{repo_path}{image_new_name}.img.info")
except Exception as error:
journal.send(f"renameImage.py: Rename Image exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
sys.exit(2)
def update_repo_info():
""" Actualiza la información del repositorio, ejecutando el script "updateRepoInfo.py".
"""
try:
journal.send("renameImage.py: Running script 'updateRepoInfo.py'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
result = subprocess.run(['python3', update_repo_script], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except subprocess.CalledProcessError as error:
journal.send(f"renameImage.py: 'updateRepoInfo.py' error: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
sys.exit(3)
except Exception as error:
journal.send(f"renameImage.py: 'updateRepoInfo.py' exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
sys.exit(4)
# --------------------------------------------------------------------------------------------
# MAIN
# --------------------------------------------------------------------------------------------
def main():
"""
"""
# Evaluamos si se ha enviado la cantidad correcta de parámetros, y en el formato correcto:
check_params()
# Almacenamos el nombre original de la imagen, y el nuevo nombre a asignar (desde los parámetros):
image_original_name = sys.argv[1]
image_new_name = sys.argv[2]
# Renombramos la imagen y sus archivos asociados:
rename_image(image_original_name, image_new_name)
# Actualizamos la información del repositorio, ejecutando el script "updateRepoInfo.py":
update_repo_info()
# --------------------------------------------------------------------------------------------
if __name__ == "__main__":
main()
# --------------------------------------------------------------------------------------------

View File

@ -16,8 +16,6 @@ No recibe ningún parámetro.
import os
import sys
import subprocess
import psutil
import re
from systemd import journal
@ -33,73 +31,29 @@ repo_path = '/opt/opengnsys/ogrepository/images' # En este caso, no lleva barra
# --------------------------------------------------------------------------------------------
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 {repo_path}".split()
print(f"Sending command: {' '.join(splitted_cmd)}")
journal.send(f"runTorrentSeeder.py: Running command: {' '.join(splitted_cmd)}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# 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 {repo_path}".split()
# print(f"Sending command: {' '.join(splitted_cmd)}")
# journal.send(f"runTorrentSeeder.py: Running command: {' '.join(splitted_cmd)}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# # Ejecutamos el comando "btlaunchmany.bittornado" en el sistema, e imprimimos el resultado:
# try:
# result = subprocess.run(splitted_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# journal.send(f"runTorrentSeeder.py: Command ReturnCode: {result.returncode}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# print(f"Bittornado ReturnCode: {result.returncode}")
# except subprocess.CalledProcessError as error:
# journal.send("runTorrentSeeder.py: Process finalized", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# print(f"Bittornado ReturnCode: {error.returncode}")
# print(f"Bittornado Error Output: {error.stderr.decode()}")
# except Exception as error:
# journal.send(f"runTorrentSeeder.py: Command exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# print(f"Unexpected bittornado error: {error}")
def run_aria2c_seeder(image_name):
"""Lanza aria2c como seeder puro para una imagen concreta ya existente."""
repo_path = '/opt/opengnsys/ogrepository/images'
torrent_file = os.path.join(repo_path, f"{image_name}.img.torrent")
image_file = os.path.join(repo_path, f"{image_name}.img")
# Verificación básica
if not os.path.exists(torrent_file):
print(f"Torrent file not found: {torrent_file}")
journal.send(f"Seeder error: Torrent file not found: {torrent_file}",
PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api")
return
if not os.path.exists(image_file):
print(f"Image file not found: {image_file}")
journal.send(f"Seeder error: Image file not found: {image_file}",
PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api")
return
# Comando aria2c como seeder puro
cmd = [
'aria2c',
'--enable-peer-exchange=true',
'--bt-seed-unverified=true',
'--check-integrity=true',
'--seed-ratio=0.0',
'--dir=' + repo_path,
torrent_file
]
journal.send(f"Launching aria2c seeder for {image_name}",
PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api")
journal.send(f"Command: {' '.join(cmd)}",
PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api")
print("Running command:", ' '.join(cmd))
# Ejecutamos el comando "btlaunchmany.bittornado" en el sistema, e imprimimos el resultado:
try:
subprocess.run(cmd, check=True)
except subprocess.CalledProcessError as e:
journal.send(f"aria2c seeder failed: {e}",
PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api")
print(f"Seeder process exited with code {e.returncode}")
result = subprocess.run(splitted_cmd, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
journal.send(f"runTorrentSeeder.py: Command ReturnCode: {result.returncode}", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"Bittornado ReturnCode: {result.returncode}")
except subprocess.CalledProcessError as error:
journal.send("runTorrentSeeder.py: Process finalized", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"Bittornado ReturnCode: {error.returncode}")
print(f"Bittornado Error Output: {error.stderr.decode()}")
except Exception as error:
journal.send(f"runTorrentSeeder.py: Command exception: {error}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"Unexpected bittornado error: {error}")
# --------------------------------------------------------------------------------------------
# MAIN
@ -110,40 +64,16 @@ def main():
"""
"""
# Finalizamos el proceso "btlaunchmany.bittornado" (en caso de que estuviera corriendo):
if len(sys.argv) != 2:
print("Usage: runTorrentSeeder.py <image_name>")
journal.send("runTorrentSeeder.py: Invalid number of arguments. Expected 1 argument: <image_name>",
PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
sys.exit(1)
image_name = sys.argv[1]
torrent_file = os.path.join(repo_path, f"{image_name}.img.torrent")
found = False
# Matamos los procesos de aria2c que sirvan la imagen en concreto. Chequeamos todos los procesos
try:
journal.send("runTorrentSeeder.py: Killing process 'btlaunchmany.bittornado'...", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
subprocess.run(f"pkill btlaunchmany".split(), check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except Exception as error_description:
journal.send("runTorrentSeeder.py: No 'btlaunchmany.bittornado' process running", PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"No btlaunchmany.bittornado process running? Returned error: {error_description}")
journal.send(f"runTorrentSeeder.py: looking for aria2c processes for {image_name}.torrent",
PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
for proc in psutil.process_iter(['pid','name','cmdline']):
try:
if proc.info['name'] != 'aria2c':
continue
# Ejecutamos el comando "btlaunchmany.bittornado" (para hacer seed de los torrents):
run_bittornado(repo_path)
if any(arg.endswith(torrent_file) for arg in proc.info['cmdline']):
proc.terminate()
found = True
print(f"Killed aria2c process with PID {proc.info['pid']} for {image_name}.torrent")
journal.send(f"runTorrentSeeder.py: Killed aria2c process with PID {proc.info['pid']} for {image_name}.torrent",
PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
except (psutil.NoSuchProcess, psutil.AccessDenied):
continue
if not found:
print(f"No aria2c process found for {image_name}.torrent")
journal.send(f"runTorrentSeeder.py: No aria2c process found for {image_name}.torrent",
PRIORITY=journal.LOG_INFO, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
# Lanzamos aria2c como seeder para la imagen proporcionada
run_aria2c_seeder(image_name)
# --------------------------------------------------------------------------------------------

View File

@ -67,50 +67,33 @@ def check_files():
continue
# Comprobamos si existe un archivo ".info" asociado a la imagen actual:
info_file = f"{img_path}.info"
try:
if os.path.exists(info_file):
# Si la fecha de modificación del archivo ".info" es anterior a la de la imagen, lo eliminamos (porque estará desactualizado):
if os.path.getmtime(info_file) < os.path.getmtime(img_path):
os.remove(info_file)
print(f"Warning: Deleted outdated file {info_file}")
if os.path.exists(info_file):
# Si la fecha de modificación del archivo ".info" es anterior a la de la imagen, lo eliminamos (porque estará desactualizado):
if os.path.getmtime(info_file) < os.path.getmtime(img_path):
os.remove(info_file)
print(f"Warning: Deleted outdated file {info_file}")
# En caso contrario, almacenamos el contenido del archivo ".info" (del tipo "PARTCLONE:LZOP:EXTFS:8500000:Ubuntu_20") en la variable "data":
else:
with open(info_file, 'r') as file:
info_data = file.read()
# 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')
else:
with open(info_file, 'r') as file:
info_data = file.read()
# 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, la extensión, y los datos extraídos del archivo ".info"):
img_name = os.path.relpath(img_path, repo_path)
add_to_json(os.path.splitext(img_name)[0], os.path.splitext(img_name)[1][1:], info_data, size, _sum, fullsum)
# Renombramos el archivo ".info" a ".info.checked", para que ya no se añada la información que contiene
# (originalmente se eliminaba el archivo, pero creo que es mejor mantenerlo):
os.rename(info_file, f"{info_file}.checked")
# 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, la extensión, y los datos extraídos del archivo ".info"):
img_name = os.path.relpath(img_path, repo_path)
add_to_json(os.path.splitext(img_name)[0], os.path.splitext(img_name)[1][1:], info_data, size, sum, fullsum)
# Renombramos el archivo ".info" a ".info.checked", para que ya no se añada la información que contiene
# (originalmente se eliminaba el archivo, pero creo que es mejor mantenerlo):
os.rename(info_file, f"{info_file}.checked")
except (IOError, OSError, PermissionError) as e:
# Si hay algún error leyendo los archivos, registramos el error y continuamos con la siguiente imagen
journal.send(f"updateRepoInfo.py: Error processing files for {img_path}: {str(e)}", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"Warning: Could not process files for {item}: {str(e)}")
continue
except ValueError as e:
# Si hay algún error con el formato de los datos en los archivos
journal.send(f"updateRepoInfo.py: Data format error for {img_path}: {str(e)}", PRIORITY=journal.LOG_WARNING, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"Warning: Data format error for {item}: {str(e)}")
continue
except Exception as e:
# Para cualquier otra excepción inesperada
journal.send(f"updateRepoInfo.py: Unexpected error processing {img_path}: {str(e)}", PRIORITY=journal.LOG_ERR, SYSLOG_IDENTIFIER="ogrepo-api_DEBUG")
print(f"Error: Unexpected error processing {item}: {str(e)}")
continue
def add_to_json(image_name, image_type, 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).
"""
# Almacenamos el contenido de la variable "data" (del tipo "PARTCLONE:LZOP:EXTFS:8500000:Ubuntu_20") en variables separadas:
@ -126,7 +109,7 @@ def add_to_json(image_name, image_type, data, size, sum, fullsum):
"filesystem": fstype.upper(),
"datasize": int(datasize) * 1024, # Convertimos el valor a bytes (desde KB)
"size": int(size),
"sum": sum,
"sum": _sum,
"fullsum": fullsum
}
# Almacenamos el contenido del archivo "repoinfo.json" en la variable "info_data"

40
debian/changelog vendored
View File

@ -1,43 +1,3 @@
ogrepository (1.1.5) UNRELEASED; urgency=medium
* refs #2363 Fix breaking forgejo permissions
-- OpenGnsys <opengnsys@opengnsys.com> Tue, 1 Jul 2025 16:05:12 +0000
ogrepository (1.1.4) UNRELEASED; urgency=medium
* refs #2363 Reduce number of required dependencies
-- OpenGnsys <opengnsys@opengnsys.com> Tue, 30 Jun 2025 15:50:11 +0000
ogrepository (1.1.3) UNRELEASED; urgency=medium
* refs #2317 Fix performance problems, remove stats
* refs #2298 Add commmits endpoint
-- OpenGnsys <opengnsys@opengnsys.com> Tue, 30 Jun 2025 15:50:11 +0000
ogrepository (1.1.2) UNRELEASED; urgency=medium
* Fix path handling when there are no repositories
* Add another search path for installer module
* Fix path handling
* Add SSH key endpoint
* Update dependencies
-- OpenGnsys <opengnsys@opengnsys.com> Tue, 30 Jun 2025 15:20:23 +0000
ogrepository (1.1.1) unstable; urgency=medium
* OgGit - fix repo path handling
-- Tu Nombre <tuemail@example.com> Jue, 5 Jun 2025 08:43:58 +0000
ogrepository (1.1.0) unstable; urgency=medium
* OgGit
-- Tu Nombre <tuemail@example.com> Tue, 11 Mar 2025 04:43:58 +0000
ogrepository (1.0.0+deb-packages20250311-1) unstable; urgency=medium
* First debian version

5
debian/control vendored
View File

@ -8,7 +8,6 @@ Build-Depends: debhelper-compat (= 12)
Package: ogrepository
Architecture: all
Pre-Depends: debian-archive-keyring , debconf (>= 1.5.0),
Depends: ${misc:Depends}, git, python3, python3-pip, python3-flask, python3-paramiko, python3-psutil, python3-flasgger, samba, gunicorn, wakeonlan , lzop , partclone , qemu-utils , udpcast, uftp, mktorrent, aria2 , opengnsys-opentracker, opengnsys-forgejo, python3-git
Depends: ${misc:Depends}, git, python3, python3-pip, python3-flask, python3-paramiko, python3-psutil, python3-flasgger, samba, gunicorn, wakeonlan , lzop , partclone , qemu-utils , udpcast
Description: Ogrepsoitory Package
This package provides Ogrepository service.
This package provides Ogrepsoitory service.

View File

@ -1,6 +1,7 @@
api/* /opt/opengnsys/ogrepository/api/
bin/* /opt/opengnsys/ogrepository/bin/
etc/* /opt/opengnsys/ogrepository/etc/
installer/files/ctorrent.sources /etc/apt/sources.list.d/
installer/files/ogrepo-api.service /etc/systemd/system/
installer/files/ogrepo-smb.conf /etc/samba/
installer/ssh-keys/* /opt/opengnsys/ogrepository/etc/

View File

@ -1,29 +1,10 @@
#!/bin/sh
set -e
set -x
set -x
. /usr/share/debconf/confmodule
restore_config_if_modified() {
local new="$1"
local backup="$1.bak.upgrade_package"
if [ -f "$backup" ]; then
if ! cmp -s "$new" "$backup"; then
echo ">>> Archivo modificado por el usuario detectado en $new"
echo " - Guardando archivo nuevo como ${new}.new"
mv -f "$new" "${new}.new"
echo " - Restaurando archivo anterior desde backup"
mv -f "$backup" "$new"
else
echo ">>> El archivo $new no ha cambiado desde la última versión, eliminando backup"
rm -f "$backup"
fi
fi
}
# Cargar variables de configuración
db_get opengnsys/ogrepository_ogrepoIp
OGREPO_IP="$RET"
@ -38,10 +19,21 @@ SAMBA_PASS="$RET"
USER="opengnsys"
# Provisionar base de datos si es necesario en caso de instalación.
# Provisionar base de datos si es necesario en caso de instalación.
# Detectar si es una instalación nueva o una actualización
if [ "$1" = "configure" ] && [ -z "$2" ]; then
systemd-run --no-block /bin/bash -c "
sleep 10;
apt update -y;
for pkg in bittorrent bittornado ctorrent; do
if ! dpkg -l | grep -qw \"\$pkg\"; then
apt install -y \"\$pkg\"
fi
done
"
sed -i "s/%%OGREPOSITORY_USER%%/$SAMBA_USER/g" /etc/systemd/system/ogrepo-api.service
sed -i "s/%%OGREPOSITORY_USER%%/$SAMBA_USER/g" /etc/samba/ogrepo-smb.conf
@ -53,72 +45,30 @@ if [ "$1" = "configure" ] && [ -z "$2" ]; then
# Copy ssh keys
cp /opt/opengnsys/ogrepository/etc/opengnsys $OPENGNSYS_HOME/.ssh/id_ed25519
cp /opt/opengnsys/ogrepository/etc/opengnsys.pub $OPENGNSYS_HOME/.ssh/id_ed25519.pub
# Change permissions
chmod 700 $OPENGNSYS_HOME/.ssh
chmod 600 $OPENGNSYS_HOME/.ssh/id_ed25519
chmod 644 $OPENGNSYS_HOME/.ssh/id_ed25519.pub
# Genera authorized_keys
cat $OPENGNSYS_HOME/.ssh/id_ed25519.pub >> $OPENGNSYS_HOME/.ssh/authorized_keys
chmod 600 $OPENGNSYS_HOME/.ssh/authorized_keys
chown -R opengnsys:opengnsys $OPENGNSYS_HOME/.ssh
if [ -f /etc/samba/smb.conf ]; then
dpkg-divert --package ogrepository --add --rename --divert /etc/samba/smb.conf.orig /etc/samba/smb.conf
cp /etc/samba/smb.conf.orig /etc/samba/smb.conf
if ! grep -q "include = /etc/samba/ogrepo-smb.conf" /etc/samba/smb.conf; then
echo "include = /etc/samba/ogrepo-smb.conf" >> /etc/samba/smb.conf
fi
(echo "$SAMBA_PASS"; echo "$SAMBA_PASS") | smbpasswd -a $SAMBA_USER
fi
systemctl enable ogrepo-api
# Configure Repo
# Incluir el archivo de configuración de samba si no está incluido ya
if ! grep -q "include = /etc/samba/ogrepo-smb.conf" /etc/samba/smb.conf; then
echo "include = /etc/samba/ogrepo-smb.conf" >> /etc/samba/smb.conf
fi
(echo "$SAMBA_PASS"; echo "$SAMBA_PASS") | smbpasswd -a $SAMBA_USER
# Configure Repo
cp /opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg.tmpl /opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg
sed -i "s/SERVERIP/$OGREPO_IP/g" /opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg
sed -i "s/OGCOREIP/$OGCORE_IP/g" /opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg
# Copiar sudoers file ogrepository/etc/opengnsys-repository
cp /opt/opengnsys/ogrepository/etc/opengnsys-repository /etc/sudoers.d/opengnsys
elif [ "$1" = "configure" ] && [ -n "$2" ]; then
echo "Actualización desde la versión $2"
# Recopy static files without configuration
cp /opt/opengnsys/ogrepository/etc/opengnsys-repository /etc/sudoers.d/opengnsys-repository
OPENGNSYS_HOME=$(getent passwd opengnsys | cut -d: -f6)
# Create .ssh directory
mkdir -p $OPENGNSYS_HOME/.ssh
# Copy ssh keys
cp /opt/opengnsys/ogrepository/etc/opengnsys $OPENGNSYS_HOME/.ssh/id_ed25519
cp /opt/opengnsys/ogrepository/etc/opengnsys.pub $OPENGNSYS_HOME/.ssh/id_ed25519.pub
cat $OPENGNSYS_HOME/.ssh/id_ed25519.pub >> $OPENGNSYS_HOME/.ssh/authorized_keys
restore_config_if_modified "/opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg"
restore_config_if_modified "/opt/opengnsys/ogrepository/etc/repoinfo.json"
restore_config_if_modified "/opt/opengnsys/ogrepository/etc/trashinfo.json"
restore_config_if_modified "/etc/samba/smb.conf"
restore_config_if_modified "/etc/samba/ogrepo-smb.conf"
restore_config_if_modified "/etc/sudoers.d/opengnsys-repository"
fi
# Cambiar la propiedad de los archivos al usuario especificado
chown opengnsys:www-data /opt/opengnsys/
chown -R opengnsys:www-data /opt/opengnsys/ogrepository
chmod 755 /opt/opengnsys
chmod 755 /opt/opengnsys/ogrepository/bin/*
# oggit -- these are from opengnsys-forgejo, and we're overwriting their
# permissions above.
#
# Check if the paths exist just in case the opengnsys-forgejo package
# stops being a dependency.
if [ -d "/opt/opengnsys/ogrepository/var/lib/forgejo/" ] ; then
chown -R oggit:oggit /opt/opengnsys/ogrepository/var/lib/forgejo/
fi
if [ -d "/opt/opengnsys/ogrepository/oggit/" ] ; then
chown -R oggit:oggit /opt/opengnsys/ogrepository/oggit/
fi
# Install http server stuff
# Reiniciar servicios si es necesario
@ -128,8 +78,39 @@ systemctl daemon-reload
systemctl enable ogrepo-api
systemctl restart ogrepo-api
systemctl restart smbd
systemctl enable --now opentracker || true
systemctl restart opentracker || true
# echo "ogrepository-trigger" > /var/lib/dpkg/triggers/ogrepository.trigger
# POST_INVOKE_SCRIPT="/var/lib/dpkg/info/ogrepository.trigger"
# echo "Registrando post-invoke para instalación de paquetes adicionales..."
# cat <<EOF > "$POST_INVOKE_SCRIPT"
# #!/bin/sh
# set -e
# echo "Ejecutando post-trigger: Instalando bittorrent, bittornado y ctorrent..."
# export DEBIAN_FRONTEND=noninteractive
# apt-get update
# apt-get install -y bittorrent bittornado ctorrent
# echo "Instalación de paquetes adicionales completada."
# exit 0
# EOF
# chmod +x "$POST_INVOKE_SCRIPT"
# # Intentar ejecutar el script ahora si no hay otro proceso de apt corriendo
# if ! pgrep -x "apt" > /dev/null; then
# echo "Ejecutando instalación de paquetes adicionales inmediatamente..."
# "$POST_INVOKE_SCRIPT"
# else
# echo "Apt está en uso, los paquetes se instalarán después."
# fi
# find /opt/opengnsys/ogrepository -type f -name "*.py" -exec chmod +x {} \;
# dpkg-trigger --by-package=ogrepository ogrepository-trigger
exit 0

View File

@ -2,13 +2,19 @@
set -e
UNIT_FILE="/etc/systemd/system/ogrepo-api.service"
NGINX_FILE="/etc/nginx/sites-enabled/oggui.conf"
UNIT_FILE="/etc/systemd/system/oggui.service"
case "$1" in
remove)
echo "El paquete se está desinstalando..."
# Aquí puedes hacer limpieza de archivos o servicios
if [ -L "$NGINX_FILE" ]; then
rm -f "$NGINX_FILE"
systemctl restart nginx
fi
if [ -L "$UNIT_FILE" ]; then
rm -f "$UNIT_FILE"
systemctl daemon-reload

View File

@ -2,18 +2,8 @@
set -e
backup_file_if_exists() {
local original="$1"
local backup="$1.bak.upgrade_package"
if [ -e "$original" ]; then
echo " - Guardando backup de $original en $backup"
cp -a "$original" "$backup"
fi
}
# KEY_FILE="/usr/share/keyrings/debian-archive-buster-stable.gpg"
# REPO_FILE="/etc/apt/sources.list.d/buster.list"
KEY_FILE="/usr/share/keyrings/debian-archive-buster-stable.gpg"
REPO_FILE="/etc/apt/sources.list.d/buster.list"
# Asegurarse de que el usuario exista
USER="opengnsys"
@ -30,17 +20,10 @@ echo "Añadiendo el repositorio de Debian Buster en $REPO_FILE..."
mkdir -p "$(dirname "$REPO_FILE")"
# Crear el archivo de repositorio si no existe
# if [ ! -f "$REPO_FILE" ]; then
# echo "deb [signed-by=$KEY_FILE] http://ftp.de.debian.org/debian buster main" > "$REPO_FILE"
# else
# echo "El repositorio ya está configurado en $REPO_FILE"
# fi
backup_file_if_exists "/opt/opengnsys/ogrepository/etc/ogAdmRepo.cfg"
backup_file_if_exists "/opt/opengnsys/ogrepository/etc/repoinfo.json"
backup_file_if_exists "/opt/opengnsys/ogrepository/etc/trashinfo.json"
backup_file_if_exists "/etc/samba/smb.conf"
backup_file_if_exists "/etc/samba/ogrepo-smb.conf"
backup_file_if_exists "/etc/sudoers.d/ogrepository"
if [ ! -f "$REPO_FILE" ]; then
echo "deb [signed-by=$KEY_FILE] http://ftp.de.debian.org/debian buster main" > "$REPO_FILE"
else
echo "El repositorio ya está configurado en $REPO_FILE"
fi
exit 0

View File

@ -44,18 +44,11 @@ case "$1" in
rm -f /var/lib/dpkg/info/ogrepository.post-invoke
fi
# Remove sudoers file
if [ -f /etc/sudoers.d/opengnsys-repository ]; then
echo "Removing sudoers file..."
rm -f /etc/sudoers.d/opengnsys-repository
fi
echo "Limpieza completada."
;;
upgrade|deconfigure)
# No hacer nada en actualización o desconfiguración
;;
*)

View File

@ -1,50 +0,0 @@
# Variables para facilitar la lectura
Cmnd_Alias MOUNT_RECOVERY = \
/usr/bin/mkdir -p /mnt/recovery, \
/usr/bin/mount /dev/* /mnt/recovery, \
/usr/bin/mount --bind /dev /mnt/recovery/dev, \
/usr/bin/mount --bind /proc /mnt/recovery/proc, \
/usr/bin/mount --bind /sys /mnt/recovery/sys, \
/usr/bin/umount /mnt/recovery/dev, \
/usr/bin/umount /mnt/recovery/proc, \
/usr/bin/umount /mnt/recovery/sys, \
/usr/bin/umount -l /mnt/recovery
Cmnd_Alias OGBOOT = \
/opt/bin/oglivecli, \
/usr/bin/chmod, \
/usr/bin/chown, \
/usr/bin/md5sum, \
/usr/bin/smbpasswd, \
/usr/bin/cat, \
/usr/bin/tee, \
/usr/bin/sed, \
/usr/bin/gzip, \
/usr/bin/lz4, \
/usr/bin/cpio, \
/usr/bin/find, \
/bin/tee, \
/usr/bin/dd, \
/usr/bin/mkfs.ext4, \
/usr/bin/rsync, \
/opt/opengnsys/ogboot/lib/*.iso /mnt
Cmnd_Alias CHROOT_GRUB = \
/usr/sbin/chroot /mnt/recovery /usr/sbin/grub-install --target=i386-pc *, \
/usr/sbin/chroot /mnt/recovery /usr/sbin/grub-mkconfig -o /boot/grub/grub.cfg
Cmnd_Alias LOOP_KPARTX = \
/usr/sbin/losetup -d *, \
/usr/sbin/kpartx -av /opt/opengnsys/ogrepository/images_virtual/*, \
/usr/sbin/kpartx -d /opt/opengnsys/ogrepository/images_virtual/*, \
/usr/sbin/blkid /dev/mapper/*
Cmnd_Alias KILL_BT = \
/usr/bin/pkill -9 btlaunchmany, \
/usr/bin/pkill -9 bttrack, \
/usr/bin/kill -9 *
Cmnd_Alias PYTHON_OGREPO = /usr/bin/python3 /opt/opengnsys/ogrepository/bin/*
# Permitir al usuario opengnsys ejecutar estos comandos sin contraseña
opengnsys ALL=(root) NOPASSWD: MOUNT_RECOVERY, CHROOT_GRUB, LOOP_KPARTX, OGBOOT, KILL_BT, PYTHON_OGREPO

View File

@ -0,0 +1,6 @@
Types: deb
URIs: http://ftp.de.debian.org/debian
Suites: buster
Components: main
Signed-By: /usr/share/keyrings/debian-archive-buster-stable.gpg

View File

@ -3,8 +3,8 @@ Description=Gunicorn instance to serve repo_api
After=network.target
[Service]
User=opengnsys
Group=opengnsys
User=%%OGREPOSITORY_USER%%
Group=%%OGREPOSITORY_USER%%
WorkingDirectory=/opt/opengnsys/ogrepository/api
ExecStart=/usr/bin/gunicorn -w 4 -b 0.0.0.0:8006 repo_api:app