I typically don't support too many distros in my own recipes, but when reading other recipes (such as from Opscode) I generally appreciate approaches similar to your second, above, the main difference is that I would tend to explicitly invoke the resource directly, rather than compile an array.
case node[:platform]
when "centos","redhat","fedora"
package 'net-snmp'
else
package 'snmpd'
end
However, there are a number of pros and cons for each case, depending on what exactly you're trying to express.
By default, chef-solo
reads its configuration from /etc/chef/solo.rb
. The command-line parameters correspond to config values that can be set in this file. This is done using the mixlib-config library.
option :config_file,
:short => "-c CONFIG",
:long => "--config CONFIG",
:default => "/etc/chef/solo.rb",
:description => "The configuration file to use"
option :json_attribs,
:short => "-j JSON_ATTRIBS",
:long => "--json-attributes JSON_ATTRIBS",
:description => "Load attributes from a JSON file or URL",
:proc => nil
option :recipe_url,
:short => "-r RECIPE_URL",
:long => "--recipe-url RECIPE_URL",
:description => "Pull down a remote gzipped tarball of recipes and untar it to the cookbook ca
che.",
:proc => nil
The 'option' is the config file value.
The actual config file, /etc/chef/solo.rb
would look like:
file_cache_path "/tmp/chef-solo"
cookbook_path "/tmp/chef-solo/cookbooks"
role_path "/tmp/chef-solo/roles"
json_attribs "/tmp/chef-solo/node.json"
recipe_url "http://www.example.com/chef-solo.tar.gz"
Also note that the JSON file can be a remote URL, too.
json_attribs "http://www.example.com/node.json"
You can use Ohai as a library within the config file as well, to detect the platform or other attributes to specify what JSON file to use.
require 'rubygems'
require 'ohai'
o = Ohai::System.new
o.all_plugins
file_cache_path "/tmp/chef-solo"
cookbook_path "/tmp/chef-solo/cookbooks"
role_path "/tmp/chef-solo/roles"
json_attribs "/tmp/chef-solo/#{o[:platform]}.json"
recipe_url "http://www.example.com/chef-solo.tar.gz"
And then you'd have "platform" specific JSON files, for example. Or you could use o[:hostname]
, o[:domain]
or o[:fqdn]
to use JSON files based on the hostname, domain or fqdn. But once you start having the scaffolding of servers to support this kind of dynamic configuration, you might look at running a Chef Server :-).
Best Answer
This is a ruby thing, not a chef thing.
When you use
( :key => value )
you are passing in an implied hash. Ruby decides that what it sees inside the parens is hash-like, and converts to a hash automatically.When you use
{ }
, you are actually passing a block. Ruby then executes the block, and passes the results of the block back as arguments. I have found this notation to be, by far, the most likely to cause you trouble.When you use
({ :key => value })
you are explicitly passing a hash to the method. The parens explicitly define the method arguments, and the brackets are the standard notation for defining a hash (no ruby magic to auto-detect the hash-ness of the arguments).I would say there is no definitive best/right way, but the ruby style guides seem to prefer the first version.