Skip to content

Instantly share code, notes, and snippets.

@yfeldblum
Created June 15, 2012 00:50
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save yfeldblum/d85be145f3ff824ccc07 to your computer and use it in GitHub Desktop.
Save yfeldblum/d85be145f3ff824ccc07 to your computer and use it in GitHub Desktop.
Intelligent Provider Action
module ChefExt
module RecipeEval
protected
def recipe_eval
sub_run_context = @run_context.dup
sub_run_context.resource_collection = Chef::ResourceCollection.new
begin
original_run_context, @run_context = @run_context, sub_run_context
yield
ensure
@run_context = original_run_context
end
begin
Chef::Runner.new(sub_run_context).converge
ensure
if sub_run_context.resource_collection.any?(&:updated?)
new_resource.updated_by_last_action(true)
end
end
end
end
end
action :do_something do
# So that we can refer to these within the sub-run-context block.
cached_new_resource = new_resource
cached_current_resource = current_resource
# Setup a sub-run-context.
sub_run_context = @run_context.dup
sub_run_context.resource_collection = Chef::ResourceCollection.new
# Declare sub-resources within the sub-run-context. Since they are declared here,
# they do not pollute the parent run-context.
begin
original_run_context, @run_context = @run_context, sub_run_context
file cached_new_resource.path
execute cached_new_resource.command do
not_if { ::File.exist?(cached_new_resource.other_path) }
end
ensure
# Restore the original run-context inherited from the calling recipe.
@run_context = original_run_context
end
# Converge the sub-run-context inside the provider action.
# Make sure to mark the resource as updated-by-last-action if any sub-run-context
# resources were updated (any actual actions taken against the system) during the
# sub-run-context convergence.
begin
Chef::Runner.new(sub_run_context).converge
ensure
if sub_run_context.resource_collection.any?(&:updated?)
new_resource.updated_by_last_action(true)
end
end
end
# Override the existing Chef::Provider#recipe_eval, which is less complete.
# This time without comments.
def recipe_eval
sub_run_context = @run_context.dup
sub_run_context.resource_collection = Chef::ResourceCollection.new
begin
original_run_context, @run_context = @run_context, sub_run_context
yield
ensure
@run_context = original_run_context
end
begin
Chef::Runner.new(sub_run_context).converge
ensure
if sub_run_context.resource_collection.any?(&:updated?)
new_resource.updated_by_last_action(true)
end
end
end
# Use it
action :do_something do
recipe_eval do
file "/etc/my-package.conf" do
owner new_resource.user
group new_resource.group
mode new_resource.mode
action :create
end
end
end
include ChefExt::RecipeEval
# Use it
action :do_something do
recipe_eval do
file "/etc/my-package.conf" do
owner new_resource.user
group new_resource.group
mode new_resource.mode
action :create
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment