ruby 如何检查 Chef 中是否存在文件夹?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18370804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I check if a folder exists in Chef?
提问by Sony Koithara
This is my 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
It always says file exists and executes the loop.
它总是说文件存在并执行循环。
回答by sethvargo
You should use Chef guardshere. Guards specify conditional execution, but still insert the resource into the resource collection. In your example and jtblin answer, the resource is never added to the collection (which I'll explain a bit further in a moment).
你应该在这里使用Chef 守卫。Guards 指定条件执行,但仍将资源插入到资源集合中。在您的示例和 jtblin 回答中,资源永远不会添加到集合中(稍后我将进一步解释)。
Here's some working code to get you started:
以下是一些可以帮助您入门的工作代码:
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
Using creates
使用 creates
Many non-idempotent Chef resources also support a createsparameter, which explains what the resource does. In other words, what does the windows_batch"create". This can be a file, directory, or executable. So, the following code is equivalent to the former answer.
许多非幂等的 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
Why not_ifvs the conditional wrapper
为什么not_ifvs 条件包装器
Chef executes in two phases - the compilation phase and the convergence phase. During the compilation phase, the recipes are evaled and the resources are added to the resource collection. In the convergence phase, the resources in the resource collection are executed and evaluated against the target system. So, consider the following example:
Chef 分两个阶段执行——编译阶段和收敛阶段。在编译阶段,将评估配方并将资源添加到资源集合中。在收敛阶段,资源集合中的资源被执行并针对目标系统进行评估。因此,请考虑以下示例:
if false
service 'foo' do
action :start
end
end
This is a fairly straight-forward recipe that starts a service based on some conditional. However, at the end of the compilation phase, the serviceresource isn't added to the resource collection. Since the recipe DSL is instance_evaled, the wrapping if falseconditional prevents that code from ever being read by the Ruby VM. In other words, it's like that service never exists.
这是一个相当直接的方法,它根据某些条件启动服务。但是,在编译阶段结束时,service资源不会添加到资源集合中。由于配方 DSL 已instance_eval编辑,因此包装if false条件会阻止 Ruby VM 读取该代码。换句话说,就好像那个服务从来不存在一样。
It's fairly common to notify resources. Later in the recipe, you might want to restart apache because of a configuration change. The "proper" way to do this is using notifications:
通知资源是相当普遍的。在本节的后面,您可能希望由于配置更改而重新启动 apache。执行此操作的“正确”方法是使用通知:
template '/var/www/conf.d/my.conf.file' do
# ...
notifies :restart, 'service[apache2]'
end
This templatecannot adequately notify the service resource, because it doesn't exist in the resource collection. So this recipe will fail. It seems like a trivial example, but if you change the conditional if falseto a node attribute test:
这template不能充分通知服务资源,因为它不存在于资源集合中。所以这个食谱会失败。这似乎是一个微不足道的例子,但是如果将条件更改if false为节点属性测试:
if node['cookbook']['use_apache']
service 'apache2' do
action :start
end
end
you have created a dichotomy in your cookbook where it will work 50% of the time. Unfortunately most cookbooks are much more complex than two resources, so the number of edge cases where a resource can notify a non-existent resource drastically increases with complexity. This is all solvable (and exhibits the correct behavior) using resource guards:
你在你的食谱中创建了一个二分法,它在 50% 的时间里都有效。不幸的是,大多数食谱比两个资源复杂得多,因此资源可以通知不存在的资源的边缘情况的数量随着复杂性的增加而急剧增加。这一切都可以使用资源守卫解决(并表现出正确的行为):
service 'apache2' do
action :start
only_if { node['cookbook']['use_apache'] }
end
回答by jtblin
Use Dir.exists?. You can also replace if ! conditionby unless conditionwhich reads a bit better.
使用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

