Metadata
Each cookbook contains a metadata.rb
file in the root directory of the cookbook that contains information about the cookbook itself, such as who maintains it, the license, version, contained recipes, supported platforms, and the cookbook's dependencies. The contents of this script are used to generate a JSON file that describes the cookbook, which is used by the Chef server for dependency resolution, searching and importing into run lists.
This is a required file for a cookbook, and here is an example metadata.rb
file from the PostgreSQL database server, which is slightly modified to fit the following:
name "postgresql" maintainer "Opscode, Inc." maintainer_email "cookbooks@opscode.com" license "Apache 2.0" description "Installs and configures PostgreSQL" long_description IO.read(File.join( File.dirname(__FILE__), 'README.md' )) version "3.3.4" recipe "postgresql", "Includes postgresql::client" recipe "postgresql::ruby", "Installs Ruby bindings" recipe "postgresql::client", "Installs client package(s)" recipe "postgresql::server", "Installs server packages" recipe "postgresql::server_redhat", "Installs RedHat server packages" recipe "postgresql::server_debian", "Installs Debian server packages" %w{ubuntu debian fedora suse amazon}.each do |os| supports os end %w{redhat centos scientific oracle}.each do |el| supports el, ">= 6.0" end depends "apt" depends "build-essential" depends "openssl"
Because the metadata.rb
file is a Ruby script, it allows you to use arbitrary Ruby code inside of it. Here, for example, the long_description
entry is generated programmatically by reading in the contents of the supplied README.md
file:
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
Here, the PostgreSQL cookbook supports multiple platforms, so instead of writing each platform that is supported on a line of its own, you could use a loop similar to the one used in the metadata.rb
file:
%w{ubuntu debian fedora suse amazon}.each do |os| supports os end
Additionally, if it only supports certain platforms with a minimum version, you could write something similar to the following, which declares support for RedHat-based distributions greater than (or equal to) Version 6.0:
%w{redhat centos scientific oracle}.each do |el| supports el, ">= 6.0" end
In this cookbook, the dependencies are listed line by line but could be represented similarly if you have a large number:
depends "apt" depends "build-essential" depends "openssl"
Dependencies could also be rewritten as follows:
%w{apt build-essential openssl}.each do |dep| depends dep end
Obviously, in this case, you aren't saving any room; however, if you had ten or more dependencies, it could make it more compact.
As long as your Ruby code produces something that is a compatible argument or configuration, you can be as clever as you want. Take advantage of your ability to dynamically generate a configuration.