Informatician
Informatician

Reputation: 319

What is the chef appropriate way to ensure idempotency when an execute block's "creates" value is not fully known?

Within the following code's creates directive, the specified value contains a (actually, more than one) wildcard.

execute "Install Vagrant plugin: #{plugin}" do
   environment ({ 'HOME' => ::Dir.home(user), 'USER' => user })
   command "vagrant plugin install #{plugin}"
   creates "/home/#{user}/.vagrant.d/gems/*/gems/vagrant-berkshelf-*"
end

I expect that there is not a chef intended method of handling a situation where only a directory pattern is known beforehand and not the actual full path. The Chef documentation for execute does not explicitly say whether or not creates will pattern match, but after testing, I believe it does not and is not intended to pattern match.

This being the case, would the above be an appropriate use for Chef::Mixin::ShellOut? Or would there be another more chef intended method?

If the former, I'm anticipating using examples from stackoverflow (1, 2) to determine whether a directory exists matching a pattern resembling the value of the creates directive above and using that return value to set whether or not to run the execute block in question.

Any tips, hints, or suggestions are greatly appreciated!

Upvotes: 0

Views: 208

Answers (1)

coderanger
coderanger

Reputation: 54211

You would use a not_if or only_if guard clause. The creates property is just a helper for not_if { ::File.exist?(the_path) }. In this case what you probably want is either not_if "vagrant plugin list | grep #{plugin}" or the slightly cleaner (IMO) not_if { shell_out!('vagrant plugin list').stdout.include?(plugin) }.

Upvotes: 1

Related Questions