<?xml version="1.0" encoding="UTF-8" standalone="no"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:georss="http://www.georss.org/georss" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:thr="http://purl.org/syndication/thread/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-2461576666827389205</atom:id><lastBuildDate>Sat, 07 Dec 2024 07:42:00 +0000</lastBuildDate><category>ruby</category><category>ubuntu</category><category>ansible</category><category>conferenciarails</category><category>devops</category><category>euruko</category><category>dell</category><category>image_science</category><category>imagen</category><category>linux</category><category>mail</category><category>memcached</category><category>rails</category><category>vostro</category><category>501</category><category>FreeImage</category><category>HELO</category><category>IE7</category><category>IE8</category><category>RFC2821</category><category>TIOBE</category><category>acts_as_attachment</category><category>amsterdam</category><category>aspgems</category><category>attachment_fu</category><category>bootstrap</category><category>capistrano</category><category>ckeditor</category><category>coldfusion</category><category>content-type</category><category>cpd</category><category>dell mini 10v</category><category>digital ocean</category><category>div</category><category>dlink</category><category>dx8400</category><category>epson</category><category>escaner</category><category>euruko berlin</category><category>eutanasia</category><category>event delegation</category><category>evictions</category><category>excel</category><category>exim</category><category>firewall</category><category>foreign key migrations</category><category>fosdem</category><category>free</category><category>google</category><category>iconv</category><category>imagemagick</category><category>iptables</category><category>javascript</category><category>linkedin</category><category>log</category><category>lua</category><category>mandrill</category><category>maps</category><category>mechanize</category><category>memoria</category><category>migracion</category><category>moblin</category><category>monit</category><category>mysql</category><category>mysqlbinlog</category><category>new relic</category><category>nginx</category><category>nil</category><category>ntp</category><category>nullmailer</category><category>nvidia</category><category>pmd</category><category>presentación</category><category>prototype</category><category>python</category><category>rails charla beruby</category><category>redhill</category><category>request queuing</category><category>resize_to</category><category>rmagick</category><category>router</category><category>rsyslog</category><category>seguridad</category><category>simple-rss</category><category>smtp</category><category>ssl</category><category>swap</category><category>tabledefinition</category><category>tagcloud</category><category>ufw</category><category>unknown</category><category>vagrant</category><category>vdi</category><category>ventilador</category><category>vertical-align</category><category>virtualbox</category><category>wifi</category><category>windows</category><title>Technical bites</title><description>Open source y de todo un poco</description><link>http://blog.diegorf.com/</link><managingEditor>noreply@blogger.com (Anonymous)</managingEditor><generator>Blogger</generator><openSearch:totalResults>51</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><language>en-us</language><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-6960784712635999724</guid><pubDate>Wed, 18 Mar 2015 11:22:00 +0000</pubDate><atom:updated>2015-03-18T12:31:13.291+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ansible</category><category domain="http://www.blogger.com/atom/ns#">firewall</category><category domain="http://www.blogger.com/atom/ns#">ubuntu</category><category domain="http://www.blogger.com/atom/ns#">ufw</category><title>Protegiendo los servidores con UFW</title><description>Hace unas semanas se armó bastante revuelo cuando se público un &lt;a href="http://cispa.saarland/wp-content/uploads/2015/02/MongoDB_documentation.pdf"&gt;documento&lt;/a&gt; de unos estudiantes&amp;nbsp;que encontraron miles de servidores de MongoDB accesibles en internet sin ningún tipo de seguridad. Y unos días despues Salvatore Sanfilippo recordó en la lista de &lt;a href="https://groups.google.com/forum/#!topic/redis-db/EX7Sm0cbX_A"&gt;Redis&lt;/a&gt; que Redis tiene exactamente el mismo problema con la configuración por defecto.&lt;br /&gt;
&lt;br /&gt;
Como buena práctica, en todos los servicios que tienen acceso por un puerto (memcached, postgres, redis, ...) siempre configuro que solo tengan acceso los servidores de la red privada (o localhost según el caso), pero hace unos meses pensé en darle una vuelta más y añadir seguridad extra por firewall, para asegurarme de que no se me pasaba nada.&lt;br /&gt;
&lt;br /&gt;
La primera idea fue usar directamente&amp;nbsp;&lt;a href="https://help.ubuntu.com/community/IptablesHowTo"&gt;IPtables&lt;/a&gt;, y como siempre que lo miro, me dio una pereza infinita pelearme con esa sintáxis que se me olvida a los cinco minutos de usarla y busqué otras opciones.&lt;br /&gt;
&lt;br /&gt;
Afortunadamente, para mis necesidades, existe otra opción mucho más asequible en ubuntu: &lt;a href="https://help.ubuntu.com/community/UFW"&gt;UncomplicatedFirewall (UFW)&lt;/a&gt;. Hay mucha literatura en internet sobre UFW, por ejemplo esta &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-setup-a-firewall-with-ufw-on-an-ubuntu-and-debian-cloud-server"&gt;guía&lt;/a&gt; de DigitalOcean y además tenemos un &lt;a href="http://docs.ansible.com/ufw_module.html"&gt;módulo&lt;/a&gt; en ansible para configurarlo.&lt;br /&gt;
&lt;br /&gt;
Así que solo he tenido que cambiar el bootstrap de los servidores con ansible bloqueando por defecto todos los puertos y abriendo solo el puerto 22&lt;br /&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style="orphans: auto; text-align: start; text-indent: 0px; widows: 1;"&gt;
&lt;pre style="background-color: #e0e0e0; border-image-outset: initial; border-image-repeat: initial; border-image-slice: initial; border-image-source: initial; border-image-width: initial; border: 0px; margin: 0px 0px 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;- name: Set firewall default policy
  ufw: state=enabled policy=reject

- name: Allow ssh access
  ufw: rule=allow port=22
&lt;/pre&gt;
&lt;/div&gt;
Y luego ir añadiendo los puertos que necesite cada servicio, p.e. en el rol de nginx&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border-image-outset: initial; border-image-repeat: initial; border-image-slice: initial; border-image-source: initial; border-image-width: initial; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;- name: Allow web access
  ufw: rule=allow proto=tcp port={{item}}
  with_items:
    - 80
    - 443&amp;nbsp;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
O si queremos dar acceso a solo unas IPs determinadas (por ejemplo en el servidor donde esté la web de administración)&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border-image-outset: initial; border-image-repeat: initial; border-image-slice: initial; border-image-source: initial; border-image-width: initial; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;- name: Firewall permissions - Add allowed IPs
  ufw: rule=allow port=443 proto=tcp src={{ item }}
  with_items: admin.allowed_ips
&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
Donde admin.allowed_ips es una lista de IPs permitidas definidas en el yaml de configuración&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
Y así de simple, con 4 líneas de configuración, ya tenemos los servidores un poco más protegidos :)&lt;br /&gt;
&lt;br /&gt;
He actualizado el proyecto de ejemplo que cree en &lt;a href="https://github.com/diec123/ansible-bootstrap"&gt;GitHub&lt;/a&gt; cuando hice el post de &lt;a href="http://diec123.blogspot.com.es/2014/05/bootstrap-con-ansible.html"&gt;Bootstrap con Ansible&lt;/a&gt; añadiendo esta configuración&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://blog.diegorf.com/2015/03/protegiendo-los-servidores-con-ufw.html</link><thr:total>1</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-1947882361815323319</guid><pubDate>Tue, 03 Feb 2015 09:34:00 +0000</pubDate><atom:updated>2015-02-03T10:34:53.621+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">fosdem</category><title>Por qué deberías ir a FOSDEM</title><description>Todos los meses asisto a varios grupos de usuarios en Madrid, siempre que puedo al&amp;nbsp;&lt;a href="https://github.com/madridrb/madridrb.github.io/wiki"&gt;Madrid.rb&lt;/a&gt;, &lt;a href="http://www.meetup.com/PostgreSQL-Espana/" target="_blank"&gt;PostgreSQL&lt;/a&gt; y &lt;a href="http://www.meetup.com/madrid-devops/" target="_blank"&gt;DevOps&lt;/a&gt; y a otros esporádicamente, como&amp;nbsp;&lt;a href="http://www.meetup.com/AngularJS_Madrid/" target="_blank"&gt;AngularJS&lt;/a&gt;, &lt;a href="http://www.meetup.com/Node-js-Madrid/"&gt;Node.js&lt;/a&gt; o &lt;a href="http://www.meetup.com/FP-Madrid/" target="_blank"&gt;programación funcional&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Además, todos los años intento ir a varias conferencias, las últimas en las que he estado fueron &lt;a href="http://2014.codemotion.es/" target="_blank"&gt;Codemotion&lt;/a&gt; y &lt;a href="http://2014.pgconf.eu/" target="_blank"&gt;PGconf&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://fosdem.org/"&gt;FOSDEM&lt;/a&gt; es ir un paso más allá, para los que no lo conoceis es la conferencia de software libre más grande de Europa. Se hace en Bruselas a principios de Febrero con entrada libre y más de 5.000 asistentes.&lt;br /&gt;
&lt;br /&gt;
Lo primero que sorprende es la agenda, con más de 20 salas de conferencias simultáneas, tratando todo tipo de temáticas y tecnologías.&lt;br /&gt;
&lt;br /&gt;
Este año he decidido ir a charlas diferentes, así que no he aparecido por las salas donde iría habitualmente, como&amp;nbsp;&lt;a href="https://fosdem.org/2015/schedule/track/postgresql/"&gt;PostgreSQL&lt;/a&gt;, &lt;a href="https://fosdem.org/2015/schedule/track/configuration_management/"&gt;Configuration Management&lt;/a&gt;&amp;nbsp;o&amp;nbsp;&lt;a href="https://fosdem.org/2015/schedule/track/infrastructure_as_a_service/"&gt;IaaS&lt;/a&gt; y en el track de &lt;a href="https://fosdem.org/2015/schedule/track/ruby/"&gt;Ruby&lt;/a&gt; solo fuí a una charla sobre &lt;a href="https://fosdem.org/2015/schedule/event/ruby_mri_vs_father_time/"&gt;MRI&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Aun así me tuve que pasar los dos días continuamente eligiendo que quería ver, intentando cuadrar una agenda donde siempre tenía dos o más charlas simultaneas. He visto varias charlas de sistemas embebidos (&lt;a href="https://fosdem.org/2015/schedule/event/hack_your_camera/"&gt;CHDK&lt;/a&gt;,&amp;nbsp;&lt;a href="https://fosdem.org/2015/schedule/event/diy_dvr/"&gt;DVR&lt;/a&gt;), &lt;a href="https://fosdem.org/2015/schedule/event/ubuntu_on_phones_and_beyond/"&gt;ubuntu&lt;/a&gt; en móviles, &lt;a href="https://fosdem.org/2015/schedule/event/a_new_version_of_firefox_is_available/"&gt;releases&lt;/a&gt;&amp;nbsp;de Mozilla, &lt;a href="https://fosdem.org/2015/schedule/event/make_your_tests_fail/"&gt;testing&lt;/a&gt;, &lt;a href="https://fosdem.org/2015/schedule/event/search_sphinx/"&gt;sphinx&lt;/a&gt;, &lt;a href="https://fosdem.org/2015/schedule/event/graph_recom/"&gt;grafos&lt;/a&gt;, unas cuantas &lt;a href="https://fosdem.org/2015/schedule/track/lightning_talks/"&gt;lighting talks&lt;/a&gt;, ...&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
Por poner un par de ejemplos, te puedes encontrar charlas tan increibles como la de un grupo que como regalo de jubilación para un amigo han diseñado un &lt;a href="http://www.ohwr.org/projects/f-watch/wiki"&gt;reloj&lt;/a&gt; con GPS (hardware, software y la parte mecánica) usando sólo herramientas libres o una fantastica disertación sobre los relojes de las CPU y el&amp;nbsp;&lt;a href="https://fosdem.org/2015/schedule/event/precise_time/"&gt;tiempo&lt;/a&gt;&amp;nbsp;en general&lt;br /&gt;
&lt;br /&gt;
Y cuando publiquen los vídeos, quiero ver algunas de las que no puede entrar, como lenguajes (&lt;a href="https://fosdem.org/2015/schedule/event/ada_introduction/"&gt;Ada&lt;/a&gt;, &lt;a href="https://fosdem.org/2015/schedule/track/java/"&gt;Java&lt;/a&gt;, &lt;a href="https://fosdem.org/2015/schedule/track/go/"&gt;Go&lt;/a&gt;), &lt;a href="https://fosdem.org/2015/schedule/track/performance/"&gt;rendimiento&lt;/a&gt;, &lt;a href="https://fosdem.org/2015/schedule/event/gnuradio/"&gt;GNU Radio&lt;/a&gt;,&amp;nbsp;&lt;a href="https://fosdem.org/2015/schedule/track/distributions/"&gt;distribuciones&lt;/a&gt;&amp;nbsp;o &lt;a href="https://fosdem.org/2015/schedule/track/mozilla/"&gt;Mozilla&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
En un evento como FOSDEM te das cuentas de la infinidad de ramas que tiene el software libre y de todo lo que nos queda por aprender...&lt;br /&gt;
&lt;br /&gt;
Nos vemos el año que viene en Bruselas!&lt;br /&gt;
&lt;br /&gt;</description><link>http://blog.diegorf.com/2015/02/por-que-deberias-ir-fosdem.html</link><thr:total>1</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-3009883620624456521</guid><pubDate>Tue, 18 Nov 2014 10:57:00 +0000</pubDate><atom:updated>2014-11-18T11:58:35.808+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ansible</category><category domain="http://www.blogger.com/atom/ns#">swap</category><title>Swap en servidores de integración</title><description>En los servidores de integración tengo el mínimo de RAM necesaria para que funcionen ya que no es importante el tiempo de respuesta ni que estén continuamente levantados.&lt;br /&gt;
&lt;br /&gt;
Ahora mismo es bastante normal que me falle al desplegar una nueva versión si tiene que compilar alguna libreria, y tengo que parar todos los servicios para que tenga memoria suficiente.&lt;br /&gt;
&lt;br /&gt;
Tambien me llegan de vez en cuando mails de &lt;a href="http://logcheck.org/" target="_blank"&gt;Logcheck&lt;/a&gt; avisando de que se ha quedado la máquina sin memoria:&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;span style="background-color: transparent; line-height: 17px;"&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;System Events
=-=-=-=-=-=-=
Nov  8 08:00:16 staging kernel: [338269.889408] ruby invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0
Nov  8 08:00:16 staging kernel: [338269.889414] ruby cpuset=/ mems_allowed=0&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;&lt;span style="line-height: 17px;"&gt;$ sudo apt-get install ntp&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Hasta ahora he aceptado estos problemas sin darles mayor importancia ya que solo ocurren en integración. Esta mañana hablando con mi amigo David me ha comentado que estaba instalando un servidor y que le había añadido swap siguiendo las indicaciones de un artículo de la magnífica documentación de &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-14-04" target="_blank"&gt;Digital Ocean&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Es una solución evidente que no se me había ocurrido hasta ahora. En producción nunca configuro swap por temas de rendimiento, pero en integración no hay ningún problema en añadirla y me soluciona los problemas comentados anteriormente.&lt;br /&gt;
&lt;br /&gt;
Así que he creado una receta de ansible para añadir swap a un servidor basada en ese artículo.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="orphans: auto; text-align: start; text-indent: 0px; widows: auto;"&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin: 0px 0px 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;&lt;span style="line-height: 17px;"&gt;# Based on https://www.digitalocean.com/community/tutorials/how-to-add-swap-on-ubuntu-14-04
- name: Create swap file
  command: fallocate -l 1G /swapfile creates=/swapfile

- name: Set swap file permissions
  file: dest=/swapfile owner=root group=root mode=600

- name: Check if swap already exists
  shell: "swapon -s | grep '/swapfile'"
  register: swapfile
  ignore_errors: True

- name: Set up the swap space
  command: mkswap /swapfile
  when: swapfile|failed

- name: Enable swap
  command: swapon /swapfile
  when: swapfile|failed

- name: Make the swap file permanent
  mount: name=none src=/swapfile fstype=swap opts=sw passno=0 dump=0 state=present

- name: Set swappiness
  sysctl: name=vm.swappiness value=10 state=present

- name: Set vfs_cache_pressure
  sysctl: name=vm.vfs_cache_pressure value=50 state=present&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
El playbook se podría hacer un poco más genérico con el tamaño y el nombre de la swap en ficheros de configuración, pero para mi caso no es necesario.&lt;br /&gt;
&lt;br /&gt;
Por último, como en los comandos &lt;i&gt;mkswap&lt;/i&gt; y &lt;i&gt;swapon&lt;/i&gt; no hay ninguna opción para que no execute si ya existe, he añadido una &lt;a href="http://docs.ansible.com/playbooks_conditionals.html" target="_blank"&gt;condición&lt;/a&gt;&amp;nbsp;chequeando previamente si ya está creada la swap en la máquina.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://blog.diegorf.com/2014/11/swap-en-servidores-de-integracion.html</link><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-9176141186767870262</guid><pubDate>Fri, 19 Sep 2014 10:33:00 +0000</pubDate><atom:updated>2014-09-19T15:43:10.072+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">new relic</category><category domain="http://www.blogger.com/atom/ns#">ntp</category><category domain="http://www.blogger.com/atom/ns#">request queuing</category><title>Request Queuing en New Relic</title><description>Una de las herramientas que usamos en &lt;a href="https://teowaki.com/" target="_blank"&gt;teowaki &lt;/a&gt;es&amp;nbsp;&lt;a href="http://newrelic.com/" target="_blank"&gt;New Relic&lt;/a&gt; para monitorizar el rendimiento de la API. Nos permite saber que páginas son las más lentas para optimizarlas y que areas de la aplicación necesitan mejoras.&lt;br /&gt;
&lt;br /&gt;
Ayer por la noche nos empezaron a llegar alertas por mail de problemas con el &lt;a href="https://docs.newrelic.com/docs/apm/new-relic-apm/apdex/apdex-measuring-user-satisfaction" target="_blank"&gt;Apdex&lt;/a&gt;, que mide el rendimiento de la aplicación&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3RaUiY-klHLXTD1bLMOKLNOo13EXKW66Kzlhy9veaxCXWsfriVWXXb4_W6xca2QWrfqFVpmWNxqw1JcX6c7SnUxZdO46dTDwVb3pyTkpEF76BSwdV1eEXaHuLj71rIPxAGA4ASyAbn1k5/s1600/teowaki_new_relic.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3RaUiY-klHLXTD1bLMOKLNOo13EXKW66Kzlhy9veaxCXWsfriVWXXb4_W6xca2QWrfqFVpmWNxqw1JcX6c7SnUxZdO46dTDwVb3pyTkpEF76BSwdV1eEXaHuLj71rIPxAGA4ASyAbn1k5/s1600/teowaki_new_relic.png" height="353" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
No había ningún motivo aparente, ya que no habíamos hecho ningún cambio significativo en los servidores ni había picos significativo de tráfico. Tampoco había carga en las máquinas y todos los servicios estaban levantados correctamente (redis, memcache, unicorn, nginx).&lt;br /&gt;
&lt;br /&gt;
El problema era con el &lt;a href="https://docs.newrelic.com/docs/apm/other-features/request-queueing/request-queuing-and-tracking-front-end-time" target="_blank"&gt;Request Queuing&lt;/a&gt;, que había subido desde prácticamente cero hasta unos 100ms, donde se había quedado estable. Este parámetro mide el tiempo desde que llega la petición al servidor web (en nuestro caso nginx) hasta que es servida por el servidor de aplicaciones (en nuestro caso unicorn).&lt;br /&gt;
&lt;br /&gt;
Si tiene un valor alto quiere decir que el servidor de aplicaciones no es capaz de servir todas las peticiones que le llegan y se quedan encoladas en el servidor web y la solución habitual es optimizar la aplicación para que sirva las peticiones más rápido o añadir nuevos servidores de aplicaciones para distribuir la carga.&lt;br /&gt;
&lt;br /&gt;
Para que aparezca esta métrica en las gráficas de New Relic, se debe añadir la cabecera &lt;i&gt;X-Request-Start&lt;/i&gt; tal y como explican en la&amp;nbsp;&lt;a href="https://docs.newrelic.com/docs/apm/other-features/request-queueing/request-queue-server-configuration-examples" target="_blank"&gt;documentación&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Como la primera opción de reiniciar nginx y unicorn por si tenían algún problema no funcionó, el siguiente paso fue leer con detalle la documentación. Si el servidor web y el servidor de aplicaciones están en diferentes servidores físicos, hay que tener cuidado con el retraso entre relojes de los servidores, lo que llaman &lt;a href="https://docs.newrelic.com/docs/apm/other-features/request-queueing/request-queuing-and-tracking-front-end-time#clock-skew" target="_blank"&gt;Clock Skew&lt;/a&gt;, que se soluciona instalando NTP.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://en.wikipedia.org/wiki/Network_Time_Protocol" target="_blank"&gt;NTP&lt;/a&gt; es un protocolo que permite sincronizar el reloj de nuestros servidores con bastante precisión a partir de una red de servidores distribuida y la instalación es tan simple como añadir un paquete&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;&lt;span style="line-height: 17px;"&gt;$ sudo apt-get install ntp&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
En este&amp;nbsp;&lt;a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-time-synchronization-on-ubuntu-12-04" target="_blank"&gt;tutorial&lt;/a&gt;&amp;nbsp;de Digital Ocean hay más detalles de configuración, pero en mi caso con la configuración por defecto ha sido suficiente. Y unos minutos despues de instalarlo los tiempos de respuesta han vuelto a su valor habitual&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3uMvJ5M1WzjPB2HixiwND2goHzwgHz5yqydGhw-4dNA4rwmkiTCTxpgbjK_D0KJewa41FuqI8q_vNvjpdPdJF__fvni1lXBKSyQSPhUJ16oZKEvfzOYGk6qN4aXPnb57d0iMBk-qjwEfU/s1600/teowaki_new_relic_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3uMvJ5M1WzjPB2HixiwND2goHzwgHz5yqydGhw-4dNA4rwmkiTCTxpgbjK_D0KJewa41FuqI8q_vNvjpdPdJF__fvni1lXBKSyQSPhUJ16oZKEvfzOYGk6qN4aXPnb57d0iMBk-qjwEfU/s1600/teowaki_new_relic_2.png" height="345" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
No se el motivo por el que se ha desincronizado de los servidores, pero bueno, al menos ya está solucionado :)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://blog.diegorf.com/2014/09/request-queuing-en-new-relic.html</link><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3RaUiY-klHLXTD1bLMOKLNOo13EXKW66Kzlhy9veaxCXWsfriVWXXb4_W6xca2QWrfqFVpmWNxqw1JcX6c7SnUxZdO46dTDwVb3pyTkpEF76BSwdV1eEXaHuLj71rIPxAGA4ASyAbn1k5/s72-c/teowaki_new_relic.png" width="72"/><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-8668843359569354525</guid><pubDate>Fri, 05 Sep 2014 10:42:00 +0000</pubDate><atom:updated>2014-09-06T11:36:10.174+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">eutanasia</category><title>Eutanasia. El derecho a decidir</title><description>Normalmente en este blog siempre escribo sobre temas técnicos, pero a veces, pasan cosas en la vida que te hacen reflexionar, como hace unos años cuando escribí &lt;a href="http://diec123.blogspot.com.es/2011/01/sobre-la-incompetencia-medica.html" target="_blank"&gt;Sobre la (in)competencia médica&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
El viernes pasado por la tarde,&amp;nbsp;despues de un par de días con dolor de estómago y algo de fiebre, me subió la fiebre a casi 39, así que nos fuimos al centro médico, que nos redirigió a urgencias. Despues de unas horas y algunas pruebas, me diagnosticaron una &lt;a href="http://es.wikipedia.org/wiki/Apendicitis" target="_blank"&gt;apendicitis&lt;/a&gt; aguda y a la mañana siguiente me operaron de urgencias. No fue la mejor forma de celebrar que ese mismo día nos habían aprobado la beta de&amp;nbsp;&lt;a href="https://datawaki.com/" target="_blank"&gt;datawaki&lt;/a&gt;&amp;nbsp;en&amp;nbsp;&lt;a href="https://addons.heroku.com/datawaki" target="_blank"&gt;heroku&lt;/a&gt;&amp;nbsp;y que empezaba las vacaciones, pero las cosas vienen como vienen.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
La primera reflexión es la suerte que tengo de vivir en un pais desarrollado, si esto mismo me hubiera pasado en un país subdesarrollado (o hace 100 años), la evolución más probable había sido que se me habría roto el apéndice, y ahora mismo ya estaría muerto o retorciéndome de dolor con una &lt;a href="http://es.wikipedia.org/wiki/Peritonitis" target="_blank"&gt;peritonitis&lt;/a&gt;&amp;nbsp;sin posible cura.&lt;br /&gt;
&lt;br /&gt;
En el &lt;a href="http://diec123.blogspot.com.es/2011/01/sobre-la-incompetencia-medica.html" target="_blank"&gt;post&lt;/a&gt; que he comentado antes, hablaba sobre lo despistada que sigue estando la medicina tradicional en temas musculares y óseos. En cambio en este caso no tengo ninguna queja, me parece que el trato recibido y la profesionalidad de todos los implicados en el hospital Ramón y Cajal de Madrid ha sido excelente.&lt;br /&gt;
&lt;br /&gt;
Una vez operado, la planta de cirugía estaba completa, así que los días que he estado en el hospital los he pasado en otra planta, donde la mayoría de pacientes eran mayores y dependientes.&lt;br /&gt;
&lt;br /&gt;
Mi compañero de habitación era un señor de 79 años con &lt;a href="http://es.wikipedia.org/wiki/Leucemia" target="_blank"&gt;leucemia&lt;/a&gt;, ingresado por problemas respiratorios. Nos dijo que no podían hacerle un transplante de médula debido a su edad, así que tendrá que convivir con la enfermedad lo que le queda de vida. El pobre hombre lo estaba pasando bastante mal, con malestar general y estaba muy delgado y cansado.&lt;br /&gt;
&lt;br /&gt;
Uno de los efectos de la leucemia, es la sudoración nocturna, lo que no le permitía dormir y en cuanto se dormía, se le empapaba la cama y se despertaba con frío. Además estaba con fiebre, lo que le incrementaba aún mas el malestar.&lt;br /&gt;
&lt;br /&gt;
Dentro de unos días probablemente se encontrará algo mejor, le darán el alta y volverá a estar unas semanas en casa, hasta que de nuevo le ataque otra enfermedad, ya que por las defensas bajas de la leucemia está enfermo bastante a menudo, y probablemente tendrán que volver a ingresarlo.&lt;br /&gt;
&lt;br /&gt;
Hablando con él nos estuvo contando un poco su vida. Por lo que nos contó ha tenido una vida muy feliz, con un trabajo de responsabilidad del que estaba bastante orgulloso, felizmente casado, y con cuatro hijos ya mayores todos con la vida resuelta.&lt;br /&gt;
&lt;br /&gt;
Al pobre hombre se le veía agotado, sin ganas de vivir, además, nos contó que su mujer estaba con &lt;a href="http://es.wikipedia.org/wiki/Enfermedad_de_Alzheimer" target="_blank"&gt;Alzheimer&lt;/a&gt; bastante avanzado y hablaba con muchísima pena de ella. Decía que la echaba mucho en falta.&lt;br /&gt;
&lt;br /&gt;
Y de aquí el título del post. Me parece muy triste que una persona con una enfermedad sin cura, a la que solo le esperan algunas temporadas de encontrarse más o menos bien, junto con otras en las que realmente lo pasa mal y sin ilusion por vivir no tenga el derecho de morir dignamente.&lt;br /&gt;
&lt;br /&gt;
Está claro que muchísima gente prefiere seguir viviendo hasta la muerte natural y que la mayoría no optaría por esa opción, pero espero que algún día tengamos la opción de poder decidir y no estar sufriendo cuando ya crees que has hecho todo lo que tenías que hacer en este mundo.&lt;br /&gt;
&lt;br /&gt;
Si algún día estoy en ese estado, espero que al menos me den la opción, y si aquí no puedo y es lo que quiero, que me &lt;a href="http://www.xatakaciencia.com/salud/eutanasia-suiza-el-turismo-suicida" target="_blank"&gt;trasladen&lt;/a&gt;&amp;nbsp;a donde si se pueda&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Por último, si teneis dolor agudo estomacal con fiebre alta, rápido a urgencias, que es una combinación que puede ser muy grave....&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://blog.diegorf.com/2014/09/eutanasia-el-derecho-decidir.html</link><thr:total>2</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-701963501376569482</guid><pubDate>Wed, 20 Aug 2014 08:13:00 +0000</pubDate><atom:updated>2014-08-20T12:16:46.433+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ansible</category><category domain="http://www.blogger.com/atom/ns#">capistrano</category><category domain="http://www.blogger.com/atom/ns#">devops</category><category domain="http://www.blogger.com/atom/ns#">monit</category><title>Capistrano y Monit</title><description>Últimamente me ha pasado un par de veces que al hacer una subida a producción, &lt;a href="http://capistranorb.com/" target="_blank"&gt;Capistrano&lt;/a&gt; y &lt;a href="http://mmonit.com/monit/" target="_blank"&gt;Monit&lt;/a&gt; no se llevan muy bien.&lt;br /&gt;
&lt;br /&gt;
El problema es que en el deploy se reinician algunos servicios, como&amp;nbsp;&lt;a href="http://sidekiq.org/" target="_blank"&gt;Sidekiq&lt;/a&gt;, y si coincide con el chequeo de Monit, se lanza otro reinicio, con el resultado de tener 2 Sidekiq arrancados en producción.&lt;br /&gt;
&lt;br /&gt;
Tambien puede pasar que quieras parar algún servicio manualmente, por ejemplo&amp;nbsp;&lt;a href="http://unicorn.bogomips.org/" target="_blank"&gt;Unicorn&lt;/a&gt;&amp;nbsp;desde una tarea de Capistrano y Monit lo levante automáticamente.&lt;br /&gt;
&lt;br /&gt;
Afortunadamente, la solución es simple, consiste en añadir unas tareas en Capistrano y dar permisos al usuario de la aplicación para ejecutar Monit.&lt;br /&gt;
&lt;br /&gt;
Para ejecutar los comandos de Monit, se necesitan permisos de sudo, pero por seguridad, no queremos dar acceso sudo sin más. Tampoco interesa dar acceso a toda la funcionalidad de Monit, ya que se podría parar cualquier servicio monitorizado con Monit externo a la aplicación.&lt;br /&gt;
&lt;br /&gt;
Así que solo daremos permiso para ver el estado de la monitorización (&lt;i&gt;monit summary&lt;/i&gt;) y parar o iniciar la monitorización (&lt;i&gt;monit monitor&lt;/i&gt; y &lt;i&gt;monit unmonitor)&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
La forma de conseguirlo es tan simple como añadir un nuevo fichero&lt;i&gt;&amp;nbsp;/etc/sudoers.d/monit &lt;/i&gt;con esos permisos&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;span style="background-color: transparent; line-height: 17px;"&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;my_user ALL = NOPASSWD: /usr/bin/monit summary, /usr/bin/monit unmonitor *, /usr/bin/monit monitor *&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
No le pedimos la contraseña al usuario para ejecutar estos comandos, ya que el usuario no tiene contraseña asignada (solo le permitimos acceder por medio de clave pública).&lt;br /&gt;
&lt;br /&gt;
Y ese mismo fichero creado desde ansible&lt;br /&gt;
&lt;div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style="orphans: auto; text-align: start; text-indent: 0px; widows: auto;"&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin: 0px 0px 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="background-color: transparent; line-height: 17px;"&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;- name: Allow execute monit commands to users
  action: 'lineinfile dest=/etc/sudoers.d/monit state=present create=yes regexp="{{item}}" line="{{item}} ALL = NOPASSWD: /usr/bin/monit summary, /usr/bin/monit unmonitor *, /usr/bin/monit monitor *" validate="visudo -cf %s"'
  with_items:
    - my_user&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
Una vez que tenemos permisos, creamos un módulo de capistrano con las diferentes tareas a ejecutar en &lt;i&gt;lib/capistrano/tasks&lt;/i&gt;&lt;br /&gt;
&lt;i&gt;&lt;br /&gt;&lt;/i&gt;
&lt;br /&gt;
&lt;div style="orphans: auto; text-align: start; text-indent: 0px; widows: auto;"&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin: 0px 0px 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;&lt;span style="line-height: 17px;"&gt;namespace :monit do
  desc 'Monit summary'
  task :summary do
    on roles :app do
      puts capture :sudo, :monit, :summary
    end
  end

  desc 'Monit unmonitor'
  task :unmonitor do
    on roles :app do
      puts capture :sudo, :monit, :unmonitor, :sidekiq
    end
  end

  desc 'Monit monitor'
  task :monitor do
    on roles :app do
      puts capture :sudo, :monit, :monitor, :sidekiq
    end
  end
end
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
Y invocamos esas tareas al empezar y al acabar el deploy&lt;br /&gt;
&lt;br /&gt;
&lt;div style="orphans: auto; text-align: start; text-indent: 0px; widows: auto;"&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin: 0px 0px 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;&lt;span style="line-height: 17px;"&gt;after 'deploy:starting',  'monit:unmonitor'
after 'deploy:finished',  'monit:monitor'&lt;/span&gt;&lt;span style="color: black; font-family: Times New Roman; font-size: small;"&gt;&lt;span style="line-height: 17px; white-space: normal;"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
Además, la tarea summary permite al usuario monitorizar el estado del servidor desde línea de comandos&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;span style="background-color: transparent; color: #222222; font-size: x-small; line-height: 17px;"&gt;$ cap production monit summary&lt;/span&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;&lt;span style="line-height: 17px;"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;&lt;span style="line-height: 17px;"&gt;...
System 'teowaki.com'                Running
Process 'sidekiq'                   Running
Process 'sshd'                      Running
Filesystem 'rootfs'                 Accessible
...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
Por último, comentar que la gema &lt;a href="https://github.com/seuros/capistrano-sidekiq" target="_blank"&gt;capistrano-sidekiq&lt;/a&gt; incluye algunas &lt;a href="https://github.com/seuros/capistrano-sidekiq/blob/master/lib/capistrano/tasks/monit.cap" target="_blank"&gt;tareas&lt;/a&gt; similares, pero no me cuadraba su uso en mi caso, ya que me obliga a cambiar el nombre del servicio monitorizado.</description><link>http://blog.diegorf.com/2014/08/capistrano-y-monit.html</link><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-5377360802379333188</guid><pubDate>Mon, 30 Jun 2014 11:01:00 +0000</pubDate><atom:updated>2014-06-30T13:01:38.165+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ansible</category><category domain="http://www.blogger.com/atom/ns#">digital ocean</category><title>Ansible y Digital Ocean</title><description>Justo hoy tenía prevista hacer una subida a producción del &lt;a href="https://api.teowaki.com/" target="_blank"&gt;API&lt;/a&gt; de Teowaki con bastantes cambios de configuración que llevo probando un tiempo en local.&lt;br /&gt;
&lt;br /&gt;
La subida incluye la actualización a &lt;a href="http://weblog.rubyonrails.org/2014/6/26/Rails-4-1-2-and-4-0-6-has-been-released/" target="_blank"&gt;Rails 4.1.2&lt;/a&gt;, y bastantes gemas, entre las que está&amp;nbsp;&lt;a href="http://capistranorb.com/documentation/upgrading/" target="_blank"&gt;Capistrano 3&lt;/a&gt;, que ha supuesto reescribir los ficheros de deploy. Para acabar de completarlo, tambien quiero actualizar a &lt;a href="https://www.ruby-lang.org/en/news/2014/05/09/ruby-2-1-2-is-released/" target="_blank"&gt;Ruby 2.1.2&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Está claro que esta subida tiene todos los números para que algo falle y dejar caído producción un rato...&lt;br /&gt;
&lt;br /&gt;
Así que he optado por la opción de crear un nuevo servidor donde probar todos esos cambios y aprovecho para ir actualizando a Ubuntu Trusty. Una vez creado el servidor y comprobado que todo está bien, simplemente cambiaré el balanceador para que apunte al nuevo servidor y apagaré el servidor antiguo.&lt;br /&gt;
&lt;br /&gt;
Aprovechando estos cambios le he dado un nuevo empujón a la configuración de ansible, creando los servidores desde los playbook en lugar de crearlos desde la consola de Digital Ocean, como hacía hasta ahora.&lt;br /&gt;
&lt;br /&gt;
Continuando la entrada del mes pasado, donde conté como hacer &lt;a href="http://diec123.blogspot.com.es/2014/05/bootstrap-con-ansible.html" target="_blank"&gt;Bootstrap con Ansible&lt;/a&gt;, aquí cuento como crear los servidores.&lt;br /&gt;
&lt;br /&gt;
Según la &lt;a href="http://docs.ansible.com/digital_ocean_module.html" target="_blank"&gt;documentación&lt;/a&gt;, el primer paso es instalar las dependencias, en este caso sólo &lt;a href="https://github.com/devo-ps/dopy" target="_blank"&gt;dopy&lt;/a&gt;, un wrapper de la API de Digital Ocean en Python.&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;$ sudo pip install dopy
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
Para facilitar la configuración, nos bajamos los ficheros de inventorio&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;$ wget https://raw.githubusercontent.com/ansible/ansible/devel/plugins/inventory/digital_ocean.py
$ chmod +x digital_ocean.py
$ wget https://raw.githubusercontent.com/ansible/ansible/devel/plugins/inventory/digital_ocean.ini
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
Creamos un par de variables de entorno con la API_KEY y el CLIENT_ID, que los consultamos en la &lt;a href="https://cloud.digitalocean.com/api_access" target="_blank"&gt;configuración&lt;/a&gt; de Digital Ocean&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;export DO_API_KEY=MI_API_KEY
export DO_CLIENT_ID=MI_CLIENT_ID
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
Y chequeamos si la configuración es correcta listando los droplets que tenemos creados (con &lt;i&gt;-h&lt;/i&gt; o &lt;i&gt;--help&lt;/i&gt; puedes ver las opciones disponibles)&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;span style="background-color: transparent; line-height: 17px;"&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;$./digital_ocean.py --droplets --pretty&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
Para crear un droplet, necesitamos 4 datos principales, la imagen que usaremos para crearlo, el tamaño, la region donde lo creamos y la clave SSH que usaremos para acceder. Todos esos datos tienen un ID único en Digital Ocean, que podemos consultar con el script anterior (con los parámetros &lt;i&gt;images&lt;/i&gt;, &lt;i&gt;sizes&lt;/i&gt;, &lt;i&gt;regions&lt;/i&gt; y &lt;i&gt;ssh-keys&lt;/i&gt;)&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;span style="background-color: transparent;"&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;&lt;span style="line-height: 17px;"&gt;$ ./digital_ocean.py --sizes --pretty
{
  "sizes": [
    {
      "cost_per_hour": "0.00744", 
      "cost_per_month": "5.0", 
      "cpu": "1", 
      "disk": "20", 
      "id": "66", 
      "memory": "512", 
      "name": "512MB", 
      "slug": "512mb"
    }, 
...&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
Para simplificar la creación de nuevos droplets, he añadido en el fichero &lt;i&gt;hosts&lt;/i&gt; una sección local (el droplet se crea desde localhost, no desde un servidor remoto)&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;[local]
localhost
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
Y un fichero de variables de grupo &amp;nbsp;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;$ more group_vars/local.yml 
---
# SIZES:
#   "slug": "512mb", "name": "512MB", "id": "66", "disk": "20", "cpu": "1", "cost_per_month": "5.0"
#   "slug": "1gb", "name": "1GB", "id": "63", "disk": "30", "cpu": "1", "cost_per_month": "10.0"
#   "slug": "2gb", "name": "2GB", "id": "62", "disk": "40", "cpu": "2", "cost_per_month": "20.0",
do_size_512mb: 66
do_size_1gb: 63
do_size_2gb: 62
# IMAGES:
#   "slug": "ubuntu-14-04-x64", "distribution": "Ubuntu", "id": "3240036", "name": "Ubuntu_14.04_x64",
do_image_ubuntu_14_04_x64: 3240036
# REGIONS;
#   "slug": "nyc2", "id": "4", "name": "New_York_2",
do_region_nyc2: 4
# KEYS:
#   "id": "xxxx", "name": "diego"
do_diego_key:  xxxx

&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
Y ya solo nos queda decidir la configuración y el nombre del servidor (SERVER_NAME en el playbook)&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;---
- hosts: local
  connection: local
  tasks:
  - name: Create new Digital Ocean Droplet
    digital_ocean: &amp;gt;
      state=present
      command=droplet
      name=SERVER_NAME
      size_id={{ do_size_1gb }}
      region_id={{ do_region_nyc2 }}
      image_id={{ do_image_ubuntu_14_04_x64 }}
      private_networking=yes
      ssh_key_ids={{ do_diego_key }}

&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
Una vez creado, ejecutamos el &lt;a href="http://diec123.blogspot.com.es/2014/05/bootstrap-con-ansible.html" target="_blank"&gt;bootstrap&lt;/a&gt; de mi post anterior y los roles del servidor.&lt;br /&gt;
&lt;br /&gt;
Existen soluciones mucho más completas para provisionar los servidores como &lt;a href="https://github.com/garethr/ansible-provisioner" target="_blank"&gt;ansible-provisioner&lt;/a&gt;, pero en mi caso con hacer la creación manualmente modificando este playbook es más que suficiente.&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://blog.diegorf.com/2014/06/ansible-y-digital-ocean.html</link><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-313559705923160641</guid><pubDate>Wed, 28 May 2014 07:54:00 +0000</pubDate><atom:updated>2014-05-28T09:54:54.224+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ansible</category><category domain="http://www.blogger.com/atom/ns#">bootstrap</category><category domain="http://www.blogger.com/atom/ns#">devops</category><category domain="http://www.blogger.com/atom/ns#">vagrant</category><title>Bootstrap con Ansible</title><description>La semana pasada en el grupo&amp;nbsp;&lt;a href="http://madrid.devops.es/" target="_blank"&gt;DevOps&lt;/a&gt;&amp;nbsp;de Madrid, hubo una magnífica charla introductoria de&lt;a href="https://twitter.com/mmoyaro" target="_blank"&gt;&amp;nbsp;Maykel Moya&lt;/a&gt;&amp;nbsp;sobre&amp;nbsp;&lt;a href="http://www.ansible.com/" target="_blank"&gt;Ansible&lt;/a&gt;. Parte de lo que explico en este post lo contó con una demo en directo.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Estuve hablando con&amp;nbsp;&lt;a href="https://twitter.com/javiervidal" target="_blank"&gt;Javier Vidal&lt;/a&gt;&amp;nbsp;sobre el tema y al día siguiente me comento en&amp;nbsp;&lt;a href="https://twitter.com/javiervidal/status/469849943327649793" target="_blank"&gt;twitter&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdmR_4QxbFHoHaQ-fMtjg9EEUTPXwafQuP6p7KR2aMVg0Jyz6O6i3pxCRu2quAVnP1XyeqLa_r7Evasp0iX3mXuxJi1DLqkLGkdRSN820XwRIR3KXpRkGItZNEclakCKueJuQLdx5kHNPf/s1600/twitter_javiervidal.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdmR_4QxbFHoHaQ-fMtjg9EEUTPXwafQuP6p7KR2aMVg0Jyz6O6i3pxCRu2quAVnP1XyeqLa_r7Evasp0iX3mXuxJi1DLqkLGkdRSN820XwRIR3KXpRkGItZNEclakCKueJuQLdx5kHNPf/s1600/twitter_javiervidal.png" height="96" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div&gt;
Y en lugar de compartirselo sólo a Javi, he creado esta entrada en el blog :)&lt;/div&gt;
&lt;br /&gt;
Para ello, he separado el role de bootstraping de nuestra instalación de &lt;a href="https://teowaki.com/" target="_blank"&gt;Teowaki&lt;/a&gt; en un proyecto independiente y lo he configurado con Vagrant, para poder probarlo en local sin problemas.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
El proyecto está disponible en &lt;a href="https://github.com/diec123/ansible-bootstrap" target="_blank"&gt;github&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Los pasos para probarlo son:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Instalar Vagrant en local (previamente debe estar instalado &lt;a href="https://www.virtualbox.org/" target="_blank"&gt;VirtualBox&lt;/a&gt;). He optado por instalarlo a partir del .deb en lugar de a partir de apt porque la opción apt me instalaba los paquetes de ruby 1.9, y ruby ya lo tengo instalado en local con &lt;a href="https://rvm.io/" target="_blank"&gt;RVM&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;$ wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.6.2_x86_64.deb
$ sudo dpkg -i vagrant_1.6.2_x86_64.deb
$ vagrant -v
Vagrant 1.6.2
$ vagrant init ubuntu/trusty64
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Una vez instalado, simplemente con &lt;i&gt;vagrant up&lt;/i&gt; levantamos el servidor, que escucha por defecto por ssh en el puerto 2222 en localhost&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Más información sobre la instalación en las páginas de &lt;a href="https://docs.vagrantup.com/v2/getting-started/index.html" target="_blank"&gt;Vagrant&lt;/a&gt; y &lt;a href="http://docs.ansible.com/guide_vagrant.html" target="_blank"&gt;Ansible&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
El siguiente paso es configurar el servidor en Ansible, que es tan simple como definir en un fichero hosts los datos de conexión al servidor. En mi caso he definido un grupo de servidores '&lt;i&gt;development&lt;/i&gt;' que incluye al servidor &lt;i&gt;dev&lt;/i&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;[development]
dev ansible_ssh_host=127.0.0.1 ansible_ssh_port=2222
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Por otra parte configuro la conexión a vagrant en &lt;i&gt;ansible.cfg&lt;/i&gt;, de forma que no hay que escribirla en cada conexión desde ansible&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;[defaults]
hostfile = hosts
private_key_file=~/.vagrant.d/insecure_private_key
remote_user = vagrant
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Y probamos que la conexión al servidor desde ansible funciona&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;$ ansible dev -m ping
dev | success &amp;gt;&amp;gt; {
    "changed": false, 
    "ping": "pong"
}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Sin el fichero de configuración la instrucción habría sido:&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;$ &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;span style="background-color: transparent; line-height: 17px;"&gt;&lt;span style="color: #222222; font-size: x-small;"&gt;ansible dev -i hosts --private-key=~/.vagrant.d/insecure_private_key -u vagrant -m ping&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Una vez comprobado que conectamos, cambiamos el fichero&amp;nbsp;&lt;i&gt;development.yml&lt;/i&gt; con la configuración local y ya podemos instalar el servidor&lt;br /&gt;
&lt;br /&gt;
&lt;div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;"&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;"&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin: 0px 0px 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;$ ansible-playbook bootstrap.yml
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
Por último, las tareas incluídas en el role son:&lt;br /&gt;
&lt;li&gt;Instalación y actualización de paquetes de ubuntu&lt;/li&gt;
&lt;li&gt;Copia de ficheros de configuración, en este caso solo /etc/environment&lt;/li&gt;
&lt;li&gt;Configuración del locale&lt;/li&gt;
&lt;li&gt;Creación de usuarios, asignando grupos y clave pública&lt;/li&gt;
&lt;li&gt;Configuración de seguridad, instalando &lt;a href="http://www.fail2ban.org/wiki/index.php/Main_Page" target="_blank"&gt;Fail2ban&lt;/a&gt; y cambiando ssh para que no permita ni acceso SSH de root ni acceso con contraseña (sólo por clave pública)&lt;/li&gt;
&lt;li&gt;Instalación y configuración de Nullmailer y Mandrill. El motivo de uso lo explique en mi anterior &lt;a href="http://diec123.blogspot.com.es/2014/04/nullmailer-y-mandrill-como-alternativa.html" target="_blank"&gt;post&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Instalación de la monitorización de servidores de &lt;a href="https://docs.newrelic.com/docs/server/installation-ubuntu-and-debian" target="_blank"&gt;NewRelic&lt;/a&gt;&lt;/li&gt;
&lt;br /&gt;
&lt;br /&gt;
Para que funcione correctamente la instalación se debe actualizar el fichero&amp;nbsp;&lt;i&gt;development.yml &lt;/i&gt;con la configuración local (usuarios y sus claves públicas, emails, dominio, claves de acceso a Mandrill y NewRelic, ...) tal y como cuento en el &lt;a href="https://github.com/diec123/ansible-bootstrap" target="_blank"&gt;README&lt;/a&gt; del proyecto.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://blog.diegorf.com/2014/05/bootstrap-con-ansible.html</link><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdmR_4QxbFHoHaQ-fMtjg9EEUTPXwafQuP6p7KR2aMVg0Jyz6O6i3pxCRu2quAVnP1XyeqLa_r7Evasp0iX3mXuxJi1DLqkLGkdRSN820XwRIR3KXpRkGItZNEclakCKueJuQLdx5kHNPf/s72-c/twitter_javiervidal.png" width="72"/><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-3826127370147401165</guid><pubDate>Thu, 24 Apr 2014 09:37:00 +0000</pubDate><atom:updated>2014-04-24T18:15:49.737+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">mail</category><category domain="http://www.blogger.com/atom/ns#">mandrill</category><category domain="http://www.blogger.com/atom/ns#">nullmailer</category><category domain="http://www.blogger.com/atom/ns#">smtp</category><title>Nullmailer y Mandrill como alternativa a un servidor de mail local</title><description>Nunca me ha gustado la idea de tener un servidor de mail local instalado en producción, por dos motivos principales:&lt;br /&gt;
&lt;br /&gt;
El primero es que según el uso (o mal uso) que le des al mail desde tu aplicación, puede que los usuarios te marquen como spam y que la IP de tu servidor se añada a una lista negra. En ese caso, tus mails salientes quedarán bloqueados y no se enviarán, y conseguir que te borren de una lista negra no es tarea fácil.&lt;br /&gt;
&lt;br /&gt;
El segundo es que hay que configurarlo, he escuchado muchas historias de miedo de lo doloroso que es administrar un servidor de correo y prefiero no pasar por eso.&lt;br /&gt;
&lt;br /&gt;
Hace un tiempo, la opción habitual era utilizar un servicio externo para las newsletters, como &lt;a href="http://mailchimp.com/" target="_blank"&gt;MailChimp&lt;/a&gt;&amp;nbsp;y el resto de mails enviarlos desde la aplicación.&lt;br /&gt;
&lt;br /&gt;
El siguiente paso natural fue enviar tambien el mail transaccional de la aplicación (bienvenida, olvido de password, ...) desde una plataforma externa, usando su SMTP o su API. Un ejemplo sería &lt;a href="http://mandrill.com/" target="_blank"&gt;Mandrill&lt;/a&gt; y las diferentes &lt;a href="https://mandrillapp.com/docs/integrations.html" target="_blank"&gt;integraciones&lt;/a&gt; que tiene.&lt;br /&gt;
&lt;br /&gt;
Pero en nuestro caso queríamos ir un paso más y directamente no tener un servidor local para envío de los mails de sistema (p.e. los cron). Y aquí es donde aparece &lt;a href="http://untroubled.org/nullmailer/" target="_blank"&gt;Nullmailer&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Nullmailer es un &lt;a href="http://en.wikipedia.org/wiki/Message_transfer_agent" target="_blank"&gt;MTA&lt;/a&gt;&amp;nbsp;que usa el mismo formato que sendmail y permite redirigir el mail saliente a un servidor externo, de forma que desde tu servidor nunca se enviará el mail.&lt;br /&gt;
&lt;br /&gt;
En Ubuntu Trusty está disponible como &lt;a href="http://packages.ubuntu.com/trusty/mail/nullmailer" target="_blank"&gt;paquete&lt;/a&gt;. La versión en&amp;nbsp;Ubuntu Precise no soporta SSL, pero hay un &lt;a href="https://launchpad.net/~mikko-red-innovation/+archive/ppa" target="_blank"&gt;backport&lt;/a&gt;&amp;nbsp;que si lo soporta.&lt;br /&gt;
&lt;br /&gt;
La configuración es bastante simple, solo hay que cambiar 4 ficheros en el directorio /etc/nullmailer:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;adminaddr&lt;/b&gt; con el email del administrador&lt;/li&gt;
&lt;li&gt;&lt;b&gt;me&lt;/b&gt; con el nombre del servidor&lt;/li&gt;
&lt;li&gt;&lt;b&gt;defaultdomain&lt;/b&gt; con el dominio de tu servidor&lt;/li&gt;
&lt;li&gt;&lt;b&gt;remotes&lt;/b&gt; con la configuración del servidor de correo&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
La configuración completa la podeis encontrar perfectamente explicada en este post de &lt;a href="http://opensourcehacker.com/2013/03/25/using-nullmailer-and-mandrill-for-your-ubuntu-linux-server-outboud-mail/" target="_blank"&gt;OpenSourceHacker&lt;/a&gt;&amp;nbsp;, escrito por el mismo que hizo el backport de Nullmailer a Precise&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Por último, destacar que Nullmailer no escucha en el puerto 25 como cualquier SMTP, así que si algún servicio depende de SMTP, se debe configurar por separado.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Un ejemplo de este último caso es &lt;a href="https://mmonit.com/" target="_blank"&gt;monit&lt;/a&gt;, donde se debe configurar un servidor para enviar las &lt;a href="https://mmonit.com/monit/documentation/monit.html#setting_a_mail_server_for_alert_delivery" target="_blank"&gt;alertas&lt;/a&gt;. Así que lo que haremos, será que apunte directamente al SMTP de mandrill&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;  server {
  set mailserver smtp.mandrillapp.com port 587
    username "youremail@domain.com" password "your_password"
    using tlsv1
  }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://blog.diegorf.com/2014/04/nullmailer-y-mandrill-como-alternativa.html</link><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-9122851145444824852</guid><pubDate>Mon, 24 Mar 2014 15:29:00 +0000</pubDate><atom:updated>2014-04-23T17:27:01.379+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">devops</category><category domain="http://www.blogger.com/atom/ns#">nginx</category><category domain="http://www.blogger.com/atom/ns#">seguridad</category><category domain="http://www.blogger.com/atom/ns#">ssl</category><title>Configurando SSL en nginx</title><description>&lt;div&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrbiSj4hSHKPKeDy0hS6PrL2yJg5vwjwztcQQ0BIGoFxLwzZ3lLrvTb8W_OlT2S7eHfD9qNLoIRNq_xaghD42vtkxHOHpG8-hxSDD58Tb0_9DhZUtVG91pbd1sJQkjpQqi_Zv_OMDcCG5u/s1600/Qualys+SSL+Labs+++Projects+++SSL+Server+Test+++teowaki.com.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrbiSj4hSHKPKeDy0hS6PrL2yJg5vwjwztcQQ0BIGoFxLwzZ3lLrvTb8W_OlT2S7eHfD9qNLoIRNq_xaghD42vtkxHOHpG8-hxSDD58Tb0_9DhZUtVG91pbd1sJQkjpQqi_Zv_OMDcCG5u/s1600/Qualys+SSL+Labs+++Projects+++SSL+Server+Test+++teowaki.com.png" height="353" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Informe SSL de teowaki.com por sslabs.com&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;br /&gt;
La configuración básica de SSL en nginx es muy sencilla. Lo primero es tener una versión de nginx compilada con el módulo&amp;nbsp;&lt;a href="http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_session_cache" target="_blank"&gt;ngx_http_ssl_module&lt;/a&gt;. Si usas la versión estandar de tu distribución linux lo más seguro es que ya tenga soporte. Puedes comprobarlo con&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;$ nginx -V
...
configure arguments: --prefix=/usr/share/nginx ...&lt;b&gt;--with-http_ssl_module&lt;/b&gt; ...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
En el virtual host indicaremos que vamos a usar SSL y el path de los ficheros de certificados. El proveedor donde contrates el certificado te dirá los pasos para generar estos ficheros. Como ejemplo las instrucciones de&amp;nbsp;&lt;a href="https://support.comodo.com/index.php?_a=viewarticle&amp;amp;_m=knowledgebase&amp;amp;kbarticleid=1365" target="_blank"&gt;Comodo&lt;/a&gt;&amp;nbsp;y&amp;nbsp;&lt;a href="https://library.linode.com/web-servers/nginx/configuration/ssl" target="_blank"&gt;Linode&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;server {
  listen        443 &lt;b&gt;ssl&lt;/b&gt;;

  ssl_certificate      /path_to/cert.crt;
  ssl_certificate_key  /path_to/cert.key;

}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
Simplemente con estas tres líneas ya tenemos nuestro servidor con soporte SSL funcionando. Pero para que tu configuración sea óptima, hay cuantos parámetros más a tener en cuenta.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
SPDY&lt;/h3&gt;
&lt;div&gt;
&lt;a href="http://www.chromium.org/spdy" target="_blank"&gt;SPDY&lt;/a&gt; es un protocolo creado por google para reducir el tiempo de carga de las páginas web. Está soportado en Firefox y Chrome desde hace tiempo y en IE desde la version 11.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Al igual que para tener soporte de SSL, se debe compilar nginx con el módulo correspondiente,&amp;nbsp;&lt;a href="http://nginx.org/en/docs/http/ngx_http_spdy_module.html" target="_blank"&gt;ngx_http_spdy_module&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Como me da mucha pereza compilar nginx cada vez que lanzan una nueva versión, tenemos dos alternativas, usar binarios precompilados por &lt;a href="http://blog.phusion.nl/2013/08/21/use-nginx-spdy-without-compiling-nginx-and-without-a-recent-openssl/" target="_blank"&gt;Passenger&lt;/a&gt;&amp;nbsp;o usar un ppa que incluya ese módulo&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
He optado por la segunda opción, usando los paquetes de &lt;a href="https://launchpad.net/~chris-lea/+archive/nginx-devel" target="_blank"&gt;Chris Lea&lt;/a&gt;. Están compilados usando la versión de desarrollo de nginx. Aunque es la versión de desarrollo es una versión estable que tambien usan en la web de nginx tal como explican en las &lt;a href="http://wiki.nginx.org/Faq#Is_it_safe_to_use_the_development_branch_in_production.3F" target="_blank"&gt;FAQ&lt;/a&gt;.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
La configuración de nuevo es tan simple como añadir spdy en la directiva listen&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style="-webkit-text-stroke-width: 0px; background-color: #e0e0e0; border: 0px; color: #333333; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 17px; margin: 0px 0px 10px; max-height: 600px; orphans: auto; overflow: auto; padding: 5px; text-align: start; text-indent: 0px; text-transform: none; vertical-align: baseline; widows: auto; width: auto; word-spacing: 0px;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;  listen        443 ssl&lt;b&gt; spdy&lt;/b&gt;;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
TLS&lt;/h3&gt;
&lt;div&gt;
La configuración por defecto de nginx soporta SSL v3 y TLS versiones 1.0, 1.1 y 1.2.&lt;/div&gt;
&lt;br /&gt;
Todos los navegadores modernos soportan TLS, y SSL v3 es un protocolo antiguo y tiene algunos problemas de &lt;a href="http://en.wikipedia.org/wiki/Transport_Layer_Security#SSL_3.0" target="_blank"&gt;seguridad&lt;/a&gt;, así que he decidido deshabilitarlo&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;  # enables TLS protocols, but not SSL which is weak and should no longer be used.
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
Strict Transport Security (HSTS)&lt;/h3&gt;
&lt;div&gt;
Si vamos a usar siempre conexión segura con nuestro servidor, añadiendo la cabecera &lt;a href="https://www.owasp.org/index.php/HTTP_Strict_Transport_Security" target="_blank"&gt;Strict Transport Security&lt;/a&gt;, indicamos al navegador que aunque el usuario escriba la URL con http, siempre debe conectarse de forma segura usando https.&lt;/div&gt;
&lt;br /&gt;
Es una buena práctica de &lt;a href="http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security#Applicability" target="_blank"&gt;seguridad&lt;/a&gt; y muchos servicios como Twitter o Paypal añaden esta cabecera en sus respuestas.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;  # Remember this setting for 365 days
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;h3&gt;
&lt;/h3&gt;
&lt;h3&gt;
Ciphers&lt;/h3&gt;
&lt;/div&gt;
&lt;div&gt;
Hay mucha literatura sobre los algoritmos de cifrado que se deberían permitir, &lt;strike&gt;en nuestro caso he optado por seguir las recomendaciones de &lt;a href="https://support.comodo.com/index.php?_a=viewarticle&amp;amp;_m=knowledgebase&amp;amp;kbarticleid=1365" target="_blank"&gt;Comodo&lt;/a&gt;.&lt;/strike&gt;&lt;br /&gt;
&lt;br /&gt;
Actualización 23-04-2014: Basado en este post sobre &lt;a href="https://hynek.me/articles/hardening-your-web-servers-ssl-ciphers/" target="_blank"&gt;SSL Ciphers&lt;/a&gt;, he actualizado la configuración, desactivando RC4.&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
Tambien he añadido otra directiva para que sea el servidor el que decida que protocolo usar entre los disponibles en lugar de dejar la elección al cliente.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="color: #222222;"&gt;&lt;span style="line-height: 17px;"&gt;  # Disables all weak ciphers
  ssl_prefer_server_ciphers on;
  &lt;strike&gt;ssl_ciphers ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM;&lt;/strike&gt;
  ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;
&lt;br /&gt;
&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;h3&gt;
OCSP Stapling&lt;/h3&gt;
&lt;/div&gt;
Al conectarse el navegador a una web segura, hace una petición adicional a la autoridad certificadora para asegurarse de que el certificado es válido usando OCSP (Online Certificate Status Protocol).&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;/code&gt;&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;
Por medio de OCSP Stapling, se evita esa petición adicional incluyendo la respuesta OCSP en la misma conexión SSL, con lo que reducimos el tiempo de conexión.&lt;br /&gt;
&lt;br /&gt;
Puedes leer más en&amp;nbsp;&lt;a href="http://blog.cloudflare.com/ocsp-stapling-how-cloudflare-just-made-ssl-30" target="_blank"&gt;Cloudfare&lt;/a&gt;, en la&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/OCSP_stapling" target="_blank"&gt;Wikipedia&lt;/a&gt;, y comprobar si tu servidor lo soporta siguiendo las instrucciones de&amp;nbsp;&lt;a href="http://unmitigatedrisk.com/?p=100" target="_blank"&gt;Unmitigated Risk&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;  # enable ocsp stapling
  ssl_stapling on;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;h3&gt;
SSL Session&lt;/h3&gt;
&lt;div&gt;
Por último, siguiendo las recomendaciones de &lt;a href="http://nginx.org/en/docs/http/ngx_http_ssl_module.html#example" target="_blank"&gt;nginx&lt;/a&gt; para reducir la carga del procesador habilitamos la caché de sesiones SSL y aumentamos el timeout&lt;/div&gt;
&lt;div style="-webkit-text-stroke-width: 0px; color: black; font-family: 'Times New Roman'; font-size: medium; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px;"&gt;
&lt;div style="margin: 0px;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;  ssl_session_cache    shared:SSL:10m;
  ssl_session_timeout  10m;&lt;/span&gt;&lt;span style="font-size: x-small;"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;
&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;
&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
Con esta configuración conseguimos una implementación SSL robusta y eficiente. Si conoces algún truco o mejora, por favor, dejalo en los comentarios, gracias!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://blog.diegorf.com/2014/03/configurando-ssl-en-nginx.html</link><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrbiSj4hSHKPKeDy0hS6PrL2yJg5vwjwztcQQ0BIGoFxLwzZ3lLrvTb8W_OlT2S7eHfD9qNLoIRNq_xaghD42vtkxHOHpG8-hxSDD58Tb0_9DhZUtVG91pbd1sJQkjpQqi_Zv_OMDcCG5u/s72-c/Qualys+SSL+Labs+++Projects+++SSL+Server+Test+++teowaki.com.png" width="72"/><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-5573795985574744671</guid><pubDate>Wed, 19 Feb 2014 13:16:00 +0000</pubDate><atom:updated>2014-02-19T14:16:46.302+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">log</category><category domain="http://www.blogger.com/atom/ns#">rails</category><category domain="http://www.blogger.com/atom/ns#">rsyslog</category><title>Agrupando el log de rails con rsyslog</title><description>En &lt;a href="https://teowaki.com/" target="_blank"&gt;teowaki&lt;/a&gt; el servicio de API lo tenemos balanceado entre dos servidores. Los objetivos principales de balancearlo, más que la carga, han sido la protección ante fallos y la posibilidad de hacer pruebas con diferentes configuraciones en los servidores.&lt;br /&gt;
&lt;br /&gt;
Por ejemplo, inicialmente teníamos ruby 2.0 y unicorn en ambos servidores. En&amp;nbsp;&lt;a href="https://www.ruby-lang.org/en/news/2013/12/25/ruby-2-1-0-is-released/" target="_blank"&gt;Navidad&lt;/a&gt;&amp;nbsp;se publicó la versión 2.1, la instalamos en uno de los servidores y durante unas semanas tuvimos las dos versiones conviviendo en produccion. Las conclusiones fueron que más o menos el tiempo de respuesta bajaba un &amp;nbsp;20% y el consumo de memoría subía tambien sobre un 20%, así que decidimos instalarlo en las dos máquinas.&lt;br /&gt;
&lt;br /&gt;
De la misma forma queremos hacer la prueba más adelante de usar diferentes servidores de aplicaciones simultáneamante (passenger / unicorn / puma) para ver cual funciona mejor. Tambien tenemos la intención de probar JRuby 9K en cuanto esté listo para producción.&lt;br /&gt;
&lt;br /&gt;
El problema del balanceo es que el log queda distribuido y es imposible seguir una petición. Afortunadamente hay una solución muy simple usando &lt;a href="http://www.rsyslog.com/" target="_blank"&gt;rsyslog&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
El primer paso es cambiar la configuración de rails para que use &lt;a href="http://ruby-doc.org/stdlib-2.1.0/libdoc/syslog/rdoc/Syslog/Logger.html" target="_blank"&gt;syslog&lt;/a&gt;, que viene por defecto en ruby, por lo que no es necesario instalar ninguna gema. Tan simple como añadir una línea en config/production.rb, donde 'teowaki-api' en nuestro caso indica el nombre que usaremos para la configuración de rsyslog.&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="-webkit-text-stroke-width: 0px; background-color: #e0e0e0; border: 0px; color: #333333; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 17px; margin: 0px 0px 10px; max-height: 600px; orphans: auto; overflow: auto; padding: 5px; text-align: start; text-indent: 0px; text-transform: none; vertical-align: baseline; widows: auto; width: auto; word-spacing: 0px;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;$ more config/production.rb 
...
config.logger = Syslog::Logger.new 'teowaki-api'
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
A partir de ahora, el log en modo production lo procesará rsyslog.&lt;br /&gt;
&lt;br /&gt;
Para configurar rsyslog, primero de todo editamos /etc/rsyslog.conf en el servidor que recibirá los logs (misc en nuestro caso), permitiendo acceso por TCP en el puerto 10514 y dando permiso de escritura solo a los servidores de API.&lt;br /&gt;
&lt;br /&gt;
En la configuración por defecto de rsyslog el puerto de TCP es 514, pero en ubuntu hay un problema de&amp;nbsp;&lt;a href="https://bugs.launchpad.net/ubuntu/+source/rsyslog/+bug/789174" target="_blank"&gt;privilegios&lt;/a&gt;&amp;nbsp;al usar puertos por debajo del 1024, así que he usado el 10514&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;$ more /etc/rsyslog.conf
....
# provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 10514
...
$AllowedSender TCP, api01, api02
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
Ahora creamos el fichero de configuración cada servidor de API, donde le decimos que guarde el log en /var/log en local y que tambien lo mande al servidor misc al puerto 10514&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;
$ more /etc/rsyslog.d/40-teowaki-api.conf 
if $programname == 'teowaki-api' then /var/log/rails/teowaki-api.log 
if $programname == 'teowaki-api' then @@misc:10514 
&amp;amp; ~&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;br /&gt;
Y finalmente, en el servidor misc le decimos que guarde el log, que le llegará desde los servidores de API, en /var/log&lt;br /&gt;
&lt;br /&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;$ more /etc/rsyslog.d/40-teowaki-api.conf 
if $programname == 'teowaki-api' then /var/log/rails/teowaki-api.log 
&amp;amp; ~&amp;nbsp;&amp;nbsp;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;div&gt;
El número 40 indica la prioridad del fichero, para que se ejecute antes que el fichero 50-default.conf, tal y como explican en este &lt;a href="http://deadunicornz.org/blog/2014/01/02/rsyslog-log-to-remote-server/" target="_blank"&gt;blog&lt;/a&gt;, que fue el que me dio la idea para esta configuración&lt;br /&gt;
&lt;br /&gt;
Y esto es todo, así de simple y ya tenemos la configuración completa.&lt;br /&gt;
&lt;br /&gt;
La instalación en producción la he hecho con un par de roles de ansible, uno para los servidores de API y otro para el servidor que recibe los logs y además le he añadido logrotate, pero bueno, de ansible ya hablaremos en otro post...&lt;br /&gt;
&lt;br /&gt;
Más adelante quiero probar otras soluciones más potentes como &lt;a href="http://www.elasticsearch.org/overview/kibana/" target="_blank"&gt;Kibana&lt;/a&gt; y &lt;a href="http://logstash.net/" target="_blank"&gt;logstash&lt;/a&gt;, pero por ahora ya tenemos el log centralizado, que era el objetivo inicial.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;</description><link>http://blog.diegorf.com/2014/02/agrupando-el-log-de-rails-con-rsyslog.html</link><thr:total>3</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-2763597448397922133</guid><pubDate>Thu, 06 Feb 2014 10:39:00 +0000</pubDate><atom:updated>2014-02-06T12:17:07.181+01:00</atom:updated><title>Recuperando el blog</title><description>Hace ya casi 6 años escribí la primera entrada en este &lt;a href="http://diec123.blogspot.com.es/2008/05/aqu-empiezo-mi-blog.html" target="_blank"&gt;blog&lt;/a&gt;. Mi idea inicial era escribir una entrada cada mes, mantuve bien el ritmo en el 2008 y el 2009, el 2010 empecé a flaquear y en el 2013 no he escrito ni una triste entrada :(&lt;br /&gt;
&lt;br /&gt;
El 2013 ha sido un año de muchos cambios, dejé la &lt;a href="http://aspgems.com/"&gt;empresa&lt;/a&gt; donde había estado trabajando desde el 2007 para intentar junto a &lt;a href="http://javier-ramirez.com/" target="_blank"&gt;Javi&lt;/a&gt; la loca aventura de montar un producto&amp;nbsp;SaaS que haga más felices a los desarrolladores. Desde diciembre tenemos &lt;a href="https://teowaki.com/" target="_blank"&gt;teowaki&lt;/a&gt; en producción, y estamos bastante orgullosos del resultado.&lt;br /&gt;
&lt;br /&gt;
Uno de las consecuencias ha sido que mi stack tecnológico ha cambiado mucho. Estos años la mayoría de mis proyectos estaban basados en ruby on rails en el servidor, MySQL como almacen de datos y una parte cliente que cada vez iba siendo más compleja, pero casi siempre basada en las vistas de rails y jQuery.&lt;br /&gt;
&lt;br /&gt;
Aprovechando que teniamos 'poder absoluto' para decidir la tecnología a usar, optamos por una arquitectura que por ahora está dando muy buen resultado.&lt;br /&gt;
&lt;br /&gt;
Para empezar, queríamos que la API fuera un ciudadano de primera clase del proyecto, así que hemos desarrollado por&amp;nbsp;un backend en modo API y el front es simplemente un cliente más de esa API.&lt;br /&gt;
&lt;br /&gt;
Tambien hemos empezado a usar redis para mucho más que para la gestión de colas y nuestra base de datos es PostgreSQL.&lt;br /&gt;
&lt;br /&gt;
Aunque ya hacía algo de sistemas anteriormente, tambien me he introducido un poco más en el mundo devops, instalando los servidores con Ansible. Otro cambio ha sido que en lugar de usar apache / passenger como servidor web y de aplicaciones, estamos probando la combinación nginx / unicorn.&lt;br /&gt;
&lt;br /&gt;
Del mismo modo, he tenido que resetear lo que sabía de JavaScript, aprendiendo a usar AngularJS en el cliente de la API.&lt;br /&gt;
&lt;br /&gt;
Así que creo que tengo bastantes cosas que contar sobre mi trabajo y voy a intentar recuperar el ritmo de una entrada por mes, a ver si lo consigo al menos durante otros dos años como cuando empecé este blog.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</description><link>http://blog.diegorf.com/2014/02/recuperando-el-blog.html</link><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-33497524640765267</guid><pubDate>Sun, 30 Sep 2012 10:52:00 +0000</pubDate><atom:updated>2012-10-10T16:31:19.083+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dell</category><category domain="http://www.blogger.com/atom/ns#">ubuntu</category><category domain="http://www.blogger.com/atom/ns#">vostro</category><title>Instalando Ubuntu en Vostro 3500 (parte 2)</title><description>&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Hace año y medio escribí una entrada en el &lt;a href="http://diec123.blogspot.com.es/2011/04/instalando-ubuntu-en-vostro-3500.html"&gt;blog&lt;/a&gt; explicando los problemas que había tenido con la instalación de Ubuntu Maverick en mi &lt;a href="http://portatiles.es/dell/dell-vostro-3500"&gt;Dell Vostro 3500&lt;/a&gt;. Por los comentarios que tuve, parece que había bastante gente con los mismos problemas que yo (y que tambien me ayudaron a arreglar mis problemas), así que ahora que hace unos meses que actualicé a Ubuntu Precise (12.04), llegó el momento de actualizar la entrada.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;b style="background-color: white; color: #333333; font-size: large; line-height: 16px; text-align: left;"&gt;Tarjeta gráfica&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b style="background-color: white; color: #333333; font-size: large; line-height: 16px; text-align: left;"&gt;&lt;br /&gt;&lt;/b&gt;
Como comenté en entrada anterior, este portátil tiene una tarjeta híbrida que no está soportada en ubuntu por defecto. Hace algo más de un año probé &lt;a href="https://wiki.ubuntu.com/Bumblebee"&gt;Bumblebee&lt;/a&gt;, pero estaba bastante verde, me dio muchos problemas y acabé por desinstalarlo. En cambio ahora es un proyecto bastante estable y llevo utilizándolo varios meses sin ningún problema.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
Usando Bumblebee, por una parte, se consigue una mejor gestión del consumo de energía desactivando la tarjeta cuando no se usa (lo que se nota bastante trabajando con batería) y por otra permite activarla manualmente ejecutando las aplicaciones desde consola anteponiendo el comando optirun&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
He leído en &lt;a href="http://www.pcworld.com/article/261874/coming_soon_to_linux_nvidia_optimus_graphics_support.html#tk.rss_news"&gt;pcworld&lt;/a&gt; y en &lt;a href="http://www.phoronix.com/scan.php?page=news_item&amp;amp;px=MTE3MzY"&gt;phoronix&lt;/a&gt; que nvidia ha empezado a trabajar en un driver para este tipo de tarjetas, pero todavía no hay fechas, así que por ahora la mejor opción sin duda es Bumblebee.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;div style="text-align: -webkit-auto;"&gt;
&lt;b style="background-color: white; color: #333333; font-size: large; line-height: 16px; text-align: left;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;HDMI&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b style="background-color: white; color: #333333; font-size: large; line-height: 16px; text-align: left;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div style="text-align: -webkit-auto;"&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;He probado a conectar el portátil a la tele con un cable HDMI y detecta la tele, pero no se ve el vídeo (con un cable VGA funciona sin problema).&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;No he investigado el problema, así que no se si es un problema de configuración o si realmente no se puede.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;
&lt;b style="background-color: white; color: #333333; font-size: large; line-height: 16px; text-align: left;"&gt;Lector de huellas&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b style="background-color: white; color: #333333; font-size: large; line-height: 16px; text-align: left;"&gt;&lt;br /&gt;&lt;/b&gt;
El lector de huellas integrado (VFS300) todavía no está soportado. Hay un error abierto en &lt;a href="https://bugs.launchpad.net/ubuntu/+source/libfprint/+bug/744310"&gt;launchpad&lt;/a&gt;&amp;nbsp;desde hace bastante tiempo y en el comentario &lt;a href="https://bugs.launchpad.net/ubuntu/+source/libfprint/+bug/744310/comments/51"&gt;#51&lt;/a&gt;&amp;nbsp;hay un paquete que añade soporte para este lector.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
Ejecutando las instrucciones del comentario en la configuración del usuario se puede activar su uso. &amp;nbsp;Pero me he encontrado varios problemas. El primero es que no va muy fino (la mayoría de las veces me da error al reconocer la huella) y el segundo es que al hacer login vuelve a pedir la contraseña para desbloquear el keyring (el keyring es donde ubuntu guarda las contraseñas, p.e. las de las wifis).&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
En la descripción del PPA oficial de &lt;a href="https://launchpad.net/~fingerprint/+archive/fprint"&gt;fprint&lt;/a&gt; está muy bien explicado que es el keyring y como desactivar que pida contraseña (sección 'Note on keyrings and passwordless login') aunque esta última parte no la he probado.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;strike&gt;Volviendo a launchpad, en el último comentario de final de agosto, pone que el bug ya está corregido, pero todavía no está aplicado en la versión de ubuntu. En resumen, seguiré con el lector desactivado por ahora hasta que esté mejor integrado.&lt;/strike&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;La última versión de fprint ya incluye el soporte para el lector, así que instalándolo según las instrucciones, ya se puede usar sin problemas, aunque con las limitaciones que he comentado antes.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;strike&gt;&lt;br /&gt;&lt;/strike&gt;&lt;/span&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;
&lt;b style="background-color: white; color: #333333; font-size: large; line-height: 16px; text-align: left;"&gt;Unity&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b style="background-color: white; color: #333333; font-size: large; line-height: 16px; text-align: left;"&gt;&lt;br /&gt;&lt;/b&gt;
Otro de los grandes cambios al actualizar ubuntu fue cambiar gnome por unity, al principio es todo un poco raro, pero a la que llevas un tiempo usándolo se nota la mejora, queda bastante más espacio libre en la pantalla al tener los menús integrados en la barra superior y no tener la barra inferior de aplicaciones y a la que te acostumbras a buscar las aplicaciones por nombre (pulsando la tecla windows) es mucho más cómodo que la búsqueda por menú de gnome.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Con Unity desaparecen todos los indicadores del menú superior (por ejemplo el icono de skype), pero se pueden activar fácilmente tal y como explican en &lt;a href="http://www.webupd8.org/2011/04/how-to-re-enable-notification-area.html"&gt;webupd8&lt;/a&gt; ejecutando desde consola&lt;/span&gt;&lt;br /&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; text-align: left; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;&lt;span style="background-color: transparent;"&gt;gsettings set com.canonical.Unity.Panel systray-whitelist "['all']"&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Otro problema para mi era no tener los applets de gnome, que usaba varios. Los que me he instalado son:&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="https://launchpad.net/indicator-multiload"&gt;System Load Indicator&lt;/a&gt;&amp;nbsp;para tener monitorizado el uso de memoría, cpu y carga del sistema&lt;/span&gt;&lt;br /&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; text-align: left; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;sudo add-apt-repository ppa:indicator-multiload/stable-daily
sudo apt-get update
sudo apt-get install indicator-multiload&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="http://www.jupiterapplet.org/"&gt;Jupiter&lt;/a&gt;&amp;nbsp;para la gestión automática del consumo cuando se trabaja con batería. Tiene más opciones, pero no las uso normalmente&lt;/span&gt;&lt;br /&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; text-align: left; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;sudo add-apt-repository ppa:webupd8team/jupitersudo apt-get update
sudo apt-get install jupiter&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;a href="https://launchpad.net/indicator-sensors"&gt;Hardware Sensors Indicators&lt;/a&gt; para tener monitorizar los sensores, principalmente el de temperatura&lt;/span&gt;&lt;/div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; text-align: left; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;sudo add-apt-repository ppa:alexmurray/indicator-sensors
sudo apt-get update
sudo apt-get install indicator-sensors&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;span style="color: #222222; font-family: Arial, Helvetica, sans-serif;"&gt;Previamente a instalar esta última aplicación ejecuté &lt;a href="http://freecode.com/projects/xsensors"&gt;xsensors&lt;/a&gt;&amp;nbsp;que detecta los sensores disponibles y instala los módulos necesarios para los sensores detectados.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; text-align: left; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;sudo apt-get install xsensors
sudo sensors-detect&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;
&lt;/span&gt;&lt;/code&gt;
&lt;br /&gt;
&lt;div&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;En &lt;/span&gt;&lt;a href="http://askubuntu.com/questions/30334/what-application-indicators-are-available" style="font-family: Arial, Helvetica, sans-serif;"&gt;AskUbuntu&lt;/a&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt; hay una lista bastante completa de applets.&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;b style="background-color: white; color: #333333; font-size: large; line-height: 16px; text-align: left;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Ventilador&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;El ventilador ya no se puede gestionar como en gnome usando las alarmas de sensors applets, así que he optado por la solución que me propuso &lt;a href="http://diec123.blogspot.com.es/2011/04/instalando-ubuntu-en-vostro-3500.html?showComment=1312352378389#c8301166361470126607"&gt;samsagax&lt;/a&gt; en mi post anterior, gracias de nuevo!&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;La solución consiste en installar i8kutils y arrancar el módulo (para que arranque automáticamente al reiniciar se debe añadir i8k en /etc/modules)&lt;/span&gt;&lt;br /&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; text-align: left; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;sudo apt-get i8kutils&lt;/span&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;
sudo modprobe i8k&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Una vez instalado, editamos el fichero .i8kmon en el home del usuario, con los umbrales de temperatura adecuados para nuestra instalación (en man i8kmon los explica perfectamente)&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; text-align: left; vertical-align: baseline; width: auto;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif; font-size: x-small;"&gt;more ~/.i8kmon&amp;nbsp;
set config(0) {{- 0} &amp;nbsp;-1 &amp;nbsp;55 &amp;nbsp;-1 &amp;nbsp;60}
set config(1) {{- 1} &amp;nbsp;50 &amp;nbsp;65 &amp;nbsp;55 &amp;nbsp;70}
set config(2) {{- 1} &amp;nbsp;50 &amp;nbsp;65 &amp;nbsp;55 &amp;nbsp;70}
set config(3) {{- 2} &amp;nbsp;60 128 &amp;nbsp;65 128}
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;Si no se configura tiene unos valores por defecto de temperatura, que en mi caso creo que son demasiado altos. Tambien se puede configurar en &lt;/span&gt;&lt;/code&gt;&lt;span style="color: #222222; font-family: Arial, Helvetica, sans-serif;"&gt;/etc/default/i8kmon. aunque prefiero la opción de ponerlo en mi home, ya que tengo particiones separadas para home y / y si formateo / no pierdo la configuración.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span style="color: #222222; font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span style="color: #222222; font-family: Arial, Helvetica, sans-serif;"&gt;Y ya solo queda arrancarlo (-a para que controle la velocidad del ventilador a parte de monitorizar y -d para que arranque en modo demonio)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;pre style="background-color: #e0e0e0; border: 0px; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; text-align: left; vertical-align: baseline; width: auto;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;i8kmon -a -d&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;div&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;code style="border: 0px; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;span style="color: #222222; font-family: Arial, Helvetica, sans-serif;"&gt;Bueno, pues por ahora esto es todo respecto a mi configuración. Como en la entrada anterior, iré actualizando a medida que vaya descubriendo nuevas configuraciones....&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span style="font-family: Arial, Helvetica, sans-serif;"&gt;&lt;b style="background-color: white; color: #333333; font-size: large; line-height: 16px; text-align: left;"&gt;&lt;br /&gt;&lt;/b&gt;
&lt;/span&gt;
&lt;b style="background-color: white; color: #333333; font-family: Verdana, Arial, sans-serif; font-size: large; line-height: 16px; text-align: left;"&gt;&lt;br /&gt;&lt;/b&gt;</description><link>http://blog.diegorf.com/2012/09/instalando-ubuntu-en-vostro-3500-parte-2.html</link><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-1312111790633495211</guid><pubDate>Fri, 15 Jun 2012 08:31:00 +0000</pubDate><atom:updated>2012-06-15T10:31:32.277+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">amsterdam</category><category domain="http://www.blogger.com/atom/ns#">euruko</category><title>Euruko 2012 - Impresiones</title><description>&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSSVJDDg3BOrhrRCV8M5NQet1y9o9K9zzpHSUHMti_pZy7-CxYATk-2ExjUVvx8tHwUjdDCQmcBR1hZmDuB9aGSfYKZRvOO6K_anplINCDIbVN3wB7EViD-fpg0JSZ-IxFIQlIUWIJddBl/s1600/img035.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSSVJDDg3BOrhrRCV8M5NQet1y9o9K9zzpHSUHMti_pZy7-CxYATk-2ExjUVvx8tHwUjdDCQmcBR1hZmDuB9aGSfYKZRvOO6K_anplINCDIbVN3wB7EViD-fpg0JSZ-IxFIQlIUWIJddBl/s640/img035.jpg" width="235" /&gt;&lt;/a&gt;Para no perder la tradición, de nuevo he estado en &lt;a href="http://www.euruko2012.org/"&gt;Euruko&lt;/a&gt;, este año en Amsterdam.&lt;br /&gt;
&lt;br /&gt;
Aprovechando que hemos puesto en común las impresiones en &lt;a href="http://aspgems.com/"&gt;ASPgems&lt;/a&gt; (agradecido porque de nuevo me financió este año el viaje) y que acaban de publicar los vídeos en &lt;a href="http://vimeo.com/euruko/videos"&gt;vimeo&lt;/a&gt;, es el momento de reflexionar un poco sobre la conferencia.&lt;br /&gt;
&lt;br /&gt;
La verdad es que este año me ha decepcionado un poco. Es una conferencia a la que he ido ya varias veces y la tenía un poco idealizada, como una conferencia pequeña, en la que siempre me sorprendían las conferencias, con multitud de aplicaciones curiosas de ruby fuera del mundo web que es el que conozco y uso habitualmente.&lt;br /&gt;
&lt;br /&gt;
Pero este año me encontré con una conferencia multitudinaria, demasiado rígida, en la que preferían cortar las preguntas antes de retrasar cinco minutos la siguiente charla, demasiado 'enterprise' (el señor jruby contando la maravillas de su producto, idem el señor rubinius, ...) y sin nada que me sorprendiera especialmente.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Espero que el año que viene en &lt;a href="http://euruko-athens.github.com/euruko13/"&gt;Atenas&lt;/a&gt; le vuelvan a dar el toque de frescura que ha perdido.&lt;br /&gt;
&lt;br /&gt;
A pesar de que parece muy negativo todo lo que he puesto, porque tenía unas espectativas demasiado altas, la conferencia ha sido interesante y ha habido unas cuantas charlas recomendables. Si me tuviera que quedar con cinco elegiría:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://vimeo.com/44025029"&gt;Bruno Aguirre - The Future is Dead: Long live the Past&lt;/a&gt;, filosofando un poco sobre programación&lt;br /&gt;
&lt;a href="http://vimeo.com/43977312"&gt;Mitchell Hashimoto - Building a Ruby Library, the Parts No One Talks About&lt;/a&gt; dando buenos consejos sobre como hacer una librería en ruby&lt;br /&gt;
&lt;a href="http://vimeo.com/43848347"&gt;Roy Tomeij - The Joy of Front-End, A Journey with Bob Ross&lt;/a&gt; con más interesantes consejos, en este caso de front-end&lt;br /&gt;
&lt;a href="http://vimeo.com/43698187"&gt;Sean Cribbs - A Case of Accidental Concurrency&lt;/a&gt; planteando un problema real de concurrencia y el proceso de resolución&lt;br /&gt;
&lt;a href="http://vimeo.com/43981884"&gt;Martin Rehfeld - Ruby &amp;amp; Erlang, At Scale with Style&lt;/a&gt; aunque no fue de las mejores charlas, siempre es interesante ver como resuelven en &lt;a href="http://www.wooga.com/"&gt;wooga&lt;/a&gt; sus problemas de escalabilidad&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Nos vemos en Atenas :)</description><link>http://blog.diegorf.com/2012/06/euruko-2012-impresiones.html</link><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSSVJDDg3BOrhrRCV8M5NQet1y9o9K9zzpHSUHMti_pZy7-CxYATk-2ExjUVvx8tHwUjdDCQmcBR1hZmDuB9aGSfYKZRvOO6K_anplINCDIbVN3wB7EViD-fpg0JSZ-IxFIQlIUWIJddBl/s72-c/img035.jpg" width="72"/><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-3906511628754811849</guid><pubDate>Thu, 25 Aug 2011 16:50:00 +0000</pubDate><atom:updated>2011-08-25T18:50:40.262+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">imagen</category><category domain="http://www.blogger.com/atom/ns#">rails</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><title>Borrando imágenes no usadas en un proyecto Rails</title><description>Para acabar el rediseño de un proyecto, estoy en la fase final de limpieza de código y me he encontrado que habían muchísimas imágenes antiguas que ya no se utilizan&lt;br /&gt;
&lt;br /&gt;
En lugar de ir buscando una por una si se usaba, que me iba a llevar demasiado tiempo, he hecho un script en ruby que busca las imágenes no usadas y las borra de subversión:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class="line" id="LC1" style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="n"&gt;images&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Dir&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'public/images/*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC2" style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC3" style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="n"&gt;images&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC4" style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;directory?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC5" style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Checking &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;..."&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC6" style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;popen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ack-grep -1 -G '(app|public)' --ruby --html --css &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;basename&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;eof?&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC7" style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="no"&gt;IO&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;popen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"svn delete &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;image&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC8" style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"  Deleted"&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC9" style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="k"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC10" style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&amp;nbsp;&amp;nbsp;&lt;span class="k"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="line" id="LC11" style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;span class="k"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
Es tan simple como buscar todas las imágenes del directorio images y aplicar sobre cada una de ellas un &lt;a href="http://betterthangrep.com/"&gt;ack-grep&lt;/a&gt; que me busca en ficheros de ruby (.rb, .erb), html y css de los directorios app y public. El párametro -1 hace que al encontrar el primer resultado deje de buscar, con lo que conseguimos que vaya un poco más rápido.&lt;br /&gt;
&lt;br /&gt;
Luego, sobre cada una de las imágenes no usadas hace un svn delete y ya solo nos queda revisar la lista de borrados para asegurarnos de todo ha ido bien y un commit al repo.&lt;br /&gt;
&lt;br /&gt;
La modificación para que busque tambien en subdirectorios de images sería&amp;nbsp; usar 'public/images/**' como parametro en Dir.glob y igual de simple sería cambiarlo para que use git, cambiando la llamada del segundo IO.popen&lt;br /&gt;
&lt;br /&gt;
Pues nada, aquí dejo el &lt;a href="https://gist.github.com/1170410"&gt;gist&lt;/a&gt; con el script para quien le pueda ser de utilidad.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
</description><link>http://blog.diegorf.com/2011/08/borrando-imagenes-no-usadas-en-un.html</link><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-105565103560163700</guid><pubDate>Fri, 17 Jun 2011 07:00:00 +0000</pubDate><atom:updated>2011-06-17T09:00:05.428+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">euruko berlin</category><title>Euruko 2011 - Impresiones</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjggJ1exkk4gAaxwWl4JbpxI-iMHjCyrGm0ef8VxNjape2R1Ca24p8wfGk5Qm_vP5WLrSjjPOzNEYQK2eekfxgVO2oSv1RBO361L7WOayldJB7NnhchbW24tKL1kmZbNTb1b02-azhjRnpF/s1600/euruko.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjggJ1exkk4gAaxwWl4JbpxI-iMHjCyrGm0ef8VxNjape2R1Ca24p8wfGk5Qm_vP5WLrSjjPOzNEYQK2eekfxgVO2oSv1RBO361L7WOayldJB7NnhchbW24tKL1kmZbNTb1b02-azhjRnpF/s320/euruko.jpg" width="231" /&gt;&lt;/a&gt;&lt;/div&gt;Manteniendo la tradicción de contar mis impresiones de las conferencias a las que asisto, le toca el turno a &lt;a href="http://euruko2011.org/"&gt;Euruko&lt;/a&gt;, que fue en Berlín a final de Mayo (ya me vale tardar casi 3 semanas en escribirlo...)&lt;br /&gt;
&lt;br /&gt;
Este año me han gustado bastante las charlas, más que el año pasado. De todas formas Euruko es una conferencia que nunca defrauda.&lt;br /&gt;
&lt;br /&gt;
La organización fue magnífica, con una sala impresionante, la wi-fi más rápida y la pantalla más grande que nunca he visto en una conferencia. Y litros y litros de &lt;a href="http://www.clubmate.de/cws/en/about-club-mate/what-is-club-mate.57.html"&gt;Club Mate &lt;/a&gt;para recuperarnos de las largas noches berlinesas.&lt;br /&gt;
&lt;br /&gt;
Por criticarles algo, el infierno que supuso conseguir un ticket para asistir, y en la sala de conferencias se les olvidó que existe mundo aparte de los mac. La única forma de conectar un portátil era con DVI, y más de uno tuvo que hacer su lighting talk sólo hablada sin poder proyectarla.&lt;br /&gt;
&lt;br /&gt;
Eso si, ese olvido nos proporcionó en una ligthing talk una extraña pareja en el escenario: un MacBook Air y&lt;a href="http://javier-ramirez.com/"&gt; Javi Ramírez&lt;/a&gt; :p&lt;br /&gt;
&lt;br /&gt;
Por destacar 3 charlas:&lt;br /&gt;
&lt;br /&gt;
* Para mi la estrella sin duda de este año fue &lt;a href="http://ducktypo.blogspot.com/"&gt;Paolo Perotta&lt;/a&gt; y su magnífica charla sobre &lt;a href="http://www.slideshare.net/paoloperrotta/the-revenge-of-methodmissing"&gt;method missing&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
* &lt;a href="http://karmi.cz/en"&gt;Karel Minařík&lt;/a&gt; hablando sobre &lt;a href="http://www.slideshare.net/karmi/your-data-your-search-elasticsearch-euruko-2011"&gt;ElasticSearch&lt;/a&gt; y su gema &lt;a href="https://github.com/karmi/tire"&gt;Tire&lt;/a&gt; , que ahora mismo creo que son la mejor alternativa para usar &lt;a href="http://lucene.apache.org/java/docs/index.html"&gt;Lucene&lt;/a&gt; desde ruby (los que esteis usando &lt;a href="http://lucene.apache.org/solr/"&gt;Solr&lt;/a&gt; vale la pena echarle un vistazo)&lt;br /&gt;
&lt;br /&gt;
* Tambien destacaría la charla de &lt;a href="http://www.wooga.com/"&gt;wooga&lt;/a&gt; sobre escalar &lt;a href="http://www.slideshare.net/wooga/games-for-the-masses-scaling-rails-to-the-extreme"&gt;juegos&lt;/a&gt; en Facebook, con muy buenos consejos, y lo mejor, todos apoyados en datos reales y su experiencia.&lt;br /&gt;
&lt;br /&gt;
Que destaque esas tres no quiere decir que fueran lo único interesante, y igual si lo escribiera dentro de unos meses eligiría otras. Hubo mucha variedad de temas, filosofía sobre patrones de diseño, eventos, concurrencia, javascript, procesado de imagen....&lt;br /&gt;
&lt;br /&gt;
En definitiva, vale la pena dedicarle unas horitas a ver los vídeos cuando se publiquen.&lt;br /&gt;
&lt;br /&gt;
Por último, parece que&amp;nbsp;&lt;a href="http://www.arduino.cc/"&gt;Arduino&lt;/a&gt; y &lt;a href="http://adhearsion.com/"&gt;Adhearsion&lt;/a&gt; se han hecho un hueco en muchas conferencias por la variedad de temática que ofrecen respecto al resto de charlas. Y de nuevo por criticar algo, al final todas las charlas que he visto de esos dos temas son muy parecidas, y me producen un sentimiento encontrado de 'como molan' y 'otro año más más de lo mismo'. &lt;br /&gt;
&lt;br /&gt;
Agradecerle a &lt;a href="http://aspgems.com/"&gt;ASPgems&lt;/a&gt; que me financiara el viaje y la estancia y nos vemos en &lt;a href="http://lasteuruko.org/"&gt;Amsterdam&lt;/a&gt; en la última Euruko antes del fin del mundo....</description><link>http://blog.diegorf.com/2011/06/euruko-2011-impresiones.html</link><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjggJ1exkk4gAaxwWl4JbpxI-iMHjCyrGm0ef8VxNjape2R1Ca24p8wfGk5Qm_vP5WLrSjjPOzNEYQK2eekfxgVO2oSv1RBO361L7WOayldJB7NnhchbW24tKL1kmZbNTb1b02-azhjRnpF/s72-c/euruko.jpg" width="72"/><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-1296497962396590173</guid><pubDate>Sat, 02 Apr 2011 19:16:00 +0000</pubDate><atom:updated>2012-10-10T16:40:16.447+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dell</category><category domain="http://www.blogger.com/atom/ns#">nvidia</category><category domain="http://www.blogger.com/atom/ns#">ubuntu</category><category domain="http://www.blogger.com/atom/ns#">ventilador</category><category domain="http://www.blogger.com/atom/ns#">vostro</category><category domain="http://www.blogger.com/atom/ns#">wifi</category><title>Instalando Ubuntu en Vostro 3500</title><description>&lt;br /&gt;&lt;pre style="background-color: #e0e0e0; border: 0px none; color: #333333; line-height: 17px; margin-bottom: 10px; max-height: 600px; overflow: auto; padding: 5px; text-align: left; vertical-align: baseline; width: auto;"&gt;&lt;span style="font-family: inherit;"&gt;&lt;span style="font-size: small;"&gt;&lt;code style="border: 0px none; color: #222222; margin: 0px; padding: 0px; vertical-align: baseline;"&gt;&lt;b&gt;Actualización 10/12&lt;/b&gt;: He creado una entrada complementaria a ésta explicando las novedades en la instalación en Ubuntu 12.04&amp;nbsp;
&lt;/code&gt;&lt;a href="http://diec123.blogspot.com.es/2012/09/instalando-ubuntu-en-vostro-3500-parte-2.html"&gt;http://diec123.blogspot.com.es/2012/09/instalando-ubuntu-en-vostro-3500-parte-2.html&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
Hace un par de meses cambié mi Dell Inspiron 6400, al que después de 4 años ya le tocaba descansar un poco, por un Dell Vostro 3500. Iba a poner un link a las especificaciones, pero veo que ya no lo venden y ahora está el &lt;a href="http://www1.euro.dell.com/content/products/productdetails.aspx/vostro-3550"&gt;Dell 3550&lt;/a&gt;, que es muy similar pero la tarjeta gráfica en lugar de ser nVidia GeForce es una ATI Radeon.&lt;br /&gt;
&lt;br /&gt;
Lo primero que hice al encenderlo despues de ver que funcionaba con el Windows 7 de serie, fue instalar Ubuntu 10.10.&lt;br /&gt;
&lt;br /&gt;
Tengo un par de compañeros de oficina que tienen ubuntu 32bits en este mismo ordenador, pero yo he probado con el de 64bits a ver que tal funciona.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Estos son los problemas que me he encontrado con el portátil:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Wi-Fi&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
La wi-fi conecta sin problemas, pero la conexión a internet no va todo lo rápida que debería ir (conectando directamente por cable al router me da 50Mbps y por wi-fi nunca me daba más de 7 o 8 Mbps). Además iwconfig siempre me daba como Bit Rate 1Mbps, así que me puse a investigar un poco...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Según las especificaciones del ordenador es una Dell Wireless 1501 (802.11b/g/n), pero según donde miraba me decía que es una Broadcom 4727 o una Broadcom 4313&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: blue;"&gt;
&lt;span style="font-size: x-small;"&gt;$ dmesg | grep Wireless&lt;/span&gt;&lt;/div&gt;
&lt;div style="color: blue;"&gt;
&lt;span style="font-size: x-small;"&gt;[&amp;nbsp;&amp;nbsp;&amp;nbsp; 8.954673] eth1: Broadcom BCM4727 802.11 Hybrid Wireless Controller 5.60.48.36&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style="color: blue;"&gt;
&lt;span style="font-size: x-small;"&gt;$ lspci -nn| grep Network&lt;/span&gt;&lt;/div&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;12:00.0 Network controller [0280]: Broadcom Corporation BCM4313 802.11b/g LP-PHY [14e4:4727] (rev 01)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En la web de Broadcom aclaré ese lío de nombres, la respuesta está en el &lt;a href="http://www.broadcom.com/docs/linux_sta/README.txt"&gt;readme.txt&lt;/a&gt; del driver. Dell 1501 es el nombre que le da Dell a la tarjeta, que realmente es una Broadcom 4313 y el 4727 es el vendor id. Al ejecutar lspci con la opción -nn muestra el id del fabricante (14e4) y de la tarjeta (4727).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En ese mismo readme.txt en la sección 'what's new' hay varios cambios que afectan a esta tarjeta que no están en el driver que instala ubuntu por defecto, así que me descargué el &lt;a href="http://www.broadcom.com/support/802.11/linux_sta.php"&gt;driver&lt;/a&gt;, compilé y instalé siguiendo las instrucciones.&lt;br /&gt;
&lt;br /&gt;
Con el nuevo driver ha subido bastante la velocidad de conexión y iwconfig ya da la velocidad de conexión real. Problema resuelto.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Tarjeta gráfica&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Este ordenador lleva una tarjeta gráfica híbrida, por lo que parece cuando hace falta poca potencia gráfica o en modo de bajo consumo utiliza sólo la tarjeta integrada y cuando se necesita toda la potencia utiliza la nVidia.&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;$ lspci |grep VGA&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;00:02.0 VGA compatible controller: Intel Corporation Core Processor Integrated Graphics Controller (rev 18)&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;01:00.0 VGA compatible controller: nVidia Corporation GT218 [GeForce 310M] (rev a2)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
pero el driver de nVidia no se lleva bien con ubuntu, y al instalarlo se queda frito el entorno gráfico&lt;br /&gt;
&lt;br /&gt;
Hay un error abierto en launchpad &lt;br /&gt;
&lt;div style="color: blue;"&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;
&lt;span style="color: blue; font-size: x-small;"&gt;&lt;a href="https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers/+bug/643895"&gt;https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers/+bug/643895&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Pero los últimos drivers siguen sin funcionar bien, así que seguiremos esperando....&lt;br /&gt;
&lt;br /&gt;
Además da un error de la tarjeta integrada al arrancar:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: blue;"&gt;
&lt;span style="font-size: x-small;"&gt;$ dmesg |grep intel&lt;br /&gt;
...&lt;/span&gt;&lt;/div&gt;
&lt;div style="color: blue;"&gt;
&lt;span style="font-size: x-small;"&gt;[&amp;nbsp;&amp;nbsp;&amp;nbsp; 7.382308] intel ips 0000:00:1f.6: failed to get i915 symbols, graphics turbo disabled&lt;br /&gt;
...&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Y tambien hay un error abierto en launchpad que dicen en los comentarios que se soluciona con la última versión del kernel&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/651104" style="color: blue;"&gt;https://bugs.launchpad.net/ubuntu/+source/linux/+bug/651104&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Y para acabar de liarla, hay algún error más en el log de arranque&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: blue;"&gt;
&lt;span style="font-size: x-small;"&gt;$ dmesg |grep Graphics&lt;br /&gt;
[&amp;nbsp;&amp;nbsp; 12.717458] agpgart-intel 0000:00:00.0: Intel HD Graphics Chipset&lt;br /&gt;
[&amp;nbsp;&amp;nbsp; 13.011187] [drm] MTRR allocation failed.&amp;nbsp; Graphics performance may suffer.&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
Así que por ahora he decidido no darle más vueltas a la tarjeta y esperar a ver si se soluciona. Será por todos estos problemas por lo que han cambiado de nVidia a ATI en el nuevo modelo???&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Lector de huellas&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Tiene integrado un lector de huellas que en windows funciona sin problemas, pero que ubuntu no lo reconoce:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-small;"&gt;$ lsusb&lt;br /&gt;
Bus 001 Device 004: ID 138a:0008 DigitalPersona, Inc &lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Actualizando la lista de Ids, al menos se entera de que es un lector de huellas&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;$ sudo update-usbids&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;$ lsusb&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;Bus 001 Device 004: ID 138a:0008 Validity Sensors, Inc. VFS300 Fingeprint Reader&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Instalé &lt;a href="http://www.n-view.net/Appliance/fingerprint/"&gt;fingerprint-gui&lt;/a&gt; desde ppa a ver si lo reconoce&lt;br /&gt;
&lt;div style="color: blue;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style="color: blue;"&gt;
&lt;span style="font-size: x-small;"&gt;$ sudo add-apt-repository ppa:fingerprint/fingerprint-gui&lt;/span&gt;&lt;/div&gt;
&lt;div style="color: blue;"&gt;
&lt;span style="font-size: x-small;"&gt;$ sudo apt-get install fingerprint-gui&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
pero no reconoce el lector, y de nuevo en launchpad encontramos otro error abierto&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/285089" style="color: blue;"&gt;https://bugs.launchpad.net/ubuntu/+source/linux/+bug/285089&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Por lo que dicen, parcheando y compilando la última versión de libfprint funciona, pero todavía no lo he probado.&lt;br /&gt;
&lt;b&gt; &lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;
&lt;/b&gt;&lt;br /&gt;
&lt;span style="font-size: large;"&gt;&lt;b&gt;Ventilador&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
Otro problema que me he encontrado es el ventilador, que una vez que arranca, ya no para nunca. No es un ruido insoportable y en un ambiente de oficina ni se nota, pero estando en casa si que se nota.&lt;br /&gt;
&lt;br /&gt;
Con &lt;a href="http://dellfand.dinglisch.net/"&gt;Dellfand&lt;/a&gt; se puede modificar la velocidad del ventilador en función de la temperatura, que parece que tiene 3 estados (parado, velocidad lenta y velocidad rápida).&lt;br /&gt;
&lt;br /&gt;
Al ejecutarlo detecta la temperatura y la velocidad del ventilador, pero no es capaz de actualizarla. En el ejemplo intenta actualizar del estado 2 al 0 pero le da error&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-small;"&gt;$ sudo ./dellfand 0 5 45 50 55&lt;br /&gt;
Fan 0 Status 2-&amp;gt;0 Speed 138000 CPU Temp 42C&lt;br /&gt;
dellfand: warning: set fan 0 status to 0 last cycle, it's now 2 (BIOS interference ?)&lt;br /&gt;
Fan 0 Status 2-&amp;gt;0 Speed 138000 CPU Temp 42C&lt;br /&gt;
Fan 0 Status 2-&amp;gt;0 Speed 138000 CPU Temp 45C&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Así que conviviremos con el ventilador por ahora...&lt;br /&gt;
&lt;br /&gt;
&lt;strike&gt;He encontrado muchas quejas por foros, pero ninguna solución.&lt;/strike&gt; Gracias a Mr. Anónimo (ver comentarios) he resuelto el problema&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Se debe instalar &lt;a href="http://packages.ubuntu.com/hardy/i8kutils"&gt;i8kutils&lt;/a&gt; (la descripción del paquete es 'utilities for Dell Inspiron and Latitude laptops' pero funciona sin problemas en mi Vostro), y i8kfan nos va a permitir cambiar la velocidad del ventilador.&lt;br /&gt;
&lt;br /&gt;
Para que funcione hay que cargar el módulo (y añadirlo en /etc/modules para que lo cargue al arrancar)&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;sudo modprobe i8k&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
i8kfan admite 2 parámetros (para controlar 2 ventiladores), como este ordenador sólo tiene un ventilador, le pasamos -1 en el primer parámetro y en el segundo parámetro la velocidad (0, 1 o 2), aunque el 0 no funciona y en pocos segundos pasa al 2 (parece que la bios no permite pararlo).&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-small;"&gt;i8kfan -1 1&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Y por último añadimos un par de alarmas en el &lt;a href="http://sensors-applet.sourceforge.net/"&gt;sensors applet&lt;/a&gt; tal y como está explicado perfectamente en los comentarios.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Actualización 07-08-2011&lt;/b&gt;:&amp;nbsp; samsagax explica en los comentarios como monitorizar automáticamente con i8kmon sin necesidad de definir las alarmas. Gracias!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En resumen podría parecer que es un desastre de ordenador, igual es que soy muy sufrido, pero la verdad es que estoy bastante contento con él y seguiré comprando Dell a pesar de todos estos problemas :)</description><link>http://blog.diegorf.com/2011/04/instalando-ubuntu-en-vostro-3500.html</link><thr:total>20</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-8538740630926557343</guid><pubDate>Tue, 18 Jan 2011 00:11:00 +0000</pubDate><atom:updated>2011-01-18T09:18:40.233+01:00</atom:updated><title>Sobre la (in)competencia médica...</title><description>Aunque este blog normalmente sólo escribo de cosas técnicas, este tema me apetece explicarselo a la humanidad (bueno, a la infinitesima parte de la humanidad que lea esta entrada, que con lo larga que es será muy infinitesimal...)&lt;br /&gt;
&lt;br /&gt;
La historia empieza hace 15 ó 20 años, ya no recuerdo la fecha. Empecé a tener molestias en la articulación del femur con la cadera cuando me sentaba en mala postura o cuando forzaba más de la cuenta. Una vez la molestia fue a más y después de andar unos días cojo decidí ir al médico.&lt;br /&gt;
&lt;br /&gt;
Me hicieron una radiografía y me dijeron que tenía &lt;a href="https://secure.wikimedia.org/wikipedia/es/wiki/Calcificaci%C3%B3n"&gt;calcificación&lt;/a&gt; en la cabeza del femur y que tomara un &lt;a href="https://secure.wikimedia.org/wikipedia/es/wiki/Antiinflamatorio_no_esteroideo"&gt;antiinflamatorio no esteroide&lt;/a&gt;, concretamente &lt;a href="http://www.prospectos.net/airtal_comprimidos"&gt;Airtal&lt;/a&gt;. Al cabo de una semana se me quitó el dolor y me quedé con la idea de que tenía un defecto de fábrica en la pierna.&lt;br /&gt;
&lt;br /&gt;
A lo largo de estos años me ha ido molestando puntualmente y cuando iba a mayores me drograba un poco. Pero el problema apareció de nuevo en Enero del año pasado, en un intento fallido de aprender a esquiar, el primer día me molestó un poco la pierna, al segundo día andaba cojo y al tercer día cuando ya iba cojo de las dos piernas tuve que dejarlo.&lt;br /&gt;
&lt;br /&gt;
Fui al médico de cabecera, le conté la historia y me dijo que debía ser una &lt;a href="https://secure.wikimedia.org/wikipedia/es/wiki/Bursitis"&gt;bursitis&lt;/a&gt; y me dio antiinflamatorios, al igual que n años antes, esta vez &lt;a href="http://www.prospectos.net/enantyum_25_mg_comprimidos"&gt;Enantyum&lt;/a&gt;. A la semana siguiente volví porque no se me acababa de curar y me dió la solución mágica 'toma pastillas otra semana más', así que le pedí que me mandara a un especialista, ya que me preocupaba tantos días andando cojo y me dieron hora para radiografía y para especialista mes y medio despues.&lt;br /&gt;
&lt;br /&gt;
Un par de semanas despues empecé a correr un poco (uno de mis objetivos del 2010), y aunque eran entrenamientos muy cortos me empezó a molestar de nuevo la pierna.&lt;br /&gt;
&lt;br /&gt;
El día que fui al especialista me estuvo haciendo giros para ver donde me dolía y me dijo que no veía nada, que podía ser una &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Synovitis"&gt;sinovitis&lt;/a&gt; (que bien, ya llevamos tres problemas, calcificación, bursitis y sinovitis) o otro nombre que no recuerdo, me mando otras dos radiografías y hasta que tuviera el resultado reposo y si me dolía ibuprofreno.&lt;br /&gt;
&lt;br /&gt;
Al cabo de dos semanas volví al especialista, esta vez me tocó otro diferente, miró todas las radiografías y como ya no me dolía me dio la solución mágica:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;'No veo ningún problema en las radiografías, si te duele al correr, búscate un deporte que no te duela, y si te duele, tómate enantyum o ibuprofeno'.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
Ahí me di cuenta que llevaba más de dos meses perdiendo el tiempo para nada. Unos días después mi amiga &lt;a href="http://molimpop.com/"&gt;Marta&lt;/a&gt; me recomendo una &lt;a href="https://secure.wikimedia.org/wikipedia/es/wiki/Osteopat%C3%ADa"&gt;osteópata&lt;/a&gt; que conocía. Como no tenía nada que perder pedí hora, fuí con las radiografías y le explique mis penas.&lt;br /&gt;
&lt;br /&gt;
Mirando las radiografías me dijo que en el fémur no veía nada y que lo único que veía era una vértebra mal puesta. Así que después de tres sesiones de masajes (la primera de las cuales me dejó hasta un morado en la espalda colocando la columna vertebral en su sitio) ya estaba perfectamente de la pierna, sin absolutamente ninguna molestía en ninguna postura, cosa que no me pasaba hacía años.&lt;br /&gt;
&lt;br /&gt;
Volví a empezar a correr, y durante el año habré vuelto tres o cuatro veces más a darme masajes para recolocarme la espalda y con un pequeño problema de &lt;a href="https://secure.wikimedia.org/wikipedia/es/wiki/Fascitis_plantar"&gt;fascitis&lt;/a&gt; por no estirar lo suficiente &lt;br /&gt;
&lt;br /&gt;
y para entrar al 2011 con buen pie, corrí la San Silvestre con unos compañeros de trabajo, tal y como contó Dani Mata en &lt;a href="http://lohagopor.com/es/users/18-daniel-de-la-mata/challenges/24-san-silvestre-2010"&gt;LoHagoPor&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Y despues de este rollo llega el momento de la reflexión ya que si le hubiera hecho caso a la última doctora que ví, habría dejado de correr cuando ahora estoy saliendo 2 o 3 veces a correr por semana sin problemas.&lt;br /&gt;
&lt;br /&gt;
- ¿ Por qué los médicos lo arreglan todo recetando drogas ?&lt;br /&gt;
- ¿ Por qué son tan cuadriculados los médicos? a ninguno se le ocurrió buscar la causa real del problema en otro sitio, ¿no saben que el origen de un dolor no tiene que estar justo en el punto que duele?&lt;br /&gt;
- ¿ Por qué ninguno de los médicos me recomendó que me probara con un masaje? ¿Es que son profesiones enfrentadas? ¿Tienen miedo a que les quiten la clientela?&lt;br /&gt;
- ¿ Por qué ese aire de superioridad y esa prepotencia? si simplemente han estudiado una carrera que consiste en memorizar muchas cosas ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Afortunadamente voy muy poco al médico, y espero que si algún día me toca ir por un problema grave de verdad, no por un simple dolor de pierna, encontrarme otro tipo de médicos, que seguro que debe haberlos....</description><link>http://blog.diegorf.com/2011/01/sobre-la-incompetencia-medica.html</link><thr:total>7</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-656389688601079370</guid><pubDate>Wed, 22 Dec 2010 22:03:00 +0000</pubDate><atom:updated>2010-12-22T23:04:21.320+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">ckeditor</category><category domain="http://www.blogger.com/atom/ns#">imagemagick</category><category domain="http://www.blogger.com/atom/ns#">rmagick</category><title>Upload de ficheros con CKEditor</title><description>Hace unos días, en un proyecto en el que estamos usando &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt; para que los administradores puedan gestionar el contenido de la web, me pidieron añadir upload de imágenes.&lt;br /&gt;
&lt;br /&gt;
La opción más simple que encontré fue utilizar el plugin &lt;a href="https://github.com/galetahub/rails-ckeditor"&gt;rails-ckeditor&lt;/a&gt;, que integra la funcionalidad de subida de imágenes de una forma bastante elegante usando &lt;a href="http://www.swfupload.org/"&gt;SWFUpload&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Como siempre, en local funcionaba todo perfectamente, pero al instalar en la máquina de integración dio un poco de guerra.&lt;br /&gt;
&lt;br /&gt;
Para empezar, el primer problema fue con la versión de &lt;a href="https://github.com/rmagick/rmagick"&gt;RMagick&lt;/a&gt;, instalando la última versión disponible (2.13.1) me daba un bonito error&lt;br /&gt;
&lt;br /&gt;
&lt;span style="background-color: #f3f3f3; color: blue; font-size: x-small;"&gt;Updating installed gems&lt;br /&gt;
Updating rmagick&lt;br /&gt;
Building native extensions.&amp;nbsp; This could take a while...&lt;br /&gt;
ERROR:&amp;nbsp; Error installing rmagick:&lt;br /&gt;
ERROR: Failed to build gem native extension.&lt;br /&gt;
...&lt;br /&gt;
checking for ImageMagick version &amp;gt;= 6.4.9... no&lt;br /&gt;
Can't install RMagick 2.13.1. You must have ImageMagick 6.4.9 or later.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
El problema es que la máquina de integración tiene Ubuntu Hardy, y la versión de &lt;a href="http://packages.ubuntu.com/hardy/imagemagick"&gt;ImageMagick&lt;/a&gt; de Hardy es la 6.3.7:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;$ convert -version&lt;br /&gt;
Version: ImageMagick 6.3.7 06/04/09 Q16 http://www.imagemagick.org&lt;br /&gt;
Copyright: Copyright (C) 1999-2008 ImageMagick Studio LLC&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
Así que mirando en github las dependencias de la Rmagick en el fichero &lt;a href="https://github.com/rmagick/rmagick/blob/RMagick_2-12-2/ext/RMagick/extconf.rb"&gt;extconf.rb&lt;/a&gt; se encuentra que la última versión que se puede usar es la 2.12.2, actualizamos bundler y instalación superada.&lt;br /&gt;
&lt;br /&gt;
El siguiente problema aparece al probar la subida de imágenes y ver que da simplemente un alert de javascript, a veces con un 401 y otras con un 2038 sin ninguna más información.&lt;br /&gt;
&lt;br /&gt;
Mirando en el log de apache se encuentra el error&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;84.79.196.203 - - [11/Nov/2010:11:16:03 +0100] "POST /es/ckeditor/create/image?.... HTTP/1.1" 401 350 "-" "Shockwave Flash"&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
El problema es debido al Flash de subida de imágenes, que no es capaz de gestionar la autentificación básica del servidor de integración y da un &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.2"&gt;Unathorized&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
La solución, permitir el acceso a esa carpeta del servidor de integración en Apache añadiendo en el virtual host&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;  &lt;br /&gt;
&amp;lt;Location /*/ckeditor/create/image*&amp;gt;&lt;br /&gt;
Satisfy Any&lt;br /&gt;
Allow from all&lt;br /&gt;
&amp;lt;/Location&amp;gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
El * porque utilizamos el plugin &lt;a href="https://github.com/svenfuchs/routing-filter"&gt;routing filter&lt;/a&gt; para gestionar el multilenguaje. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;Y con estos dos pequeños cambios, prueba superada. Aquí lo dejo por si a alguien le sirve de ayuda....</description><link>http://blog.diegorf.com/2010/12/upload-de-ficheros-con-ckeditor.html</link><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-5442321282652936362</guid><pubDate>Mon, 15 Nov 2010 23:34:00 +0000</pubDate><atom:updated>2010-11-16T00:34:38.113+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">conferenciarails</category><title>Conferencia Rails 2010 - Impresiones</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4vYIpfxkkfbJnF7CGP4-NEHHxICbvW2U_ry-1p9q9g_gfV0c2BexvyccoJ6QOzKeSpuWnlWXkrx6IOIpncSfDoCSXt7AqaQb4TH5CYGnBmEM0hLBlidgfXMMzbBpRu92NfYvxDN3pP-jc/s1600/conferencia_rails.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4vYIpfxkkfbJnF7CGP4-NEHHxICbvW2U_ry-1p9q9g_gfV0c2BexvyccoJ6QOzKeSpuWnlWXkrx6IOIpncSfDoCSXt7AqaQb4TH5CYGnBmEM0hLBlidgfXMMzbBpRu92NfYvxDN3pP-jc/s320/conferencia_rails.jpg" width="216" /&gt;&lt;/a&gt;&lt;/div&gt;Retomo mi abandonado blog desde hace meses para hablar un poco de la &lt;a href="http://conferenciarails.org/"&gt;conferencia rails&lt;/a&gt; que se celebró en Madrid hace un par de semanas.&lt;br /&gt;
&lt;br /&gt;
No se como explicarlo, pero me ha dejado una sensación extraña esta conferencia. En las dos primeras que asistí, en 2007 y 2008, la mayoría de conferencias a las que fui estaban centradas exclusivamente en rails (funcionalidades, escalabilidad, buenas prácticas, ....) y en testing de aplicaciones desarrolladas con rails&lt;br /&gt;
&lt;br /&gt;
El año pasado cambió un poco la cosa, se introdujeron algunas charlas en inglés, se habló de las novedades (rack, sinatra, rails 3),&amp;nbsp; y se filosofó mucho sobre programación&lt;br /&gt;
&lt;br /&gt;
En cambio este año, tengo la impresión de que no se ha hablado practicamente nada de rails y no acabo de entender muy bien el motivo. Puede ser porque la comunidad rails española ya es bastante madura y interesa más explorar otros temas, que no se presentaran propuestas interesantes de charlas centradas en rails, pero no acabo de entenderlo, y de ahí esa sensación extraña de la conferencia (rails?) &lt;br /&gt;
&lt;br /&gt;
Aunque todas las charlas han sido en inglés, la mayoría de los asistentes eran locales, supongo que en parte debido a que en fechas muy cercanas, se ha celebrado la primera &lt;a href="http://rubyconfuruguay.org/"&gt;RubyConf Uruguay&lt;/a&gt; y la &lt;a href="http://rubyandrails.eu/"&gt;Ruby And Rails&lt;/a&gt; en Amsterdam&lt;br /&gt;
&lt;br /&gt;
A destacar las charlas sobre &lt;a href="http://www.slideshare.net/christkv/nodejs-and-ruby-5701395"&gt;node.js&lt;/a&gt; y de &lt;a href="http://joyeur.files.wordpress.com/2010/11/html5-web-sockets-ruby-nodejs-2010-11-05.pdf"&gt;WebSockets&lt;/a&gt;, que son temas a tener en vista y que pueden dar mucho juego dentro de un tiempo, y los siempre brillantes Pablo Delgado hablando de &lt;a href="http://www.slideshare.net/pablete/neo4j-for-ruby-and-rails"&gt;neo4j&lt;/a&gt; y Cavallé sobre &lt;a href="http://www.slideshare.net/cavalle/the-cqrs-diet"&gt;CQRS&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
A ver que nos depara la conferencia 2011... allí estaremos para verlo...</description><link>http://blog.diegorf.com/2010/11/conferencia-rails-2010-impresiones.html</link><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4vYIpfxkkfbJnF7CGP4-NEHHxICbvW2U_ry-1p9q9g_gfV0c2BexvyccoJ6QOzKeSpuWnlWXkrx6IOIpncSfDoCSXt7AqaQb4TH5CYGnBmEM0hLBlidgfXMMzbBpRu92NfYvxDN3pP-jc/s72-c/conferencia_rails.jpg" width="72"/><thr:total>5</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-8502332436953559164</guid><pubDate>Thu, 03 Jun 2010 18:39:00 +0000</pubDate><atom:updated>2010-11-15T23:34:13.973+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">euruko</category><category domain="http://www.blogger.com/atom/ns#">ruby</category><title>Euruko 2010</title><description>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyJshWhnH0tlt4sOED-ldpLVWToejDqUZpmqV6Dr1qD9MQJfTcepkgnn9pDz9OWzgF-HRTWI3RMouX7Zk7u6suEL3CMOp7PGr4hGwlrSndq_SVHmqcUdVbP98X7juZa5ay8IAONwS1_sA8/s1600/euruko_logo_final.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyJshWhnH0tlt4sOED-ldpLVWToejDqUZpmqV6Dr1qD9MQJfTcepkgnn9pDz9OWzgF-HRTWI3RMouX7Zk7u6suEL3CMOp7PGr4hGwlrSndq_SVHmqcUdVbP98X7juZa5ay8IAONwS1_sA8/s320/euruko_logo_final.gif" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Para no perder la costumbre, como cada vez que voy a una conferencia, unas notas sobre la &lt;a href="http://euruko2010.org/"&gt;European Ruby Conference&lt;/a&gt; de este año, que ha sido en Cracovia.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
En cuanto a las &lt;a href="http://euruko2010.org/agenda"&gt;charlas&lt;/a&gt;, por citar unas cuantas, son destacables:&lt;br /&gt;
- El keynote tardío de Matz&lt;br /&gt;
- Jose Valim con una charla algo filosófica sobre cuando usar &lt;a href="http://en.wikipedia.org/wiki/Domain-specific_language"&gt;DSL&lt;/a&gt;&lt;br /&gt;
- Karel Minařík, hablando sobre como enseñar a programar usando ruby&lt;br /&gt;
- Sven Fuchs explicando las novedades de i18n en Ruby&lt;br /&gt;
- Jason Goecke y su presentación de &lt;a href="http://tropo.com/"&gt;Tropo&lt;/a&gt;, para añadir voz a las aplicaciones&lt;br /&gt;
- Piotr Szotkowski y profiling en Ruby 1.9&lt;br /&gt;
- Florian Hanke que está desarrollando un buscador en ruby&lt;br /&gt;
- Florian Glicher contando como funciona el Character encoding in Ruby 1.9 &lt;br /&gt;
&lt;br /&gt;
&lt;strike&gt;(tengo que añadir links a todas las charlas, los añadiré en breve...)&amp;nbsp; &lt;/strike&gt;Los vídeos de las charlas están publicados en &lt;a href="http://www.vimeo.com/agilece"&gt;Vimeo&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
La representación española estuvo en las lightning talks, a cargo de &lt;a href="http://javier-ramirez.com/"&gt;javi&lt;/a&gt;, que nos contó como documentar usando las plantillas de las&lt;a href="http://guides.rails.info/"&gt; rails guides&lt;/a&gt; y anunció que la &lt;a href="http://conferenciarails.org/"&gt;Conferencia Rails&lt;/a&gt; de este año será en inglés, invitando a participar a los asistentes y de &lt;a href="http://www.fernandoguillen.info/"&gt;fernando guillén&lt;/a&gt;, con una de las presentaciones más aplaudidas y divertidas de toda la conferencia hablando de un &lt;a href="http://oneofzombies.com/"&gt;juego&lt;/a&gt; que hizo con &lt;a href="http://www.libgosu.org/"&gt;gosu&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Y de las que no vi, que fueron pocas, me supo mal perderme la de &lt;a href="http://tomash.wrug.eu/"&gt; Tomasz&lt;/a&gt;, que dio una gran charla el año pasado&lt;br /&gt;
&lt;br /&gt;
He encontrado estas notas de &lt;a href="http://twitter.com/cypher"&gt;@cypher&lt;/a&gt; sobre el &lt;a href="http://nuclearsquid.com/writings/euruko-day1.html"&gt;primer&lt;/a&gt; y &lt;a href="http://nuclearsquid.com/writings/euruko-day2.html"&gt;segundo&lt;/a&gt; día donde hay un resumen bastante completo de las conferencias &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Y comparando con &lt;a href="http://diec123.blogspot.com/2009/05/euruko-2009.html"&gt;Euruko 2009&lt;/a&gt;, me han gustado menos las charlas, el año pasado fueron mucho más variadas y tocaron muchos temas. En cambio, en las de este año, en casi todas tenía la impresión de que aunque ninguna hablaba de rails, casi todo era aplicable a rails, por lo que me llevo la sensación de que ha sido más monotemática, aunque no lo parezca por los contenidos.&lt;br /&gt;
&lt;br /&gt;
Tampoco me gustó que no se publicará ninguna información sobre las charlas aparte del título, aunque sólo había un track y no se podía elegir charlas, siempre es interesante saber de que van a ir...&lt;br /&gt;
&lt;br /&gt;
En cambio, las actividades 'extraescolares' fueron bastante mejores, con zumos, bebida y comida disponibles prácticamente durante todo el día, las conferencias en el centro de la ciudad de forma que nos pudimos mover a pie durante todo el fin de semana y un gran ambiente nocturno, donde el triunfador absoluto fue el &lt;a href="http://www.jazzrockcafe.pl/"&gt;Jazz Rock Cafe &lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Nos vemos en Berlin el año que viene en la &lt;a href="http://euruko2011.org/"&gt;Euruko 2011&lt;/a&gt;</description><link>http://blog.diegorf.com/2010/06/euruko-2010.html</link><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyJshWhnH0tlt4sOED-ldpLVWToejDqUZpmqV6Dr1qD9MQJfTcepkgnn9pDz9OWzgF-HRTWI3RMouX7Zk7u6suEL3CMOp7PGr4hGwlrSndq_SVHmqcUdVbP98X7juZa5ay8IAONwS1_sA8/s72-c/euruko_logo_final.gif" width="72"/><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-4367303019615001750</guid><pubDate>Wed, 28 Apr 2010 22:38:00 +0000</pubDate><atom:updated>2010-04-29T00:43:25.079+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">google</category><category domain="http://www.blogger.com/atom/ns#">maps</category><title>Actualizando Google Maps API de la v2 a la v3</title><description>Me ha tocado actualizar unos mapas que estaban utilizando la &lt;a href="http://code.google.com/apis/maps/documentation/index.html"&gt;versión 2&lt;/a&gt; de la API de Google Maps a la &lt;a href="http://code.google.com/apis/maps/documentation/v3/"&gt;versión 3&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Algunas de las novedades de la versión 3 son el soporte a iPhone y Android, mejora de la velocidad de carga, ya no es necesaria una clave de acceso y siguiendo la línea del resto de aplicaciones de Google ya no soporta IE6.&lt;br /&gt;
&lt;br /&gt;
La idea de este post es hacer una guía rápida de migración, con el código de la v2 y el equivalente de la v3, no he utilizado ninguna nueva funcionalidad.&lt;br /&gt;
&lt;br /&gt;
Suponiendo que tenemos definidas las variables &lt;i&gt;longitude&lt;/i&gt;, &lt;i&gt;latitude&lt;/i&gt;, &lt;i&gt;zoom_level&lt;/i&gt;, &lt;i&gt;image_path, html_content &lt;/i&gt;y &lt;i&gt;div_element&lt;/i&gt; (autoexplicativas todas)&lt;br /&gt;
&lt;br /&gt;
Primero de todo incluimos el JS de google, que ha pasado de&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;http://maps.google.com/maps?file=api&amp;amp;v=2&amp;amp;key=API_KEY&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
a &lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-small;"&gt;http://maps.google.com/maps/api/js?sensor=false&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Donde &lt;a href="http://code.google.com/apis/maps/documentation/#SpecifyingSensor"&gt;sensor&lt;/a&gt; indica si la aplicación utiliza un sensor para localizar al usuario.&lt;br /&gt;
&lt;br /&gt;
La creación de un mapa en la v2 era&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-small;"&gt;var myLatlng = new GLatLng(latitude, longitude)&lt;br /&gt;
map = new GMap2(div_element);&lt;br /&gt;
map.setCenter(myLatlng, zoom_level);&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Y en la nueva versión&lt;br /&gt;
&lt;div style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/div&gt;&lt;span style="color: blue; font-size: x-small;"&gt;var myLatlng = new google.maps.LatLng(latitude,longitude);&lt;br /&gt;
var myOptions = {&lt;br /&gt;
&amp;nbsp; zoom: zoom_level,&lt;br /&gt;
&amp;nbsp; center: myLatlng,&lt;br /&gt;
}&lt;br /&gt;
map = new google.maps.Map(div_element, myOptions);&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Por una parte se ha sustituido la &lt;i&gt;'G&lt;/i&gt;' del nombre de los objetos por el namespace &lt;i&gt;'google.maps&lt;/i&gt;.' y por otra parte, las propiedades se asignan a través de un objeto (myOptions en este caso) en lugar de utilizando métodos.&lt;br /&gt;
&lt;br /&gt;
Una vez creado el mapa, se le pueden cambiar / asignar nuevas propiedades con el método setOptions, p.e. los controles del mapa, que en la versión 2 se asignaban con&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: blue;"&gt;&lt;span style="font-size: x-small;"&gt;map.addControl(new GSmallMapControl());&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
Ahora se asignan&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;map.setOptions({&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; navigationControl: true,&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; navigationControlOptions: { style: google.maps.NavigationControlStyle.SMALL}&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;})&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt;
No es exactamente el mismo control, pero todavía no están implementados todos en la nueva versión.&lt;br /&gt;
&lt;br /&gt;
A la hora de crear un marcador con imagen personalizada pasamos de&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-size: x-small;"&gt;var icon = new GIcon(G_DEFAULT_ICON);&lt;br /&gt;
icon.image = image_path;&lt;br /&gt;
marker = new GMarker(new GLatLng(latitude, longitude), icon);&lt;br /&gt;
map.addOverlay(marker);&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
a&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;marker = new google.maps.Marker({&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; position: point,&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; map: map,&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; icon: image_path&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;});&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Igual que en la creación del mapa, por medio de un objeto pasamos todas las propiedades al marker.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Al borrar elementos de pantalla la cosa se complica. En la versión anterior simplemente llamando a &lt;span style="color: blue;"&gt;map.clearOverlays()&lt;/span&gt; limpiabamos el mapa. En la nueva versión hay que guardar la referencia a los objetos para borrarlos manualmente aplicando el método &lt;span style="color: blue;"&gt;setMap(null)&lt;/span&gt;. En la documentación hay un &lt;a href="http://code.google.com/apis/maps/documentation/v3/overlays.html#RemovingOverlays"&gt;ejemplo&lt;/a&gt; bastante completo &lt;br /&gt;
&lt;br /&gt;
Por último tambien ha cambiado tambien la creación de mensajes (bubbles), antes era:&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;var myLatlng = new GLatLng(latitude, longitude)&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;map.openInfoWindowHtml(myLatlng, html_content)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Y ahora&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-size: x-small;"&gt;&lt;span style="color: blue;"&gt;var myLatlng = new google.maps.LatLng(latitude,longitude);&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;var infowindow = new google.maps.InfoWindow({&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; content: html_content,&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; position: myLatlng&lt;/span&gt;&lt;br style="color: blue;" /&gt;&lt;span style="color: blue;"&gt;});&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Disclaimer: No he pretendido hacer una guía exhaustiva de migración, simplemente explicar los cambios que me aplicado migrando un mapa ya existente. Es posible que tanto la implementación anterior como la nueva no fueran de la forma más óptima o canónica, ya que como en la mayoría de las cosas, no soy experto en el tema....</description><link>http://blog.diegorf.com/2010/04/actualizando-google-maps-api-de-la-v2.html</link><thr:total>5</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-6865282952163312854</guid><pubDate>Mon, 29 Mar 2010 21:46:00 +0000</pubDate><atom:updated>2010-04-12T09:36:13.457+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">dell mini 10v</category><category domain="http://www.blogger.com/atom/ns#">moblin</category><category domain="http://www.blogger.com/atom/ns#">ubuntu</category><title>Ubuntu Remix Edition en Dell Mini 10v</title><description>Hace algo más de un mes compré un &lt;a href="http://www1.euro.dell.com/es/es/domestica/Port%C3%A1tiles/laptop-inspiron-10/pd.aspx?refid=laptop-inspiron-10&amp;amp;s=dhs&amp;amp;cs=esdhs1"&gt;Dell mini 10v&lt;/a&gt;. Viene con Windows 7 starter y con 1GB de RAM y al ver lo lento que iba todo, lo que tardaba en arrancar, ... decidí formatearlo y instalarle Linux.&lt;br /&gt;
&lt;br /&gt;
Dell tiene algunos modelos con Ubuntu, así que buscando un poco encontré que tienen una versión de &lt;a href="http://moblin.org/"&gt;Moblin&lt;/a&gt; para descargar en su &lt;a href="http://en.community.dell.com/wikis/linux/ubuntu-9-04-moblin-remix-developer-edition.aspx"&gt;wiki&lt;/a&gt;, que se instala sin ningún problema desde USB y que funciona perfectamente.&lt;br /&gt;
&lt;br /&gt;
Eso si, despues de unas semanas de uso no me convenció la interfaz gráfica de Moblin, no me parece cómoda de usar, así que decidí instalar &lt;a href="http://www.ubuntu.com/GetUbuntu/download-netbook"&gt;Ubuntu Remix Edition&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Una vez instalado todo funciona perfectamente, todo... menos la wi-fi... que es una Broadcom BCM4312 (se puede ver el modelo con lspci). Parece que no se instala el driver por defecto porque es un controlador no libre suministrado por el fabricante&lt;br /&gt;
&lt;br /&gt;
Y para instalar el driver, de nuevo buscando un poco, en la sección de &lt;a href="https://help.ubuntu.com/community/WifiDocs"&gt;WifiDocs&lt;/a&gt; de la ayuda de Ubuntu hay una &lt;a href="https://help.ubuntu.com/community/WifiDocs/Driver/bcm43xx"&gt;página&lt;/a&gt; donde lo explica todo paso a paso.&lt;br /&gt;
&lt;br /&gt;
Simplemente hay que instalar un par de paquetes (dkms y patch, tambien dicen que hace falta fakeroot pero a mi me funcionó sin instalarlo), instalar bcmwl-kernel-source y habilitar el controlador privativo&lt;br /&gt;
&lt;br /&gt;
Y si os pasa como a mi, que a mi router wi-fi le han dejado de funcionar los puertos ethernet para poder conectarlo directamente, pues os tocará bajaros los ficheros desde otro ordenador uno a uno desde la web de &lt;a href="http://packages.ubuntu.com/karmic/"&gt;ubuntu&lt;/a&gt; y luego instalarlos a mano...&lt;br /&gt;
&lt;br /&gt;
Eso es todo, relativamente sencillo y realmente me gusta mucho más el entorno de Ubuntu Remix Edition que el de Moblin y va mucho más rápido que con Windows.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;ACTUALIZACIÓN 12/04/2010&lt;/b&gt;: En los comentarios me recomiendan &lt;a href="http://www.jolicloud.com/"&gt;Jolicloud&lt;/a&gt;, no lo he probado, pero tiene buena pinta. Gracias por la sugerencia!</description><link>http://blog.diegorf.com/2010/03/ubuntu-remix-edition-en-dell-mini-10v.html</link><thr:total>1</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-4252923882731502123</guid><pubDate>Sat, 27 Feb 2010 10:45:00 +0000</pubDate><atom:updated>2010-02-27T12:38:40.393+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">event delegation</category><category domain="http://www.blogger.com/atom/ns#">javascript</category><category domain="http://www.blogger.com/atom/ns#">prototype</category><title>Event Delegation en Javascript</title><description>Hace unos días haciendo una página que básicamente es un listado con 3 radio buttons por fila (si, &lt;a href="http://twitter.com/porras"&gt;porras&lt;/a&gt;, aunque en tu &lt;a href="http://github.com/porras/madrid-rb-feb-2010"&gt;charla&lt;/a&gt; del &lt;a href="http://groups.google.com/group/madrid-rb"&gt;madrid-rb&lt;/a&gt; del jueves dijeras que no sabes para que se usan, a veces son útiles), quería que se enviara el formulario al seleccionar uno de los radio-buttons sin tener que pulsar en submit.&lt;br /&gt;
&lt;br /&gt;
Para hacerlo un poco limpio, lo hice con&lt;a href="http://en.wikipedia.org/wiki/Unobtrusive_JavaScript"&gt; javascript no intrusivo&lt;/a&gt; y &lt;a href="http://www.prototypejs.org/"&gt;prototype&lt;/a&gt; de la siguiente forma, donde cada uno de los input tiene definida la clase radio_submit&lt;br /&gt;
&lt;br /&gt;
&lt;div style="color: blue; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;span style="font-size: x-small;"&gt;document.observe("dom:loaded", function() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $$('input.radio_submit').each(function(item) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; item.observe('click', function() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; item.parentNode.submit();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; });&lt;br /&gt;
});&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
Pero no me gustaba esa solución donde tengo 3 function anidados, así que le pedí consejo a &lt;a href="http://twitter.com/pacoguzman"&gt;Paco&lt;/a&gt; a ver si se le ocurría una mejor solución.&lt;br /&gt;
&lt;br /&gt;
Y evidentemente había una solución mejor, basada en Event Delegation&lt;br /&gt;
&lt;br /&gt;
&lt;span style="color: blue; font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace; font-size: x-small;"&gt;document.observe("dom:loaded", function() {&lt;br /&gt;
&amp;nbsp; $('user_source_list').observe('click', function(event){&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; var element = event.target;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; if (element.match('input.radio_submit')){&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; element.up('form').submit();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp; });&lt;br /&gt;
});&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
La idea es que en lugar de crear un evento en cada uno de los elementos, se crea sólo un evento en un objeto que los contiene a todos (en este caso es un div con el id 'user_source_list'), y capturamos el click sobre ese objeto.&lt;br /&gt;
&lt;br /&gt;
Otra mejora que me propuso es que en lugar de usar parentNode para ir al elemento padre usara &lt;a href="http://www.prototypejs.org/api/element/up"&gt;up('form')&lt;/a&gt;, de esa forma, si cambia el diseño de la página y se introduce algún elemento intermedio en el dom de la página, el código seguirá funcionando.&lt;br /&gt;
&lt;br /&gt;
Paco tambien me pasó este &lt;a href="http://github.com/rails/prototype-ujs/blob/master/src/rails.js"&gt;enlace&lt;/a&gt; donde se ve como en &lt;a href="http://guides.rails.info/3_0_release_notes.html"&gt;Rails 3&lt;/a&gt; se utilizará la misma técnica de javascript no intrusivo con delegación de eventos.</description><link>http://blog.diegorf.com/2010/02/event-delegation-en-javascript.html</link><thr:total>8</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-2461576666827389205.post-8160749886482814784</guid><pubDate>Mon, 18 Jan 2010 16:29:00 +0000</pubDate><atom:updated>2010-11-15T23:37:12.358+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">rails charla beruby</category><title>Notas sobre webs un poco grandes</title><description>En &lt;a href="http://www.aspgems.com/"&gt;ASPgems&lt;/a&gt; desde hace bastante tiempo vamos dando charlas internas para compartir el conocimiento entre nosotros, y desde hace unos meses las charlas son abiertas a todo el que quiera apuntarse.&lt;br /&gt;
&lt;br /&gt;
Las charlas se publican en el &lt;a href="http://blog.aspgems.com/"&gt;blog&lt;/a&gt; y en &lt;a href="http://twitter.com/aspgems"&gt;twitter&lt;/a&gt; y la inscripción es en &lt;a href="http://aspgems.stagehq.com/"&gt;stage&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
La última charla me ha tocado a mi, en la que he hablado un poco sobre mi experiencia durante más de dos años desarrollando &lt;a href="http://www.beruby.com/"&gt;BeRuby&lt;/a&gt;, un proyecto que ha pasado en este tiempo a ser el mayor proyecto de &lt;a href="http://rubyonrails.org/"&gt;Rails&lt;/a&gt; en España y entre los 40 mayores del mundo (según en ranking de Alexa en la lista de &lt;a href="http://rails100.pbworks.com/Alexa+Rankings"&gt;rails100&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
Repasando la presentación me he dado cuenta de que hablé muy poquito de Rails y mucho de MySQL, así que va a ser que uno de los puntos más importantes a la hora de escalar es un buen diseño y uso de base de datos, por mucho que las malas lenguas digan por ahí que Rails no escala :-)&lt;br /&gt;
&lt;br /&gt;
La presentación tambien se grabó en vídeo (es la primera que grabamos y todavía está pendiente de retocar porque el audio no se oye muy bien), así que por ahora publico las transparencias, aunque sin la explicación algunas páginas no aportan mucho ....&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;iframe frameborder="0" height="451" src="http://docs.google.com/present/embed?id=ddswt7rh_0g4mv4hgz&amp;amp;size=m" width="555"&gt;&lt;/iframe&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
De todas formas, entre nosotros, el orador no se puede decir que sea un comunicador nato, así que no espereis una gran charla cuando se publique el vídeo.... eso si, si hay cualquier duda o sugerencia sobre la presentación, aquí estoy para contestarla.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
NOTA: La charla al final se publicó en el canal de &lt;a href="http://vimeo.com/channels/aspgems"&gt;Vimeo&lt;/a&gt; de ASPgems</description><link>http://blog.diegorf.com/2010/01/notas-sobre-webs-un-poco-grandes.html</link><thr:total>0</thr:total><author>noreply@blogger.com (Diego Rodriguez)</author></item></channel></rss>