这是我的代码:
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
Run Code Online (Sandbox Code Playgroud)
它总是说文件存在并执行循环.
set*_*rgo 27
你应该在这里使用厨师守卫.Guards指定条件执行,但仍将资源插入资源集合.在您的示例和jtblin答案中,资源永远不会添加到集合中(稍后我将进一步解释).
这里有一些工作代码可以帮助您入门:
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
Run Code Online (Sandbox Code Playgroud)
creates
许多非幂等的Chef资源也支持一个creates
参数,该参数解释了资源的作用.换句话说,windows_batch
"创造" 是什么.这可以是文件,目录或可执行文件.因此,以下代码等同于前一个答案.
windows_batch "Backup IIS Config" do
code %Q|#{node['iis']['home']}"\\appcmd add backup BkpB4Chef|
creates"#{node['iis']['home']}\\backup\\BkpB4Chef"
end
Run Code Online (Sandbox Code Playgroud)
not_if
vs条件包装器Chef分两个阶段执行 - 编译阶段和收敛阶段.在编译阶段,将逐步调整配方并将资源添加到资源集合中.在收敛阶段,资源集合中的资源将针对目标系统执行和评估.因此,请考虑以下示例:
if false
service 'foo' do
action :start
end
end
Run Code Online (Sandbox Code Playgroud)
这是一个相当直接的配方,它基于某些条件启动服务.但是,在编译阶段结束时,service
资源不会添加到资源集合中.由于配方DSL已instance_eval
编辑,因此包装if false
条件可防止Ruby VM读取该代码.换句话说,就像服务永远不存在一样.
通知资源是相当普遍的.在配方的后面,您可能希望因配置更改而重新启动apache."正确"的方法是使用通知:
template '/var/www/conf.d/my.conf.file' do
# ...
notifies :restart, 'service[apache2]'
end
Run Code Online (Sandbox Code Playgroud)
这template
不能充分通知服务资源,因为它在资源集合中不存在.所以这个配方会失败.这似乎是一个简单的例子,但是如果你将条件更改if false
为节点属性测试:
if node['cookbook']['use_apache']
service 'apache2' do
action :start
end
end
Run Code Online (Sandbox Code Playgroud)
你已经在你的食谱中创造了一种二分法,它可以在50%的时间里起作用.不幸的是,大多数烹饪书比两个资源复杂得多,因此资源可以通知不存在的资源的边缘情况的数量急剧增加.这是使用资源保护所有可解决的(并表现出正确的行为):
service 'apache2' do
action :start
only_if { node['cookbook']['use_apache'] }
end
Run Code Online (Sandbox Code Playgroud)
使用Dir.exists?
。您也可以用代替,if ! condition
以unless condition
使阅读效果更好。
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
Run Code Online (Sandbox Code Playgroud)