Chris B.
Chris B.

Reputation: 90309

How can I install a program and then execute it in the same Chef run?

I'm using Chef to install serf and then I need to execute serf members -format=JSON. My code looks like this:

include_recipe "mycookbook::serf"
log `serf members -format=json`

However, nothing prints to the log. Rerunning the chef run (after serf is installed) produces JSON output in the log.

Why doesn't it get the info the first time? How can we ensure the program is installed before it calls serf members?

Upvotes: 1

Views: 93

Answers (2)

sethvargo
sethvargo

Reputation: 26997

You want to put it in a ruby_block

include_recipe "mycookbook::serf"
ruby_block do
  block do
    Chef::Log.info `serf members -format=json`
  end
end

Upvotes: 1

Figuring out exactly when code gets evaluated in Chef can be a bit tricky. It's a multi pass process. First chef evaluates all the cookbooks in it's run list to build a list of things to do. If you write "raw ruby" it gets evaluated during this phase.

So in your case, the serf binary is not yet available when you shell out to run it.

There are a couple ways to handle this, the easiest would be to put the serf command in a report handler at the end of the chef run.

http://docs.opscode.com/handlers.html

If you need the serf results during the run, you need to specify that running the serf command is dependent on a resource. The easiest way to do that would be to put the serf command inside a ruby_block resource.

http://docs.opscode.com/resource_ruby_block.html

This ensures that the ruby will be executed after the initial pass through and after the serf install cookbook.

Upvotes: 1

Related Questions