¿Puede alguien explicarme cómo funciona el chef? Esa es una pregunta bastante amplia, así que para reducirla tengo esta receta muy simple que recorre una lista de usuarios y crea cada uno si aún no existen. No funciona.
Por lo que puedo decir, el ciclo parece estar sucediendo como era de esperar. Una vez que el ciclo se ha completado, se ejecutan mis comandos bash para crear cada usuario, una vez para cada iteración en el ciclo. Sin embargo, cuando se ejecutan los comandos bash, solo parecen tener el valor de usuario de la primera iteración del bucle.
¿Cuál es la forma correcta de escribir una receta que recorra datos variables similares a este ejemplo?
Aquí está la receta:
node[:users].each do |user|
puts "in loop for #{user['username']}"
bash "create_user" do
user "root"
code do
puts "running 'useradd' for #{user['username']}"
"useradd #{user['username']}"
end
not_if do
puts "checking /etc/passwd for #{user['username']}"
"cat /etc/passwd | grep #{user['username']}"
end
end
end
Estoy probando esto usando Vagrant con la siguiente configuración:
Vagrant::Config.run do |config|
config.vm.box = "precise32"
config.vm.box_url = "http://files.vagrantup.com/precise32.box"
config.vm.provision :chef_solo do |chef|
chef.add_recipe "sample"
chef.json = {
:users => [
{:username => 'testA'},
{:username => 'testB'},
{:username => 'testC'},
{:username => 'testD'},
{:username => 'testE'},
],
}
end
end
Los mensajes que generan las declaraciones de venta en la receta tienen este aspecto:
2013-03-08T01:03:46+00:00] INFO: Start handlers complete.
in loop for testA
in loop for testB
in loop for testC
in loop for testD
in loop for testE
[2013-03-08T01:03:46+00:00] INFO: Processing bash[create_user] action run (sample::default line 5)
checking /etc/passwd for testA
[2013-03-08T01:03:46+00:00] INFO: Processing bash[create_user] action run (sample::default line 5)
checking /etc/passwd for testA
[2013-03-08T01:03:46+00:00] INFO: Processing bash[create_user] action run (sample::default line 5)
checking /etc/passwd for testA
[2013-03-08T01:03:46+00:00] INFO: Processing bash[create_user] action run (sample::default line 5)
checking /etc/passwd for testA
[2013-03-08T01:03:46+00:00] INFO: Processing bash[create_user] action run (sample::default line 5)
checking /etc/passwd for testA
[2013-03-08T01:03:46+00:00] INFO: Chef Run complete in 0.026071 seconds
El comportamiento que está viendo puede explicarse al comprender la diferencia entre dos de las etapas clave en una ejecución de cliente Chef: compilación y convergencia.
Durante la fase de "compilación", el cliente Chef ejecuta el código en sus recetas para construir una colección de recursos . Esta es una lista de los Recursos que le ha dicho a Chef que administre en su sistema, junto con su estado objetivo. Por ejemplo, un recurso de Directorio para decir que
/tmp/foo
debería existir y ser propiedad de root:Durante la fase de "convergencia", el cliente Chef utiliza proveedores para cargar el estado actual de cada recurso, luego lo compara con el estado objetivo. Si son diferentes, Chef actualizará el sistema. Para nuestro recurso Directorio, Chef crearía el directorio si no existiera, y cambiaría su propietario a "raíz" si fuera necesario.
Los recursos se identifican de manera única por su nombre y tipo, sería nuestro Directorio
directory[/tmp/foo]
. Sucederán cosas extrañas cuando tenga dos recursos con el mismo nombre pero con atributos diferentes, eso explica su problema y se puede solucionar con la respuesta de Darrin Holst:Sin embargo, en este caso particular, se beneficiaría de utilizar el recurso de usuario de Chef. Aquí hay un reemplazo para su receta (sin los mensajes de depuración):
¿Por qué es esto mejor que un conjunto de recursos bash?
Pero la mejor razón para usar los recursos correctos es que comunica más claramente su intención. Su objetivo probablemente no sea ejecutar un montón de comandos de shell, es asegurarse de que algunos usuarios estén presentes en su sistema. Los comandos utilizados para hacer eso son solo un detalle de implementación.
Los proveedores encapsulan esos detalles, dejándonos libres para centrarnos en describir lo que queremos.
fuente