<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Notas de ant30</title>
    <description>Quién sabe como has llegado hasta aquí</description>
    <link>/</link>
    <atom:link href="/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Wed, 15 May 2019 15:49:24 +0000</pubDate>
    <lastBuildDate>Wed, 15 May 2019 15:49:24 +0000</lastBuildDate>
    <generator>Jekyll v3.8.5</generator>
    
      <item>
        <title>Mi primera aplicación en Google Play, eldiario.es para android</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.thegeekbunch.eldiario&quot;&gt;&lt;img class=&quot;alignleft size-full wp-image-232&quot; alt=&quot;eldiario.es enlace&quot; src=&quot;/wp-content/uploads/2013/02/brand-128.png&quot; width=&quot;128&quot; height=&quot;128&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Es una aplicación para leer los contenidos de eldiario.es en tu móvil o tablet.&lt;/p&gt;

&lt;p&gt;Se trata básicamente de un lector de RSS, pero en vez de leer la fuente RSS directamente del medio en cuestión, pasa a través de un backend que es capaz de ir almacenando las noticias de cada sección y redimensionar las imágenes para que estén optimizadas en tamaño para móviles y tabletas. Dependiendo del tamaño de la pantalla, ofrece vista a una o dos columnas, así como imágenes de diferentes tamaños.&lt;/p&gt;

&lt;p&gt;El backend está compuesto por &lt;a title=&quot;Pyramid&quot; href=&quot;http://www.pylonsproject.org/&quot; target=&quot;_blank&quot;&gt;Pyramid&lt;/a&gt;, &lt;a href=&quot;http://www.mongodb.org/&quot;&gt;MongoDB&lt;/a&gt; e &lt;a href=&quot;http://www.imagemagick.org&quot;&gt;ImageMagick&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;En el cliente móvil tenemos &lt;a href=&quot;http://phonegap.com/&quot;&gt;phonegap&lt;/a&gt;, &lt;a href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt;, &lt;a href=&quot;http://backbonejs.org/&quot;&gt;backbonejs&lt;/a&gt;, &lt;a href=&quot;http://underscorejs.org/&quot;&gt;underscore&lt;/a&gt;, &lt;a href=&quot;http://cubiq.org/iscroll-4&quot;&gt;iScroll&lt;/a&gt;, … Toda una fauna de librerías típicas que acompañan a una aplicación web.&lt;/p&gt;

&lt;p&gt;Desde hace unos meses, andaba jugueteando con conceptos de aplicaciones móviles a modo de entretenimiento con algunos compañeros del trabajo, así que un día de estas navidades, comencé otra prueba de concepto enfocado a realizar una aplicación móvil de un periódico. Entonces seleccioné a &lt;eldiario.es&gt; por publicar sus contenidos con licencia [Creative Commons](http://www.eldiario.es/licencia/) y empecé a jugar con sus fuentes RSS.&lt;/eldiario.es&gt;&lt;/p&gt;

&lt;p&gt;Para ir a la página de la aplicación en el market de android puedes pulsar en este enlace:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://play.google.com/store/apps/details?id=com.thegeekbunch.eldiario&quot;&gt;Enlace a la aplicación eldiario.es para android&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Sun, 24 Feb 2013 09:03:58 +0000</pubDate>
        <link>/2013/02/mi-primera-aplicacion-en-google-play-eldiario-es-para-android/</link>
        <guid isPermaLink="true">/2013/02/mi-primera-aplicacion-en-google-play-eldiario-es-para-android/</guid>
        
        
        <category>android</category>
        
        <category>aplicaciones</category>
        
        <category>eldiario.es</category>
        
      </item>
    
      <item>
        <title>Red Hat, Virtualización y Fail-Over de servicios</title>
        <description>&lt;p&gt;He publicado un post en el &lt;a href=&quot;http://www.yaco.es/blog/&quot; title=&quot;Blog&quot; target=&quot;_blank&quot;&gt;blog&lt;/a&gt; de &lt;a href=&quot;http://www.yaco.es/&quot; title=&quot;Yaco&quot; target=&quot;_blank&quot;&gt;Yaco&lt;/a&gt; sobre el despliegue que hemos realizado para el cluster del portal web del &lt;a href=&quot;http://www.alhambra-patronato.es/&quot; title=&quot;Patronato de La Alhambra&quot; target=&quot;_blank&quot;&gt;Patronato de la Alhambra.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.yaco.es/blog/?p=1500&quot; title=&quot;Implantación de Alta Disponibilidad con Red Hat y Virtualización&quot; target=&quot;_blank&quot;&gt;Implantación de Alta Disponibilidad con Red Hat y Virtualización&lt;/a&gt;&lt;/p&gt;

&lt;!--more--&gt;
</description>
        <pubDate>Mon, 09 Apr 2012 10:32:18 +0000</pubDate>
        <link>/2012/04/red-hat-virtualizacion-y-fail-over-de-servicios/</link>
        <guid isPermaLink="true">/2012/04/red-hat-virtualizacion-y-fail-over-de-servicios/</guid>
        
        
        <category>Sysadmin</category>
        
        <category>Virtualización</category>
        
      </item>
    
      <item>
        <title>Cómo conseguir la IP de una máquina virtual de libvirt / kvm</title>
        <description>&lt;p&gt;Una de esas pequeñas cosas que molestan de libvirt en su combinación por virsh es que no tiene un método para obtener la IP de una máquina virtual. Y sin la IP ¿cómo conectamos por ssh a la máquina?&lt;/p&gt;

&lt;p&gt;En los últimos cambios incorporados en libvirt, se permite controlar parte del gestor dhcp/dns que viene incorporado, dnsmasq y que seguro que en un futuro nos permitirá obtener la IP sin hacer trucos. Se puede ver en la documentación de &lt;a href=&quot;http://libvirt.org/formatnetwork.html#elementsAddress&quot; title=&quot;Addressing de libvirt&quot;&gt;Addressing de libvirt&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;La forma trivial de obtener la IP es bastante fácil. A través de virt-manager, accedes a la pantalla de la máquina mediante VNC. Haces login con tu usuario y contraseña, y bastaría con ejecutar &lt;em&gt;ifconfig&lt;/em&gt; o &lt;em&gt;ip a&lt;/em&gt; para ver la IP entre toda la información de la red.&lt;/p&gt;

&lt;p&gt;Este método es un poco tedioso, y además, si el servidor se encuentra en una red lejana con mucho &lt;em&gt;lag&lt;/em&gt; en la terminal, el efecto sobre la consola VNC puede ser temible. Por tanto, hay que buscar alternativas más cómodas. Cómo mediante la información arp.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Hasta ahora, mi método solía ser mirar la mac de máquina obtenida del XML de la máquina con:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;virsh dumpxml nombrevm
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Y luego buscarla en la tabla arp, fácilmente accesible mediante:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;arp &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Para refrescar la memoria de algún rezagado, con el comando arp se obtiene la información de la tabla de caché del sistema que vincula “macs” vecinas con sus respectivas IPs, de forma que se evite tener que estar continuamente haciendo peticiones de descubrimiento de asociaciones mac-ip en la red en cada envío de paquete tcp/ip. Si quieres más información sobre el protocolo ARP siempre puedes consultar su &lt;a href=&quot;http://es.wikipedia.org/wiki/Address_Resolution_Protocol&quot; title=&quot;ARP en Wikipedia&quot; target=&quot;_blank&quot;&gt;página en la Wikipedia&lt;/a&gt;. Como inconveniente tenemos que solo es válida su ejecución en el host de virtualización donde esté corriendo la máquina virtual. De otra forma, al no llegarnos la petición de IP de DHCP mediante broadcast, no podremos obtener esta IP.&lt;/p&gt;

&lt;p&gt;Este método es muy manual, pero es bastante fácil meterlo todo en un comando de una sola línea combinando esos comandos que tanto nos gusta usar en la shell como cut y grep:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;env &lt;span class=&quot;nv&quot;&gt;NOMBREVM&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;nombrevm arp &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;$(&lt;/span&gt;virsh dumpxml &lt;span class=&quot;nv&quot;&gt;$NOMBREVM&lt;/span&gt; | &lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;mac&lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt;address | cut &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\'&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; 2 &lt;span class=&quot;k&quot;&gt;)&lt;/span&gt; | cut &lt;span class=&quot;nt&quot;&gt;-d&lt;/span&gt; &lt;span class=&quot;se&quot;&gt;\ &lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Y si ya tenemos todo en una línea ¿porqué no incorporarlo como comando del sistema?&lt;/p&gt;

&lt;p&gt;Como adjunto, he incorporado el script que uso para obtener la IP de una máquina virtual indicándole el nombre de la máquina. El comando lo llamo virt-ip y lo suelo colocar bajo la ruta &lt;em&gt;/usr/local/bin/virt-ip&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.ant30.es/wp-content/uploads/2012/03/virt-ip.gz&quot;&gt;virt-ip&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Fri, 09 Mar 2012 20:58:05 +0000</pubDate>
        <link>/2012/03/como-conseguir-la-ip-de-una-maquina-virtual-de-libvirt-kvm/</link>
        <guid isPermaLink="true">/2012/03/como-conseguir-la-ip-de-una-maquina-virtual-de-libvirt-kvm/</guid>
        
        <category>kvm</category>
        
        <category>libvirt</category>
        
        <category>redes</category>
        
        <category>virt-manager</category>
        
        
        <category>Sysadmin</category>
        
        <category>Virtualización</category>
        
      </item>
    
      <item>
        <title>Clonando máquinas virtuales con virt-clone</title>
        <description>&lt;p&gt;En el post anterior, &lt;a href=&quot;http://www.ant30.es/2011/12/creando-una-imagen-plantilla-de-debian-y-derivados-para-kvm/&quot; title=&quot;Creando una imagen plantilla de Debian y derivados para kvm&quot; target=&quot;_blank&quot;&gt;Creando una imagen plantilla de Debian y derivados para kvm&lt;/a&gt;, ya vimos lo fácil que era crear imágenes de sistemas virtualizados a través de imágenes skels o plantillas y concluíamos creando la máquina mediante virt-install. También comenté que era posible realizarlo con virt-clone.&lt;/p&gt;

&lt;p&gt;Virt-clone aún no soporta el tratamiento de snapshots o backing image directamente. De momento, lo que sí que podemos hacer si ya tenemos la imagen creada y el dominio virtualizado disponible en libvirt es invocar al clonado, indicando que queremos preservar los datos de la imagen destino. En nuestro caso, la imagen destino la indicaremos nosotros y se correspondeerá con la imagen del sistema nuevo.&lt;/p&gt;

&lt;p&gt;Como ventajas tenemos que copiaremos los datos de ram, cpu, tarjetas de red, contexto selinux/apparmor y el resto de configuraciones del dominio xml asociado a la máquina virtual. Por tanto, resulta interesante principalmente para máquinas con muchos añadidos de configuración.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Recordamos el proceso de clonación de usando plantillas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Dirigiéndonos a nuestro almacen de imágenes. Congelamos la imagen plantilla quitando permisos de escritura.&lt;/p&gt;

    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;chmod &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; ubuntu1110-master.img
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Indicamos que queremos crear una nueva imagen de disco basándonos en la plantilla&lt;/p&gt;

    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;qemu-img create &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; qcow2 &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt; ubuntu1110-master.img ubuntu1110-clon.img
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Usamos virt-clone para crear la nueva réplica. Con características similares a la máquina original, en este caso, cambian la mac de la máquina y el UUID del dominio.&lt;/p&gt;

    &lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;virt-clone &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; ubuntu1110-clon &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; ubuntu1110 &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; ubuntu1110-clon.img &lt;span class=&quot;nt&quot;&gt;--preserve-data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;En algunos casos puede ser que tengamos que forzar a que se conecte con el libvirt local, en este caso, lo ejecutamos de esta forma:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;virt-clone &lt;span class=&quot;nt&quot;&gt;--connect&lt;/span&gt; qemu:///system &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; ubuntu1110-clon &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; ubuntu1110 &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; ubuntu1110-clon.img &lt;span class=&quot;nt&quot;&gt;--preserve-data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En nuestro caso, como queremos lanzar un clon de forma rápida, ha sido necesario el comando &lt;code class=&quot;highlighter-rouge&quot;&gt;--preserve-data&lt;/code&gt;. Sin embargo, si queremos que la imagen sea independiente, se puede hacer sin la opción &lt;code class=&quot;highlighter-rouge&quot;&gt;--preserve-data&lt;/code&gt;. La operación durará varios minutos porque revisará todos los mapas de bloques vacíos para resumir el espacio de la nueva imagen de disco.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;virt-clone &lt;span class=&quot;nt&quot;&gt;--connect&lt;/span&gt; qemu:///system &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; ubuntu1110 &lt;span class=&quot;nt&quot;&gt;-n&lt;/span&gt; ubuntu1110-clon2 &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; ubuntu1110-clon2.img
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;El comando nos muestra el progreso de la ejecución en la salida incluyendo un tiempo estimado de finalización y el porcentaje.&lt;/p&gt;

&lt;p&gt;Virt-clone pertenece al grupo de utilidades de gestión de virtualización &lt;a title=&quot;virt-manager&quot; target=&quot;_blank&quot; href=&quot;http://virt-manager.org/&quot;&gt;virt-manager&lt;/a&gt; que funcionan haciendo uso de la api &lt;a title=&quot;libvirt&quot; target=&quot;_blank&quot; href=&quot;http://libvirt.org&quot;&gt;libvirt&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Tue, 31 Jan 2012 19:47:20 +0000</pubDate>
        <link>/2012/01/clonando-maquinas-virtuales-con-virt-clone/</link>
        <guid isPermaLink="true">/2012/01/clonando-maquinas-virtuales-con-virt-clone/</guid>
        
        <category>kvm</category>
        
        <category>libvirt</category>
        
        <category>qcow2</category>
        
        <category>qemu</category>
        
        <category>virt-manager</category>
        
        
        <category>Sysadmin</category>
        
        <category>Virtualización</category>
        
      </item>
    
      <item>
        <title>Creando una imagen plantilla de Debian y derivados para kvm</title>
        <description>&lt;h2 id=&quot;qué-es-una-imagen-plantilla&quot;&gt;¿Qué es una imagen plantilla?&lt;/h2&gt;

&lt;p&gt;Imagen Skel, plantilla, Imagen Gold, template, Appliance, base, .. todo estos términos se acaban refiriendo a lo mismo. En los sistemas de virtualización más habituales, tenemos la posibilidad de guardar el disco duro del sistema virtualizado en nuestro propio disco duro en una imagen que habitualmente contiene unos metadatos de información como por ejemplo el tamaño del disco y además contiene lo que sería equivalente al disco duro físico de la máquina virtual. Existen múltiples formatos de imagen de disco como vmdk, vdi, raw, qcow2 o qed. En nuestro caso, vamos a usar qcow2 y porque es el formato más estable para el sistema de virtualización que vamos a usar, libvirt con kvm.&lt;/p&gt;

&lt;p&gt;Si solemos trabajar con sistemas virtualizados, es bastante habitual tener múltiples máquinas con una misma versión de debian, aunque luego tengan software diferente. También puede resultar que tengamos todo el sistema y una aplicación desplegada en muchas máquinas, de forma que luego solo hacemos algunas personalizaciones sobre la aplicación. Es decir, que realmente estas máquinas comparten mucha información como sistema operativo y aplicaciones. Intentar evitar la repetición de información compartida es el objetivo de las imágenes gold o plantillas. Pero no solo por evitar la duplicidad de información, sino para conseguir ahorrar tiempo en la creación de nuevas máquinas virtuales de características similares.&lt;/p&gt;

&lt;p&gt;A continuación veremos una forma de reducir drásticamente el tiempo de creación de nuevas máquinas virtuales a través de imágenes plantilla.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2 id=&quot;un-ejemplo&quot;&gt;Un ejemplo&lt;/h2&gt;

&lt;p&gt;Imagina que te necesitas 10 máquinas virtuales con debian squeeze, y por tanto, tuvieras que instalar debian 10 veces. Qué pérdida de tiempo ¿no?&lt;/p&gt;

&lt;p&gt;Una posible solución, y suele ser la primera solución que hemos hecho alguna vez todos, es tras acabar de instalar debian en esa imagen, copiarla 9 veces. Con un disco duro medianamente rápido conseguimos una tasa de copia en un mismo disco de 40MB/s, te puedes ir a tomar un café mientras se termina la copia y quizás cuando vuelvas aún no haya terminado.&lt;/p&gt;

&lt;p&gt;Tras arrancar cada una de las nuevas 9 máquinas es posible que nos encontremos sin red, porque se nos habrá creado una nueva interfaz de red que no está contemplada en la configuración (/etc/network/interfaces) para que se active durante el arranque. Esto ocurre porque la MAC de la tarjeta de red de la nueva máquina virtual es diferente a la que se generó primero. Para solucionar esto, basta con borrar el fichero /etc/udev/rules.d/70-persistent-net.rules y reiniciar.&lt;/p&gt;

&lt;p&gt;Bien, ya tenemos las 10 máquinas arrancadas y con red, si hacemos un ssh y nos fijamos tenemos un nuevo problema. Todos los servidores tienen la misma key. Por tanto toca regenerarlas para cada servidor y reiniciar servicio ssh.&lt;/p&gt;

&lt;p&gt;También puede resultar problemático que todas las máquinas tengan el mismo hostname y por tanto, al hacer ssh, todas tengan el mismo prompt, lo cual puede resultar confuso.&lt;/p&gt;

&lt;p&gt;Por tanto, seguimos teniendo varios problemas. Larga espera para la copia de las imágenes y modificaciones manuales máquina a máquina. Necesitamos algo más práctico.&lt;/p&gt;

&lt;h2 id=&quot;mejora-1-reduciendo-modificaciones-manuales-del-primer-arranque&quot;&gt;Mejora 1: Reduciendo modificaciones manuales del primer arranque&lt;/h2&gt;

&lt;p&gt;Una vez tenemos nuestra imagen preparada, recién instalada, antes de empezar a usarla como imagen plantilla, deberíamos intentar simplificar al máximo las tareas manuales a realizar durante el primer arranque. Además de limpiar de datos que no sean útiles para los futuros clones.&lt;/p&gt;

&lt;h3 id=&quot;eliminar-persistencia-de-nombres-de-dispositivos-de-red-de-udev&quot;&gt;Eliminar persistencia de nombres de dispositivos de red de udev&lt;/h3&gt;

&lt;p&gt;Si estamos usando una imagen con una distribución debian o basada en debian como ubuntu, tendremos el problema de udev, así que lo ideal es siempre borrar el fichero /etc/udev/rules.d/70-persistent-net.rules para que cuando se arranque una copia de la máquina, se cree un nuevo fichero de nuevo. En VMware y XEN este problema no ocurre, pero sí con KVM. El problema radica en que el identificador del dispositivo en KVM es como el de un dispositivo real, ya sea Realtek o Intel, y con esto, udev, no puede distinguir cuando se está usando una interfaz virtual o no.&lt;/p&gt;

&lt;p&gt;Actualmente, las reglas para inhibir la creación del fichero de persistencia para redes de KVM están en el fichero /lib/udev/rules.d/75-persistent-net-generator.rules pero también se puede apreciar como existen reglas para Realtek que entran en colisión. Por tanto, también puedes anular la regla de Realtek para se haga efectiva, pero entonces estarás modificando ficheros del paquete udev, práctica nada recomendable para futuras actualizaciones.&lt;/p&gt;

&lt;h3 id=&quot;eliminar-historial&quot;&gt;Eliminar historial&lt;/h3&gt;

&lt;p&gt;Dependiendo de nuestras necesidades o de quien pueda usar después la imagen que estamos preparando, lo ideal es borrar rastros como por ejemplo el fichero .bash_history de todos los usuarios.&lt;/p&gt;

&lt;p&gt;Hay quien incluso limpiaría logs y otros restos.&lt;/p&gt;

&lt;h3 id=&quot;preparar-tareas-para-el-primer-arranque&quot;&gt;Preparar tareas para el primer arranque&lt;/h3&gt;

&lt;p&gt;No existe o no conozco una forma elegante de programar una tarea que se ejecute solo en el próximo arranque. Así que lo que vamos a preparar es una forma poco intrusiva para llevarlo a cabo.&lt;/p&gt;

&lt;p&gt;Creamos en /root un script llamado firstboot.sh con el siguiente contenido:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;#!/bin/bash&lt;/span&gt;
rm /etc/ssh/ssh&lt;span class=&quot;se&quot;&gt;\_&lt;/span&gt;host&lt;span class=&quot;se&quot;&gt;\_&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;
/usr/sbin/dpkg-reconfigure openssh-server
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En nuestro caso, solo vamos a regenerar las claves del servicio ssh.&lt;/p&gt;

&lt;p&gt;Ahora, creamos un nuevo fichero en cron.d para que invoque a nuestro script al completar el arranque, por tanto creamos el fichero /etc/cron.d/firstboot con el siguiente contenido:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@reboot root bash /root/firstboot.sh &amp;amp;&amp;amp; rm -f /etc/cron.d/firstboot /root/firstboot.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Primero se ejecutará firstboot.sh y luego se borrará la entrada del cron y el script del primer arranque para que no se vuelvan a ejecutar.&lt;/p&gt;

&lt;p&gt;Ya avisé que no era una forma muy elegante de hacerlo.&lt;/p&gt;

&lt;p&gt;El script firstboot.sh descrito es lo mínimo, pero sería interesante recoger el hostname desde el DNS y aplicar el cambio, realizar las tareas para inicializar un sistema de gestión de configuración centralizada o cualquier otra tarea.&lt;/p&gt;

&lt;h3 id=&quot;prepara-tu-entorno&quot;&gt;Prepara tu entorno&lt;/h3&gt;

&lt;p&gt;Una vez finalizada la instalación de debian, tenemos vi, pero no vim, basta con instalar el paquete, pero aprovechando que estamos haciendo nuestra template, deberíamos instalar esas cosas que siempre acabamos usando, y aquí va una lista de las cosas que suelo tener en mis imágenes plantillas independientemente de para qué se usen:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;El metapaquete vim-nox, o vim&lt;/li&gt;
  &lt;li&gt;Mi configuración de vim, .vimrc&lt;/li&gt;
  &lt;li&gt;Mis claves públicas ssh en /root/.ssh/authorized_keys para no tener que estar metiendo contraseñas en cada ssh&lt;/li&gt;
  &lt;li&gt;Un .bashrc con los alias que suelo usar&lt;/li&gt;
  &lt;li&gt;Screen y su configuración&lt;/li&gt;
  &lt;li&gt;¿Está instalado ssh server y aptitude? ¿Necesito sudo?&lt;/li&gt;
  &lt;li&gt;htop, un top mucho más cómodo&lt;/li&gt;
  &lt;li&gt;Algunos alias en el fichero /etc/hosts&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;mejora-2-técnica-alternativa-al-copiado-de-imágenes-backing-images&quot;&gt;Mejora 2: técnica alternativa al copiado de imágenes, backing images&lt;/h2&gt;

&lt;p&gt;Estamos usando libvirt con kvm, que en definitiva se trata de qemu y por tanto, para la creación de imágenes, usamos qemu-img. Para crear una imagen nueva basada en nuestra plantilla es tan fácil como ir al directorio de imágenes y suponiendo que la imagen creada se llame debian6.img creamos un clon, debian6-clon.img, con el comando qemu-img como sigue:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;qemu-img create -f qcow2 -b debian6.img debian6-clon.img
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Tendremos la nueva imagen en segundos y el nuevo fichero debian6-clon.img ocupará solo unos kbytes. Esta nueva imagen irá almacenando bloques que se creen que no estén o hayan sido modificados respecto a la imagen base.&lt;/p&gt;

&lt;p&gt;Como inconveniente, tenemos una bajada en el rendimiento de IO por los múltiples accesos a disco por cada petición. Este problema se puede solventar en gran medida si las plantillas las alojamos en discos SSD. Aún así, sino vamos a realizar pruebas de rendimiento, no debería suponer mucho problema.&lt;/p&gt;

&lt;p&gt;Si vas a usar la propia imagen como backing image para el resto, recuerda quitar los permisos de escritura para que nunca se vuelva a arrancar, y si puede ser posible, deberías desvincularla de cualquier dominio libvirt. En caso de arranque, el resto de imágenes clonadas que se basen en tu backing image, perderán consistencia y dejarán de funcionar. Casi mejor, por tanto, tener cuidado con la imagen plantilla.&lt;/p&gt;

&lt;p&gt;Por otro lado, si queremos convertir la imagen de este clon en imagen plantilla, deberíamos aplanarla, es decir, separarla de la imagen debian6.img fusionando sus datos en una nueva imagen que sea independiente. Esta nueva imagen independiente la podremos mover a otra ruta o incluso a otro servidor. Esto se consigue mediante el comando:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;qemu-img convert -f qcow2 -O qcow2 debian6-clone.img debian6-plana.img
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Que además, evitará poner en la nueva imagen bloques vacíos y por tanto puede ocupar menos de lo que uno espera.&lt;/p&gt;

&lt;h2 id=&quot;creando-una-máquina-virtual-con-virt-install-usando-la-plantilla&quot;&gt;Creando una máquina virtual con virt-install usando la plantilla&lt;/h2&gt;

&lt;p&gt;Entre las utilidades que solemos encontrar con libvirt, tenemos virt-install, que nos permite crear una máquina virtual desde bash, también podríamos crearla desde virt-manager de forma gráfica, pero en nuestro caso la vamos a crear mediante virt-install.&lt;/p&gt;

&lt;p&gt;Suponiendo que tengamos la imagein debian6-clon.img creada en el punto anterior, en el directorio /var/lib/libvirt/images/ y teniendo en cuenta que este es el almacenamiento por defecto para las imágenes, para crear un sistema con 512MB de RAM y especificando que está basado en Debian Squeeze (debian 6), ejecutaríamos lo siguiente:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo virt-install --name debian-clone --ram 512 --os-variant=debiansqueeze --disk /var/lib/libvirt/images/debian6-clone.img --import
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Se nos abrirá un visor vnc con virt-viewer para que podamos acceder, por ejemplo para ver si el script de primer arranque se ha ejecutado correctamente, o para conocer la IP de la máquina y poder acceder por ssh de un modo más cómodo.&lt;/p&gt;

&lt;p&gt;Por tanto las nuevas réplicas, tanto por la clonación del disco, como del esquema XML de la máquina en libvirt se obtienen en segundos y las tendremos disponibles en nuestro Virt-Manager.&lt;/p&gt;

&lt;p&gt;También podríamos usar virt-clone para la generación del XML, pero eso ya lo dejamos para otro día.&lt;/p&gt;
</description>
        <pubDate>Thu, 29 Dec 2011 21:48:40 +0000</pubDate>
        <link>/2011/12/creando-una-imagen-plantilla-de-debian-y-derivados-para-kvm/</link>
        <guid isPermaLink="true">/2011/12/creando-una-imagen-plantilla-de-debian-y-derivados-para-kvm/</guid>
        
        <category>debian</category>
        
        <category>kvm</category>
        
        <category>libvirt</category>
        
        <category>qcow2</category>
        
        <category>qemu</category>
        
        <category>Virtualización</category>
        
        
        <category>blog</category>
        
        <category>Sysadmin</category>
        
        <category>Virtualización</category>
        
      </item>
    
      <item>
        <title>Este blog ya está migrado de Drupal 6 a WordPress 3</title>
        <description>&lt;p&gt;Tras 3 años con Drupal, ahora he migrado a WordPress. Teniendo en cuenta que solo se trata de un blog, necesito algo que sea más fácil de gestionar, actualizar, utilizar y creo que en eso WordPress gana de sobra a Drupal. Me encantan las Views y los CCK de Drupal, pero es que realmente, para este tipo de blog no los estaba usando.&lt;/p&gt;

&lt;p&gt;Existen unas cuantas formas de migrar de Drupal a WordPress, pero no todas contemplan todas las opciones. Lógicamente, migrar funcionalidades de los módulos principales es una tarea que acaba siendo manual.&lt;/p&gt;

&lt;p&gt;En mi caso, tenía algunos requisitos mínimos sin los cuales, no podría considerar hacer la migración:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Conservar todos los nodos de Drupal. En Drupal, las páginas, libros y entradas de blogs son nodos.&lt;/li&gt;
  &lt;li&gt;Conservar las taxonomías, pero no en categorías, sino transformándolas a tags.&lt;/li&gt;
  &lt;li&gt;Resaltado de sintáxis de código. Tengo varios posts con bloques de código, así que es imprescindible que sigan apareciendo con resaltado de sintaxis.&lt;/li&gt;
  &lt;li&gt;Migración de adjuntos, y en el caso de las imágenes, que por lo menos, sean visibles. No siempre están como html en el contenido, porque mediante el módulo img_filter, se visualizaban de forma automática en los posts.&lt;/li&gt;
  &lt;li&gt;Conservar los comentarios, aunque cambien un poco el formato. En drupal hay asunto del comentario y en WordPress no.&lt;/li&gt;
  &lt;li&gt;Solo hay un usuario, así que esto no debería suponer un problema.&lt;/li&gt;
  &lt;li&gt;Debe haber pocos 404 tras la migración.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Esta no iba a ser mi primera migración entre diferentes softwares de servicios web, he realizado diferentes migraciones tanto a nivel profesional, en &lt;a href=&quot;http://www.yaco.es&quot;&gt;Yaco Sistemas&lt;/a&gt;, como para diferentes proyectos personales u otros fines sin ánimos de lucro. En este caso, quiero un resultado no necesariamente profesional, pero sí que esos requisitos mínimos especificados arriba queden satisfechos. Así que como indica el sentido común para realizar migraciones en un sistema de producción, lo ideal es prepararse un entorno de desarrollo con una copia de los datos de producción. En este caso, preparé un chroot con un sistema operativo a donde está hosteado el blog y luego desplegué un clon de Drupal con un dump de la base de datos, y una base de WordPress para comenzar a realizar pruebas.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Las primeras pruebas que hice, eran pruebas de migración realizando modificaciones sobre el SQL siguiendo algunas guías que existen:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://socialcmsbuzz.com/convert-import-a-drupal-6-based-website-to-wordpress-v27-20052009/&quot;&gt;Post de Lincoln Hawks&lt;/a&gt; en Socialcmsbuzz.com&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://scurker.com/blog/2010/02/migration-from-drupal-6-x-to-wordpress-2-9x/&quot;&gt;Migration from Drupal 6.x to WordPress 2.9x&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;El problema con estos procesos de migración, son los adjuntos. En estos posts, se propone reemplazar las rutas de los tags img en el body, pero es que en mi caso hay tags para img_filters de tipo [img:01 yy:left] o sin ni siquiera tag, indicando en el adjunto como se debe publicar.&lt;/p&gt;

&lt;p&gt;Al final, entre diversas pruebas, he optado por pasar por un formato intermedio, &lt;a href=&quot;http://es.wikipedia.org/wiki/MovableType&quot;&gt;MovableTypes&lt;/a&gt; Viendo &lt;a href=&quot;http://andrew.sterling.hanenkamp.com/2008/03/drupal-to-movable-type.html&quot;&gt;este post&lt;/a&gt; de Andrew Sterling parece bastante fácil manipular el body, los tags y el resto de información creando un nodo con contenido php en Drupal.&lt;/p&gt;

&lt;p&gt;finalmente, mi código de exportación de Drupal, basándome en el publicado por Andrew Sterling, ha quedado como en el siguiente bloque. No es que sea bonito, pero es funcional:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;header('Content-type: text/plain');
$nids = db_query(&quot;select distinct n.nid from {node} n inner join {term_node} t on t.nid = n.nid&quot;);
while ($node = node_load(db_fetch_object($nids)-&amp;gt;nid, NULL, TRUE)) {
  print &quot;AUTHOR: &quot;.$node-&amp;gt;name.&quot;\n&quot;;
  print &quot;TITLE: &quot;.$node-&amp;gt;title.&quot;\n&quot;;
  print &quot;STATUS: &quot;.($node-&amp;gt;status?&quot;Publish&quot;:&quot;Draft&quot;).&quot;\n&quot;;
  print &quot;ALLOW COMMENTS: &quot;.($node-&amp;gt;comment&amp;gt;0).&quot;\n&quot;;
  print &quot;CONVERT BREAKS: 1\n&quot;;
  print &quot;ALLOW PINGS: &quot;.($node-&amp;gt;comment&amp;gt;0).&quot;\n&quot;;
  print &quot;DATE: &quot;.strftime(&quot;%m/%d/%Y %I:%M:%S %p&quot;, $node-&amp;gt;created).&quot;\n&quot;;
  print &quot;CATEGORY: blog \n&quot;;
  print &quot;KEYWORDS: \n&quot;;
  foreach ($node-&amp;gt;taxonomy as $vid =&amp;gt; $term) {
    print $term-&amp;gt;name.&quot;,&quot;;
  }
  foreach ($node-&amp;gt;category as $category) {
    print $category-&amp;gt;title.&quot;,&quot;;
  }
  print &quot;\n&quot;;
  print &quot;-----\n&quot;;
  print &quot;BODY:\n&quot;;

  $body = str_replace(&quot;&amp;lt;python&amp;gt;&quot;, &quot;[py]&quot;, $node-&amp;gt;body);
  $body = str_replace(&quot;&amp;lt;/python&amp;gt;&quot;, &quot;[/py]&quot;, $body);

  $body = str_replace(&quot;&amp;lt;bash&amp;gt;&quot;, &quot;[sh]&quot;, $body);
  $body = str_replace(&quot;&amp;lt;/bash&amp;gt;&quot;, &quot;[/sh]&quot;, $body);

  $body = str_replace(&quot;&amp;lt;code&amp;gt;&quot;, &quot;&amp;lt;pre class=&quot;crayon-plain-tag&quot;&amp;gt;&quot;, $body);
  $body = str_replace(&quot;&amp;lt;/code&amp;gt;&quot;, &quot;&amp;lt;/pre&amp;gt;&quot;, $body);

  $body = str_replace(&quot;/files/&quot;, &quot;/wp-content/uploads/&quot;, $body);

  $media_base = &quot;/wp-content/uploads/&quot;;

  $patterns = array(&quot;/\[img:01 align:left\]/s&quot;,
                    &quot;/\[img:vista-navegacion.png yy:float_left\]/s&quot;,
                    &quot;/&amp;lt;\!-- break --&amp;gt;/s&quot;,
                    &quot;/&amp;lt;\!--break--&amp;gt;/s&quot;,
                    &quot;/&amp;lt;h3&amp;gt;/s&quot;,
                    &quot;/&amp;lt;\/h3&amp;gt;/s&quot;
                     );

  $replace = array('&amp;lt;img src=&quot;'.$media_base.'01_antes_de_comenzar.jpg&quot;/&amp;gt;',
                   '&amp;lt;img src=&quot;'.$media_base.'vista-navegacion.png&quot;/&amp;gt;',
                   &quot;&amp;lt;!--more--&amp;gt;&quot;,
                   &quot;&amp;lt;!--more--&amp;gt;&quot;,
                    &quot;&amp;lt;h2&amp;gt;&quot;,
                    &quot;&amp;lt;/h2&amp;gt;&quot;
                   );

  $body = preg_replace($patterns, $replace, $body);

  print $body.&quot;\n&quot;;

  $uploads = db_query(&quot;select * from {upload} u where u.nid= %d and list = 1&quot;, $node-&amp;gt;nid);
  while ($upload = db_fetch_object($uploads)) {
      $file_query = db_query(&quot;select * from {files} f where f.fid = %d&quot;, $upload-&amp;gt;fid);
      $file = db_fetch_object($file_query);
      $file_url = str_replace(&quot;files/&quot;, &quot;/wp-content/uploads/&quot;, $file-&amp;gt;filepath);
      $pos = stripos($body, $file_url);
      if ($pos === false){
        $pos_mime = stripos($file-&amp;gt;filemime, &quot;image/&quot;);
        if ($pos_mime === false){
            print '&amp;lt;a href=&quot;'.$file_url.'&quot;&amp;gt;'.$file-&amp;gt;name.'&amp;lt;/a&amp;gt;';
        }
        else {
            print '&amp;lt;img alt=&quot;'.$file-&amp;gt;filename.'&quot; src=&quot;'.$file_url.'&quot;/&amp;gt;';
        }
        print &quot;\n&quot;;
      }
  }

  print &quot;-----\n&quot;;
  $comments = db_query(&quot;select * from {comments} c where c.nid = %d&quot;, $node-&amp;gt;nid);
  while ($comment = db_fetch_object($comments)) {
    print &quot;-----\n&quot;;
    print &quot;COMMENT:\n&quot;;
    print &quot;AUTHOR: &quot;.$comment-&amp;gt;name.&quot;\n&quot;;
    print &quot;EMAIL: &quot;.$comment-&amp;gt;mail.&quot;\n&quot;;
    print &quot;IP: &quot;.$comment-&amp;gt;hostname.&quot;\n&quot;;
    print &quot;URL: &quot;.$comment-&amp;gt;homepage.&quot;\n&quot;;
    print &quot;DATE: &quot;.strftime(&quot;%m/%d/%Y %I:%M:%S %p&quot;, $comment-&amp;gt;timestamp).&quot;\n&quot;;
    print $comment-&amp;gt;subject.&quot;\n&quot;;
    print $comment-&amp;gt;comment.&quot;\n&quot;;
  }
  print &quot;--------\n&quot;;
}
exit;
?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Con este código, las imágenes adjuntas que no estaban insertadas con tags img ya sea de image_filter o html img, se añaden al final. En el caso de que el adjunto no sea una imagen, se incorpora un enlace. Es importante mover las imágenes del directorio drupal files, al de wordpress, /wp-content/uploads/&lt;/p&gt;

&lt;p&gt;En los comentarios, el asunto de muestra en la primera línea, y luego se incorpora el body. También hay ciertas personalizaciones como la conversión del &lt;em&gt;break&lt;/em&gt; de drupal al &lt;em&gt;more&lt;/em&gt; de wordpress y otras conversiones &lt;em&gt;caseras&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;El único problema a resolver ahora está en las URL. En el script de Andrew, se incorporaban como categorías, de forma, que luego mediante un redirect a una búsqueda de wordpress, fuera fácil localizar el post. Sin embargo, esto acaba creando muchas categorías que no son útiles, y aunque se puedan usar módulos para ocultarlas, a la hora de publicar contenidos, estas categorías siguen apareciendo. En mi caso tengo 70 posts, así que si tenemos 2 tipos de urls, el permalink y la pretty url, tendríamos 140 categorías inválidas, demasiadas.&lt;/p&gt;

&lt;p&gt;Como opción, finalmente, he escrito un pequeño script en php que haga un redirect a la url de búsqueda de wordpress si se detecta en apache una url con el formato de drupal. Este script sí que no lo publico, son 5 líneas que dan vergüenza.&lt;/p&gt;

&lt;p&gt;También he tenido en cuenta en la migración la antigua url del feed de Drupal, que se cambia al nuevo formato de WordPress mediante un Redirect en Apache.&lt;/p&gt;

&lt;p&gt;He cambiado el color de la cabecera a blanco y negro, en escala de grises, añadido los botones de twitter y google+ y Akismet y poco más. Esta es la historia de una migración de Drupal a WordPress.&lt;/p&gt;
</description>
        <pubDate>Wed, 28 Dec 2011 14:43:27 +0000</pubDate>
        <link>/2011/12/este-blog-ya-esta-migrado-de-drupal-6-a-wordpress-3/</link>
        <guid isPermaLink="true">/2011/12/este-blog-ya-esta-migrado-de-drupal-6-a-wordpress-3/</guid>
        
        <category>Drupal</category>
        
        <category>web</category>
        
        <category>Wordpress</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>TCOS ha entrado en Debian</title>
        <description>&lt;p&gt;He escrito una entrada sobre TCOS y su entrada en Debian en el &lt;a href=&quot;http://www.yaco.es/blog&quot;&gt;Blog de Yaco&lt;/a&gt; En la que he colaborado poniendo en contacto a Mario, desarrollador de TCOS con desarrolladores de Debian como GheRivero
&lt;a href=&quot;http://www.yaco.es/blog/virtualizacion/2011/12/tcos-ya-forma-parte-debian/&quot;&gt;TCOS ya forma parte de Debian en el blog de Yaco&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enhorabuena Mario.&lt;/p&gt;
</description>
        <pubDate>Tue, 13 Dec 2011 01:43:37 +0000</pubDate>
        <link>/2011/12/tcos-ha-entrado-en-debian/</link>
        <guid isPermaLink="true">/2011/12/tcos-ha-entrado-en-debian/</guid>
        
        <category>escritorio</category>
        
        <category>Linux</category>
        
        <category>tcos</category>
        
        <category>thin-clients</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Puppet, gestión de configuración centralizada.</title>
        <description>&lt;p&gt;&lt;a href=&quot;http://puppetlabs.com/&quot;&gt;Puppet&lt;/a&gt; es una herramienta gestión de configuraciones
centralizada que nos ayudará en la laboriosa gestión de servidores cuando el
número de estos empieza a crecer.&lt;/p&gt;

&lt;p&gt;Recientemente ha cambiado de licencia, de GPL a Apache a partir de la versión
2.7.0. Está basado en Ruby, pero las descripciones de configuraciones se
escriben en modo declarativo. Existen paquetes construidos que ya vienen en el
sistema de paquetería para las principales distribuciones Linux, en nuestro
caso usaremos Debian Squeeze y los paquetes a los que tenemos acceso en su
repositorio. También tienen soporte para otros sistemas UNIX como Solaris,
*BSD o Mac OS X. Y en desarrollo tienen un soporte básico de sistemas Windows.&lt;/p&gt;

&lt;p&gt;El desarrollo es público desde 2006 y destaca por su estabilidad y facilidad de
manejo, aunque como todo este tipo de herramientas, la curva de aprendizaje, no
es muy liviana. Entre los principales clientes de la solución enterprise para
empresas destacan empresas como Nokia, RackSpace, Zynga, Twitter, Digg, …&lt;/p&gt;

&lt;p&gt;En este post, veremos como configurar Puppet en Debian Squeeze y podremos ver
dos ejemplos de aplicación de configuraciones.
&lt;!--more--&gt;&lt;/p&gt;

&lt;h2 id=&quot;porqué-escribir-sobre-puppet&quot;&gt;¿Porqué escribir sobre puppet?&lt;/h2&gt;

&lt;p&gt;Nunca he profundizado en el uso puppet, nunca más allá que algunas de pruebas
de concepto o funcionalidad y es por esta razón quiero escribir esta serie de
posts, obligarme a conocer mucho mejor esta herramienta. En nuestro caso
queremos usar puppet para controlar un entorno virtualizado con libvirt.
Nuestro objetivo es controlar solo a Guests, es decir, máquinas virtuales,
debido a que este es el entorno más heterogéneo y difícil de mantener, entre
nuestros componentes Hosts/Guests. Se supone, que en un sistema de
virtualización relativamente grande, todo está controlado mediante una
herramienta de orquestado, ya seas herramientas basadas en VMWare como vCenter
o vSphere o del tipo RedHat RHEV / Ovirt, Proxmox, Eucalyptus, OpenStack …
Por tanto, los nodos de virtualización deberían estar bastante controlados.&lt;/p&gt;

&lt;p&gt;Para la siguiente prueba usaremos tres máquinas procedentes de una misma
plantilla de kvm con una instalación de debian6 básica. En otro artículo
hablaré sobre como crear templates de kvm, pero para nuestro caso, imagínate
que son 3 máquinas virtuales recién instaladas usando virt-manager. En una de
las máquinas instalaremos lo que se denomina Master, que será el servidor
encargado de gestionar la configuraciones del resto.&lt;/p&gt;

&lt;p&gt;El objetivo de la prueba enviar un par de ficheros a los clientes, cliente1 y
cliente2 a partir de ahora. Uno de estos ficheros tendrá un contenido diferente
según sea el receptor del fichero cliente1 o cliente2.&lt;/p&gt;

&lt;p&gt;En la segunda prueba, instalaremos un par de paquetes y al igual que en la
prueba anterior, nos aseguraremos de que el paquete 1 se instale en las dos
máquinas, y que además, en el cliente1 se instale el paquete 2 y el paquete 3.&lt;/p&gt;

&lt;p&gt;Tras bucear un poco en la red, no he encontrado ninguna guía actualizada para
debian 6 (squeeze), pero sí que he podido localizar muchas guías de
introducción, con las que he ido recomponiendo este post.&lt;/p&gt;

&lt;p&gt;En mi caso, me ha ayudado bastante tanto la &lt;a href=&quot;http://docs.puppetlabs.com/&quot;&gt;documentación de
puppet&lt;/a&gt; como esta &lt;a href=&quot;http://www.ctrip.ufl.edu/centralized-system-administration-debian-using-puppet&quot;&gt;Introducción a Puppet de la Universidad de
Florida&lt;/a&gt;.
Aunque en este último caso, los ejemplos hablan de debian lenny, es decir, una
versión de debian anterior. Realmente, como veremos en los ejemplos, no hay
mucha diferencia entre la configuración de Lenny y Squeeze, lo que nos permite
confiar en la estabilidad del código.&lt;/p&gt;

&lt;h2 id=&quot;antes-de-empezar&quot;&gt;Antes de empezar&lt;/h2&gt;

&lt;p&gt;Antes de empezar, nos debemos asegurar de que los nombres de las máquinas
resuelven correctamente entre ellas. Esto nos permitirá olvidarnos de problemas
con certificados y similares, que son difíciles de depurar después.&lt;/p&gt;

&lt;p&gt;En mi caso, las dos máquinas clientes, tienen en el /etc/hosts una línea que
hace referencia al master, de forma que tiene un nombre del tipo
master.cluster. Además, en la máquina master.cluster tengo registrado los
nombres de los clientes como client1 y client2.&lt;/p&gt;

&lt;p&gt;Por tanto, para verificar que todo está correctamente en cuanto a DNS debemos
asegurarnos que tenemos valores de este tipo para el comando hostname&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;root@master:~# hostname
master
root@master:~# hostname &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt;
master.cluster
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Es un error muy habitual, que por ejemplo hostname -f nos de localhost o localhost.localdomain. Esto es debido a que la línea donde debemos especificar el alias hacia nuestra máquina, debe ser la primera del fichero /etc/hosts&lt;/p&gt;

&lt;h2 id=&quot;preparando-el-master&quot;&gt;Preparando el master&lt;/h2&gt;

&lt;p&gt;Instalamos el paquete puppetmaster.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt-get install puppetmaster
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Una vez la instalación haya finalizado, hay que configurar el directorio donde se compartiran los ficheros, así que rango de IPs tendrá acceso al directorio de ficheros y plugins.&lt;/p&gt;

&lt;p&gt;Abrimos el fichero fileserver.conf&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;editor /etc/puppet/fileserver.conf
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Si estás usando libvirt para gestionar la máquina y usas la configuración de red que viene por defecto, tus máquinas virtuales tendrán una IP dentro del rango 192.168.122.0/24 . Por tanto, para nuestro ejemplo, usaremos este rango. Con esto, el fichero fileserver.conf quedaría de esta forma:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;files]
path /etc/puppet/files
allow 192.168.122.0/24
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;plugins]
allow 192.168.122.0/24
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;También puedes usar nombres DNS, o directamente, permitir a todo el mundo con
una regla del tipo allow &lt;code class=&quot;highlighter-rouge&quot;&gt;*.&lt;/code&gt; Puedes ver más información en la doc de
&lt;a href=&quot;http://docs.puppetlabs.com/guides/file_serving.html&quot;&gt;puppetlab&lt;/a&gt; sobre este
fichero de configuración.&lt;/p&gt;

&lt;p&gt;Ahora vamos a crear los ficheros básicos de manifest casi vacíos.&lt;/p&gt;

&lt;p&gt;Primero creamos el fichero /etc/puppet/manifests/nodes.pp&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pruebanode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'client1.cluster'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;inherits&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pruebanode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'client2.cluster'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;inherits&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pruebanode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Para que este fichero sea tomado en cuenta, hay que crear el fichero
/etc/puppet/manifests/site.pp e incluir el fichero nodes.pp que hemos comentado
antes. En las reglas de estilo de puppet indican que además habría que crear en
este directorio un fichero modules.pp e importarlo desde site.pp, pero en
nuestro caso no va a ser necesario porque los modulos que crearemos se
importarán automáticamente.&lt;/p&gt;

&lt;p&gt;Este es el contenido del fichero /etc/puppet/manifests/site.pp&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;import &quot;nodes&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;También es conveniente saber que el nombre del servicio en el servidor es
puppetmaster. Por tanto, para reiniciarlo, ejecutaríamos algo como:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;service puppetmaster restart
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;preparando-los-clientes&quot;&gt;Preparando los clientes&lt;/h2&gt;

&lt;p&gt;Este proceso lo repetiremos en cada uno de las máquinas que queremos controlar.&lt;/p&gt;

&lt;p&gt;Instalamos el paquete puppet&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;apt-get install puppet
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Revisamos el fichero de configuración del cliente, que debería lucir así:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;root@client1:~# &lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /etc/puppet/puppet.conf
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;main]
&lt;span class=&quot;nv&quot;&gt;logdir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/var/log/puppet
&lt;span class=&quot;nv&quot;&gt;vardir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/var/lib/puppet
&lt;span class=&quot;nv&quot;&gt;ssldir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/var/lib/puppet/ssl
&lt;span class=&quot;nv&quot;&gt;rundir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/var/run/puppet
&lt;span class=&quot;nv&quot;&gt;factpath&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$vardir&lt;/span&gt;/lib/facter
&lt;span class=&quot;nv&quot;&gt;templatedir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$confdir&lt;/span&gt;/templates
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;agent]
&lt;span class=&quot;nv&quot;&gt;server&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;master.cluster
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Para que pueda funcionar puppetd, el demonio que funciona en los clientes, es
necesario habilitarlo. Hay que editar el fichero &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/default/puppet&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;editor /etc/default/puppet
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Y debemos asegurarnos que START está confirado como yes&lt;/p&gt;

&lt;p&gt;Arrancamos el servicio puppet con service&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;service puppet start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Una vez realizado esto, nos debemos fijar en el syslog del cliente, si vemos
líneas con información como esta:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Could not request certificate: Retrieved certificate does not match private key; please remove certificate from server and regenerate it with the current key
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Está claro que algo no está funcionando. Verifica la configuración de DNS antes
de instalar como comenté en la sección de Antes de empezar&lt;/p&gt;

&lt;p&gt;Ahora procedemos a verificar desde el master que se han registrado
correctamente los identificadores de las firmas de los clientes:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;root@master:~# puppet cert &lt;span class=&quot;nt&quot;&gt;--list&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--all&lt;/span&gt;
client1.cluster &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;00:00:ssl_fingerprint:00:00&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
client2.cluster &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;00:00:ssl_fingerprint:00:00&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
+ master.cluster &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;00:00:ssl_fingerprint:00:00&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Tenemos que firmar los certificados de los clientes&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;root@master:~# puppet cert &lt;span class=&quot;nt&quot;&gt;--list&lt;/span&gt;
client2.cluster
client1.cluster
root@master:~# puppet cert &lt;span class=&quot;nt&quot;&gt;--sign&lt;/span&gt; client1.cluster
notice: Signed certificate request &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;client1.cluster
notice: Removing file Puppet::SSL::CertificateRequest client1.cluster at &lt;span class=&quot;s1&quot;&gt;'/var/lib/puppet/ssl/ca/requests/client1.cluster.pem'&lt;/span&gt;
root@master:~# puppet cert &lt;span class=&quot;nt&quot;&gt;--sign&lt;/span&gt; client2.cluster
notice: Signed certificate request &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;client2.cluster
notice: Removing file Puppet::SSL::CertificateRequest client2.cluster at &lt;span class=&quot;s1&quot;&gt;'/var/lib/puppet/ssl/ca/requests/client2.cluster.pem'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;creación-de-un-módulo-básico-y-asignación-de-clientes-al-módulo&quot;&gt;Creación de un módulo básico y asignación de clientes al módulo&lt;/h2&gt;

&lt;p&gt;Podemos tener varios módulos. En un módulo es donde definiremos todas las
configuraciones y ficheros de un perfil de máquinas. También se puede tener una
configuración determinada. Como ejemplo, podríamos tener un módulo para
configurar un LAMP y luego otro para poder desplegar Drupal en el LAMP. Puedes
ver más información en &lt;a href=&quot;http://projects.puppetlabs.com/projects/puppet/wiki/Puppet_Modules&quot;&gt;La doc de puppet&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Creamos la estructura básica:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; /etc/puppet/modules/prueba/&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;manifests,files,templates&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Creamos un fichero vacío donde pondremos luego la receta de puppet&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;touch /etc/puppet/modules/prueba/manifests/init.pp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ahora editamos el fichero de configuración de nodos. Este fichero lo tendremos
en la ruta &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/puppet/manifests/nodes.pp&lt;/code&gt; y deberá tener este aspecto:&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pruebanode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;prueba&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'client1.cluster'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;inherits&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pruebanode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'client2.cluster'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;inherits&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pruebanode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Con esto, tendremos el modulo prueba aplicado a client1 y client2.&lt;/p&gt;

&lt;h2 id=&quot;prueba-1-distribución-de-ficheros&quot;&gt;Prueba 1: Distribución de ficheros&lt;/h2&gt;

&lt;p&gt;La primera prueba que realizaremos será colocar un fichero en una ruta en concreto de las dos máquinas.&lt;/p&gt;

&lt;p&gt;En el directorio &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/puppet/prueba/files&lt;/code&gt; creamos un fichero llamado
ficherodeprueba que contiene solo la siguiente frase:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;esto es un fichero de prueba
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ahora nos dirigimos al init.pp del módulo prueba en
&lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/puppet/modules/prueba/manifests/init.pp&lt;/code&gt; y ponemos el siguiente contenido&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;prueba&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/root/ficherodeprueba&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;owner&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;group&lt;/span&gt;   &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;root&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;mode&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;400&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;source&lt;/span&gt;  &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;puppet:///modules/prueba/ficherodeprueba&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Normalmente, la configuración puede tardar bastante tiempo en aplicarse, para
forzarla vamos a ejecutar el siguiente puppetrun en el master.&lt;/p&gt;

&lt;p&gt;Además, si queremos verificar si funciona, puede ser de utilidad ejecutar el
proceso de actualización de forma manual y en modo de depuración, para esto
ejecutaríamos en el cliente:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;root@client1:~# puppetd &lt;span class=&quot;nt&quot;&gt;-vt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;ls
&lt;/span&gt;info: Caching catalog &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;client1.cluster
info: Applying configuration version &lt;span class=&quot;s1&quot;&gt;'1322082679'&lt;/span&gt;
notice: Finished catalog run &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;0.05 seconds
ficherodeprueba
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;prueba-2-instalación-de-software-procedente-de-paquetería&quot;&gt;Prueba 2: Instalación de software procedente de paquetería&lt;/h2&gt;

&lt;p&gt;En esta prueba, vamos a instalar un paquete diferente en cada máquina. En
client1 instalaremos nginx y en client2 instalaremos el paquete memcached.&lt;/p&gt;

&lt;p&gt;Comenzamos con la creación del módulo para instalar nginx. Lo vamos a llamar
httpd y empezamos creando la estructura de directorios en el master:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; /etc/puppet/modules/httpd/&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;manifests,files,templates&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Ahora en files crearemos un fichero estático para ser servido por nginx.
Creamos el fichero en &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/puppet/modules/httpd/wp-content/uploads/texto&lt;/code&gt; y
añadimos unas cuantas líneas de texto plano.&lt;/p&gt;

&lt;p&gt;Hay que crear el manifiest en &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/puppet/modules/httpd/manifests/init.pp&lt;/code&gt; con
el siguiente contenido:&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;httpd&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;nginx&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
         &lt;span class=&quot;py&quot;&gt;ensure&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;latest&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/var/www/texto&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;owner&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;www-data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;www-data&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;mode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;640&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;ensure&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;present&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;puppet:///httpd/texto&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;nginx::server&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nginx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;ensure&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;running&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;En este manifest, tenemos tres pasos. Primero instalamos el paquete nginx,
después incorporamos un fichero en un ruta de servicio y después arrancamos el
servicio nginx y nos aseguramos de que esté arrancado.&lt;/p&gt;

&lt;p&gt;Para que se aplique esta ejecución en el servidor client1, tenemos que
incorporar la asignación en el fichero &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/puppet/manifests/nodes.pp&lt;/code&gt; con lo
que el fichero quedaría como sigue:&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pruebanode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;prueba&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'client1.cluster'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;inherits&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pruebanode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;httpd&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;node&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'client2.cluster'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;inherits&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pruebanode&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Esta vez solo lo hemos incorporado en client1.cluster para que solo se instale en este servidor.&lt;/p&gt;

&lt;p&gt;Una vez salvemos este fichero, cuando toque actualizar, o si forzamos
simplemente reiniciando el agente en el cliente con service puppet restart,
podremos ver si se ha instalado el paquete nginx, si está funcionando y si
además, se puede acceder al fichero de texto que hemos enviado.&lt;/p&gt;

&lt;p&gt;Ahora vamos con la instalación memcached, creamos los directorios necesarios:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mkdir &lt;span class=&quot;nt&quot;&gt;-p&lt;/span&gt; /etc/puppet/modules/memcached/&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;manifests,files,templates&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Hay que crear el manifiest en &lt;code class=&quot;highlighter-rouge&quot;&gt;/etc/puppet/modules/memcached/manifests/init.pp&lt;/code&gt;
con el siguiente contenido:&lt;/p&gt;

&lt;div class=&quot;language-puppet highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;memcached&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;memcached&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;ensure&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;latest&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;memcached::server&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memcached&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;ensure&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;running&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;py&quot;&gt;enable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Tras guardar, añadimos tal y como hicimos con nginx (httpd) en site.pp, este
módulo en la parte de client2, con una línea que contenga include memcached .
Una vez hecho esto, es cuestión de esperar a que se apliquen los cambios, o
forzar a que se apliquen reiniciando el agente en el cliente.&lt;/p&gt;

&lt;p&gt;Pues sí que quedó largo al final.&lt;/p&gt;
</description>
        <pubDate>Wed, 23 Nov 2011 14:48:39 +0000</pubDate>
        <link>/2011/11/puppet-gestion-de-configuracion-centralizada/</link>
        <guid isPermaLink="true">/2011/11/puppet-gestion-de-configuracion-centralizada/</guid>
        
        <category>Linux</category>
        
        <category>puppet</category>
        
        <category>software</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Mis impresiones sobre la Apache Barcamp 2011 celebrada en Sevilla</title>
        <description>&lt;p&gt;He publicado un post en el &lt;a href=&quot;http://www.yaco.es/blog&quot;&gt;blog de Yaco&lt;/a&gt; sobre la Apache Barcamp celebrada este fin de semana en Sevilla.&lt;a href=&quot;http://www.yaco.es/blog/yaco/2011/10/yaco-en-apache-barcamp-espana-2011-en-sevilla/&quot;&gt;Yaco en la Apache Barcamp España 2011 en Sevilla&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Fri, 14 Oct 2011 04:16:25 +0000</pubDate>
        <link>/2011/10/mis-impresiones-sobre-la-apache-barcamp-2011-celebrada-en-sevilla/</link>
        <guid isPermaLink="true">/2011/10/mis-impresiones-sobre-la-apache-barcamp-2011-celebrada-en-sevilla/</guid>
        
        <category>eventos</category>
        
        <category>yaco</category>
        
        
        <category>blog</category>
        
      </item>
    
      <item>
        <title>Hay que seguir de cerca al proyecto ownCloud</title>
        <description>&lt;p&gt;Monta un &lt;a href=&quot;http://owncloud.org/&amp;gt;owncloud&quot;&gt;owncloud&lt;/a&gt; y tendrás un sistema web para compartir ficheros. Bueno, eso era antes, ya se ha publicado la versión 2.0 y ahora es algo más que compartir ficheros. Tienes la posibilidad de escuchar tu música almacenada en el servidor, tener un listado de marcadores web o bookmarks, un calendario y una agenda. Lo tienes en tu servidor y funciona incluso en sharing hostings baratos tipo DreamHost. Con licencia AGPL
&lt;img src=&quot;/wp-content/uploads/vista-navegacion.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Lo que me gusta es su simpleza, si tienes disponible un servidor web con php5, conseguir que funcione es muy fácil. Descomprimir y acceder a la url correcta. Al acceder la primera vez nos pide el nombre del usuario administrador y crea la base de datos en sqlite. Y ya queda listo para usar.&lt;/p&gt;

&lt;p&gt;Soporta webdav para poder exportar los contenidos. De esta forma, si el servidor donde lo tenemos desplegando lo permite, podremos disponer de acceso desde un navegador de ficheros, ya sea usando davfs2 para montarlo o accediendo desde gnome o kde. No he conseguido que me funcione correctamente el uso de webdav y nginx, pero es que realmente, el soporte de webdav en nginx está aún muy verde.&lt;/p&gt;

&lt;p&gt;En esta base de datos se controlan los usuarios y las quotas de disco de cada uno. También se pueden tener grupos y compartir ficheros entre usuarios, entre grupos o publicarlos mediante un enlace con un hash.
&lt;img src=&quot;/wp-content/uploads/perfil-usuario.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Una vez hemos subido algunos ficheros, nos podemos centrar en la parte del almacenado de ficheros. Se crea un directorio por usuario creado y dentro de este otro directorio files que es donde residen los ficheros subidos. La ventaja es que si subes un fichero sin pasar por la web, este sí que se verá en la web. De este modo, sería fácil incorporarlo a un sistema con homes UNIX desplegados mapeando los usuarios correctamente. Se le puede indicar donde reside la raíz de los datos.&lt;/p&gt;

&lt;p&gt;Se pueden tomar usuarios desde un ldap, y también ofrece la posibilidad de servir de fuente de autenticación OpenID, aunque no he visto como hacer el camino inverso, es decir, autenticare en ownCloud mediante un id OpenID externo.&lt;/p&gt;

&lt;p&gt;En la versión de desarrollo tienen incorporadas una app de galería de imágenes y otra para editar ficheros de texto plano en el servidor. Por otro lado, Rekonq, el navegador de KDE4, permite sincronizar los bookmarks con ownCloud. Sería interesante que se pudieran sincronizar con Firefox y Chrome.&lt;/p&gt;

&lt;p&gt;La creación de aplicaciones no parece muy complicada y además tienen ya planteado un repositorio de aplicaciones en la web del proyecto.&lt;/p&gt;

&lt;p&gt;¿Qué cosas faltan para que pueda ser un reemplazo de dropbox y similares? Lógicamente, aún queda mucho trabajo por hacer, entre otras cosas, aplicaciones locales que faciliten la integración con el escritorio, aún así, accediendo a los contenidos mediante webdav/https, nos quitaríamos el problema de muchas redes corporativas donde resulta complicado abrir nuevos puertos y en otros entornos menos hostiles, se podría incorporar acceso ftp/smb/sshfs a las carpetas de usuario, dando así más posibilidades de integración sin llegar a tener aplicaciones.&lt;/p&gt;
</description>
        <pubDate>Tue, 11 Oct 2011 17:15:42 +0000</pubDate>
        <link>/2011/10/hay-que-seguir-de-cerca-al-proyecto-owncloud/</link>
        <guid isPermaLink="true">/2011/10/hay-que-seguir-de-cerca-al-proyecto-owncloud/</guid>
        
        <category>software</category>
        
        
        <category>blog</category>
        
      </item>
    
  </channel>
</rss>
