SyntaxHighlighter

miércoles, 16 de septiembre de 2015

Crear un nuevo item en el menú de Aplicaciones de Fedora 22

En el último post hablé sobre la instalación de Packet Tracer en Fedora. Tenemos el programa y funciona, pero aún no tenemos esa nueva aplicación en el menú de aplicaciones ni tampoco aparece como aplicación en el menú contextual cuando hacemos clic derecho sobre un fichero. Vamos a configurarlo.

Lo más fácil es instalar "alacarte", que es un gestor de menús para Gnome y añadir el programa. Alacarte nos creará un fichero en ~/.local/share/applications/ con extensión .desktop en el que podremos ver una información como esta:


[Desktop Entry]
Comment=
Terminal=false
Name=Packet Tracer
Exec=/opt/pt/bin/PacketTracer6
Type=Application
Categories=Application;Network;
Icon=/opt/pt/art/app.png

Sólo con esto ya tenemos la aplicación en el menú. Pero si además queremos que aparezca en el menú contextual cuando pinchamos encima de un fichero del tipo Packet Tracer, debemos añadir algunas opciones más para que quede como sigue:


[Desktop Entry]
Comment=
Terminal=false
Name=Packet Tracer
Exec=/opt/pt/bin/PacketTracer6 %f
Type=Application
Categories=Application;Network;
Icon=/opt/pt/art/app.png
MimeType=application/octet-stream


Necesitamos asociar un tipo Mime que se corresponda con el tipo del fichero y además añadir el "%f" al final de la línea del ejecutable para que Gnome interprete que es una aplicación que puede abrir fichero y, por tanto, lo muestre en el menú contextual en los ficheros que coincidan con su tipo mime.

miércoles, 26 de agosto de 2015

CISCO Packet Tracer 6.2 en Fedora 22

Cambio de portátil y cambio de sistema operativo también... Dejo mi antiguo MacBook de plastiquete blanco y lo cambio por un Mountain donde poder ejecutar Linux sin complicaciones.

Como últimamente empiezo a empacharme de Ubuntu, he decidido darle una oportunidad a Fedora, confiando en que la gente de RedHat lo haga lo mismo de bien que en sus productos para empresas.

El sistema se instala rápido y GNOME 3 me gusta un poco más que Unity. A priori parece que la comunidad de Fedora es menos numerosa y la variedad de paquetes de sus repositorios es menor ya que Fedora sólo admite paquetes OpenSource. Esperemos que sean suficientes para las tareas diarias, entre ellas la simulación de redes con Packet Tracer.

Packet Tracer se dejaba instalar en MacOS usando Wineskin, pero la verdad es que no funcionaba todo lo rápido que se podría es
perar. Los sistemas que CISCO recomienda son Windows y Ubuntu Linux.

Para instalar Packet Tracer en Fedora 22 he seguido algunos pasos de este blog, con algunas modificaciones.

Primero descargamos, descomprimimos e instalamos Packet Tracer 6.22. Aunque el programa se instala no se ejecutará ya que necesita algunos ajustes
Primero descargamos libopenssl.

wget ftp://fr2.rpmfind.net/linux/opensuse/update/12.2/x86_64/libopenssl1_0_0-32bit-1.0.1e-2.8.1.x86_64.rpm

Necesitamos satisfacer las dependencias (glibc.i686 y zlib) para poder continuar:

sudo dnf install glibc.i686
sudo dnf install zlib.i686

Ahora sí podemos instalar libopenssl y ejecutar Packet Tracer.

sudo rpm -Uvh libopenssl1_0_0-32bit-1.0.1e-2.8.1.x86_64.rpm
/opt/pt/bin/PacketTracer


miércoles, 25 de marzo de 2015

Buscando y moviendo ficheros a un punto de montaje (script bash)

Supongamos que tenemos una máquina que va almacenando ficheros constantemente, por ejemplo, una máquina que hace copia de seguridad de otras remotamente y almacena los ficheros de forma indefinida. Habrá un momento en el que consumiremos todo el espacio. La solución sería plantearnos una política de borrado de ficheros o mover esos ficheros a unidades fuera del almacenamiento local de la máquina.

Los ficheros podrían ser copiados a otro servidor con rsync o scp, pero en este caso voy suponer que tenemos una unidad de red o un disco USB montado de forma permanente en un directorio de la máquina.

El problema con los puntos de montaje es que el directorio sobre el que se monta el dispositivo siempre está creado y si por algún motivo el dispositivo se desmonta, escribiremos sobre ese mismo directorio pero en el almacenamiento local del servidor. Esto puede hacer que acabemos con el espacio del servidor en una operación de copia fácilmente. Para evitar ese problema el script primero comprobará que efectivamente estamos escribiendo sobre un punto de montaje activo.

El script está programado de manera que se pueda ejecutar desde cron, no recibe parámetros, toda la configuración se realiza modificando las variables de las primeras líneas.  La variable TEXT_IN_FILEPATH, en realidad es una expresión con wildcards que se buscará en el path completo del fichero, por lo que podemos usar cualquier subcadena del path del fichero para realizar la búsqueda.


#!/bin/bash
#This script perform a find command to look for files path in "SOURCE_DIRECTORY" containing "TEXT_IN_FILEPATH" substring RECURSIVELY, then move to a target mount point path.
#The script checks the target directory is a mount point to ensure that the files will be written to an external device.
SOURCE_DIRECTORY=/var/backups/
TARGET_MOUNT_POINT=/media/NAS
TARGET_PATH=/db_backup
TEST_MODE=0
TEXT_IN_FILEPATH='*monthly*bz2'
#********************************************************************************************************************************

MOVED_FILES=0
DIRECTORIES_CREATED=0
if ! mountpoint -q $TARGET_MOUNT_POINT
then
 echo "Not a Mount Point"
 exit 1;
fi

if [ ! -e "$TARGET_MOUNT_POINT$TARGET_PATH" ] 
then
 echo "Target directory not created"
 exit 1;
fi

for i in `find $SOURCE_DIRECTORY -wholename "$TEXT_IN_FILEPATH" -type f` 
do 
# Build target filename: target mount point + target directory inside mountpoint + file without source_directory path begining
 TARGET_FILE=$TARGET_MOUNT_POINT$TARGET_PATH${i/"$SOURCE_DIRECTORY/"//}
 TARGET_FILE_PATH=`dirname $TARGET_FILE`

 
 if [ ! -d $TARGET_FILE_PATH ]
 then
  if [ $TEST_MODE -gt 0 ]
  then
   #TEST MODE
   echo "TEST MODE: mkdir -p $TARGET_FILE_PATH" 
  else
   echo "Creating folder: $TARGET_FILE_PATH"
   mkdir -p $TARGET_FILE_PATH   
   ((DIRECTORIES_CREATED++))
  fi
 fi

 if [ $TEST_MODE -gt 0 ]
 then
  #TEST MODE
  echo "TEST MODE: mv $i $TARGET_FILE_PATH"
 else
  echo "Moving $i"
  mv $i  $TARGET_FILE_PATH
  ((MOVED_FILES++))
 fi
done

echo "Moved backups files summary"
echo "$DIRECTORIES_CREATED directories created"
echo "$MOVED_FILES moved"

martes, 3 de febrero de 2015

Ubuntu 14.04 LTS + MACOSX Lion en MacBook

Desde 2008 mi viejo MacBook 4.1 de plastiquete blanco lleva dando guerra... Una ampliación de memoria (a 4GB), después un cambio de disco duro (un WD de 500GB 7200rpm). Durante algún tiempo tuve arranque dual SnowLeopard+Linux 12.04, pero con mi antiguo disco de 120GB estaba un poco escaso de espacio así decidí dejar sólo MACOSX.

La gran mayoría de las herramientas que uso tienen su equivalente en OSX: LibreOffice, terminal, editores de texto, Dropbox... Pero siempre hay momentos en los que echas de menos algunos programas que no tienen equivalente o que te ves obligado a ejecutar de forma precaria usando "trucos" como Wineskin, VirtualBox, un emulador de X11...
Dispuesto a hacer una pequeña limpieza y reinstalar el entorno Linux+OSX, os cuento como lo he hecho.

Cada cosa en su lugar

Vamos a cargarnos todo, así que una copia de seguridad en dispositivo externo es OBLIGATORIA.
El esquema de particionado del disco sería:
  • OSX
  • Linux
  • Linux-swap
  • DatosCompartidos
Estas son las particiones que recomiendo. Una partición para OSX el sistema de archivos hfsplus. Una partición para la raíz (/) de Linux, elegid vuestro filesystem preferido, ext4 por ejemplo. Linux-swap, la partición de intercambio. Una partición de Datos que usaremos de comodín, para que sea accesible tanto por OSX como por Linux.

En mi ordenador tenía ya dos particiones hechas: OSX y Datos. Reduciré la partición de OSX y en el espacio que gane crearé las particiones de Linux. Después explicaré como se puede conseguir acceder a la partición de datos con formato hfsplus desde Linux, que tiene su aquel. Si no queréis complicaros mucho elegid FAT32, pero tened en cuenta que tenéis un techo de 4GB en el tamaño de fichero; o NTFS, que os obligará a instalar macfuse/osxfuse o similar en OSX.

Instalar los Sistemas Operativos y el gestor de arranque

El orden que yo he seguido ha sido OSX -> Gestor de Arranque -> Linux -> Reinstalar Gestor de Arranque. Posiblemente instalando primero Linux podría haberme ahorrado la reinstalación del Gestor de Arranque.

Instalar OSX no tiene ninguna ciencia. Se introduce el disco y se siguen las instrucciones, con cuidado de instalarlo en la partición correcta.

Tras OSX, podemos instalar rEFInd, un gestor de arranque sucesor de rEFIt. La instalación es muy sencilla. Sólamente hay que abrir un terminal y hacer un

sudo ./install.sh

La próxima vez que arranquemos saltará un gestor de arranque. Aprovechamos ahora para introducir el disco de Ubuntu 14.04 LTS, importante que sea de 64 bits. El arranque de Ubuntu 32 bits no es compatible con la EFI de MAC.

Instalamos Ubuntu. También trivial, ojo con las particiones! Cuando Ubuntu pregunta dónde instala grub (su propio gestor de arranque) elegimos el disco que ofrece por defecto.

El problema de esto es que habremos sobreescrito rEFInd. Para recuperarlo, podemos iniciar el ordenador pulsando el botón de "opción" (alt), para elegir el disco de arranque y elegimos de nuevo OSX, para arrancar el sistema y volver a instalar rEFInd usando install.sh.

Arreglar cosas que no funcionan en Ubuntu

Y una vez Unbuntizados, vemos que hay cosas que no van bien. En mi caso el panel táctil no funciona. Busco en el cajón un ratón USB y le hago caso a los amigos de la página de ayuda de ubuntu. Reviso que synaptics-input esté instalado en el sistema, busco el archivo /usr/share/X11/xorg.conf.d/51-synaptics-quirks.conf y añado las siguientes líneas:

Section "InputClass"
        Identifier "Apple Macbook 4,1"
        MatchProduct "appletouch"
        MatchDevicePath "/dev/input/event*"
        Driver "synaptics"
        Option "JumpyCursorThreshold" "20"
        Option "FingerLow" "10"
        Option "FingerHigh" "20"
        Option "FingerPress" "200"
        Option "MaxTapTime" "0" 
EndSection

MaxTapTime = 0 desactiva el molesto "tap to click", que interpreta que hacemos clic cuando tocamos el touchpad. Más información sobre el significado de las opciones aquí.
Reinicio el servidor X saliendo de la sesión y entrando otra vez y arreglado, ya tengo ratón. Funcionan los gestos (arrastrar con dos dedos para simular la rueda de scroll).

Un sistema de archivos compartido por un León y un pingüino. 

Si optamos por FAT32 o NTFS. No tendremos mayores problemas. Solo hay que instalar el soporte correspondiente y montar el sistema en Linux con permisos de escritura. En cambio, para hacer que un usuario "no root" de Linux sea capaz de escribir en hfsplus, el id de usuario Linux debe coincidir con el id del propietario del fichero en hfsplus, que normalmente es 501 para MACOSX, así ambos sistemas no entrarán en conflicto y creerán que los ficheros están siendo modificados por el mismo usuario.

Para conseguirlo debemos cambiar el uid del usuario de Linux al que queremos permitir la escritura en el sistema de archivos hfsplus... Y esto es un poco delicado: en Ubuntu, por defecto no podemos entrar como root. Entramos con un usuario sin privilegios y utilizamos la orden sudo para tareas de administración. Pues bien, si intentamos cambiar el uid del usuario con el que hemos iniciado la sesión el sistema informa que ese usuario tiene una sesión abierta y no es posible. Sin problema, creamos un usuario adicional, y ejecutamos la orden de cambio del uid.

sudo usermod --uid 501 emilio

Reiniciamos la sesión X y... oh, sorpresa!! El usuario emilio no está entre los disponibles para el inicio de la sesión. El motivo es que Linux empieza a numerar los usuarios regulares por el número 1000 y no muestra los que tienen uid menores ya que suelen ser usuarios del sistema. Pero en Linux casi siempre podemos arreglar cosas tocando en el correspondiente fichero de texto, en este caso: /etc/login.defs. Buscamos la opción UID_MIN y la cambiamos a 500.

Y listo, ya tenemos todo configurado. MACOSX Lion + (X)Ubuntu 14.04 en mi viejo MacBook 4.1.

Felices y contentos, ahora sólo me falta encontrar una pegatina de Tux para pegarla encima de la manzanita... Donde podré encontrar una de estas??




Referencias:
Instalación y configuración del arranque dual con rEFInd
Configuración de hfs en ubuntu
Configuración del touchpad

viernes, 31 de octubre de 2014

Cambio de disco en una cabina de discos HP Modular Smart Array (MSA 2000)

No es la primera vez, ni será la última. Puedes gastarte un dineral en comprar los dispositivos más fiables del mercado, intentar que las condiciones de funcionamiento sean las mejores (UPS, refrigeración, etc) pero al final sabes que se romperán.

Los administradores de sistemas tenemos la obligación de ser paranoicos dentro de las posibilidades económicas de la empresa y las de que nuestra salud mental, por eso en cada intervención delicada en uno de nuestros sistemas debemos, al menos:

  1. Ponernos al día sobre la actuación leyendo el material recomendado por el fabricante, foros explicando procedimientos similares
  2. Documentar el estado actual del sistema, para poder reproducirlo después del cambio: versiones del software, opciones de configuración más importantes, etc
  3. Ensayar la actuación en un sistema de pre-producción
  4. Hacer copias de seguridad
  5. Si es posible tener un sistema "gemelo" montado aunque sea en máquinas menos potentes o virtuales para usar como "plan B" en caso de que las cosas se compliquen
  6. Hacer copias de seguridad... ¿Lo he puesto antes? Da igual, no está de más decirlo otra vez
Presento el sistema. Matriz de discos HP MSA Modular:


Los sistemas de gama empresarial normalmente sintonizan con nuestra paranoia. Algo tan aparentemente leve como que uno de los discos tarde un poco más en girar (spin-up time) o se detecte alguna anomalía eléctrica hace que se disparen las alarmas y el disco pase a ser "no confiable". Ahora entran en juego dos conceptos muy importantes en sistemas de este tipo.

RAID y SPARE

  • RAID. Algunas configuraciones de RAID son tolerantes a fallos, de manera que aunque perdemos espacio de almacenamiento ganamos seguridad. Por ejemplo, un conjunto de discos configurados en RAID 5 utiliza el espacio de almacenamiento de un disco como espacio de redundancia, de manera que si perdemos un disco, no se pierden datos. Se puede sustituir por otro disco y el sistema reconstruirá el conjunto.
  • Discos SPARE (hotspare) o "discos reserva". Además podemos definir dentro de la cabina discos que no se utilizan, pero están preparados para sustituir a otro que falle inmediatamente, sin intervención nuestra.
En sistemas de este nivel SIEMPRE se utiliza algún sistema de redundancia que variará para maximizar la seguridad, la velocidad de escritura, la velocidad de lectura, etc.,  y, por supuesto, discos spare.

Por ejemplo, los sistemas RAID 1 (mirror) acelera las lecturas ya que se puede leer de dos discos al mismo tiempo, en cambio, la escritura lleva un tiempo similar a sistemas de disco único. Usamos la mitad de la capacidad total en datos de redundancia. Aquí somos tolerantes a fallos siempre que el disco o discos se encuentren en el mismo conjunto del espejo.

Otros niveles de RAID, como RAID5, hacen que se pierda menos espacio. Si tenemos n discos, el espacio total será el de n-1 discos ya que uno se usa como disco redundante. Aquí no se gana tanto rendimiento de lectura como en RAID1 pero aún así, bajo ciertas circunstancias, se acelera la lectura respecto a sistemas de disco único. La escritura se ve penalizada al tener que calcular el contenido del bloque de paridad, que ya no es un proceso tan inmediato como hacer una copia del bloque en otro disco. Este nivel RAID tolera fallos en un sólo disco. RAID6, es similar a RAID5, pero usa dos discos para redundancia, por lo que se tiene tolerancia a fallos en dos discos.

Las combinaciones de niveles RAID están permitidas. Es decir, se puede hacer RAID5+0.

Frío y Calor

Hay sistemas capaces de implementar RAID en software, pero lo interesante es tener una controladora de discos que lo soporte en hardware y así hacerlo menos dependiente del sistema operativo. Éste es el caso de las controladoras de discos que estamos viendo.

Suponiendo una configuración RAID5 con spare, en el momento que falle un disco, la cabina lo detecta, lo tacha como "no confiable" y usa el disco spare como nuevo disco en el conjunto RAID. Este proceso puede hacerse en frío, si necesitamos reiniciar el sistema o dar la orden de resconstrucción y esperar el tiempo necesario para que se reconstruya; o en caliente, si la controladora es capaz de seguir dando servicio mientras el disco spare se reconstruye y además no necesita que intervengamos en el proceso.

Rompiendo un disco

Lo que voy a hacer es reproducir el proceso de sustitución de un disco en fallo en una cabina en la que todos los discos están bien. Extraeré uno de los discos del array para simular en fallo. 
Primero vamos a ver el estado de la cabina:


En la imagen vemos que hay ocho discos, siete forman un conjunto RAID6 y uno de ellos configurado como SPARE. Podrían romperse dos discos del conjunto RAID6 y aún no perderíamos datos. Además, como veremos, en el momento que falle uno de ellos el disco SPARE intentará sustituirlo.

Otra vista, pero esta vez voy a insertar un disco nuevo en la cabina. Como no hemos dicho para qué debe utilizar ese nuevo disco lo define como "disponible". Este disco no se utilizará para nada hasta que no se defina su función de forma explícita. Vemos el disco spare (VDISKSP).


Sacamos un disco y a ver que pasa.


Reconstrucción de un VDISK (RAID 6)

Si pinchamos en el estado de la MSA vemos que ha empezado a reconstruir el RAID6 inmediatamente. El proceso tardará unas horas dependiendo del tamaño del VDISK, la configuración RAID y el grado de utilización de los datos de la cabina mientras se hace la reconstrucción ya que la cabina seguirá activa para lectura y escritura.

En la figura anterior tenemos varios campos relacionados con la salud (health). Vemos que la cabina está degradada aunque aún es tolerante a fallos. En la parte inferior vemos en current job que el disco se está reconstruyendo.


En el esquema gráfico de la cabina se puede ver que hemos vuelto "pinchar" el disco en su lugar. La MSA sabe qué disco es, sabe que ha estado pinchado con anterioridad y por algún motivo ha fallado, así que lo marca como LEFTOVR (descartado). No usará este disco más a no ser que la "hagamos olvidar".

Una vez reconstruido el disco tenemos esta estructura.


El disco 1.8 que antes estaba como SPARE pasa a formar parte del VDISK.

Ahora para recuperar el disco que hemos sacado debemos borrar sus metadatos. Esto se puede hacer desde la opción clear disk metadata, como vemos en la imagen siguiente.


Borrando los metadatos el disco volverá a estar disponible (AVAIL). Por último modificamos los discos SPARE de la MSA para incluir estos discos disponibles no usados.


En el menú provisioning la opción Manage Global Spares donde podemos definir los discos que se podrán usar como SPARE en cualquier VDISK de la MSA. También podríamos definir discos SPARE reservados para un VDISK determinado.

Este sería el estado final donde se ve el primer disco que retiramos de la cabina como Global Spare. Y el VDISK totalmente reconstruido.


Todo correcto :D



viernes, 21 de marzo de 2014

Data Protector. Recuperación usando la directiva POST-EXEC y SCRIPTING

Con Data Protector podemos programar una agenda de copias de seguridad fácilmente usando la GUI Java, lo que no es tan simple es planificar una calendario de restauración que, por ejemplo, recupere la última copia de seguridad realizada en otra localización.

La primera aproximación sería intentar ejecutar esta restauración llamando al programa omnir con los argumentos necesarios e incluir la llamada en el cron del servidor para que se ejecute periódicamente. Lo que a priori parece algo sencillo se complica con sólo mirar la la página de manual de omnir (o buscar "data protector cli reference" en cualquier buscador). El Backend de comandos de Data Protector da toda la funcionalidad que necesitamos para restaurar una copia de seguridad, pero es necesario la ejecución de varias órdenes para "montar" los argumentos que necesita omnir.

Hay otro problema en cuanto a la inclusión en cron de esta orden podría dar lugar a solapamientos en el uso de la unidad sobre la que estemos haciendo la copia de seguridad.

Imaginad que la copia de seguridad programada comienza a las 2:00 am, y nuestra orden de restauración se ejecuta vía cron a las 4:00 am. Si la copia de seguridad tarda más de 2h, la restauración se podrá en cola. Pasado cierto tiempo de espera configurable en Data Protector, si aún no ha comenzado el trabajo de restauración, se procederá a su cancelación. Esto se puede evitar usando las opciones POST-EXEC y PRE-EXEC del trabajo de copia de seguridad.

Estas dos opciones se encargan de ejecutar un script en el cliente de data protector que indiquemos antes (PRE-EXEC) o después (POST-EXEC) de que se realice el trabajo de backup. El uso más extendido de estas dos opciones es el de parar un servicio antes de realizar el trabajo de copia y levantarlo después.

Para conseguir el comportamiento que necesitamos lo ideal sería ejecutar un script en POST-EXEC que llame a omnir con los datos de la última copia de seguridad. Para conseguir los datos necesarios de la última sesión de copia de seguridad hay que ejecutar la orden onmidb, que consulta la BD de Data Protector para extraer la información que requiere omnir:

/opt/omni/bin/omnir -filesystem [datalist] [label] -session [session] -tree [path] -as [target_path] -target [target_client]

Pasos del script:
  1. Considera un número de días hacia atrás desde la fecha actual para buscar la última sesión de la agenda especificada.
  2. Determinar sesión más reciente que se terminó satisfactoriamente en el intervalo definido en el paso anterior.
  3. Buscar el árbol de directorios que queremos restaurar y extraer el datalist y label, argumentos necesarios para ejecutar omnir.
  4. Ejecutar omnir con los parámetros adecuados.
El código del script (un poco sucio):

#!/bin/bash
OMNI_PATH=/opt/omni/bin/

if [ $# -ne 5 ]; then
  echo "Ilegal number of arguments" >&2
  echo "Use: $0 [dataList] [label] [targetClient] [targetDir] [RestoreOnlyIfFull 0/1]" >&2
  exit 1
fi

ARG_DATALIST=$1
ARG_LABEL=$2
ARG_TARGETCLIENT=$3
ARG_TARGETDIR=$4
ARG_ONLYFULL=$5
DAYSTOINSPECT=30

INITIALDATE=$(date '+%Y/%m/%d' --date="${DAYSTOINSPECT} days ago")
LASTSESSION=$(${OMNI_PATH}omnidb -session -datalist $ARG_DATALIST -since $INITIALDATE | grep -i backup | grep -i completed | tail -n1 | cut -f 1 -d " ")
FILESYSTEM=$(${OMNI_PATH}omnidb -session $LASTSESSION | grep \'${ARG_LABEL}\' | cut -f1 -d " ")
LABEL=$(${OMNI_PATH}omnidb -session $LASTSESSION | grep \'${ARG_LABEL}\' | cut -f2 -d " ")
BACKUP_LEVEL=$(${OMNI_PATH}omnidb -filesystem $FILESYSTEM ${ARG_LABEL} -session $LASTSESSION | egrep -o "Incremental|Full")

if [ -z "$LASTSESSION" ]; then
 echo "Session not found: $ARG_DATALIST. Available schedules:"
 ls /etc/opt/omni/server/schedules >&2
 exit 1
fi

if [[ $ARG_ONLYFULL -eq 1 && $BACKUP_LEVEL != "Full" ]]; then
 echo "Mode is set to full but cannot find full backup" >&2
 exit 1
fi

if [ -z "$LABEL" ]; then 
 echo "Label not found: $ARG_LABEL. Backed up filesystems and labels:"
 omnidb -filesystem >&2
 exit 1
fi

#Print command options
echo "Restoring label: ${LABEL}, filesystem: < $FILESYSTEM > from Session: $LASTSESSION into ${ARG_TARGETCLIENT}:${ARG_TARGETDIR}, backup_level: $BACKUP_LEVEL"
#Print omnir command used to perform the restore job. Debug.
echo ${OMNI_PATH}omnir -filesystem ${FILESYSTEM} ${LABEL} -session ${LASTSESSION} -tree ${ARG_LABEL} -as ${ARG_TARGETDIR} -target ${ARG_TARGETCLIENT}
OMNI_COMMAND="${OMNI_PATH}omnir -filesystem ${FILESYSTEM} ${LABEL} -session ${LASTSESSION} -tree ${ARG_LABEL} -as ${ARG_TARGETDIR} -target ${ARG_TARGETCLIENT}"
eval $OMNI_COMMAND

Si a la orden omnir que se llama al final del script añadimos -full antes del argumento -filesystem se restaurará una copia completa del árbol de directorios usando la última copia completa que se realizó y todas las incrementales hasta la sesión que estamos restaurando. De otra manera sólo se restaurarán los ficheros que se respaldaron en la sesión en cuestión.  El último argumento del script controla los problemas que se puedan derivar de esto: sólo se ejecutará la restauración si la última copia ha sido full.

No está de más ejecutar el script comentando la última línea (eval ...), para comprobar que todo es correcto antes de empezar a utilizarlo. Si alguno de los parámetros no es correcto imprimirá posibles soluciones.

Por último, el directorio en el que tenemos que incluir el script para que no haya problemas es /opt/omni/lbin y así podremos llamarlo sin usar path completo, algo que parece que no funciona bien si configuramos el POST-EXEC desde la GUI Java.

NOTA. Si la restauración toma demasiado tiempo, Data Protector puede abortar el Script. Para evitarlo se puede modificar la opción ScriptOutputTimeout en el fichero /etc/opt/omni/server/options/global

jueves, 20 de marzo de 2014

Netstat y Zabbix

Ya he hablado otras veces de la herramienta de monitorización de servidores Zabbix y de lo fácil que resulta extenderla.

Hoy hemos recibido una petición por parte de compañeros para que añadiéramos varios monitores más a los datos que se recogen de los servidores, en particular, datos derivados de la ejecución de la orden netstat que devuelve datos sobre las conexiones de red establecidas con el servidor. Por ejemplo, para ver el número de conexiones establecidas a un determinado puerto, ya sean de salida o de entrada. La orden en cuestión es: netstat -an | grep STABLISHED  | grep [port]

Para poder parametrizar la orden he creado un fichero de configuración de zabbix similar al que hay en varios foros para valores de mysql, que nos permite utilizar argumentos. Fichero userparameter_netstat.conf (crear en /etc/zabbix/ e incluir desde el dichero /etc/zabbix/zabbix_agentd.conf):

# Flexible parameter to grab global variables. On the frontend side, use keys like netstat.port[Port_number].
# Key syntax is netstat.port[Port_number].
UserParameter=netstat.port[*],netstat -na | grep $1 | grep ESTABLISH | wc -l
O mejor aún (actualizado):
UserParameter=netstat.port[*],netstat -na | grep ESTABLISH | egrep ':$1[[:blank:]]+' | wc -l

Para considerar sólo cadenas que del tipo: "dos puntos + puerto especificado + espacios" y así, evitar que se incluyan en el conteo líneas que en realidad no son conexiones a ese puerto.
Con esto conseguimos que zabbix_agent responda a peticiones de un nuevo parámetro: netstat.port[puerto] con la orden

netstat-na | grep puerto | grep STABLISH | wc -l

que devuelve el número de conexiones al puerto que se le pase.

Activamos los cambios reiniciando el servicio zabbix-agent. Y probamos que la instrucción funciona correctamente llamando al parámetro por línea de órdenes:
[root@host zabbix]# zabbix_agentd --test netstat.port[80]
netstat.port[80]                            [t|4]

En caso de no estar bien configurado la respuesta sería
[root@host zabbix]# zabbix_agentd --test netstat.port[80]
netstat.port[80]                            [t|NOT_SUPPORTED]

Ya tenemos la "parte cliente" hecha. Ahora toca crear una plantilla que podamos asociar a nuestros hosts para que se llame a ese parámetro de usuario.

Vamos a la sección de plantillas dentro de la administración de Zabbix y creamos una nueva plantilla. Añadimos tantos items como puertos queramos monitorizar. Por ejemplo para el puerto HTTP usaríamos la siguiente definición de item:

netstat.port[80]

Añadimos los items que queramos y por último podemos incluso añadir un gráfico a la plantilla añadiendo todos los monitores de netstat.

Una vez creada la plantilla hay que enlazarla al host que queremos monitorizar y que debe tener en su fichero de configuración la definición del userparameter. Activamos los items para que comience su monitorización y listo.

Archivo XML de la plantilla:

    2.0
    2014-03-20T12:10:04Z
    
        
            Templates
        
    
    
        
    
    
        
            Connections (netstat)
            500
            200
            0.0000
            100.0000
            1
            1
            0
            1
            0
            0.0000
            0.0000
            0
            0
            0
            0
            
                
                    0
                    0
                    00DD00
                    0
                    2
                    0
                    
                        Template_Netstat
                        netstat.port[80]
                    
                
                
                    1
                    0
                    BBBB00
                    0
                    2
                    0
                    
                        Template_Netstat
                        netstat.port[43]
                    
                
                
                    2
                    0
                    CC00CC
                    0
                    2
                    0
                    
                        Template_Netstat
                        netstat.port[3306]
                    
                
                
                    3
                    0
                    0000CC
                    0
                    2
                    0
                    
                        Template_Netstat
                        netstat.port[1251]
                    
                
            
        
    

jueves, 13 de febrero de 2014

Alta disponibilidad Moodle

Muy buen vídeo sobre alta disponibilidad para la plataforma Moodle, aunque sea un poco antiguo (Moodlemoot 2009).

Todo el reconocimiento para Antonio Jesús Lozano y Felipe Retortillo.

jueves, 3 de octubre de 2013

Load Testing Moodle con Jmeter

Jmeter es una herramienta muy útil para hacer test de carga de distintas aplicaciones. Es tan flexible puede servir para poner a prueba tanto una aplicación web, como un servidor de base de datos o incluso un servicio tipo SOAP.

La potencia de Jmeter radica en la capacidad para simular la actividad de usuarios o las peticiones a un determinado servicio o aplicación, de forma concurrente. Estas pruebas nos pueden ayudar en el dimensionamiento del servidor, posibles fallos o problemas derivados de la concurrencia, etc.

Otra característica muy interesante de la herramienta es que puede "grabar" la actividad del navegador para después lanzar una determinada cantidad de usuarios o "hebras" que ejecuten esta misma actividad. Esto se realiza creando un proxy en jmeter al que debemos apuntar nuestro navegador. Jmeter se encargará de ir almacenando todas las peticiones que se realicen. Para encontrar más información podéis buscar "jmeter proxy record" o términos similares.

Obviamente cualquier prueba de carga nunca debería ser ejecutada en un servicio/servidor de producción.

Para ponerse al día con la herramienta lo mejor es pasar por su documentación y buscar algún ejemplo en concreto e ir modificándolo para adaptarlo a nuestras necesidades. Esto mismo es lo que he hecho yo, basándome en un plan de pruebas existente en los foros de moodle.org (todos los agradecimientos a su autor). A partir de este plan de pruebas he ido parametrizando algunos procedimientos y adaptando su funcionamiento a los cambios de Moodle v2.5.

Las tareas que he incluido en el plan son:
  • Abrir la página principal de Moodle
  • Login en Moodle
  • Entrar en el curso
  • Acciones del usuario en orden aleatorio:
    • Actividad de texto
    • Mensaje en el chat
    • Mensaje en el foro y contestar a un mensaje en el foro
    • Subir un fichero a archivos privados
    • Enviar un fichero a una actividad (implica subir fichero)
  • Salir de Moodle

Peticiones y respuestas

La forma de proceder para cada una de las tareas de nuestro test será la siguiente:
  1. Realizar una petición al servidor web con una serie de parámetros
  2. Recibir la respuesta del servidor y comprobar que se ha realizado con éxito
  3. Capturar nuevos parámetros que nos serán útiles en peticiones posteriores
  4. Realizar una pausa aleatoria antes de llevar a cabo la siguiente petición y así adaptar el test a los tiempos que emplearía un operador humano.
Pero... ¿Cómo sabemos si una petición ha sido correcta? Lo más indicado es seguir los pasos "manualmente" en el navegador y así ver (directamente en pantalla o abriendo el código fuente devuelto) cual es la respuesta de la plataforma a cada clic. De esta manera podemos ir identificando los textos que se presentarán después de cada petición y utilizarlos en Jmeter.

Bien, ya hemos considerado dos de los elementos más importantes en el diálogo que se establece entre nosotros (o nuestro navegador) y el servidor web: peticiones y respuestas. Pero hay un elemento que aún falta y que es imprescindible si queremos simular ese diálogo: las cookies!! 

Como ya sabéis prácticamente todas las aplicaciones web utilizan cookies. Moodle también necesita crear una cookie en el navegador del usuario para mantener la sesión. En Jmeter dispondremos de un objeto que hará de gestor de cookies de manera que "cada usuario virtual" pueda mantener una sesión con el servidor.

El plan

Variables globales

Definir las "variables globales" del experimento. Como por ejemplo el host al que accederemos y el path dentro de ese host que aloja la plataforma. Esto no es obligatorio, pero siempre está bien para poder cambiar la máquina o la ruta de forma fácil. Si no parametrizamos estos datos tendremos que modificar cada petición cuando queramos probar contra otra máquina o si ha habido cambios en la ruta.
Estas variables no varían durante toda la ejecución del plan, por lo que podemos definirlas a nivel de "Test Plan".
Si llamamos a las variables host y path, cada vez que hagamos una petición podremos utilizar la ruta ${host}${path}. Supongo que queda claro que para hacer referencia al valor de una variable debemos utilizar la forma ${variable}.
Además de estas variables también he definido una ruta para el almacenamiento de los resultados de los tests, donde utilizo la expresión ${__time(yyyyMMdd_HHmm)} que devuelve la fecha y hora en la que se realizó el test.

Grupo de hilos

El siguiente elemento a definir es nuestro grupo de hilos (cuantos hilos y cuantas veces queremos repetir cada hilo). Este elemento será el que contendrá el resto de objetos de nuestro plan. Dentro de este objeto definimos elementos para cada una de las hebras (usuarios) que lanzamos. Esto queda claro si nos detenemos en el elemento UserParameters que contiene una serie de variables que distintas para cada hebra. Por ejemplo, cada hebra accederá con un usuario/contraseña distintos, para ello se sortea  un número del 1 al 10 con la función __Random y se añade al prefijo de usuario y al prefijo de contraseña (UsernameHead y PasswordHead respectivamente). También se tienen los nombres de los objetos de Moodle a los que accederemos: jmeter course, jmeter text assignment, jmeter forum, etc. Estos objetos, así como los usuarios deben estar creados previamente en la instalación de Moodle sobre la que estamos trabajando.

Interacciones con la plataforma

Analizaremos sólo una de las peticiones/respuestas, por ejemplo, la de login. El resto de peticiones son muy similares. Como se ve en la imagen, definimos las variables de la petición en el espacio Parameters. Estos parámetros construyen usando las variables que hemos definido en el grupo de hilos. En la parte superior de la ventana se da el host y el path completo de la petición.



Y ahora podemos comprobar si es usuario se ha identificado correctamente en la plataforma buscando la cadena "you are logged in as", que aparece en cualquier página de Moodle una vez que el usuario se ha identificado. Para ello añadimos un elemento del tipo Response Assertion y la configuramos para que busque la cadena en la respuesta del servidor.


De la respuesta que nos da el servidor también debemos extraer más cosas. Moodle necesita en muchas de las llamadas un id de session sesskey y además nosotros necesitamos el id del curso al que queremos acceder para realizar la próxima llamada que será del tipo

${host}${path}/course/view.php?id=${courseid}

Para obtener el id del curso, por ejemplo, configuramos un elemento de tipo Xpath Extractor que revisará la respuesta del servidor y buscará el id del curso. La expresión que se ha usado es:

substring-after(//*/a[text()='${course_name}']/@href,'=')

Explicación breve:

La función substring-after busca un carácter dentro de una cadena y devuelve la subcadena que hay después de ese carácter.

Lo que hay dentro de la función es una expresión xpath. Estamos diciendo que busque un enlace (tag "a" de HTML) en cualquier parte del documento que tenga como texto el nombre del curso (recordad que lo tenemos definido en las variables) y devuelva el valor de su atributo href. Si el enlace en cuestión es

<a class="" href="http://host/path/course/view.php?id=33">jmeter course</a>

La función devolverá lo que hay después del "=", dentro del atributo href, es decir, 33.



Después se incluyen dos elementos, en elemento de retardo para simular la interacción humana y otro que irá construyendo un gráfico con todas los valores obtenidos en cuando los usuarios ejecuten la tarea en cuestión.

Controladores lógicos

Después de entrar a la plataforma programaremos una serie de tareas que deberán realizar todos los usuarios. Para ello vamos a incluir un controlador lógico de orden aleatorio... ¿Qué quiere decir esto? Las tareas que se incluyen dentro de este controlador serán ejecutadas por las hebras de forma desordenada. Unas hebras entregarán la actividad primero, otras postearán en el foro, etc. Todo para intentar que la actividad sea todo lo "caótica" que podría ser en un periodo de alta actividad en el servidor web.

Subida de ficheros

Además de los parámetros típicos, ya sean vía metodos GET o POST del servidor podemos utilizar ficheros para que sean subidos a la plataforma. En un objeto Request se pueden incluir ficheros dando la ruta al fichero en la sección Send files with the request. Además del MIME/Type y el nombre del parámetro con que se enviará el mismo.



Esto es muy útil cuando estamos probando aplicaciones que previsiblemente recibirán ficheros de cierto tamaño mientras siguen respondiendo a peticiones de otros usuarios.

Depurado

Para intentar detectar fallos en nuestro plan o fallos en nuestra aplicación tenemos dos herramientas básicas que nos ayudarán: El debug sampler y el objeto View Result Tree. Con el primero tendremos acceso a todas las variables y parámetros que hemos definido en el plan. Con el segundo podremos ver el diálogo entre el cliente y el servidor a bajo nivel, es decir, las cabeceras de la petición HTTP, los parámetros que se han enviado y la respuesta del servidor en HTML, los mensajes de error del servidor en caso de que los hubiera, etc. Como vemos en la figura muestra las el resultado de las assertions que hemos definido, para que detectemos fácilmente errores en el script. Si alguna respuesta del servidor no verifica la condición que hemos establecido, en lugar del triángulo verde mostraría un símbolo rojo informando del fallo.


Resultados

Los datos que genera Jmeter serán normalmente el tiempo que ha llevado cada petición contando desde que se ha enviado la misma hasta que se ha recibido la respuesta al completo. Para visualizar estos datos tenemos muchas opciones aunque las más interesantes son el simple data writer que generará un archivo con los datos en crudo para poder ser procesados posteriormente con otra herramienta o cualquiera de las opciones gráficas o de resumen que dan algunas medidas estadísticas. Todas estas opciones pueden ser utilizadas simultáneamente añadiéndolas desde la sección Listeners. Además cualquiera de estos informes pueden ser salvados a fichero para un posterior análisis en un fichero en disco.
En un post siguiente mostraré los resultados de una ejecución contra varias instalaciones de Moodle y lo más interesante y complejo: cómo interpretar los resultados... Pero para eso aún me faltan conos y bastones que quemar.

Descargar fichero de test

lunes, 9 de septiembre de 2013

Amanda Backup II: Órdenes útiles

Más en la página oficial de Amanda.

Información

Ver las información sobre las copias existentes para un determinado recurso, en este caso /var. Podemos ver la fecha del dump, la cinta y el nivel (0=full 1=diff >1=inc).

[amandabackup@host root]$ amadmin DailySet1 find host.domain /var

date                host        disk         lv tape or file     file part status
2013-03-11 13:58:04 host.domain /var/backups  0 DailySet1-01    1  1/1 OK
2013-03-12 07:05:02 host.domain /var/backups  0 DailySet1-02    1  1/1 OK
2013-03-13 07:05:02 host.domain /var/backups  1 DailySet1-03    1  1/1 OK

Determinar cual es la próxima cinta en el programa.
[amandabackup@host root]$ amadmin DailySet1 tape
The next Amanda run should go onto 1 new tape.
The next new tape already labelled is: DailySet1-04.

Estado de las últimas copias. Fecha y nivel de backup usado.
[amandabackup@host root]$ amoverview DailySet1 

         date                 03 03 03
host     disk                 11 12 13

host /etc                  0  1  1
host /var/backups          0  0  1


Backup

Forzar copia completa. Se deben especificar al final qué "discos" se respaldarán.
amadmin DailySet1 force host.domain /var/backups /etc
Realizar Dump (usando su para no tener que cambiar de usuario)
su -c "amdump DAilySet1" amandabackup

Recuperación

amrecover

Lo mejor es usar la herramienta amrecover, que funciona de forma similar a un ftp interactivo: tienes órdenes para moverte por las copias de seguridad y órdenes con prefijo "l" para moverte los por directorios de la máquina local desde la que se ejecuta la herramienta. 
Órdenes dentro de recover:
  • listdisk: lista los discos (directorios respaldados) en el host activo.
  • setdisk: Establece el disco (directorio respaldado) sobre el que vamos a trabajar.
  • history: Muestra el histórico de las copias que se han hecho sobre ese disco, incluyendo la fecha, el nivel de respaldo (0-full) y la cinta en la que se encuentra.
  • setdate: Establece la fecha sobre la que trabajaremos, de manera que la copia que se recupere será la última que había en esa fecha. Si no se establece una distinta se tiene en cuenta la fecha actual, recuperándose la última copia.
  • add [fichero o path]: Admite comodines. Añade ficheros o directorios a la lista de extracción.
  • lcd: Similar al de cualquier ftp. Establece el directorio local. Cuando se haga un extract se recuperará a ese directorio.
  • extract: Extrae la lista de extracción al directorio local.
  • help: Muestra la ayuda.
  • quit: Salir.

Esta herramienta debe ejecutarse con el usuario root. Ejemplo de uso: OJO!! A veces extract no funciona directamente porque no reconoce el dispositivo. Para solucionarlo hay que ejecutar la orden setdevice /dev/nst0 (ver el ejemplo).

amrestore

No hace falta acceder al índice de Amanda. Lee directamente de la cinta y extrae los archivos que encuentra.
Orden para extraer todos los archivos que hay en una cinta al directorio actual:
amrestore /dev/nst0 host.domain
Esta orden extraerá los archivos encontrados en la cinta e informará del formato en el que se encuentran para poder descomprimirlos ya que por defecto no anexa la extensión del tipo de archivo al nombre del fichero sino un número que indica el nivel de backup (0=full 1=diff >1=inc). Formato para el nombre de los ficheros recuperados con amrestore:
hostname.diskname.datestamp.dumplevel
Después debemos descomprimir el archivo (normalmente será tar: tar xvf <archivo>). Si en la cinta sólo hay copias diferenciales/incrementales en los archivos solo encontraremos los ficheros que han cambiado desde la última copia aunque la estructura de directorios sí estará completa.

viernes, 2 de agosto de 2013

Amanda Backup I: Instalación y Configuración

Amanda es una de las soluciones OpenSource (BSD License) de tipo empresarial que puedes utilizar para realizar copias de seguridad de tus servidores.

Una de las características que me hicieron elegir este software frente a otros a la hora de hacer backup de los datos más importantes de mi empresa es que no utilizar ningún tipo de formato propio para almacenar esas copias, es decir, puedes recuperar las copias de seguridad desde otra máquina sin la necesidad de tener instalado/configurado el software, puedes manejar todo el proceso con órdenes estándar del sistema operativo, como tar, mt, cron, etc.
Es un software muy potente comparable a Bacula, por ejemplo, y que tiene una estructura similar: habrá una máquina que hará de servidor de copias de seguridad que atenderá a varios clientes siguiendo una agenda determinada. La instalación y configuración es bastante sencilla, quizás más que la de Bacula, la herramienta

En esta entrada haré un repaso de la instalación y configuración del software en un equipo HP Proliant con una unidad de cinta Ultrium 232 (LTO1) algo antigua, en la que se ejecuta un sistema CentOS 6.

Backup en cintas

Para ejecutar Amanda usando la unidad Ultrium como dispositivo de copia de seguridad  debemos tener instaladas todas las herramientas de sistema que trabajarán de forma subyacente, especialmente mt-st:
yum install mt-st

Comprobamos la unidad de cinta:

[root@host ~]# cat /proc/scsi/scsi 
Attached devices:
Host: scsi1 Channel: 00 Id: 00 Lun: 00
  Vendor: HL-DT-ST Model: CD-ROM GCR-8486B Rev: 2.00
  Type:   CD-ROM                           ANSI  SCSI revision: 05
Host: scsi3 Channel: 00 Id: 03 Lun: 00
  Vendor: HP       Model: Ultrium 1-SCSI   Rev: P61D
  Type:   Sequential-Access                ANSI  SCSI revision: 03
Host: scsi2 Channel: 00 Id: 00 Lun: 00
  Vendor: BENQ     Model: DVD DD EW162I    Rev: 47F9
  Type:   CD-ROM 
[root@host ~]# dmesg | grep -i tape
st 3:0:3:0: Attached scsi tape st0
osst :I: Tape driver with OnStream support version 0.99.4


Tenemos la unidad ultrium en st0. Aquí tenemos una de las primeras curiosidades con respecto a la gestión de dispositivos secuenciales: las interfaces /dev/st0 y /dev/nst0 ser refieren al mismo dispositivo, la diferencia es que si usamos st0 el sistema considerará el dispositivo como "rebobinable" en cambio si usamos nst0 accederemos a un dispositivo "no rebobinable". La diferencia es que después de cualquier operación sobre st0 la cinta se rebobinará, por lo tanto toda operación sobre la cinta comenzará en el bloque 0 lista para una operación de "rewrite". En el dispositivo nst0, después de una operación la cinta estará lista para una operación de "append" sin destruir los datos grabados hasta el momento.

Comprobaré que la cinta funciona correctamente, por ejemplo, extrayendo información sobre la misma o extrayendo la unidad:

mt -f /dev/nst0 offline # Extrae la cinta

[amandabackup@host root]$ mt -f /dev/nst0 status
SCSI 2 tape drive:
File number=0, block number=1, partition=0.
Tape block size 0 bytes. Density code 0x40 (DLT1 40 GB, or Ultrium).
Soft error count since last status=0
General status bits on (1010000):
 ONLINE IM_REP_EN


Al intentar ejecutar otras órdenes en las que si se accede a la cinta como mt -f /dev/nst0 tell, que dice el bloque en que se encuentra la cinta, da un error de entrada salida. Para solucionarlo se han de ejecutar estas dos órdenes: Más información sobre la configuración de las cintas Ultrium en los manuales de HP.

mt -f /dev/nst0 stsetoptions scsi2logical # Hace que el driver st use direccionamiento lógico
mt -f /dev/nst0 setblk 0                  # Establece la lectura de bloques de tamaño variable. Ver enlace de Info anterior.

Instalación y configuración de Amanda

Server: Instalación


Una vez comprobado el funcionamiento de la unidad de cinta continuamos con la instalación y configuración de Amanda en CentOS. Vamos a configurar Amanda para que realice copias de seguridad del mismo servidor (local), así que necesitamos instalar el software de cliente y de servidor. 

yum install amanda amanda-server amanda-client

La instalación en CentOS crea el usuario amandabackup que será desde el que realizaremos la mayoría de las interacciones con Amanda. También crea los grupos disk y tape en los que incluirá al usuario amandabackup, estos grupos tendrán permisos para acceder a varios directorios, dispositivos y ficheros de configuración necesarios. También crea archivos de configuración que tendremos que modificar. En el directorio /etc/amanda y /etc/amanda/DailySet1 tenemos también plantillas de archivos de configuración.
Amanda se ejecuta vía xinetd, así que tendremos que configurar el servicio. Aunque la instalación ha creado el archivo en /etc/xinetd.d/amanda sustituimos por el archivo xinetd.amandaserver que encontramos en el directorio /etc/amanda/DailySet1/. Este archivo define los servicios de Amanda que estarán activos en el servidor, estos servicios vienen determinados por el parámetro server_args.

  • amdump. Es el servicio (máquina cliente y servidor) que se encarga de realizar las copias de seguridad.
  • amindexd. Es el servicio (servidor) que mantiene el catálogo de Amanda. Muchas herramientas de Amanda se comunican con este servicio. Es necesario para ejecutar amrecover, la herramienta interactiva de recuperación de datos, es muy similar a un servicio de FTP que es accedido por la herramienta amrecover.
  • amidxtaped. Servicio (servidor) que se comunica con la unidad de cinta.
Archivo /etc/xinetd.d/amanda

# default: on
#
# description: Amanda services for Amanda server and client.
#
service amanda
{
        disable         = no
        flags           = IPv6
        socket_type     = stream
        protocol        = tcp
        wait            = no
        user            = amandabackup
        group           = disk
        groups          = yes
        server          = /usr/lib64/amanda/amandad
        server_args     = -auth=bsdtcp amdump amindexd amidxtaped
}

Siempre que hagamos algún cambio en este archivo debemos recargar xinetd con la orden service xinetd reload.

Server: Configuración de los trabajos de copia

La configuración de los trabajos de copia de seguridad se hace desde los subdirectorios dentro de /etc/amanda. Por ejemplo, hemos copiado la configuración por defecto que incluye la instalación al directorio DailySet1. Dentro de este directorio establecemos todos los parámetros para realizar las copias de seguridad. Hay que tener en cuenta que para casi cualquier operación que hagamos con Amanda tendremos que especificar este identificador.
El fichero principal es el fichero amanda.conf dentro del directorio de configuración. Los cambios más importantes son:
mailto= "admin@email.es"     # Email que recibirá las notificaciones. Hay que modificar .mailrc en /var/lib/amanda/ para que funcione. Después se explica.
dumpuser="amandabackup"     # Usuario que se utiliza para ejecutar dump en el cliente.

dumpcycle 1 weeks           # Asegura al menos haya una copia completa cada 1 semana
runspercycle 4              # Cuantas veces se lanza el dump cada dumpcycle
tapecycle 4 tapes           # Número de cintas que se conservan antes de empezar a reciclar.

runtapes 1                  # Número de cintas que se permiten para un trabajo de copia. Si una copia no cabe en una cinta debemos subirlo. Sólo se usan las necesarias.
#tpchanger "scrtip"         # Script que se encarga de cambiar cintas. Como cambiaremos las cintas manualmente comentamos.
tapedev "tape:/dev/nts0"    # Dispositivo que se usa para realizar las copias.
tapetype HP-ULTRIUM-LTO1    # Tipo de cinta. HP-ULTRIUM-LTO1 debe estar definido como tipo de cinta en la sección ''define tapetype''. Ver más adelante.
labelstr "^DailySet1-[0-9][0-9]*$"     # Expresión regular que restringe la etiqueta de las cintas que se aceptan. Todas las cintas ser etiquetadas según este patrón.

#holdingdisk  hd1 {         # Discos buffer en los que se hará un dump previo, después se copiará a la cinta. Desactivado (comentado) por problemas de espacio en el servidor.
#...
#}

infofile "/etc/amanda/DailySet1/curinfo"    # database DIRECTORY
logdir   "/etc/amanda/DailySet1"            # log directory
indexdir "/etc/amanda/DailySet1/index"              # index directory
tapelist "/etc/amanda/DailySet1/tapelist"   # list of used tapes

define tapetype HP-ULTRIUM-LTO1 {          # Definición de la cinta. Extraída del enlace http://tirpitz.iat.sfu.ca/wiki/index.php?title=Backups_with_AMANDA
    comment "LTO-1. Añadido por Emilio"    # Amanda puede examinar la cinta para obtener su definición usando la orden 'amtapetype -f /dev/nst0'
    length 96512 mbytes
    filemark 0 kbytes
    speed 13611 kps
}

# A continuación vienen las definiciones de los tipos de dumps estándares. En el fichero se comentan todas las opciones posibles y se pueden crear nuevos o modificar existentes, 
# que después habrá que especificar en el fichero disklist. Estas definiciones se pueden anidar, como se ve en el ejemplo. Estamos usando comp-user-tar, cuya definición es:
define dumptype global {
    comment "Global definitions"
    # This is quite useful for setting global parameters, so you don't have
    # to type them everywhere.  All dumptype definitions in this sample file
    # do include these definitions, either directly or indirectly.
    # There's nothing special about the name `global'; if you create any
    # dumptype that does not contain the word `global' or the name of any
    # other dumptype that contains it, these definitions won't apply.
    # Note that these definitions may be overridden in other
    # dumptypes, if the redefinitions appear *after* the `global'
    # dumptype name.
    # You may want to use this for globally enabling or disabling
    # indexing, recording, etc.  Some examples:
    # index yes
    # record no
    # split_diskbuffer "/raid/amanda"
    # fallback_splitsize 64m
    auth "bsdtcp" # Añadido para forzar la autenticación bsdtcp
}


define dumptype root-tar {
    global
    program "GNUTAR"
    comment "root partitions dumped with tar"
    compress none
    index
#   exclude list "/etc/amanda/exclude.gtar"
    priority low
}
define dumptype user-tar {
    root-tar
    comment "user partitions dumped with tar"
    priority medium
}
define dumptype comp-user-tar {
    user-tar
    compress client fast
}

...
...
Puede que al hacer un amcheck <ID> no se pueda conectar al cliente dando este error:

[amandabackup@host root]$ amcheck DailySet1
Amanda Tape Server Host Check
-----------------------------
read label `DailySet1-04', date `20130314070502'.
Tape with label DailySet1-04 is still active and cannot be overwritten.
       (expecting tape DailySet1-01 or a new tape)
Server check took 0.096 seconds

Amanda Backup Client Hosts Check
--------------------------------
WARNING: host: selfcheck request failed: timeout waiting for ACK
Client check: 1 host checked in 30.036 seconds.  1 problem found.

(brought to you by Amanda 2.6.1p2)
Se soluciona especificando en amanda.conf el tipo de autenticación en la definición dumptype. Yo lo he añadido en la definición de dumptype global, como aparece en el enlace.

Ahora debemos indicar a Amanda las máquinas a las que tendrá que acceder, los datos que deberá respaldar y el tipo de dump que realizará para cada uno. Esto se hace mediante el archivo disklist dentro del directorio /etc/amanda/DailySet1:

host  /var/backups comp-user-tar
host  /etc   comp-user-tar

Antes de poder hacer copias de seguridad debemos etiquetar las cintas para que sean reconocidas por amanda. Para ello introducimos una por una las cintas y las etiquetamos de la siguiente forma, donde XX es el número de cinta:
amlabel DailySet1 DailySet1-XX

Cada vez que etiquetemos una cinta se añadirá al archivo /etc/amanda/[id]/tapelist. Se puede listar este fichero para ver las cintas.
Para comprobar que funciona podemos ejecutar:
[amandabackup@host root]$ amcheck DailySet1
Amanda Tape Server Host Check
-----------------------------
read label `DailySet1-02', date `20130312070502'.
Tape with label DailySet1-02 is still active and cannot be overwritten.
       (expecting a new tape)
WARNING: tapecycle (4) <= runspercycle (4).
Server check took 0.097 seconds

Amanda Backup Client Hosts Check
--------------------------------
Client check: 1 host checked in 2.135 seconds.  0 problems found.

OJO! Esta salida se obtiene una vez configurado todo, la salida real en esta etapa de configuración debería ser similar, lo importante es que no aparezcan problemas en el resultado.

Server: Cron

En el directorio /etc/amanda/ hay un ejemplo de cron. Se puede modificar el cron del usuario amandabackup para programar las copias. Cambiarse al usuario amandabackup y hacer un crontab -e. El contenido actual (pruebas) es el siguiente:

#Amanda Backup
00 07 * * 1-5    /usr/sbin/amcheck -m DailySet1
05 07 * * 1-4    /usr/sbin/amdump DailySet1

Server: Notificaciones por email

Para que funcionen las notificaciones de las copias de seguridad hay que configurar los parámetros de envío creando el archivo /var/lib/amanda/.mailrc:

set smtp=[smtp server]
set from=[admin@email.es]

Client

Primero debemos configurar el servicio amanda en xinetd. Esto ya lo hemos hecho ya que el servidor también es el cliente. Permitir al servidor que acceda al servicio amanda. Para esto se modifica el fichero /var/lib/amanda/.amandahosts:

# host user services. 
# root en el cliente accederá a los servicios amindexdx y amidxtaped para recuperar ficheros.
# amandabackup accederá al servicio amdump
server1 root amindexd amidxtaped
server1 amandabackup amdump

En un segundo post haré un repaso por las órdenes más útiles para hacer copias de seguridad, restauraciones, extraer información del catálogo... Además del manejo de las copias realizadas con herramientas del sistema como mt o tar.

martes, 9 de abril de 2013

Revisión de opciones para el uso de la plataforma Moodle en dispositivos Móviles

Aceptado el artículo que hemos escrito Vanesa Gámiz Sánchez y yo en la revista RED donde hablamos de las distintas alternativas para acceder a Moodle con dispositivos móviles.

Abstract.

Los espacios y modelos de aprendizaje se han visto modificados radicalmente en los últimos tiempos gracias al avance de las tecnologías de la comunicación que han hecho posible el acceso y la producción de grandes cantidades de información; el desarrollo de aplicaciones y herramientas para mejorar la interacción entre las personas; y la extensión de dispositivos que han permitido el aumento de la movilidad de los usuarios. En este artículo analizamos cuáles son las circunstancias que están permitiendo el desarrollo y la expansión del uso de los dispositivos móviles en los procesos de aprendizaje en lo que se conoce como mobile learning o m-learning. En especial, nos interesa su implementación a través del entorno de enseñanza virtual Moodle. Para su estudio revisamos brevemente las opciones móviles más usadas para acceder a la plataforma Moodle ya sean aplicaciones nativas o plantillas/temas optimizados para dispositivos móviles. Por último, proponemos una de las metodologías más usadas para analizar la usabilidad de soluciones móviles, adaptándola al ámbito del estudio.

Enlace al texto completo.

miércoles, 13 de marzo de 2013

Fuentes de ancho fijo en GMAIL

Algo muy molesto para los que normalmente recibimos notificaciones automáticas mediante correo electrónico en texto plano de aplicaciones, servidores, etc., es que gmail no utiliza fuentes de ancho fijo. Muchos de los servicios que instalamos en una máquina envían notificaciones simulando tablas y gmail nos destroza las tabulaciones. Mejor verlo: este es un ejemplo de informe de una herramienta de copia de seguridad (Amanda).

Para solucionar esto podéis instalar el complemento de Chrome Fixed Width Text for Gmail, el resultado será mucho más cómodo de leer:


La extensión sólo modificará los correos que reconozca como texto plano, por lo que el resto de correos electrónicos más "complejos" se verán como siempre.

Mejor no??

lunes, 17 de diciembre de 2012

Migración de materiales de WebCT a Moodle usando SCORM

En el evento MoodleMoot 2008 presentamos desde el CEVUG el proceso que utilizamos para migrar los materiales de nuestro antiguo WebCT a Moodle.
Aunque posiblemente ya queda un poco lejos aquel proceso, comparto la presentación que llevamos por si a alguien le resulta de utilidad.


martes, 30 de octubre de 2012

Clase introductoria de eportafolios con Moodle y Mahara

Proyecto de Innovación Docente coordinado por Vanesa Gámiz: "El e-portafolio como estrategia didáctica de aprendizaje y evaluación. Implementación con Mahara integrado con Moodle"

Fragmentos de la clase de introducción impartida a los alumnos que participan en el PID.


Ir a la página del proyecto

domingo, 29 de julio de 2012

Analizando logs de Flash Media Server con Perl

El log de Flash Media Server es muy completo, pero al mismo tiempo difícil de analizar con herramientas estándar de análisis de logs. La solución que utilicé la última vez que vinieron pidiendo estadísticas urgentes fue importar el log en LibreOffice Calc e intentar sacar los datos lo más rápido posible para salir del paso.

Como hace tiempo que no toco Perl (al final siempre acabo utilizando PHP porque me es más familiar), he decidido hacer un pequeño script para obtener algunos datos estadísticos de las aplicaciones que se ejecutan en Flash Media Server.

El script recibe el nombre del fichero log y la aplicación FMS sobre la que queremos información, hace un recuento de las ips que se conectan entre los eventos publish y unpublish e imprime un resumen. Me centro en aplicaciones tipo "live" en las que un cliente publica y el resto conectan para seguir la emisión de ese cliente.

Aquí el código:
#!/usr/bin/perl

(scalar @ARGV == 2) || die ("Wrong number of arguments.\nUse: $0 filename app_name \n");

$filename = $ARGV[0];
$appname = $ARGV[1];


$APP_NAME_FIELD = 12;
$DATE_FIELD = 2;
$TIME_FIELD = 3;
$CLIENT_IP_FIELD = 16;


open FILE, $filename or die "File not found!!\n";

$publishing = 0;
while (<FILE>){
 @line = split;
 
 if (  (($line[0]) eq "publish") and (($line[$APP_NAME_FIELD]) eq $appname)   ){
  $publishing = 1;
  print "Application '$appname' started at $line[$TIME_FIELD] ($line[$DATE_FIELD])\n"; 
 }
 
 if (  (($line[0]) eq "unpublish") and (($line[$APP_NAME_FIELD]) eq $appname)   ){
  $publishing = 0;
  
  print "Application '$appname' stopped at $line[$TIME_FIELD] ($line[$DATE_FIELD])\n"; 
  
  # Print ips and number of connections of each one.
  print scalar keys %ip_array ," different clients received the broadcast\n";
  print "IP \t #Connections\n";
  foreach $ip (keys %ip_array){
   print "$ip \t $ip_array{$ip}\n";
  }
  undef %ip_array;
  print "********************************************************************\n";
 }
 
 if ($publishing){
  if (  (($line[0]) eq "connect") and (($line[$APP_NAME_FIELD]) eq $appname)   ){
   if (exists ( $ip_array{$line[$CLIENT_IP_FIELD]} ) ){
    $ip_array{$line[$CLIENT_IP_FIELD]}++;
   }else{
    $ip_array{$line[$CLIENT_IP_FIELD]}=1;
   }
  }  
 }

}

El resultado es el siguiente:

new-host-2:fms_log emilio$ ./fms_stats.pl access.2012032100.log live 
Application 'live' started at 11:13:22 (2012-03-21)
Application 'live' stopped at 12:11:26 (2012-03-21)
15 clients received the broadcast
IP   #Connections
90.170.72.143   1
172.20.18.215   1
111.111.23.53   2
111.111.17.203   2
111.111.23.152   1
172.20.8.133   1
172.20.18.83   2
83.33.247.36   1
172.20.17.167   1
111.111.31.78   1
111.111.23.173   1
111.111.23.55   1
111.111.204.147   1
83.32.145.161   1
111.111.22.139   5
********************************************************************
Application 'live' started at 17:08:00 (2012-03-21)
Application 'live' stopped at 17:08:08 (2012-03-21)
0 clients received the broadcast
IP   #Connections
********************************************************************
Application 'live' started at 17:09:26 (2012-03-21)
Application 'live' stopped at 17:14:16 (2012-03-21)
1 clients received the broadcast
IP   #Connections
111.111.104.51   1
********************************************************************
Application 'live' started at 17:14:50 (2012-03-21)
Application 'live' stopped at 18:48:12 (2012-03-21)
4 clients received the broadcast
IP   #Connections
90.170.72.143   2
111.111.36.4   3
217.216.52.82   1
111.111.104.51   5
********************************************************************