A vast amount of information from a given system is available to Chef through Ohai. This program is executed during each Chef run and stores all of the gathered information in the Chef database to make it available right from the cookbooks. The kind of information gathered by default is quite large.
It ranges from networking details—such as link speed, MTU, or addresses—to all the memory usage details you'd find on a utility such as top
, all of the imaginable data regarding filesystems or virtualization systems, or the list of every single installed package and logged-in users.
On top of this, Ohai is a modular system with a lot of community plugins to integrate Dell DRAC information with support information related to a KVM, LXC, or XenServer.
It can even be used to retrieve some specific data related to Windows Management Instrumentation (WMI). We obviously can write our own plugins, but that's way beyond the scope of this book.
To step through this recipe, you will need:
In a fresh and minimal installation of a CentOS 7.2 virtual machine, the ohai
output is 5,292 lines long, which is full of information. To see it bit by bit, refer to the following:
$ ohai | more { "cpu": { "0": { "vendor_id": "GenuineIntel", "family": "6", "model": "69", "model_name": "Intel(R) Core(TM) i7-4578U CPU @ 3.00GHz", "stepping": "1", "mhz": "2999.991", "cache_size": "4096 KB", "physical_id": "0", "core_id": "0", "cores": "1",
Alternatively, another solution is to redirect its content to a file so it's easier to process with a dedicated tool:
$ ohai > ohai.json
All of this information is also graphically available on the Chef interface when you select a node in the Attributes tab:
Now let's access this information from a recipe. We'd like an index.html
page with some of this information, so let's edit the one we already have from the apache
cookbook; however, you can start from scratch as well. We'd like this page to dynamically display something like this:
This centos 7.2.1511 linux system version 3.10.0-327.el7.x86_64 listening on 192.168.146.129 is up since 25 minutes 55 seconds
All the information we need is stored somewhere in ohai: platform
, platform_version
, os
, os_version
, ipaddress
, or uptime
are all valid values. Let's use them.
In apache/templates/index.html.erb
, add the following:
This <%= node['platform'] %> <%= node['platform_version'] %> <%= node['os'] %> system version <%= node['os_version'] %> listening on <%= node['ipaddress'] %> is up since <%= node['uptime'] %>
To build something more interesting, as the platform name is available, let's make our apache
cookbook a bit more portable across Linux distributions. When running on Ubuntu, install the apache2
package; else, install the httpd
package. (This will have to be more precise to handle all the real cases.) In the apache::default
recipe, make the following change so the httpd
variable is set to apache2
when running Ubuntu and to the default httpd
elsewhere:
if node['platform'] == 'ubuntu' httpd = 'apache2' else httpd = 'httpd' end package httpd do action :install end service httpd do action [:enable, :start] end
This is how we can start leveraging the use of the powerful ohai
command in our Chef infrastructure.
The counterpart for Puppet is facter
, which is installed with the Puppet agent. Like ohai
, facter
is a command-line tool:
$ facter | more aio_agent_version => 1.8.0 augeas => { version => "1.4.0" } disks => { sda => { model => "VBOX HARDDISK", size => "40.00 GiB", size_bytes => 42949672960, vendor => "ATA" } } dmi => { bios => { release_date => "12/01/2006", vendor => "innotek GmbH", version => "VirtualBox" }, board => { manufacturer => "Oracle Corporation", product => "VirtualBox" }, ...
As for Chef, the facter
information can be accessed from a Puppet manifest. Such information in the Puppet world is named facts.
Starting from Puppet 4.x, facts can be accessed from manifests using the $facts
hash. Let's try to create more portable lines of code for the apache
module:
if $facts['os']['family'] == 'debian' { $packagename='apache2' } else { $packagename='httpd' } package{'apache2': ensure => present, name => $packagename, } service{'apache2': ensure => running, enable => true, name => $packagename, }
18.191.150.231