Voici mon code:
if !::File.exist?("#{node['iis']['home']}\\backup\\BkpB4Chef")
windows_batch "Backup IIS Config" do
code <<-EOH
"#{node['iis']['home']}"\\appcmd add backup BkpB4Chef
EOH
end
end
Il indique toujours que le fichier existe et exécute la boucle.
Vous devez utiliser chefs de garde ici. Les gardes spécifient l'exécution conditionnelle, mais insèrent toujours la ressource dans la collection de ressources. Dans votre exemple et votre réponse jtblin, la ressource n'est jamais ajoutée à la collection (que j'expliquerai un peu plus loin dans un instant).
Voici un code de travail pour vous aider à démarrer:
windows_batch "Backup IIS Config" do
code %Q|#{node['iis']['home']}"\\appcmd add backup BkpB4Chef|
not_if { ::File.directory?("#{node['iis']['home']}\\backup\\BkpB4Chef") }
end
creates
De nombreuses ressources Chef non idempotentes prennent également en charge un paramètre creates
, qui explique ce que fait la ressource. En d'autres termes, qu'est-ce que le windows_batch
"créer". Il peut s'agir d'un fichier, d'un répertoire ou d'un exécutable. Ainsi, le code suivant est équivalent à l'ancienne réponse.
windows_batch "Backup IIS Config" do
code %Q|#{node['iis']['home']}"\\appcmd add backup BkpB4Chef|
creates"#{node['iis']['home']}\\backup\\BkpB4Chef"
end
not_if
vs l'encapsuleur conditionnelChef s'exécute en deux phases - la phase de compilation et la phase de convergence. Pendant la phase de compilation, les recettes sont évaluées et les ressources sont ajoutées à la collection de ressources. Dans la phase de convergence, les ressources de la collection de ressources sont exécutées et évaluées par rapport au système cible. Considérez donc l'exemple suivant:
if false
service 'foo' do
action :start
end
end
Il s'agit d'une recette assez simple qui démarre un service basé sur certaines conditions. Cependant, à la fin de la phase de compilation, la ressource service
n'est pas ajoutée à la collection de ressources. Puisque la recette DSL est instance_eval
ed, l'emballage if false
conditionnel empêche ce code d'être lu par la machine virtuelle Ruby. En d'autres termes, c'est comme si ce service n'existait jamais.
Il est assez courant de notifier les ressources. Plus loin dans la recette, vous souhaiterez peut-être redémarrer Apache en raison d'un changement de configuration. La façon "appropriée" de procéder consiste à utiliser les notifications:
template '/var/www/conf.d/my.conf.file' do
# ...
notifies :restart, 'service[Apache2]'
end
Ce template
ne peut pas notifier correctement la ressource de service, car il n'existe pas dans la collection de ressources. Cette recette échouera donc. Cela semble être un exemple trivial, mais si vous modifiez la conditionnelle if false
à un test d'attribut de nœud:
if node['cookbook']['use_Apache']
service 'Apache2' do
action :start
end
end
vous avez créé une dichotomie dans votre livre de cuisine où cela fonctionnera 50% du temps. Malheureusement, la plupart des livres de cuisine sont beaucoup plus complexes que deux ressources, de sorte que le nombre de cas Edge où une ressource peut notifier une ressource inexistante augmente considérablement avec la complexité. Tout cela est résoluble (et présente le comportement correct) en utilisant des gardes de ressources:
service 'Apache2' do
action :start
only_if { node['cookbook']['use_Apache'] }
end
Utilisation Dir.exists?
. Vous pouvez également remplacer if ! condition
par unless condition
qui se lit un peu mieux.
unless Dir.exist? "#{node['iis']['home']}\\backup\\BkpB4Chef"
windows_batch "Backup IIS Config" do
code <<-EOH
"#{node['iis']['home']}"\\appcmd add backup BkpB4Chef
EOH
end
end