docs/dev/design_documents/event_handler_recipe_dsl.md
Allow cookbook authors to easily add custom logic on Chef events.
Chef has an extensive event dispatch mechanism. But incorporating some custom logic against any of the events is an onerous process, which involves subclassing the based event handler and adding it via the config. This RFC proposes a recipe DSL method to ease this. For new Chef users, this will reduce the entry barrier.
Currently, chef-client sets up couple of default handlers -- e.g. doc, base -- during
initialization. An additional empty event handler -- a subclass
of the base handler without any custom logic -- can be added alongside the
existing handlers, which will used as a placeholder for user-specific hooks.
A top level (::Chef) method will be introduced (event_handler) to wrap the
main event handler DSL (on). Users can tap into one of the event types
-- as specified in base dispatcher -- using this DSL to execute their custom logic.
The additional top level method(Chef.event_handler) will allow the handler
DSL usage in and outside of recipes, and also ease writing backward-compatible
changes for the on method if need be.
The following is an example of sending hipchat notification on chef run failure.
Chef.event_handler do
on :run_failed do |exception|
hipchat_notify exception.message
end
end
The following is another example of taking a distributed lock via etcd, to
prevent concurrent chef runs in different nodes.
lock_key = "#{node.chef_environment}/#{node.name}"
Chef.event_handler do
on :converge_start do |run_context|
Etcd.lock_acquire(lock_key)
end
end
Chef.event_handler do
on :converge_complete do
Etcd.lock_release(lock_key)
end
end
The following is another example of sending a hipchat alert on a key config change.
Chef.event_handler do
on :resource_updated do |resource, action|
if resource.to_s == 'template[/etc/nginx/nginx.conf]'
Helper.hipchat_message("#{resource} was updated by chef")
end
end
end