3

I have a simple recipe like the following, and currently I am using a local file to indicate if the command has been run or not

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

Are there better method? It is the recommended way?

1

This is generally the method I use, especially if the command you take results in a file being created as a side effect For example disabling or enabling sites in Debian's apache2 package removes or creates links in /etc/apache2 which you can test for using File.exists?.

A trick is to set an attribute after the execute resource has run:

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

Note that it's still possible for the execute resource to be run twice in some situations so this technique isn't perfect, but you can now use knife-search to determine which nodes have performed the execute.

  • Hi, actually what is the differe.nt between your version and my version? Thanks – Ryan Mar 12 '13 at 14:52
  • I'm using a Chef node attribute to store whether the recipe has been executed or not. The value of the attribute is stored on the Chef server and can be queried (or modified) using knife. – Tim Potter Mar 12 '13 at 18:28
3

There are some ways to keep execute from running several times on node:

  • Using not_if, only_if statements.
  • Using action :nothing and then notifying this execute resource to run from another resource. (only if you need to run it every time the first resource changes)
  • Using creates [some/file] (Chef will run it, only if the file does not exist, equivalent to not_if { ::File.exists? '[some/file]' }

If you cannot easily determine, if your script has run without creating an additional file, then it is the only way. So you, actually, are doing everything right.

Except that the code you provided will actually run, if the file exists. But I suppose that is a typo.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.