Chef Event Handler - How do I know what variables/classes/methods/etc are available to me?


#1

Implementing a web service to track Chef runs over time. Really struggling to understand what Chef variables/classes/methods are available to me within the context of Chef.event_handler.

In my recipes/default.rb file, I have the following event handler definition:
Chef.event_handler do
on :run_completed do
HandlerSendEmail::Helper.new.log_run(Chef.run_context.node.name, ‘0’, Array(Chef.run_context.node.run_list).join(’,’))
end
end

Is there a place I can look to see what variables/classes/methods are available for me to pass to my downstream log_run method (for use in logging, etc)?

I see the Class definitions and documentation out at places like http://www.rubydoc.info/gems/chef/Chef/RunContext, but I just can’t seem to track down how to get to things like run_status to get at things like elapsed time, success/failure, backtrace, etc. Fully aware that this might just be my Ruby n00bery, so any help is appreciated.

Also - Somewhat related - I seem to be able to do basically the same kinds of things from chef_handler as with the Chef Handler DSL. Is there a preferred method?

-Ray


#2

Here’s what I built out so far: https://gist.github.com/rayterrill/2bf2bb7de4ca60ae4ceb349649c0d37f


#3

Hi @rayterrill

When first learning Chef I used the DSL relatively successfully but did not really know what I was doing or how best to write a cookbook. What I would say is do not underestimate the role of Ruby in the Chef DSL; as I said you don’t need to know Ruby to write a cookbook but it will help you write better cookbooks and you’ll know what to do when things go wrong.

Here are a few possible ways to get to know the Classes and methods

  • Branch or download the Chef source code
  • Debug your code with Chef Zero and Pry
  • Debug your code with Chef-Zero and Chef-Shell

The chef source code is here https://github.com/chef/chef

Debugging with Chef-Zero and Pry can be a bit involved, I wrote some notes here https://github.com/chrisgit/chef-debugging

A quick win will be to load up Chef-Shell (ideally with your recipes and handler loaded) but you can just run Chef-Shell without loading any cookbooks.

Chef-Shell is an interactive environment used to help debug Chef cookbooks, I love it, especially when tracking down where the value of an attribute comes from.

With Chef installed at a command prompt type “chef-shell”. Chef-Shell has various “modes” such as attribute mode and recipe mode, for interrogating classes though you just need to be in the default mode after Chef-Shell has loaded, here are a few helpful commands.

Get methods of an instance of the Chef::Node class

node.methods

Get methods from a class definition

Chef::Node.methods
Chef::Node.instance_methods

If the method list is to big then restrict with grep

Chef::Node.methods.grep(/method/)
Chef::RunStatus.methods

Get all of the classes loaded

class_list = []
ObjectSpace.each_object { |o| class_list << o.name if o.class == Class }
class_list

Therefore if you want to look at the methods that contain the word “time” you can interrogate the instance of Chef::RunStatus or the class definition in your handler (using puts or Chef::Log.info if you can’t get a break point to work), below looks at the class definition for RunStatus and gets the instance methods with the word time in them.

Chef::RunStatus.instance_methods.grep(/time/)

Ruby has a rich metadata system which can be interrogated so once you are in Ruby prompt you can start to interrogate the classes!

So if you don’t want to use Chef-Shell then you can run interactive Ruby (IRB), go to a command prompt on a machine with Ruby installed and in the path, type “irb”, when interactive Ruby loads at the prompt load the chef libraries by typing require ‘chef’. After typing that the significant Chef libraries will be loaded and you can start to reflect on the class definitions.

Hope this answers your question and helps with your handler.


#4

Awesome. I’m checking this out. Didn’t even know about some of these tools. Thanks! :slight_smile: