Knife’s exec sub-command makes it easier to interact with a Chef server from the command line. Let’s assume I’ve created a data bag named cluster as follows:
{ "id": "www1", "cats": "lol", "hostname": "www1.example.org" } { "id": "www2", "cats": "lol", "hostname": "www2.example.org" } { "id": "www3", "cats": "plz", "hostname": "www3.example.org" }
If I wanted to get a list of hostnames for each data bag item where the value of ‘cats’ is ‘lol’, I would run:
$ knife exec -E "search(:cluster, 'cats:lol').each {|host| puts host[:hostname] }" www2.example.org www1.example.org
Granted, I could get this data from the search sub-command as well:
$ knife search cluster cats:lol { "start": 0, "total": 2, "rows": [ { "id": "www2", "cats": "lol", "hostname": "www2.example.org" }, { "id": "www1", "cats": "lol", "hostname": "www1.example.org" } ] }
However, it is hard to manipulate the result of this data. For instance, if I wanted to to check the status of ntp on each of these nodes as a “one-off command”, I could run:
$ knife ssh -m \ "`knife exec -E "search(:cluster, 'cats:plz').each {|host| puts host[:hostname] }" | xargs`" \ '/etc/init.d/ntp status' www1.example.org * NTP server is running www2.example.org * NTP server is running
The quoting can get pretty tricky fast. Instead, if you leave off the -E flag to knife exec, you can pass a script file to knife where you can write clearer scripts, which makes it easier to do more.
# Script contents $ cat /tmp/knife.exec targets = Array.new search(:cluster, 'cats:lol').each do |host| targets << host[:hostname] end puts targets.join(' ') # Execute the script $ knife exec /tmp/knife.exec www2.example.org www1.example.org
What if you needed to reconcile your hardware support contracts with the systems currently deployed? It is no problem to get a list of hardware with chef and knife.
# Script contents $ cat /tmp/dell.exec search(:node, 'dmi_system_manufacturer:Dell*').each do |node| puts node[:dmi][:system][:serial_number] + "\t" + node[:fqdn] end # Execute the script $ knife exec /tmp/dell.exec XJS1NF1 www1.example.org XJS1NF2 www2.example.org XJS1NF3 www3.example.org
These are pretty simple examples, but hopefully you can see how easy it is with Chef to use knife scripts to create reports, collect data, and execute one-off commands.
Pingback: Chef Client Installer for Windows | Opscode.com