---
swagger: "2.0"
info:
  title: "ogRepository API"
  version: "1.0"
  description: |
    ---

# -----------------------------------------------------------------------------------------------------------

# Esto hace que el Swagger se ordene por los tags (apartados), de la forma especificada:
tags:
  - name: "Estado de ogRepository"
  - name: "Información de Imágenes"
  - name: "Eliminar y Recuperar Imágenes"
  - name: "Transferencia de Imágenes (UDPcast)"
  - name: "Transferencia de Imágenes (UFTP)"
  - name: "Transferencia de Imágenes (P2P)"
  - name: "Transferencia entre Repositorios y Backup"
  - name: "Importar y Exportar Máquinas Virtuales"
  - name: "Varios"


# -----------------------------------------------------------------------------------------------------------
#                                      Apartado "Estado de ogRepository"
# -----------------------------------------------------------------------------------------------------------

paths:
  /ogrepository/v1/status:
    get:
      summary: "Obtener Información de Estado de ogRepository"
      description: >
        Este endpoint ejecuta el script "**getRepoStatus.py**" y devuelve su salida en formato JSON,
        incluyendo información sobre la CPU, memoria RAM, disco duro, servicios, y procesos específicos de ogRepository, e instalación de ogGit.
      tags:
        - "Estado de ogRepository"
      responses:
        "200":
          description: "La información de estado se obtuvo exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: object
                properties:
                  oggit:
                    type: object
                    properties:
                      installed:
                        type: string
                        example: "True"
                  cpu:
                    type: object
                    properties:
                      used_percentage:
                        type: string
                        example: "35%"
                  ram:
                    type: object
                    properties:
                      total:
                        type: string
                        example: "7.8GB"
                      used:
                        type: string
                        example: "0.3GB"
                      available:
                        type: string
                        example: "7.2GB"
                      used_percentage:
                        type: string
                        example: "7%"
                  disk:
                    type: object
                    properties:
                      total:
                        type: string
                        example: "11.7GB"
                      used:
                        type: string
                        example: "7.7GB"
                      available:
                        type: string
                        example: "3.4GB"
                      used_percentage:
                        type: string
                        example: "69%"
                  services:
                    type: object
                    properties:
                      ssh:
                        type: string
                        example: "active"
                      smbd:
                        type: string
                        example: "active"
                      rsync:
                        type: string
                        example: "active"
                  processes:
                    type: object
                    properties:
                      udp-sender:
                        type: string
                        example: "stopped"
                      uftp:
                        type: string
                        example: "stopped"
                      bttrack:
                        type: string
                        example: "stopped"
                      btlaunchmany.bittornado:
                        type: string
                        example: "stopped"
        "500 (Error)":
          description: "Error al consultar y/o devolver la información de estado."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al consultar y/o devolver la información de estado."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------
#                                      Apartado "Información de Imágenes"
# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/images:
    put:
      summary: "Actualizar Información del Repositorio"
      description: |
        Este endpoint actualiza la información de las imágenes almacenadas en el repositorio, reflejándola en los archivos "**repoinfo.json**" y "**trashinfo.json**".
        Utiliza el script "**updateRepoInfo.py**", que a su vez llama al script "**updateTrashInfo.py**", para actualizar también la información de la papelera.

        No hace falta que se le llame al crear o exportar una imagen, ya que lo llama el endpoint "**Crear archivos auxiliares**" (que sí debe ser llamado en esos casos).
      tags:
        - "Información de Imágenes"
      responses:
        "200":
          description: "La actualización de la información de las imágenes se realizó exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Repository info updated successfully"
        "500 (Error)":
          description: "Error al actualizar la información de las imágenes."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al actualizar la información de las imágenes."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  #/ogrepository/v1/images:
    get:
      summary: "Obtener Información de todas las Imágenes"
      description: |
        Este endpoint ejecuta el script "**getRepoInfo.py**" con el parámetro "**all**", para devolver información de todas las imágenes almacenadas en el repositorio y en la papelera, que a su vez llama al script "**updateRepoInfo.py**", para actualizar previamente la información del repositorio.
        Devuelve detalles como el nombre de la imagen, tipo, nombre del cliente, clonador, compresor, sistema de archivos, tamaño de los datos, tamaño de la imagen, y hashes MD5.
      tags:
        - "Información de Imágenes"
      responses:
        "200":
          description: "La información de las imágenes se obtuvo exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: object
                properties:
                  REPOSITORY:
                    type: object
                    properties:
                      directory:
                        type: string
                        example: "/opt/opengnsys/ogrepository/images"
                      images:
                        type: array
                        items:
                          type: object
                          properties:
                            name:
                              type: string
                              example: "Ubuntu24"
                            type:
                              type: string
                              example: "img"
                            clientname:
                              type: string
                              example: "Ubuntu24_clientname"
                            clonator:
                              type: string
                              example: "partclone"
                            compressor:
                              type: string
                              example: "lzop"
                            filesystem:
                              type: string
                              example: "EXTFS"
                            datasize:
                              type: integer
                              example: 9859634200000
                            size:
                              type: integer
                              example: 4505673214
                            sum:
                              type: string
                              example: "065a933c780ab1aaa044435ad5d4bf87"
                            fullsum:
                              type: string
                              example: "33575b9070e4a8043371b8c6ae52b80e"
                  TRASH:
                    type: object
                    properties:
                      directory:
                        type: string
                        example: "/opt/opengnsys/ogrepository/images_trash"
                      images:
                        type: array
                        items:
                          type: object
                          properties:
                            name:
                              type: string
                              example: "Windows10"
                            type:
                              type: string
                              example: "img"
                            clientname:
                              type: string
                              example: "Windows10_clientname"
                            clonator:
                              type: string
                              example: "partclone"
                            compressor:
                              type: string
                              example: "lzop"
                            filesystem:
                              type: string
                              example: "NTFS"
                            datasize:
                              type: integer
                              example: 8912896000000
                            size:
                              type: integer
                              example: 3803794535
                            sum:
                              type: string
                              example: "081a933c780ab1aaa044435ad5d4bf56"
                            fullsum:
                              type: string
                              example: "22735b9070e4a8043371b8c6ae52b90d"
        "500 (Error)":
          description: "Error al consultar y/o devolver la información de las imágenes."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al consultar y/o devolver la información de las imágenes."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/images/{imageId}:
    get:
      summary: "Obtener Información de una Imagen concreta"
      description: |
        Este endpoint devuelve información de la imagen especificada mediante su ID, en formato JSON.
        Utiliza el script "**getRepoInfo.py**" que recibe como parámetro el nombre de la imagen (con extensión), que a su vez llama al script "**updateRepoInfo.py**", para actualizar previamente la información del repositorio.
        La imagen puede estar en el archivo "**repoinfo.json**" (si está almacenada en el repositorio) o en "**trashinfo.json**" (si está en la papelera).
      tags:
        - "Información de Imágenes"
      parameters:
        - name: imageId
          in: path
          required: true
          type: string
          description: "Identificador de la imagen (correspondiente al contenido del archivo 'full.sum')"
      responses:
        "200":
          description: "La información de la imagen se obtuvo exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: object
                properties:
                  directory:
                    type: string
                    example: "/opt/opengnsys/ogrepository/images"
                  images:
                    type: array
                    items:
                      type: object
                      properties:
                        name:
                          type: string
                          example: "Ubuntu24"
                        type:
                          type: string
                          example: "img"
                        clientname:
                          type: string
                          example: "Ubuntu24_clientname"
                        clonator:
                          type: string
                          example: "partclone"
                        compressor:
                          type: string
                          example: "lzop"
                        filesystem:
                          type: string
                          example: "EXTFS"
                        datasize:
                          type: integer
                          example: 9859634200000
                        size:
                          type: integer
                          example: 4505673214
                        sum:
                          type: string
                          example: "065a933c780ab1aaa044435ad5d4bf87"
                        fullsum:
                          type: string
                          example: "33575b9070e4a8043371b8c6ae52b80e"
        "400":
          description: "No se ha encontrado la imagen especificada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image not found"
        "500 (Error)":
          description: "Error al consultar y/o devolver la información de la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al consultar y/o devolver la información de la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/status/images/{imageId}:
    get:
      summary: "Chequear Integridad de Imagen"
      description: |
        Este endpoint comprueba la integridad de la imagen especificada como parámetro, comparando el tamaño y el hash MD5 del último MB con los valores almacenados en los archivos ".size" y ".sum".
        Utiliza el script "**checkImage.py**", que recibe el nombre de la imagen (con extensión) como parámetro.
      tags:
        - "Información de Imágenes"
      parameters:
        - name: imageId
          in: path
          required: true
          type: string
          description: "Identificador de la imagen (correspondiente al contenido del archivo 'full.sum')"
      responses:
        "200 (Check OK)":
          description: "La imagen se ha chequeado exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Image file passed the Integrity Check correctly"
        "200 (Check KO)":
          description: "La imagen se ha chequeado exitosamente, pero no ha pasado el test de integridad."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Image file didn't pass the Integrity Check"
        "400":
          description: "No se ha encontrado la imagen especificada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image not found (inexistent or deleted)"
        "500 (Error)":
          description: "Error al chequear la integridad de la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al chequear la integridad de la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------
#                                     Apartado "Eliminar y Recuperar Imágenes"
# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/images/{imageId}?method={method}:
    delete:
      summary: "Eliminar una Imagen"
      description: |
        Este endpoint elimina la imagen especificada como parámetro (y todos sus archivos asociados), moviéndolos a la papelera o eliminándolos permanentemente (dependiendo del parámetro "method").
        Utiliza el script "**deleteImage.py**" que recibe el nombre de la imagen (con extensión) como primer parámetro, y opcionalmente el parámetro "-p" (para eliminación permanente), que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio.
      tags:
        - "Eliminar y Recuperar Imágenes"
      parameters:
        - name: imageId
          in: path
          required: true
          type: string
          description: "Identificador de la imagen (correspondiente al contenido del archivo 'full.sum')"
        - name: method
          in: query
          required: true
          type: string
          description: "Método de eliminación (puede ser 'trash', para enviar la imagen a la papelera, o 'permanent', para eliminarla definitivamente)"
      responses:
        "200":
          description: "La imagen se eliminó exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Image deleted successfully"
        "400":
          description: "No se ha encontrado la imagen especificada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image not found (inexistent or deleted)"
        "500 (Error)":
          description: "Error al eliminar la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al eliminar la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/trash/images:
    post:
      summary: "Recuperar una Imagen"
      description: |
        Este endpoint recupera la imagen especificada, moviéndola desde la papelera al repositorio de imágenes.
        Utiliza el script "**recoverImage.py**", que recibe el nombre de la imagen (con extensión), que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio.
      tags:
        - "Eliminar y Recuperar Imágenes"
      parameters:
        - name: JSON
          in: body
          required: true
          description: |
            * **ID_img** - Identificador de la imagen, correspondiente al contenido del archivo 'full.sum'
          schema:
            type: object
            properties:
              ID_img:
                type: string
                example: "22735b9070e4a8043371b8c6ae52b90d"
      responses:
        "200":
          description: "La imagen se recuperó exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Image recovered successfully"
        "400":
          description: "No se ha encontrado la imagen especificada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image not found (inexistent or recovered previously)"
        "500 (Error)":
          description: "Error al recuperar la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al recuperar la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/trash/images/{imageId}:
    delete:
      summary: "Eliminar una Imagen de la Papelera"
      description: |
        Este endpoint elimina permanentemente la imagen especificada, desde la papelera.
        Utiliza el script "**deleteTrashImage.py**", que recibe el nombre de la imagen (con extensión), que a su vez llama al script "**updateTrashInfo.py**", para actualizar la información de la papelera.
      tags:
        - "Eliminar y Recuperar Imágenes"
      parameters:
        - name: imageId
          in: path
          required: true
          type: string
          description: "Identificador de la imagen (correspondiente al contenido del archivo 'full.sum')"
      responses:
        "200":
          description: "La imagen se eliminó exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Image deleted successfully"
        "400":
          description: "No se ha encontrado la imagen especificada en la papelera."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image not found at trash"
        "500 (Error)":
          description: "Error al eliminar la imagen de la papelera."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al eliminar la imagen de la papelera."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------
#                                  Apartado "Transferencia de Imágenes (UDPcast)"
# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/udpcast:
    post:
      summary: "Enviar una Imagen mediante UDPcast"
      description: |
        Este endpoint envía la imagen especificada a través de UDPcast, utilizando el script "**sendFileMcast.py**".
        Recibe la imagen y los parámetros de configuración de transferencia, que son usados para construir la cadena de parámetros que se envía al script.

        **NOTA**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está enviando, y abre un proceso paralelo (pero no avisa a ogCore de su finalización, porque no puede comprobar cuando acaba la tarea de restauración de la imagen).
      tags:
        - "Transferencia de Imágenes (UDPcast)"
      parameters:
        - name: JSON
          in: body
          required: true
          description: |
            * **ID_img** - Identificador de la imagen, correspondiente al contenido del archivo 'full.sum'
            * **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 minimo de clientes
            * **maxtime** - Tiempo máximo de espera
          schema:
            type: object
            properties:
              ID_img:
                type: string
                example: "22735b9070e4a8043371b8c6ae52b90d"
              port:
                type: string
                description: "Puerto Multicast a utilizar para la transmisión"
                example: "9000"
              method:
                type: string
                description: "Modalidad de transmisión (puede ser 'half' o 'full' para half-duplex o full-duplex)"
                example: "full"
              ip:
                type: string
                description: "IP Multicast a la que se enviará la imagen"
                example: "239.194.17.2"
              bitrate:
                type: string
                description: "Velocidad de transmisión en Mbps"
                example: "70M"
              nclients:
                type: integer
                description: "Número mínimo de clientes"
                example: 20
              maxtime:
                type: integer
                description: "Tiempo máximo de espera en segundos"
                example: 120
      responses:
        "200":
          description: "La imagen se está enviando mediante UDPcast."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Sending image.."
        "400":
          description: "No se ha encontrado la imagen especificada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image not found"
        "500 (Error)":
          description: "Error al enviar la imagen mediante UDPcast."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image send failed"
        "500 (Exception)":
          description: "Excepción inesperada al enviar la imagen mediante UDPcast."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  #/ogrepository/v1/udpcast:
    get:
      summary: "Ver Estado de Transmisiones UDPcast"
      description: |
        Este endpoint devuelve información sobre los procesos activos de "**udp-sender**" en formato JSON, permitiendo comprobar las transferencias UDPcast activas.
        Utiliza el script "**getUDPcastInfo.py**" para obtener esta información.
      tags:
        - "Transferencia de Imágenes (UDPcast)"
      responses:
        "200":
          description: "La información de las transmisiones UDPcast activas se obtuvo exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: object
                additionalProperties:
                  type: object
                  properties:
                    image_id:
                      type: string
                      example: "22735b9070e4a8043371b8c6ae52b90d"
                    image_name:
                      type: string
                      example: "Ubuntu20.img"
        "400":
          description: "No se han encontrado transmisiones UDPcast activas."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "No UDPCast active transmissions"
        "500 (Error)":
          description: "Error al comprobar las transmisiones UDPcast activas."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al comprobar las transmisiones UDPcast activas."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/udpcast/images/{imageId}:
    delete:
      summary: "Cancelar Transmisión UDPcast"
      description: |
        Este endpoint cancela la transmisión UDPcast activa de la imagen especificada, deteniendo el proceso "**udp-sender**" asociado.
        Utiliza el script "**stopUDPcast.py**" para finalizar la transmisión.
      tags:
        - "Transferencia de Imágenes (UDPcast)"
      parameters:
        - name: imageId
          in: path
          required: true
          type: string
          description: "Identificador de la imagen (correspondiente al contenido del archivo 'full.sum')"
      responses:
        "200":
          description: "La transmisión UDPcast se ha cancelado exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Image transmission canceled successfully"
        "400 (Image not found)":
          description: "No se ha encontrado la imagen especificada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Image not found"
        "400 (No transmissions for image)":
          description: "No hay transmisiones UDPcast activas para la imagen especificada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "No UDPCast active transmissions for specified image"
        "500 (Error)":
          description: "Error al cancelar la transmisión UDPcast."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Check Exception)":
          description: "Error al verificar las transmisiones UDPcast activas."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Unexpected error checking UDPcast transmissions"
        "500 (Finalize Exception)":
          description: "Error inesperado al finalizar la transmisión UDPcast."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Unexpected error finalizing UDPcast transmission"
        "500 (General Exception)":
          description: "Excepción inesperada al cancelar la transmisión UDPcast."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------
#                                    Apartado "Transferencia de Imágenes (UFTP)"
# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/uftp:
    post:
      summary: "Enviar una Imagen mediante UFTP"
      description: |
        Este endpoint envía una imagen especificada a través de UFTP, utilizando el script "**sendFileUFTP.py**".
        Requiere que los clientes ogLive estén previamente en escucha con un daemon "UFTPD", ejecutando el script "**listenUFTPD.py**".
        Recibe la imagen y los parámetros de configuración de transferencia, que son usados para construir la cadena de parámetros que se envía al script.

        **NOTA**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está enviando, y abre un proceso paralelo (pero no avisa a ogCore de su finalización, porque no puede comprobar cuando acaba la tarea de restauración de la imagen).
      tags:
        - "Transferencia de Imágenes (UFTP)"
      parameters:
        - name: JSON
          in: body
          required: true
          description: |
            * **ID_img** - Identificador de la imagen, correspondiente al contenido del archivo 'full.sum'
            * **port** - Puerto Multicast
            * **ip** - IP Unicast/Multicast),
            * **bitrate** - Velocidad de transmisión, con 'K' para Kbps, 'M' para Mbps o 'G' para Gbps
          schema:
            type: object
            properties:
              ID_img:
                type: string
                example: "22735b9070e4a8043371b8c6ae52b90d"
              port:
                type: string
                description: "Puerto para la transmisión UFTP"
                example: "9000"
              ip:
                type: string
                description: "IP Unicast o Multicast para la transmisión"
                example: "239.194.17.2"
              bitrate:
                type: string
                description: "Velocidad de transmisión (con 'K' para Kbps, 'M' para Mbps, o 'G' para Gbps)"
                example: "1G"
      responses:
        "200":
          description: "La imagen se está enviando mediante UFTP."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Sending image..."
        "400":
          description: "No se ha encontrado la imagen especificada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image not found"
        "500 (Error)":
          description: "Error al enviar la imagen mediante UFTP."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image send failed"
        "500 (Exception)":
          description: "Excepción inesperada al enviar la imagen mediante UFTP."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  #/ogrepository/v1/uftp:
    get:
      summary: "Ver Estado de Transmisiones UFTP"
      description: |
        Este endpoint devuelve información sobre los procesos activos de "**uftp**" en formato JSON, permitiendo comprobar las transferencias UFTP activas.
        Utiliza el script "**getUFTPInfo.py**" para obtener esta información.
      tags:
        - "Transferencia de Imágenes (UFTP)"
      responses:
        "200":
          description: "La información de las transmisiones UFTP activas se obtuvo exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: object
                additionalProperties:
                  type: object
                  properties:
                    image_id:
                      type: string
                      example: "22735b9070e4a8043371b8c6ae52b90d"
                    image_name:
                      type: string
                      example: "Ubuntu20.img"
        "400":
          description: "No se han encontrado transmisiones UFTP activas."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "No UFTP active transmissions"
        "500 (Error)":
          description: "Error al comprobar las transmisiones UFTP activas."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al comprobar las transmisiones UFTP activas."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/uftp/images/{imageId}:
    delete:
      summary: "Cancelar Transmisión UFTP"
      description: |
        Este endpoint cancela la transmisión UFTP activa de una imagen especificada, deteniendo el proceso "**uftp**" asociado.
        Utiliza el script "**stopUFTP.py**" para finalizar la transmisión.
      tags:
        - "Transferencia de Imágenes (UFTP)"
      parameters:
        - name: imageId
          in: path
          required: true
          type: string
          description: "Identificador de la imagen (correspondiente al contenido del archivo 'full.sum')"
      responses:
        "200":
          description: "La transmisión UFTP se ha cancelado exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Image transmission canceled successfully"
        "400 (Image not found)":
          description: "No se ha encontrado la imagen especificada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Image not found"
        "400 (No transmissions for image)":
          description: "No hay transmisiones UFTP activas para la imagen especificada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "No UFTP active transmissions for specified image"
        "500 (Error)":
          description: "Error al cancelar la transmisión UFTP."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Check Exception)":
          description: "Error al verificar las transmisiones UFTP activas."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Unexpected error checking UFTP transmissions"
        "500 (Finalize Exception)":
          description: "Error inesperado al finalizar la transmisión UFTP."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Unexpected error finalizing UFTP transmission"
        "500 (General Exception)":
          description: "Excepción inesperada al cancelar la transmisión UFTP."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------
#                                    Apartado "Transferencia de Imágenes (P2P)"
# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/p2p:
    post:
      summary: "Enviar una Imagen mediante P2P"
      description: |
        Este endpoint inicia el tracker y el seeder de torrents para enviar una imagen especificada mediante P2P.
        Utiliza los scripts "**runTorrentTracker.py**" y "**runTorrentSeeder.py**" para iniciar el tracker y el seeder en el directorio de imágenes.

        **NOTA**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está enviando, y abre un proceso paralelo (pero no avisa a ogCore de su finalización, porque no puede comprobar cuando acaba la tarea de restauración de la imagen).
      tags:
        - "Transferencia de Imágenes (P2P)"
      parameters:
        - name: JSON
          in: body
          required: true
          description: |
            * **ID_img** - Identificador de la imagen, correspondiente al contenido del archivo 'full.sum'
          schema:
            type: object
            properties:
              ID_img:
                type: string
                example: "22735b9070e4a8043371b8c6ae52b90d"
      responses:
        "200":
          description: "La imagen se está enviando mediante P2P."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Tracker and Seeder serving image correctly"
        "400":
          description: "No se ha encontrado la imagen especificada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image not found"
        "500":
          description: "Error al enviar la imagen mediante P2P."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Tracker or Seeder (or both) not running"

# -----------------------------------------------------------------------------------------------------------

  #/ogrepository/v1/p2p:
    delete:
      summary: "Cancelar Transmisiones P2P"
      description: |
        Este endpoint cancela todas las transmisiones P2P activas, finalizando los procesos "**bttrack**" (tracker) y "**btlaunchmany.bittornado**" (seeder).
        Utiliza el script "**stopP2P.py**" para detener las transmisiones P2P activas en el servidor.
      tags:
        - "Transferencia de Imágenes (P2P)"
      responses:
        "200":
          description: "Las transmisiones P2P se han cancelado exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "P2P transmissions canceled successfully"
        "500 (Error)":
          description: "Error al cancelar las transmisiones P2P."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al cancelar las transmisiones P2P."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------
#                          Apartado "Transferencia entre Repositorios y Backup"
# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/repo/images:
    post:
      summary: "Transferir una Imagen entre Repositorios"
      description: |
        Este endpoint importa la imagen especificada desde un repositorio remoto al repositorio local (en el que se ejecuta el endpoint).
        Utiliza el script "**importImage.py**", que recibe como parámetros el nombre de la imagen, la IP o hostname del servidor remoto, y el usuario con el que conectar al servidor remoto.
        que a su vez llama al script "**updateRepoInfo.py**", para actualizar la información del repositorio.

        **NOTA**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está importando, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
      tags:
        - "Transferencia entre Repositorios y Backup"
      parameters:
        - name: JSON
          in: body
          required: true
          description: |
            * **image** - Nombre de la imagen, con extensión
            * **repo_ip** - Dirección IP del servidor remoto
            * **user** - Usuario con el que conectar al servidor remoto
          schema:
            type: object
            properties:
              image:
                type: string
                example: "Windows10.img"
              repo_ip:
                type: string
                description: "Dirección IP del repositorio remoto"
                example: "192.168.56.100"
              user:
                type: string
                description: "Usuario para acceder al repositorio remoto"
                example: "user_name"
      responses:
        "200":
          description: "La imagen se está transfiriendo."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Importing image..."
        "400 (Connection fail)":
          description: "Error de conexión con el servidor remoto."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Can't connect to remote server"
        "400 (Image not found)":
          description: "No se ha encontrado la imagen remota."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Remote image not found"
        "400 (Image locked)":
          description: "La imagen remota está bloqueada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Remote image is locked"
        "500":
          description: "Error al importar la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image import failed"
        "500 (Error)":
          description: "Error al importar la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al importar la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  #/ogrepository/v1/repo/images:
    put:
      summary: "Hacer Backup de una Imagen"
      description: |
        Este endpoint hace un backup de la imagen especificada, exportándola desde el servidor local a un equipo remoto (que no tiene por qué tener OpenGnsys instalado, pero si conectividad SSH).
        Utiliza el script "**backupImage.py**", que recibe como parámetros el nombre de la imagen, la IP o hostname del servidor remoto, el usuario con el que conectar al servidor remoto, y la ruta remota en la que guardar el backup.

        **NOTA**: Este endpoint es asíncrono, ya que puede tardar mucho tiempo, por lo que solo informa de que la imagen se está copiando, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
      tags:
        - "Transferencia entre Repositorios y Backup"
      parameters:
        - name: JSON
          in: body
          required: true
          description: |
            * **ID_img** - Identificador de la imagen, correspondiente al contenido del archivo 'full.sum'
            * **repo_ip** - Dirección IP del servidor remoto
            * **user** - Usuario con el que conectar al servidor remoto
            * **remote_path** - Ruta remota en la que copiar la imagen
          schema:
            type: object
            properties:
              ID_img:
                type: string
                example: "22735b9070e4a8043371b8c6ae52b90d"
              repo_ip:
                type: string
                description: "Dirección IP del repositorio remoto"
                example: "192.168.56.100"
              user:
                type: string
                description: "Usuario para acceder al repositorio remoto"
                example: "user_name"
              remote_path:
                type: string
                description: "Ruta remota en la que copiar la imagen"
                example: "/home/opengnsys"
      responses:
        "200":
          description: "Se está haciendo backup de la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Making image backup..."
        "400 (Image not found)":
          description: "No se ha encontrado la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Image not found"
        "400 (Image locked)":
          description: "La imagen está bloqueada."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Image is locked"
        "400 (Connection fail)":
          description: "Error de conexión con el equipo remoto."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Can't connect to remote host"
        "500 (Error)":
          description: "Error al copiar la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al copiar la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"


# -----------------------------------------------------------------------------------------------------------
#                           Apartado "Importar y Exportar a Máquinas Virtuales"
# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/images/virtual:
    post:
      summary: "Convertir Imagen Virtual a Imagen OpenGnsys"
      description: |
        Este endpoint convierte la imagen virtual especificada como primer parámetro en una imagen "img" como las que se generan desde OpenGnsys, debiendo haberse copiado previamente en la ruta "opt/opengnsys/ogrepository/images_virtual".
        Utiliza el script "**convertVMtoIMG.py**", que recibe como parámetros el nombre de la imagen virtual, y el sistema de archivos de la partición a clonar (en formato "blkid").
        Se puede comprobar todos los sistemas de archivos aceptados por "blkid" ejecutando el comando "blkid -k".

        **NOTA**: 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).
      tags:
        - "Importar y Exportar Máquinas Virtuales"
      parameters:
        - name: JSON
          in: body
          required: true
          description: |
            * **virtual_image** - Nombre de la imagen virtual, con extensión
            * **filesystem** - Sistema de archivos de la partición a clonar, en formato "blkid"
          schema:
            type: object
            properties:
              virtual_image:
                type: string
                example: "UbuntuVM.vdi"
              filesystem:
                type: string
                example: "ext4"
      responses:
        "200":
          description: "La imagen virtual se está convirtiendo."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Converting virtual image..."
        "400 (Virtual image not found)":
          description: "No se ha encontrado la imagen virtual."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Virtual image not found"
        "400 (Name incorrect)":
          description: "Ya existe una imagen con el mismo nombre que la imagen virtual."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "There is an image with the same name as the virtual image"
        "400 (No disk space)":
          description: "No hay espacio suficiente en disco."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "There is not enough free disk space"
        "500":
          description: "Error al convertir la imagen virtual."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Virtual image conversion failed"
        "500 (Error)":
          description: "Error al convertir la imagen virtual."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al convertir la imagen virtual."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  #/ogrepository/v1/images/virtual:
    put:
      summary: "Convertir Imagen OpenGnsys a Imagen Virtual"
      description: |
        Este endpoint convierte la imagen "img" especificada como primer parámetro en una imagen virtual con la extensión especificada como segundo parámetro ("vdi", "vmdk", etc), guardándola en la ruta "opt/opengnsys/ogrepository/images_virtual/export".
        Utiliza el script "**convertIMGtoVM.py**", que recibe como parámetros el nombre de la imagen, y la extensión del disco virtual destino ("vdi", "vmdk", etc).

        **NOTA**: 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).
      tags:
        - "Importar y Exportar Máquinas Virtuales"
      parameters:
        - name: JSON
          in: body
          required: true
          description: |
            * **ID_img** - Identificador de la imagen, correspondiente al contenido del archivo 'full.sum'
            * **vm_extension** - Extensión del disco virtual destino ("vdi", "vmdk", etc)
          schema:
            type: object
            properties:
              ID_img:
                type: string
                example: "22735b9070e4a8043371b8c6ae52b90d"
              vm_extension:
                type: string
                example: "vdi"
      responses:
        "200":
          description: "La imagen se está convirtiendo a virtual."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Converting image to virtual..."
        "400 (Image not found)":
          description: "No se ha encontrado la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Image not found"
        "400 (Name incorrect)":
          description: "Ya existe una imagen virtual exportada con el mismo nombre que la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "There is an exported virtual image with the same name as the image"
        "400 (No disk space)":
          description: "No hay espacio suficiente en disco."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "There is not enough free disk space"
        "500":
          description: "Error al convertir la imagen a virtual."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "Image conversion to virtual failed"
        "500 (Error)":
          description: "Error al convertir la imagen a virtual."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al convertir la imagen a virtual."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------
#                                            Apartado "Varios"
# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/images/torrentsum:
    post:
      summary: "Crear archivos auxiliares"
      description: |
        Este endpoint crea los archivos "**size**", "**sum**", "**full.sum**" y "**torrent**" para la imagen especificada.
        Utiliza el script "**createTorrentSum.py**", que recibe como parámetro el nombre de la imagen (con extensión), que a su vez llama al script "**updateRepoInfo.py**, para actualizar la información del repositorio".

        Debe ser llamado cada vez que se cree una imagen desde un ogLive, y cada vez que se llame al endpoint "**Exportar una Imagen**" (en este último caso, debe ejecutarse en el ogRepository destino de la exportación).

        **NOTA**: Este endpoint es asíncrono, ya que puede tardar cierto tiempo, por lo que solo informa de que se están creando los archivos auxiliares, y abre un proceso paralelo, que avisará a ogCore cuando finalice la tarea (llamando a un endpoint de ogCore).
      tags:
        - "Varios"
      parameters:
        - name: JSON
          in: body
          required: true
          description: |
            * **image** - Nombre de la imagen, con extensión
          schema:
            type: object
            properties:
              image:
                type: string
                example: "Windows10.img"
      responses:
        "200":
          description: "Los archivos auxiliares se están creando."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Creating auxiliar files..."
        "400 (Image not found)":
          description: "No se ha encontrado la imagen."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "Image not found"
        "500 (Error)":
          description: "Error al crear los archivos auxiliares."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al crear los archivos auxiliares."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------

  /ogrepository/v1/wol:
    post:
      summary: "Enviar paquete Wake On Lan"
      description: |
        Este endpoint envía un paquete mágico Wake On Lan (**WOL**) a la dirección MAC especificada, a través de la IP de broadcast especificada.
        Utiliza el script "**sendWakeOnLan.py**", que recibe como parámetros la IP de broadcast y la dirección MAC del equipo a encender.
      tags:
        - "Varios"
      parameters:
        - name: JSON
          in: body
          required: true
          description: |
            * **broadcast_ip** - IP de broadcast a la que se enviará el paquete WOL, que puede ser '255.255.255.255' o la IP de broadcast de una subred
            * **mac** - Dirección MAC del equipo que se desea encender via Wake On Lan
          schema:
            type: object
            properties:
              broadcast_ip:
                type: string
                example: "255.255.255.255"
              mac:
                type: string
                example: "00:19:99:5c:bb:bb"
      responses:
        "200":
          description: "El paquete Wake On Lan se ha enviado exitosamente."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: true
              output:
                type: string
                example: "Wake On Lan packet sent successfully"
        "500 (Error)":
          description: "Error al enviar el paquete Wake On Lan."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              error:
                type: string
                example: "(Error description)"
        "500 (Exception)":
          description: "Excepción inesperada al enviar el paquete Wake On Lan."
          schema:
            type: object
            properties:
              success:
                type: boolean
                example: false
              exception:
                type: string
                example: "(Exception description)"

# -----------------------------------------------------------------------------------------------------------
