我的食谱configuration如下所示:
package "scribe" do action :install end package "supervise-scripts" do action :install end remote_directory "/var/service/" do source "#{node['site-scribe']['cluster']}" end Dir.foreach('/var/service') do |dir| next if dir == '..'|| dir == '.' execute "svc_add_#{dir}" do command "/usr/bin/svc-add #{dir}" not_if { ::Dir.exists?("/var/service/#{dir}/supervise") } end execute "svc_restart_#{dir}" do command "/usr/bin/svc-restart #{dir}" end end
而现在我有奇怪的行为..第一次运行的服务器上的唯一执行remote_directory块Dir.foreach客户端,而不是启动Dir.foreach循环。 在第二次运行时,它通常执行Dir.foreach (总是在没有下载remote_directory时候)。 为什么我的循环Dir.foreach不启动,如果remote_directory块被执行?
同样的行为是当我删除not_if 。
// holosian
循环Dir.foreach在远程目录操作实际发生之前执行。 厨师分两个阶段执行。 在第一个过程中,您的所有配方代码都会运行,并将资源放在一个数组中供以后评估。 在第二阶段,这些资源将运行到真正的工作。 正如StephenKing所指出的那样,
remote_directory块将运行,并在该模板上放置一个资源以下拉该远程目录。 Dir.foreach循环运行,但由于#1的资源仍在数组中(尚未执行),因此/var/service目录中没有子项。 所以循环遍历0个元素,然后退出。 chef-client运行,然后你在/var/service有值,所以循环工作很好。 除非你只需要一个厨师就可以完全融合,否则你确实没有问题。 只要确保使用not_if和only_if语句来确保每个资源只在需要时运行。 但是,如果您需要在一次运行中完成所有工作,则必须破解一个解决scheme。 最简单的select是通过执行如下操作来强制立即评估remote_directory资源:
remote_directory "/var/service/" do source "#{node['site-scribe']['cluster']}" end.run_action(:create)
这将强制行动在厨师执行的第一阶段实际执行,然后你的循环将工作。