防止厨师食谱执行以前执行的行动?

我有一个简单的配方,如下所示,目前我正在使用本地文件来指示命令是否已经运行

execute "test" do command "sh test.sh && touch /opt/myapp/done.log" only_if {File.exists?("/opt/myapp/done.log")} end 

有更好的方法吗? 这是推荐的方式?

这通常是我使用的方法,特别是如果您的命令导致文件被创build为副作用例如,禁用或启用Debian的apache2软件包中的站点将删除或创build/etc/apache2链接,您可以使用File.exists?

一个技巧是在执行资源运行后设置一个属性:

 if !node["did_test"] execute "test" do command "touch /tmp/foo" end end ruby_block "did_test" do block do node.normal["did_test"] = true end end 

请注意,执行资源在某些情况下仍可能运行两次,所以这种技术并不完美,但您现在可以使用刀形search来确定哪个节点执行了执行。

有几种方法可以保证在节点上运行多次execute

  • 使用not_ifonly_if语句。
  • 使用action :nothing ,然后通知这个execute资源从另一个资源运行。 (只有当您每次第一个资源发生更改时都需要运行它)
  • 使用not_if { ::File.exists? '[some/file]' } creates [some/file] (只有当文件不存在时,Chef才会运行它,相当于not_if { ::File.exists? '[some/file]' }

如果你不能轻易确定,如果你的脚本没有创build一个额外的文件运行,那么这是唯一的方法。 所以你们其实都做对了。

除了您提供的代码将实际运行, 如果该文件存在 。 但我想这是一个错字。