This adds a simple function to the Chef library scope to
rewind or unwind an existing resource. If the given resource does not exist,
a Chef::Exceptions::ResourceNotFound
exception will be raised.
These functions are designed to assist the library cookbook pattern.
Effectively, rewind/unwind resource allows you to monkeypatch a cookbook that you would rather not modify directly. It will modify some properties of a resource, during the complile phase, before chef-client actually starts the run phase.
Add this line to your application's Gemfile:
gem 'chef-rewind'
And then execute:
$ bundle
Or install it yourself as:
$ gem install chef-rewind
# file postgresql/recipes/server.rb
user "postgres" do
uid 26
home '/home/postgres'
supports :manage_home => true
end
# file my-postgresql/recipes/server.rb
chef_gem "chef-rewind"
require 'chef/rewind'
include_recipe "postgresql::server"
rewind "user[postgres]" do
home '/var/lib/pgsql/9.2'
end
The user postgres
will act once with the home directory
/var/lib/pgsql/9.2
and the cookbook_name
attribute is now
my-postgresql
instead of postgresql
. This last part is
particularly important for templates and cookbook files.
# file postgresql/recipes/server.rb
user "postgres" do
uid 26
home '/home/postgres'
supports :manage_home => true
end
# file my-postgresql/recipes/server.rb
chef_gem "chef-rewind"
require 'chef/rewind'
include_recipe "postgresql::server"
unwind "user[postgres]"
This will completely remove the resource. It is useful
for resources that are impossible to change correctly.
Resource notifications, for example,
can't be overwritten by rewind
, only appended.
So if you need to change notifications of a resource,
you need to unwind
and redefine the resource. Example:
# file cookbook-elasticsearch/recipes/default.rb
template "logging.yml" do
path "#{node.elasticsearch[:path][:conf]}/logging.yml"
source "logging.yml.erb"
owner node.elasticsearch[:user] and group node.elasticsearch[:user] and mode 0755
notifies :restart, 'service[elasticsearch]'
end
# file my-elasticsearch/recipes/default.rb
chef_gem "chef-rewind"
require 'chef/rewind'
unwind "template[logging.yml]"
template "logging.yml" do
path "#{node.elasticsearch[:path][:conf]}/logging.yml"
source "logging.yml.erb"
owner node.elasticsearch[:user] and group node.elasticsearch[:user] and mode 0755
cookbook_name "elasticsearch"
# this is the only change from original definition
notifies :run, 'execute[Custom ElasticSearch restarter]'
end
This allows you to define your own ElasticSearch restart script.
It's impossible to rewind
notifications,
thus you need to unwind
and redefine it based on the original version.
The rewind method does not automatically change the cookbook_name attribute for a resource to the current cookbook. Doing so could cause some unexpected behavior, particularly for less expert chef users.
Example
# file postgresql/recipes/server.rb
template "/var/pgsql/data/postgresql.conf" do
source "postgresql.conf.erb"
owner "postgres"
end
# file my-postgresql/recipes/server.rb
chef_gem "chef-rewind"
require 'chef/rewind'
include_recipe "postgresql::server"
# my-postgresql.conf.erb located inside my-postgresql/templates/default/my-postgresql.conf.erb
rewind :template => "/var/pgsql/data/postgresql.conf" do
source "my-postgresql.conf.erb"
cookbook_name "my-postgresql"
end
If you do not specify cookbook_name the rewind function will likely return an error since Chef will look in the postgresql cookbook for the source file and not in the my-postgresql cookbook.
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Added some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request