"Después del juego es antes del juego"
Sepp Herberger

sábado, 14 de mayo de 2016

Dos funciones puppet para instalar paquetes debian.

Muchas veces queremos instalar un paquete en nuestro Linux controlado por puppet y resulta que este paquete no está dentro de los repositorios ya que no es un paquete "oficial", por lo que no podemos usar el recurso package.

En ese caso, la tarea puppet debe llevar el fichero .deb hasta la máquina cliente y luego instalarlo, usando varios "exec" de puppet encadenados. Esto con el tiempo es tan frecuente que he decidido hacer un par de funciones para implementarlo y poder usarlo de forma cómoda.

Vamos allá, el primer define lo he llamado "instala_paquete_local", que coge el paquete ".deb" del directorio "files" del módulo desde donde se invoca la función. En los parámetros decimos el nombre del paquete, su versión y el .deb que lo contiene y la función se encarga de copiar el paquete al cliente e instalarlo si no estaba ya instalado.

root@servidor:/etc/puppet/defines# cat instala_paquete_local.pp 

#Coge un paquete .deb del directorio files del modulo desde donde se llama el define y se instala en el equipo si no está.
# $title = nombre del paquete
# $version = versión del paquete
# $paquete = nombre completo del paquete

#Ejemplo uso dentro de un módulo de /etc/puppet/modules/nombre-modulo/manifests/init.pp:
#   instala_paquete_local {"brother-udev-rule-type1":
#       version=>"1.0.0-1",
#       paquete=>"brother-udev-rule-type1-1.0.0-1.all.deb",
#   }
#El fichero brother-udev-rule-type1-1.0.0-1.all.deb estaría en /etc/puppet/modules/nombre-modulo/files/


define instala_paquete_local($version,$paquete) {

       #$caller_module_name es una builtin variable que identifica el modulo llamante del define

       file {"descarga_$title":
                path => "/var/cache/$paquete",
                owner => root, group => root, mode => 644,
               source => "puppet:///modules/$caller_module_name/$paquete",
                notify => Exec["instala_$title"]
       }
      
       exec { "instala_$title":
              path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
              command => "lsof /var/lib/dpkg/lock || (dpkg -i --force-architecture /var/cache/$paquete; apt-get -y -f install)",
              refreshonly => true,
              unless => "dpkg -l |grep $title | grep $version | grep ^ii",
              require => File["descarga_$title"]
       }

}
El segundo define lo he llamado "instala_paquete_web", ya que descarga el paquete ".deb" de una URL que le indicamos como parámetro, siendo el resto de parámetros iguales al caso anterior.
 root@servidor:/etc/puppet/defines# cat instala_paquete_web.pp 
#Descarga un paquete desde una URL web y lo instala si no está instalado en el equipo.
# $title = nombre del paquete
# $version = versión del paquete
# $url = url de descarga

#Ejemplo uso dentro de un módulo de /etc/puppet/modules/nombre-modulo/manifests/init.pp:
#   instala_paquete_web {"brother-udev-rule-type1":
#       version=>"1.0.0-1",
#       url=>"http://servicor-web/ficheros/puppet/brother-udev-rule-type1-1.0.0-1.all.deb",
#   }


define instala_paquete_web($version,$url) {

       exec { "descarga_$title":
           path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
           command => "wget -q $url -O /var/cache/$title.deb",
           unless => "dpkg -l | grep $title | grep $version | grep ^ii",
           notify => Exec["instala_$title"]
       }

       exec { "instala_$title":
              path => "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
              command => "lsof /var/lib/dpkg/lock || (dpkg -i --force-architecture /var/cache/$title.deb; apt-get -y -f install)",
              unless => "dpkg -l |grep $title | grep $version | grep ^ii",
              refreshonly => true,
              require => Exec["descarga_$title"]
       }

}

Unos cuantos comentarios:

1) Las dos funciones: junto con el resto de funciones que ya tengamos, estarán /etc/puppet/defines/... del servidor puppet.
2) Si tenemos pkgsync en los clientes no olvidar poner el paquete instalado en el mayhave del cliente.
3) El "lsof /var/lib/dpkg/lock" sirve para comprobar que no está en marcha ningún proceso sobre el sistema de paquetes, asegurando así que la instalación se realiza sin errores.

Bueno, pues a instalar, a instalar, que el mundo se va a acabar.

No hay comentarios:

Publicar un comentario