wiki:Version2/Desarrollo/Communications

Version 3 (modified by edulix, 9 years ago) (diff)

--

Introducción

Las comunicaciones entre clientes y servidor se realizan mediante tareas (jobs). Dichas tareas permiten ejecutar comandos del sistema o comandos de opengnsys en los clientes y recibir información acerca de esa ejecución en el servidor.

Características principales

El sistema de tareas se caracteriza principalmente por:

  • Toda comunicación se establece mediante peticiones GET/POST mediante HTTPS.
  • El socket de comunicación está autenticado siempre entre ambas partes mediante un certificado SSL.
  • Existen tests unitarios de todo el sistema de comunicaciones.

Elementos comunicantes

Existen tres elementos que se comunican entre sí, estos son:

  • La consola web, que es un servicio web que se ejecuta en el servidor y que a instancias del usuario es la que crea una nueva tarea, que se guarda en la BD de la consola y solicita al cliente (o clientes) la ejecución de dicha tarea.
  • El job executer, que es un servicio web que se ejecuta en el cliente donde deben ejecutarse las tareas. Se encarga de recibir las peticiones, ejecutar los comandos asociados a dichas peticiones, y mantener al servidor Opengnsys informado del estado de la tarea.
  • El job receiver, que es un servicio web que se ejecuta en el servidor Opengnsys y es el encargado de recibir las actualizaciones de los clientes, guardarlas en la BD del servidor para que la consola web tenga noticia de las mismas, y procesar las actualizaciones, puesto que cada tarea puede tener asociada una función a tal efecto.

La consola web y el job receiver son sendos servidores web que se ejecutan en el servidor Opengnsys y comparten la misma BD. La razón por la cual fue necesaria la creación de un segundo servicio web (job receiver) es porque mientras que la consola web no autentica mediante SSL al cliente HTTP, el job receiver necesita hacerlo.

Vida de una tarea

La vida de una tarea simple suele ser la siguiente:

  1. Un usuario desde la consola web de administración de Opengnsys solicita la realización de una tarea, por ejemplo restaurar una imagen de disco en un ordenador cliente opengnsys.
  2. La consola web crea un objeto de tipo Job que será guardado en la BD, y realiza una petición HTTPS al job receiver del cliente.
  3. El servicio web job receiver del cliente recibe la petición HTTP, la procesa, y lanza en un hilo el comando a ejecutar.
  4. El job receiver mantiene informado del estado de la tarea al servidor opengnsys mediante mensajes de actualización que se envían mediante una petición HTTP al servicio job receiver del servidor. Básicamente hay dos tipos de actualizaciones:
    1. Actualizaciones de estado, que indican un tipo de estado que puede ser "INPROGRESS", "FINISHED" o "ERROR", y una cadena de mensaje que será procesada por el servidor. INPROGRESS se envía automáticamente cada cierto tiempo en tareas lentas para que el servidor sepa que la tarea sigue en proceso.
    2. Actualizaciones de progreso. Se envían cuando el comando que se ejecuta es de tipo ogr y la salida de información del comando ha lanzado un mensaje de progreso. Este tipo de mensajes de progreso indican dos cosas: el porcentaje de completitud de la tarea, y un mensaje informativo.

Mensajería

Los puertos, certificados SSL utilizados y direcciones ip del job receiver son configurables en los ficheros de configuración config.py de cada servicio web. Por defecto, el servicio web job executer se ejecuta en el puerto 1100, y el job receiver en el 1101.

Los mensajes que se intercambian en este protocolo son los siguientes:

Request

Es el mensaje que envía la consola web al servicio job request de un cliente cuando desde la consola web se solicita la realización de una tarea. La petición debe ir a la url /jobrequest/(?P<id>[0-9]+) del servicio job executer. El id se utilizará para luego poder referenciar este trabajo, y el contenido de los mensajes tiene formato JSON, con los siguientes campos:

{
   'type': '(command|ogr)',
   'command': '<command name>',
   'args' : ['arg1', 'arg2', 'arg3', ...],
   'sequential': (True|False)
   'files': ['data in file 1', 'data in file2', ...]
}

Sólo los dos primeros campos (type y command) son requeridos, el resto son opcionales:

  • El campo type es requerido e indica el tipo de comando y tiene dos posibles valores:
    • command, para ejecutar comandos del sistema.
    • ogr, para ejecutar comandos de ogr.
  • El campo command es requerido e indica qué comando ejecutar.
    • Ejemplos de comandos del sistema (cuando type es command):
      • ls
      • cat
      • /usr/bin/python
    • Ejemplos de comandos ogr:
      • Boot.sh
      • GetIpAddress.sh
  • El campo args es opcional y indica los argumentos que se le pasarán al comando a ejecutar, y es una lista de cadenas. Por ejemplo si queremos ejecutar cat /dev/null, el valor de args sería ['/dev/null'].
  • El campo sequential es opcional e indica si el comando se debe ejecutar inmediatamente (False), o debe encolarse de tal manera que se ejecute en la cola de comandos importantes que se deben ejecutar uno detrás de otro (True). Por defecto los comandos se ejecutan inmediatamente sin ser encolados.
  • El campo files es opcional y contiene una lista de cadenas que contienen datos que deben meterse en un fichero temporal y pueden ser referenciados mediante la lista de argumentos args. Así, el primer fichero puede ser referenciado en args utilizando un argumento con valor '$0', el segundo fichero con '$1', y así sucesivamente.