Python

Hoy decidí escribir sobre Python

Para empezar este lenguaje lo llevo 3 semanas usando en el trabajo y para mi tesis lo use para generar la tablas de Latex de los resultados. Hasta los momentos me ha parecido excelente. Considero que es justamente para una de las cosas que fue creado: scripting. Tiene un sintaxis muy simple y que a su vez lo hace ser bastante entendible, además de tener un montón de librerías con muchas cosas hechas. Ahora cosas resaltantes que decir:

  • Es interpretado y su máquina virtual está escrita en C, en líneas generales es un lenguaje relativamente rápido. Además hay diversas herramientas para mejorar el código bien sea optimizando o compilando a otro lenguaje de bajo nivel el código.
  • Tiene muchas cosas ya hechas
  • No hay chequeo estático de tipos, lo cual es una ventaja y desventaja. Te permite hacer cosas interesantes con el lenguaje, pero hace el código más difícil de mantener
  • Obliga a identar el código, cosa que me parece genial
  • Se pueden escribir cosas bastante complejas con pocas líneas
  • El manejo de memoria es automático
  • Es orientado a objetos
  • Tiene diversas cosas de los lenguajes funcionales para las listas (map, fold)

Ahora comento de mi experiencias:

  1. La primera vez que la use fue para crear un script que leyera una base de datos de sqlite y generara diversos archivos .tex con tablas de Latex. Esto hacerlo en algo estilo C, Java, C++ era muchas líneas de código. En Python me tomó unas 200 líneas. Ya tengo el módulo para conectarme a sqlite, el manejo de strings es muy fácil, del mismo modo lo que uno puede hacer con los arreglos. Simplemente cree ciertos arreglos y una función que se le pasaban diversos valores y extraía lo que quería de la base de datos. A medida que hacía eso simplemente iba concatenando los datos en strings con el formato de la tabla latex y los escribía a un archivo. Super simple.
  2. En el trabajo uso Django y acá uno ve muchas cosas del potencial del lenguaje. Recomiendo mucho este framework para hacer páginas, es muy potente. Al estar tocando el código he podido notar muchas cosas interesantes del lenguaje: se pueden hacer funciones con número de parámetros variable (estilo printf de C), crear listas por comprensión (este nombre lo tome así de como lo nombran en un artículo que ando leyendo que  coloque al final).

En fin échenle un ojo, este lenguaje es muy usado por google (solo conozco su uso en páginas web por parte de ellos),  y recomiendo este artículo que estoy leyendo de como optimizar el código de python, que pienso que a su vez enseña parte de como funciona el lenguaje.

http://wiki.python.org/moin/PythonSpeed/PerformanceTips

Advertisements

Configurando diversas máquinas virtuales y vigilarlas con puppet

Este sera mi primer post,

Les explico en el trabajo, producción consta de diversas máquinas (usan ubuntu), en las cuales corren diversas cosas:

nginx

haproxy

uwsgi

python

Usualmente ocurren problemas que hacen que se caiga todo y eso causa mucha molestia, ya que la mayoría de las cosas para levantarlas de vuelta, es necesario hacerlo mano.

Por ello se decidió usar alguna herramienta de administración automática, pero primero se tenía que montar el ambiente de pruebas. Se uso VirtualBox.

Se hizó lo siguiente:

  1. Se creó una imagen base
  2. La máquina donde se colocan las máquinas virtuales no tiene X, por lo que todo se hizo por cónsola, cosa que era necesaria ya que la idea es hacer un shell script que teniendo la imagen base cree el resto de las cosas. En las máquinas creadas se agregó la clave pública, que es la misma en todas las máquinas creadas, en .ssh/authorized_keys de forma que no preguntara el password a la hora de usar ssh y además se quitó la necesidad de tener que colocar clave para hacer sudo. Tardó un buen rato ver la manera más eficaz y sencilla de crear las cosas mediante VirtualBox (se copia el disco duro, el archivo .vdi),  además lograr darle las capacidad de que tomen ip propia de la red usando la configuración bridged . El problema es que hay que eliminar un archivo en /etc/udev/rules.d/70-net… (no me acuerdo bien), de forma que tomaran una macadress única y el servidor dhcp diera ip distintas. Luego cada una se le agregan los hosts a /etc/hosts para que cada una se comunicara con las otra sin la necesidad de colocar alguna ip.
  3. A cada máquina se le creo un script que la configurar con las consas necesarias. También se tuvo que crear 3 servicios, que reiniciaran diversas cosas que no corren como demonios, eso también robó un buen rato, la mejor forma de correr programas como demonios es start-stop-daemon, permite darle toda la configuración necesaria.
  4. Ya con las máquinas corriendo las cosas, la tarea era ver que herramienta usar para la administración automática usar. Existen varias. Se empezó a leer de CFEngine, la cual es conocida y es muy capaz. Estuve un buen rato leyendo su documentación y todo el mundo la pintaba como una maravilla, cosa que no dudo. Pero debo decir que la documentación es muy básica y mala, no me agradó en nada. El lenguaje de programación que usa, está basado en la teoría de promesas. Éste es no intuitivo y complicado en su forma de uso. Tiene cosas muy complejas que se pueden hacer con el. Pero lo que menos me gustó, fue que todos los ejemplos que conseguí eran para probar y no lo que buscaba:  algo que estuviera cada cierto tiempo vigilando el sistema y lo recuperará, avisando de todas formas que paso algo.  Leí y si tiene la capacidad, pero no conseguí un ejemplo práctico.
  5. Al ver no lograr nada, decidí tomar otro camino usando otra herramienta. Me tope con otras dos muy usadas: chef y puppet. Ambas están escritas en ruby. Busque full información de ambas. Unos amaban chef y otro puppet. A la final tome la decisión de usar puppet por diversas razones: el lenguaje es MUY fácil, es MUY usado y esta apoyado por google y otras compañías. Chef recién salió, y fue creado por una persona que estuvo involucrado con puppet, pero sentía que le faltaba.  Me parece algo complejo también además, y por no se muy viejo, podía tener falta de documentación.

Configurando puppet

Puppet es super fácil de configurar. Su arquitectura consta de dos componentes:

  • Servidor(es) maestro(s)
  • Cliente(s)

Lo primero es instalar las cosas en cada máquina.

Configurando el servidor maestro

Instala lo siguiente:

aptiude install puppetmaster

Luego edita el archivo /etc/puppet/fileserver.conf agregando que direcciones de ips quieres permitir.

Een mi caso: allow 192.168.24.0/24. (ejecuté el comando sed -i ’12s/#  allow 192.168.0.0\/24/allow 192.168.24.0\/24/’  /etc/puppet/fileserver.conf)

Finalmente a edita /etc/puppet/puppet.conf y agrega al final las siguientes líneas:

certname=servidormaestro

autosign=false

Ésta última anda por default, pero para estar seguro. Eso es para que se tenga que certificar a los nodos.

Configurando los clientes

Instala lo siguiente:

sudo apitude install puppet

Luego edita el /etc/puppet/puppet.conf

En la sección [main] agrega

server=servidormaestro

runinterval=segundos

Se puede ejecutar:

sudo sed -i '/\[main\]/a\server=servidormaestro' /etc/puppet/puppet.conf
sudo sed -i '/server=servidormaestroa\runinterval=60' /etc/puppet/puppet.con

Y agrega la siguiente sección:

[agent]

certaname=nombre del cliente

Puedes ejecutar:

sudo sh -c "echo \"[agent]\ncertname=${NAME}\" >> /etc/puppet/puppet.conf"

Ésta última para indicar cada cuantos segundos uno quiere que puppet se ejecute.

Recuerda ejecutar lo siguiente:

sudo sed -i 's/START=no/START=yes/g' /etc/default/puppet

Agregando los certificados

Luego de un rato los clientes hacen una petición al sevidor y se va a emitir un falló. Éste sucede porque puppet usa certificados y el servidor debe agregar a los clientes. Para ello primero en los clientes ejecuta:

sudo service puppet stop
sudo puppetd --waitforcert 30 -v
sudo service puppet start

Después en el servidor

for mc in `sudo puppetca --list | sed 's/([A-Z0-9:]*)//g'`
do
 sudo puppetca --sign ${mc}
do

Probando

En el servidor crea las carpetas /etc/puppet/modules/nginx/manifests (sudo mkdir -p /etc/puppet/modules/nginx/manifests) . Ahí crea el archivo init.pp (si tiene que ser este nombre sino no lo importa). Si quieres colocarle el nombre que desee debes importarlo así include ngnix::nombre y tener el archivo dentro de /etc/puppet/modules/nginx/manifests

Ahí coloca lo siguiente:

class nginx
{
 package
 {
    "nginx":
     ensure => installed
 }
 service
 {
     "nginx":
     ensure => running,
     hasrestart => "true",
     enable => "true",
 }
}

Luego en /etc/puppet/manifests crea dos archivos nodes.pp y site.pp (ambos son convención de puppet)

En nodes colocas como el va a mapear los nodos que se conoecten. Supongamos que la máquina que queremos que reinicie el nginx si se cae se llama, clienteweb. Para ello se coloca lo siguiente en el archivo:

node /^clienteweb/
{
 include nginx
}

Algo muy bueno es que se pueden colocar expresiones regulares, lo que facilita muchísimo.

Finalmente en site.pp colóca lo siguiente:

import "nodes.pp"

Ahora procede a probar que las cosas anden bien, para ellos puede tumbar el servicio puppet y correr puppetd -t, que es para hacer pruebas. Algo muy bueno ademas es que puppet tiene opción de debugeo (-debug), cosa fenomenal.

En teoría si configuraste todo como debías si tumbas los sevicios en clienteweb, despues del tiempo que colocaste, este debe reiniciarse.

Espero que esto sea de ayuda,  hasta luego