Con una API definida e implementada, es el turno de crear los clientes que han de interactuar con ella: los CGIs y plantillas en mason. Tal y como vimos en Sección 7.1, nuestro módulo va a poder prestar el servicio de sincronización a un cliente de la red. En Sección 7.3 implementamos los métodos necesarios para realizar esta habilitar o deshabilitar este servicio. Ahora crearemos dos CGIs y una plantilla en mason que van hacer uso de esos métodos y mostrarán información sobre el estado del servicio al usuario.
El primer CGI es EBox::CGI::NTP::Index,
que hereda de la clase EBox::CGI::ClientBase
e implementa el constructor de la clase en el que le pasaremos:
el título y la plantilla en mason a utilizar. Veamos la
implementación:
Ejemplo 7.11. Constructor del CGI EBox::CGI::NTP::Index
package EBox::CGI::NTP::Index;
use strict;
use warnings;
use base 'EBox::CGI::ClientBase';
use EBox::Global;
use EBox::Gettext;
sub new {
my $class = shift;
my $self = $class->SUPER::new('title' => NTP,
'template' => 'ntp/index.mas', @_);
$self->{domain} = "ebox-ntp";
bless($self, $class);
return $self;
} Fijémonos en un detalle interesante, la cadena
title de este CGI no es traducible
y es por ello que no seguimos las indicaciones de Sección 2.4.1 acerca del uso de cadenas en el
desarrollo de módulos. En el caso de que el título de alguno de
nuestros CGIs fuera traducible, sí deberiamos seguir las indicaciones
de Sección 2.4.
Pasemos ahora a implementar el método
_process que va a obtener la información sobre
el estado del servicio de sincronización del módulo y se la va a pasar
a la plantilla en mason para que la muestre.
Ejemplo 7.12. Envío del estado del servicio a la plantilla mason
sub _process
{
my $self = shift;
my $ntp = EBox::Global->modInstance('ntp');
my @array = ();
my $active = 'no';
if ($ntp->service()) {
$active = 'yes';
}
push (@array, 'active' => $active);
$self->{params} = \@array;
}Como podemos ver, lo primero que hacemos es pedir a
EBox::Global una instancia de nuestro
módulo ntp, sobre el que realizaremos una llamada al método
service. Esta llamada nos retorna el
estado del servicio y se lo pasamos a plantilla mason mediante
el atributo param. En este caso solo
vamos a necesitar pasarle un dato a la plantilla, pero si
necesitáramos pasarle mas datos bastaría con añadirlos a la variable
array.
Acabamos de implementar el CGI con el que pasamos el estado del servicio de sincronización a la plantilla en mason. Pasemos a implementar el CGI que le complementa, que recibe el estado que el usuario ha seleccionado y se lo pasa al módulo.
Ejemplo 7.13. CGI que habilita o deshabilita el servicio NTP
package EBox::CGI::NTP::Enable;
use strict;
use warnings;
use base 'EBox::CGI::ClientBase';
use EBox::Global;
use EBox::Gettext;
sub new
{
my $class = shift;
my $self = $class->SUPER::new('title' => 'NTP', @_);
$self->{redirect} = "NTP/Index";
$self->{domain} = "ebox-ntp";
bless($self, $class);
return $self;
}
sub _process
{
my $self = shift;
my $ntp= EBox::Global->modInstance('ntp');
$self->_requireParam('active', __('module status'));
$ntp->setService(($self->param('active') eq 'yes'));
}
1; Vemos que la implementación es muy sencilla, tan solo tenemos que tener en cuenta dos detalles.
Por un lado que en el constructor establecemos el
atributo redirect con el valor de
NTP/Index para que cuando establezcamos el nuevo
estado del servicio, se llame de nuevo a ese CGI para actualizar el
valor del estado del servicio que se muestra al usuario.
El otro detalle que debemos fijarnos es la llamada a
setService en la que recogemos el parámetro
active de la petición HTTP mediante la llamada
$self->param('active').
Vamos a implementar ahora la plantilla mason que nos permite
mostrar al usuario el estado del servicio de sincronización y
modificarlo. Este es un caso un tanto especial, casi todos los
módulos que se desarrollen para eBox van a necesitar habilitar e
deshabilitar el servicio. Para que en todos ellos se haga de una
manera similar se implementó en el sistema base la plantilla
enable.mas.
La manera de utilizarla es sencilla, nos creamos una plantilla que recibe como parámetro el estado del servicio. Tal y como se explicó en Sección 5.2 podemos incluir una plantilla mason dentro de otra plantilla mediante:
<& plantilla.mas, @parametros &>
. Nosotros
incluiremos la plantilla enable.mas en la que
nos estamos implementando y le pasaremos como parámetros el título
y el estado del servicio de sincronización. Veamos como quedaría su
implementación:
Ejemplo 7.14. Plantilla mason para habilitar el servicio NTP
<%args> $active </%args>
<%init> use EBox::Gettext; </%init>
<div class='ntpnew'>
<br />
<& enable.mas, title => __('Enable the local NTP server'),
active => $active &>
</div>
Sin embargo este sistema nos obliga a que el CGI que se
encargue de habilitar o deshabilitar el servicio se ha de llamar
Enable ya que quien realiza la llamada a este
CGI no es nuestra plantilla mason, si no la plantilla mason predefinida
enable.mas. Si echamos otro vistazo al CGI que
realiza esta operación, vemos que hemos llamado a la clase como
EBox::CGI::NTP::Enable con lo que cumplimos este
requerimiento.
En este momento nos queda por ver como están implementados los CGIs para cambiar la fecha y hora del sistema de manera manual, cambio de la zona horaria y el establecimiento del servicio de sincronización mediante servidores externos junto con sus plantillas en mason. La implementación de estos CGIs y plantillas es bastante sencilla, para ver el código puede ir al repositorio de subversion y descargarlo libremente. El lector podrá realizar una lectura del código sin problemas asi que no entraremos a explicar el código en profundidad y simplemente explicaremos cómo están relacionados y que es lo que hace cada uno de los ficheros.
Tenemos dos partes bien diferenciadas, por un lado vamos a poder cambiar la zona horaria del sistema cuya gestión la realizaremos mediante dos CGIs.
Timezone que será el
encargado de mandar información a la plantilla en mason
(timezone.mas).
ChangeTimeZone con el que recogeremos
la nueva zona horaria y la estableceremos mediante el método
SetNewTimeZone.
Tan solo quedaría comentar un pequeño detalle del CGI
TimeZoner. En él mandamos a la plantilla en
mason los valores de continente y país que tiene el sistema en ese
momento y por otro lado le mandamos un array con todos los continentes
posibles y una tabla hash en la que se relacionan cada uno de los
continentes anteriores con un array con los paises que pertenecen a ese
continente. Toda esta información nos está accesible en el fichero
/usr/share/zoneinfo/zone.tab.
La otra parte es el cambio de fecha y hora del sistema, que
bien lo podremos realizar manualmente o sincronizándonos a través
de servidores ntp externos. La implementación de estas opciones va a
ser excluyente. Vamos a tener el CGI Datetime,
cuya misión va a ser enviar toda información acerca de la fecha y
hora actual del sistema, el estado del servicio de sincronización
externa y los servidores ntp externos almacenados en la configuración
interna de gconf. Para establecer los nuevos valores que el usuario
haya elegido vamos a tener dos CGIs: Synch cuyo
trabajo será habilitar el servicio de sincronización externa y
ChangeDate que como podemos adivinar establecera
la nueva fecha y hora del sistema.
Hemos dicho antes que la opción de establecer la fecha y hora de
manera manual o mediante sincronización externa son excluyentes, tarea
realizada mediante las plantillas en mason. Veamos como implementarlo.
Por un lado tenemos la plantilla datetime.mas
que recibe toda información del CGI Datetime,
carga la plantilla mason synch.mas que ofrece
la posibilidad de arrancar o no el servicio de sincronización
externa y, dependiendo de si está activado o no, mostrará la
plantilla de selección de servidores ntp externos a los que
sincronizarse(servers.mas) o permitirá cambiar
manualmente la fecha y hora del sistema mediante otra plantilla
(date.mas) si el servicio de sincronización
externa está habilitado.
Ejemplo 7.15. Código de plantilla mason de selección de plantillas
<& /ntp/synch.mas, title => __('Synchronize with external NTP servers'),
synchronized => $synchronized &>
% if ($synchronized eq 'yes') {
<& /ntp/servers.mas, title => __('External NTP servers'), servers => \@servers
&>
% }
% if ($synchronized eq 'no') {
<& /ntp/date.mas, title => __('Change Date and Time'), date => \@date &>
% }Las plantillas synch.mas,
server.mas y date.mas
simplemente muestran la información que desde la plantilla
datetime.mas se les manda.