Quelqu'un peut-il m'expliquer comment fonctionne le chef? C'est une question assez large, donc pour la réduire, j'ai cette recette très simple qui fait une boucle sur une liste d'utilisateurs et crée chacun d'eux s'ils n'existent pas déjà. Ça ne marche pas.
D'après ce que je peux dire, la boucle semble se produire comme je m'y attendais. Une fois la boucle terminée, mes commandes bash pour créer chaque utilisateur sont exécutées, une fois pour chaque itération de la boucle. Cependant, lorsque les commandes bash sont exécutées, elles ne semblent avoir la valeur utilisateur qu'à partir de la première itération de boucle.
Quelle est la bonne façon d'écrire une recette qui boucle sur des données variables similaires à cet exemple?
Voici la recette:
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
Je teste cela en utilisant Vagrant avec la configuration suivante:
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
Les messages générés par les instructions put dans la recette ressemblent à ceci:
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
Le comportement que vous voyez peut être expliqué en comprenant la différence entre deux des étapes clés d'une exécution client Chef: la compilation et la convergence.
Pendant la phase de "compilation", le client Chef exécute le code dans vos recettes pour créer une collection de ressources . Il s'agit d'une liste des ressources que vous avez demandé à Chef de gérer sur votre système, ainsi que leur état cible. Par exemple, une ressource d'annuaire pour dire qu'elle
/tmp/foo
devrait exister et appartenir à root:Pendant la phase de "convergence", le client Chef utilise des fournisseurs pour charger l'état actuel de chaque ressource, puis le compare à l'état cible. S'ils sont différents, Chef mettra à jour le système. Pour notre ressource Annuaire, Chef créerait l'annuaire s'il n'existait pas et changerait son propriétaire en "root" si nécessaire.
Les ressources sont identifiées de manière unique par leur nom et leur type - ce serait notre répertoire
directory[/tmp/foo]
. Des choses étranges se produisent lorsque vous avez deux ressources avec le même nom mais des attributs différents - cela explique votre problème, et il peut être résolu en utilisant la réponse de Darrin Holst:Cependant, dans ce cas particulier, vous auriez avantage à utiliser la ressource Utilisateur de Chef. Voici un remplacement pour votre recette (sans les messages de débogage):
Pourquoi est-ce mieux qu'un ensemble de ressources bash?
Mais la meilleure raison d'utiliser les bonnes ressources est qu'elle communique plus clairement votre intention. Votre objectif n'est probablement pas d'exécuter un tas de commandes shell - c'est de vous assurer que certains utilisateurs sont présents sur votre système. Les commandes utilisées pour ce faire ne sont qu'un détail d'implémentation.
Les fournisseurs résument ces détails, nous laissant libres de nous concentrer sur la description de ce que nous voulons.
la source