Ohai is a tool that is used to detect certain properties about a node’s environment and provide them to the chef-client during every Chef run. The types of properties Ohai reports on include:
When Chef configures the node object during each Chef run, these attributes are used by the chef-client to ensure that certain properties remain unchanged. (These properties are also referred to as automatic attributes.) Ohai is part of the required configuration on each node that is registered with the Chef Server.
An automatic attribute is a specific detail about a node, such as an IP address, a host name, a list of loaded kernel modules, and so on. Automatic attributes are detected by Ohai and are then used by Chef to ensure that these attribute are handled properly during every Chef run. The most commonly accessed automatic attributes are:
| Attribute | Description |
|---|---|
| node['platform'] | The platform on which a node is running. This attribute helps determine which providers will be used. |
| node['platform_version'] | The version of the platform. This attribute helps determine which providers will be used. |
| node['ipaddress'] | The IP address for a node. If the node has a default route, this is the IPV4 address for the interface. If the node does not have a default route, the value for this attribute should be nil. The IP address for default route is the recommended default value. |
| node['macaddress'] | The MAC address for a node, determined by the same interface that detects the node['ipaddress']. |
| node['fqdn'] | The fully qualified domain name for a node. This is used as the name of a node unless otherwise set. |
| node['hostname'] | The host name for the node. |
| node['domain'] | The domain for the node. |
| node['recipes'] | A list of recipes associated with a node (and part of that node’s run-list). |
| node['roles'] | A list of roles associated with a node (and part of that node’s run-list). |
| node['ohai_time'] | The time at which Ohai was last run. This attribute is not commonly used in recipes, but it is saved to the Chef Server and can be accessed using the knife status sub-command. |
Get a list of automatic attributes for a node .. include:: ../../includes_ohai/includes_ohai_attribute_list.rst
Note
Attributes can be configured in cookbooks (attribute files and recipes), roles, and environments. In addition, Ohai collects attribute data about each node at the start of the Chef run. See the overview of attributes for more information about how all of these attributes fit together.
At the beginning of a Chef run, all default, override, and automatic attributes are reset. Chef rebuilds them using data collected by Ohai at the beginning of the Chef run and by attributes that are defined in cookbooks, roles, and environments. Normal attributes are never reset. All attributes are then merged and applied to the node according to attribute precedence. At the conclusion of the Chef run, all default, override, and automatic attributes disappear, leaving only a collection of normal attributes that will persist until the next Chef run.
Attributes are always applied to Chef in the following order:
where the last attribute in the list is the one that is applied to the node.
Note
The attribute precedence order for roles and environments is reversed for default and override attributes. The precedence order for default attributes is environment, then role. The precedence order for override attributes is role, then environment. Applying environment override attributes after role override attributes allows a role to exist in multiple environments.
Attribute precedence, viewed from the same perspective as the Chef overview diagram, where the numbers in the diagram match the order of attribute precedence:
Attribute precedence, when viewed as a table:
Ohai is a requirement for Chef and is installed whenever (and wherever) Chef is installed. Ohai can also be installed separately from Chef.
To install Ohai from git, run the following command:
$ clone git repository
or install from RubyGems with Rake:
$ rake install
To install Ohai from RubyGems, do the following:
Add the gem server to the local resources:
$ sudo gem source -a http://rubygems.org
Install Ohai:
$ sudo gem install ohai
Ohai (version 0.6.x or higher) can be run on the following versions of Microsoft Windows:
To install Ohai on Microsoft Windows, do the following:
Install Ruby using the one-click installer: http://rubyforge.org/frs/download.php/69034/rubyinstaller-1.8.7-p249-rc2.exe.
Install Ohai and WMI bindings:
$ C:\Ruby>gem install ohai ruby-wmi
Run Ohai:
$ C:\Ruby>ohai
Ohai is a requirement for Chef and is installed whenever (and wherever) Chef is installed. Ohai can also be installed separately from Chef.
When additional data about a system infrastructure is required, a custom Ohai plugin can be used to gather that information. An Ohai plugin is a Ruby DSL. For example, the following is about as simple as it gets:
provides "orly"
orly "yeah, rly."
To load a plugin, create a “plugins” folder and put the above code in the plugins/orly.rb file.
Now to fire up irb (and assuming the directory “plugins” is the current folder; if not adjust your path):
>> require 'ohai'
>> Ohai::Config[:plugin_path] << './plugins'
>> o = Ohai::System.new
>> o.all_plugins
>> o.orly #=> "yea, rly"
Most of the information we want to lookup would be nested in some way, and Ohai tends to do this by storing the data in a Mash. This can be done by creating a new mash and setting the attribute to it.
In plugins/canhas.rb:
provides "canhas"
canhas Mash.new
canhas[:burger] = "want"
One of the main reasons for using Ohai is to gather information regardless of the operating system. Luckily this is made easy by optionally loading recipes based on the platform. With that platform specific calls abstracted away you can keep your code DRY.
The builtin plugins that come with Ohai use the following trick to load platform specific code. It works by creating a base cross-platform plugin that loads the platform specific plugin from a subdirectory. In plugins/lolcode.rb:
provides "languages/lolcode"
require_plugin "languages"
require_plugin "#{os}::lolcode"
languages[:lolcode] = Mash.new unless languages[:lolcode]
languages[:lolcode][:version] = "TEH VERSHIONS"
In plugins/darwin/lolcode.rb:
provides "languages/lolcode"
require_plugin "languages"
languages[:lolcode] = Mash.new unless languages[:lolcode]
languages[:lolcode][:platform] = "MACKERS"
Checkout ohai’s os.rb for the list of platform names.
All of these examples can be found in the ohai-plugin-howto github repo, you should be able to clone that and run the ruby scripts in the repo’s root directory. If you figure out any other handy tricks please fork the project and add them.
Ohai makes it very easy to extend a current plugin with new information. Simply require the plugin you want to extend and extend away. In this example we want to add LOLCODE to languages.
In plugins/lolcode.rb:
provides "languages/lolcode"
require_plugin "languages"
languages[:lolcode] = Mash.new
languages[:lolcode][:version] = "TEH VERSHIONS"
To download the ohai cookbook to the Chef repository:
Run the following command:
$ knife cookbook site install ohai
Knife will return something like the following:
INFO: Downloading ohai from the cookbooks site at version 0.9.0
INFO: Cookbook saved: /Users/jtimberman/chef-repo/cookbooks/ohai.tar.gz
INFO: Checking out the master branch.
INFO: Checking the status of the vendor branch.
INFO: Creating vendor branch.
INFO: Removing pre-existing version.
INFO: Uncompressing ohai version 0.9.0.
INFO: Adding changes.
INFO: Committing changes.
INFO: Creating tag chef-vendor-ohai-0.9.0.
INFO: Checking out the master branch.
INFO: Merging changes from ohai version 0.9.0.
[ ... SNIP ... ]
INFO: Cookbook ohai version 0.9.0 successfully vendored!
To change the directory in which plugins are located edit the cookbook attributes file and change the path for the node[:ohai][:plugin_path] attribute. For example:
default[:ohai][:plugin_path] = "/etc/chef/ohai_plugins"
To upload the Ohai cookbook to the Chef Server, use Knife and run the following:
knife cookbook upload ohai
to return something similar to:
INFO: Saving ohai
INFO: Validating ruby files
INFO: Validating templates
INFO: Syntax OK
INFO: Generating Metadata
INFO: Uploading files
[ ... SNIP ... ]
To upload the Ohai cookbook to the Chef Server, use Knife and run the following:
knife cookbook upload ohai
to return something similar to:
INFO: Saving ohai
INFO: Validating ruby files
INFO: Validating templates
INFO: Syntax OK
INFO: Generating Metadata
INFO: Uploading files
[ ... SNIP ... ]
To disable an Ohai plugin, add the following code to the client.rb file:
Ohai::Config[:disabled_plugins] = ["plugin_name", "plugin_name"]
where plugin_name is a comma-delimited list of Ohai plugins. For example:
Ohai::Config[:disabled_plugins] = ["passwd", "rackspace", "dmi", "dmi_common"]
The following Ohai plugins are available in the Chef open source community:
| Plugin | Description |
|---|---|
| dell.rb | Adds some useful Dell server information to Ohai. For example: service tag, express service code, storage info, RAC info, and so on. To use this plugin, OMSA and SMBIOS applications need to be installed. |
| dpkg.rb | Adds dpkg info to Ohai. This collections information about the status of Debian packages and about the various packages that are installed. |
| ipmi.rb | Adds an IPMI mac and IP address to Ohai, where available. |
| kvm_extensions.rb | Adds extensions for virtualization attributes to provide additional host and guest information for KVM. |
| ladvd.rb | Adds ladvd information to Ohai, when it exists. |
| lxc_virtualization.rb | Adds extensions for virtualization attributes to provide host and guest information for Linux containers. |
| network_addr.rb | Adds extensions for network attributes with additional ipaddrtype_iface attributes to make it semantically easier to retrieve addresses. For example: node['network']['ipaddress_eth0'] versus node['network']['interfaces']['eth0']['addresses'].guesswhichisfirst. |
| network_ports.rb | Adds extensions for network attributes so that Ohai can detect to which interfaces TCP and UDP ports are bound. |
| parse_host_plugin.rb | Adds the ability to parse a host name using three top-level attribute and five nested attributes. |
| r.rb | Adds the ability to collect basic information about the R Project. |
| rpm.rb | Adds RPM Package Manager information to Ohai and collects information about the status of RPM Package Manager packages and about the various packages that are installed. |
| sysctl.rb | Adds sysctl information to Ohai. |
| vserver.rb | Adds extensions for virtualization attributes to allow a Linux virtual server host and guest information to be used by Ohai. |
| wtf.rb | Adds the irreverent wtfismyip.com service so that Ohai can determine a machine’s external IPv4 address and geographical location. |
| xenserver.rb | Adds extensions for virtualization attributes to load up Citrix XenServer host and guest information. |
| win32_software.rb | Adds the ability for Ohai to use Windows Management Instrumentation (WMI) discover useful information about software that is installed on any node that is running Microsoft Windows. |
| win32_svc.rb | Adds the ability for Ohai to query using Windows Management Instrumentation (WMI) to get information about all services that are registered on a node that is running Microsoft Windows. |