viernes, julio 18, 2014

Comparando el contenido de directorios para linux y mac con diff

El otro día estuve probando un par de servicios de sincronización (por cierto, Copy está de lo más interesante). El caso es que antes de borrar los contenidos que teníamos en Dropbox quería asegurarme que se había copiado correctamente todo y tenía que hacerlo necesariamente desde MacOS.

Para comparar el contenido de dos directorios lo más fácil el usar el comando diff, que ya había utilizado anteriormente para comparar el contenido de dos ficheros. Es tan sencillo como abrir una terminal y escribir:

$ diff -rq directorio1 directorio2

Por ejemplo:

$ diff -rq prueba_diff_1/ prueba_diff_2/
Los archivos prueba_diff_1/documento.txt y prueba_diff_2/documento.txt son distintos
Los archivos prueba_diff_1/.DS_Store y prueba_diff_2/.DS_Store son distintos
Sólo en prueba_diff_1/: Spot OFICIAL.mp4
Sólo en prueba_diff_2/: wetransfer-af86cd.zip

En el caso particular de MacOS me generaba muchas líneas indicando que en todos los directorios los archivos .DS_Store eran distintos. Como son archivos que en realidad no importan me interesaba ignorarlos. Eso se puede hacer con la opción "-x '*.extension_a_ignorar' "

Por ejemplo 

$ diff -rq -x '*.DS_Store' prueba_diff_1/ prueba_diff_2/
Los archivos prueba_diff_1/documento.txt y prueba_diff_2/documento.txt son distintos
Sólo en prueba_diff_1/: Spot OFICIAL.mp4
Sólo en prueba_diff_2/: wetransfer-af86cd.zip

...y una cosa importante es que es muy rápido procesando grandes volúmenes de archivos.

viernes, junio 06, 2014

Añadiendo un RAID 1 a una instalación de ubuntu 14.04 preexistente

Vamos a añadir dos discos de 1TB formando un RAID 1 a un servidor que ya tiene instalado previamente un disco de 140GB con su sistema operativo Ubuntu 14.04.

Me he inspirado en estos dos artículos

http://feeding.cloud.geek.nz/posts/setting-up-raid-on-existing/
http://www.guia-ubuntu.com/index.php?title=Crear_una_Software_RAID

Preliminares
Son dos discos WD SATA de 1TB, instalados normalmente y comprobado que están disponibles con
lsblk. Los ha identificado como /dev/sdb y /dev/sdc

Al pasarle el fdisk me ha dicho que no estaban alienados correctamente (más información en este artículo)

Solucionado con el comando:
sudo fdisk -H 224 -S 56 /dev/sdb (seguido de 'w' cuando nos pregunte para confirmar los cambios)
sudo fdisk -H 224 -S 56 /dev/sdc

Asegurarse de que tenemos todo el software instalado con
sudo apt-get install mdadm rsync initramfs-tools

Iniciamos

Creo las particiones (en mi caso una única partición primaria con todo el disco) con
sudo fdisk -/dev/sdb

  • m para ayuda
  • n nueva particin
  • p de primaria
  • valores predeterminados para el resto
  • 1
  • t para indicar el tipo
  • L para listar
  • fd para Linux Raid Auto


Como lo he hecho varias veces durante las prueba al final he usado cfdisk, una alternativa mucho más interactiva y fácil.

Una vez creadas las particiones creamos el RAID con

sudo mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sdb1 /dev/sdc1

Aceptamos y empieza a crearlo en segundo plano. Podemos consultar el estado con:
$cat /proc/mdstat 
Personalities : [raid1] 
md0 : active raid1 sdc1[1] sdb1[0]
      972725056 blocks super 1.2 [2/2] [UU]
      [>....................]  resync =  0.8% (8456320/972725056) finish=82.6min speed=194392K/sec

Tomate un cafetín o dos que la cosa va para rato

Finalizada la creación del RAID hay que formatearlo. Asegúrate de que identificador de dev le ha asignado:
$ sudo mkfs.ext4 /dev/md0

Y finalmente preparamos en el montaje
$sudo mkdir /media/raid

Editamos el fichero /etc/fstab y añadimos
/dev/md0        /media/raid     ext4    defaults,       0       0

Con sudo mount -a nos deja montadas todas las particiones

Ya puedes crear las carpetas que desees en el RAID ten en cuenta el tema de los permisos para saber si los usuarios podrán escribir en ellas.

...y reinicia... para encontrar un error :-(

Por alguna razón Como no había guardado la configuración del RAID no encuentra el dispositivo /dev/md0 así que me salto el montaje y cuando ejecuto
$ sudo mdadm --detail --scan
ARRAY /dev/md/woody:0 metadata=1.2 name=woody:0 UUID=230eecee:2560d588:bf244ba0:f0adfdd8

...me encuentro con el que el dispositivo ha pasado a ser /dev/md/woody:0.

El caso es que no es mucho problema puesto que el RAID sigue existiendo con otro nombre. Modifico el /etc/fstab
/dev/md/woody:0 /media/raid ext4 defaults 0 0

...y en previsión de futuros errores y para que se guarde correctamente la configuración  (aunque Ubuntu autodetecta los RAIDs al arrancar) algo lo siguiente. Añadir al /etc/mdadm/mdadm.conf los dispositivos usados

DEVICE /dev/sdb* /dev/sdc*  
 (verás que la línea está comentada)

...y también añadimos los datos de los arrays creados (es conveniente que te pases a root y no lo hagas con sudo, puede darte problemas)
mdadm --detail --scan >> /etc/mdadm/mdadm.conf  

Por último y para dejarlo fino del todo lanzamos la reconfiguración de mdadm para que seleccionar chequeos periódicos, la dirección email donde tiene que enviar los avisos...
sudo dpkg-reconfigure mdadm

Esto último instalará un proceso del tipo mdadm --monitor --scan --daemonize que chequeara los discos e irá enviando informes por corre electrónico. Para estar seguro de que funciona correctamente tienes que tener instalado y configurado correctamente postfix. Para probarlo puedes hacer un kill al proceso mdadm --monitor arrancado y probarlo manualmente con:

$ sudo mdadm --monitor /dev/md0 --test --mail=tumail@ejemplo.com

Eso dejará el proceso arrancado y a los pocos minutos deberías recibir un correo electrónico. Si no es así primero deberás comprobar que el postfix esta correctamente configurado.

Podemos instalar adicionalmente las smartmoontols y programar un chequeo periódico para detectar la degradación de los discos (por si tienen tasas de fallo demasiado elevadas)

$ sudo apt-get install smartmontools
$ sudo smartctl -d sat --all /dev/sdb #test basico para discos SATA

...y lo instalamos para que semanalmente realice un chequeo y envíe un correo en caso de problemas
# new test to RAID involved disks with mailing
/dev/sdb -d sat -o on -S on -s (S/../.././02|L/../../6/03)  -m USUARIOCORREO@EJEMPLO.COM
/dev/sdc -d sat -o on -S on -s (S/../.././02|L/../../6/03)  -m USUARIOCORREO@EJEMPLO.COM


También existe un GUI que podemos usar (si conectamos por ssh activa la opcion -X)
$ sudo apt-get install gsmartcontrol
$ sudo gsmartcontrol


Algunos comandos útiles


Si dejamos de detectar el RAID en algún momento
sudo mdadm --detail --scan

Para detener y eliminar un RAID si no lo hemos configurado correctamente
sudo mdadm --stop /dev/md0
sudo mdadm --remove /dev/md0 (no ha sido necesario en mi caso)
Para eliminar los superblock
sudo mdadm --zero-superblock /dev/sda1 /dev/sdb1 /dev/sdc1 (particiones involucradas)

Monitorizar el estado del RAID
cat /proc/mdstat  o sudo mdadm --query /dev/md0 o sudo mdadm --detail /dev/md0

Similar para monitorizar el estado de los discos
sudo mdadm --query /dev/sdb1 o sudo mdadm --examine /dev/sdb1

Probando performance del disco
http://askubuntu.com/questions/87035/how-to-check-hard-disk-performance

miércoles, junio 04, 2014

Usando el server SMTP de la UA Alicante para hacer envíos de correo desde mi propio servidor

Tengo varios servidores dentro de la red interna de la Universidad de Alicante y necesitaba que pudieran enviar correo electrónico para poder hacer el seguimiento de su estado o recibir notificaciones.

Como no estaba interesado en convertirlos en servidores completos de correo y sólo quería que pudieran enviar mensajes he usado el propio servidor SMTP de la UA y una cuenta de correo de las institucionales que manejo para la administración.

Las instrucciones son un mix entre la ayuda de postfix, la web del SI y mi propia experiencia.

Primero debería asegurarme que postfix está instalado

$sudo apt-get install postfix

Da igual lo que eligamos en la opción de configuración porque vamos a editar el fichero manualmente después.

Una vez finalizada editamos el fichero /etc/postifix/main.cf y añadimos el siguiente contenido

relayhost = [aitana.cpd.ua.es]:587
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous, noplaintext
smtp_use_tls = yes
myhostname = ua.es
smtp_generic_maps = hash:/etc/postfix/generic
inet_interfaces = loopback-only

relayhost = aitana.cpd.ua.es
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_use_tls = yes
myhostname = ua.es
smtp_generic_maps = hash:/etc/postfix/generic
inet_interfaces = loopback-only
myorigin = /etc/mailname
mydestination = 
mynetworks = 127.0.0.0/8 [::1]/128
mailbox_size_limit = 0
recipient_delimiter = +

inet_protocols = all


  • La primera línea indica el host en el que delegamos el envío de correo
  • La segunda que usaremos autentificación (como exigen las instrucciones del SI)
  • La tercera advierte de dónde se indican los parámetros de usuario y contraseña (y sí, estarán en texto plano aunque protegidos por permisos de lectura) por tanto en el fichero /etc/postfix/sasl_passwd debemos incluir la siguiente línea:
    [aitana.cpd.ua.es]:587    USUARIO@ua.es:CONTRASEÑA
    ...y protegerlo con...
    $sudo chmod 400 /etc/postfix/sasl_passwd
    ...y añádelo el formato postmap con...
    $sudo postmap /etc/postfix/sasl_passwd
  • Cuarta y quinta son parámetros sobre la conexión realizada. La opción noplaintext encripta todo el envío de correo pero parece que ralentiza unos minutos el envío. Considera eliminarla
  • La sexta indica el dominio de la cuenta del usuario que envía el mail. Inprescindible para que los servidores de destino acepten el email (porque lo reconoceran del dominio ua.es)
  • smtp_generic_maps servirá para indicar una serie de alias para la dirección de origen de los correos. Si no aparecerían como NOMBREUSUARIO@NOMBREMAQUINA.es y existen posibilidades de que nos filtren como spam. Crea un archivo /etc/postfix/generic y añade el siguiente contenido:
    @NOMBREMAQUINA.es         USUARIOUA@ua.es
    ...y reconstruyelo como un db con ...
    $sudo postmap /etc/postfix/generic
  • myorigin = /etc/mailname debe contener un dominio real de origen de los correos como:
    aitana.cdp.ua.es
  • inet_interfaces indica que no aceptamos conexiones, no vamos a recibir correo en esta máquina

Después de los cambios en la configuración reinicia el servicio con:
sudo service postfix restart

Prueba la configuración con el siguiente comando:
echo "Texto del mail " | mail -s "Subject del mensaje" direciondestion@ejemplo.com

Puedes comprobar el estado de la cola de envío de tu usuario con mailq. Si todo ha ido correctamente debería aparecer:
$mailq
Mail queue is empty
En caso de error mostrará los mensajes en cola y el problema que tienen.

sábado, marzo 01, 2014

Wget para descargar todos los ficheros txt enlazados desde una página

Tanto me ha costado que vale la pena dejar apuntado por alguna parte cómo hacer esto. Para descargar únicamente los archivos txt que están enlazados desde una página y que están en un único directorio evitando navegar por todo el site podemos usar este comando

wget -I "/static/public/constellations/txt/" -X * -r -A *.txt -P . http://www.iau.org/public/themes/constellations/


  • -I Indica el directorio que queremos incluir
  • -X Indica los directorios que queremos excluir (todos)
  • -A *.txt indica el patrón de archivos que queremos descargar
  • -P . indica la localización donde queremos dejar los archivos

martes, febrero 11, 2014

Mover cadenas en una línea con el comando sed

Sed es un útil comando para manipular cadenas de un archivo.

En mi caso me encontraba con la necesidad de alterar unas sentencias update de una sql de la siguiente forma

UPDATE VIDEOTECA SET 
    TAGS = 'CIENCIA-FICCIÓN, ESPACIO, EXTRATERRESTRES, MICROBIO, ENFERMEDAD, PLAGA, DISTRI U', DISTRIBUIDORA = NULL
WHERE (VIDEOID = 326);

Que debería convertir en:

UPDATE VIDEOTECA SET 
    TAGS = 'CIENCIA-FICCIÓN, ESPACIO, EXTRATERRESTRES, MICROBIO, ENFERMEDAD, PLAGA', DISTRIBUIDORA = 'U'
WHERE (VIDEOID = 326);

Así durante más 500 líneas.

Como podéis ver en realidad lo que quiero es coger el valor que hay tras   'DISTRI' y moverlo donde está el NULL (básicamente, para actualizar los valores de una tabla moviendo uno de los tags a una nueva columna)

SED nos permite recorrer línea a línea nuestro archivo buscando patrones y, entre otras operaciones posibles, realizar sustituciones. Para ello utiliza expresiones expresiones regulares. Como nuestra cadena está muy cerrada es fácil determinar una expresión regular que detecte la cadena que queremos mover y mediante los argumentos \1 (\2 si hubiera más expresiones) mover las partes variables a donde queramos

sed -r "s/, DISTRI (.*)', DISTRIBUIDORA = NULL/', DISTRIBUIDORA = '\1'/" archivo_origen.sql > archivo_destino.sql

Revisando rápidamente el comando

  • sed [parámetros] "s/patron/sustitucion/" archivo_origen > archivo destino
  • -r para que use las expresiones regulares extendidas
  • s para que realice las operaciones de sustituciones
  • / son los separadores
  • , DISTRI (.*)', DISTRIBUIDORA = NULL el patrón que queremos detectar, la parte en negrita detecta cualquier cadena de caracteres que previa que luego vaya seguida de ', DISTRIBUIDORA = NULL y la almacena en el token \1
  • ', DISTRIBUIDORA = '\1'el patrón por el que queremos sustuir. Usamos el token  \1 para recuperar la primera variable detectada en el patrón de búsqueda
Otro ejemplo encontrado durante el mismo desarrollo y que es algo más complicado
Cambiar este sql

UPDATE VIDEOTECA SET 
    TAGS = 'DistriSONY, Drama, Rural, Años 50, Adolescencia, Cine, Jeff Bridges, Ben Johnson', DISTRIBUIDORA = NULL
WHERE (VIDEOID = 1917);

por este otro

UPDATE VIDEOTECA SET 
    TAGS = 'Drama, Rural, Años 50, Adolescencia, Cine, Jeff Bridges, Ben Johnson', DISTRIBUIDORA = 'SONY'
WHERE (VIDEOID = 1917);

El comando

sed -r "s/Distri([A-Za-z0-9]*), (.*)', DISTRIBUIDORA = NULL/\2', DISTRIBUIDORA = '\1'/" videoteca-update.sql > videotec-distri-update.sql




sábado, junio 08, 2013

Copias de seguridad de tarjetas SD desde linux: guardando nuestra Raspberry Pi

Vista la facilidad con la que se corrompen la tarjetas en mi última instalación completa me he decidido a hacer una copia de seguridad de la RPi para poder restaurarla completamente en unos momentos.

De hecho, como lo utilizo de servidor multimedia y siempre me doy cuenta en el momento de estar sentado frente a la tele, me he creado una copia de respaldo en otra tarjeta para poder cambiarla y en el momento disfrutar de la película.

Usamos una máquina linux y un par de comandos rápidos:

Para hacer la copia de seguridad, me aseguro de meter la tarjeta desmontar las particiones con umount y hacer las copias de seguridad así:

$umount /dev/sdb1
$umount /dev/sdb2
$sudo dd if=/dev/sdb | gzip > /path/a/tu/imagen/nombre.bkp.gz

Y para restaurarla en otra tarjeta o en la misma:

$umount /dev/sdb1
$umount /dev/sdb2
$ sudo gzip -dc /path/a/tu/imagen/nombre.bkp.gz | dd of=/dev/sdb

Puede que tu sistema no monte la tarjeta en /dev/sdb ajústalo a tus necesidades.