我有一个简单的配方,如下所示,目前我正在使用本地文件来指示命令是否已运行
execute "test" do
command "sh test.sh && touch /opt/myapp/done.log"
only_if {File.exists?("/opt/myapp/done.log")}
end
有没有更好的方法?这是推荐的方法吗?
答案1
这通常是我使用的方法,特别是如果您执行的命令导致文件作为副作用被创建时,例如,禁用或启用 Debian 的 apache2 包中的站点会删除或创建/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.default["did_test"] = true
end
end
请注意,在某些情况下执行资源仍有可能运行两次,因此这种技术并不完美,但您现在可以使用 knife-search 来确定哪些节点执行了执行。
答案2
有一些方法可以避免execute
在节点上运行多次:
- 使用
not_if
,only_if
语句。 - 使用
action :nothing
然后通知此execute
资源从另一个资源运行。(仅当您每次需要在第一个资源更改时运行它时) - 使用
creates [some/file]
(Chef 将运行它,仅当文件不存在时,相当于not_if { ::File.exists? '[some/file]' }
如果您无法轻松确定脚本是否在不创建附加文件的情况下运行,那么这是唯一的方法。所以,实际上,您做的一切都是正确的。
除非你提供的代码能够真正运行,如果文件存在。但我想那是一个打字错误。