diff options
author | danielsdeleo <dan@opscode.com> | 2014-01-31 16:44:48 -0800 |
---|---|---|
committer | danielsdeleo <dan@opscode.com> | 2014-02-03 17:08:54 -0800 |
commit | b4c8facbf495423950345937ab4a8d6d8792ad16 (patch) | |
tree | 6ef2f4bc852b4ee3e2080f612dd9b43921f1e9ac /lib/chef | |
parent | 040865b55964056d3249de896baafe60587f5105 (diff) | |
download | chef-b4c8facbf495423950345937ab4a8d6d8792ad16.tar.gz |
Expose resource creation via more static methods
Diffstat (limited to 'lib/chef')
-rw-r--r-- | lib/chef/dsl/recipe.rb | 136 |
1 files changed, 98 insertions, 38 deletions
diff --git a/lib/chef/dsl/recipe.rb b/lib/chef/dsl/recipe.rb index f3507a8031..a1bdd9d665 100644 --- a/lib/chef/dsl/recipe.rb +++ b/lib/chef/dsl/recipe.rb @@ -31,53 +31,113 @@ class Chef include Chef::Mixin::ConvertToClassName + # Default +cookbook_name+ implementation, always returns "none". This + # should be overriden in including classes whenever a meaningful value + # can be provided. + def cookbook_name + "none" + end + + # Default +recipe_name+ implementation, always returns "none". This + # should be overridden in including classes whenever a meaningful value + # can be provided. + def recipe_name + "none" + end + def method_missing(method_symbol, *args, &block) # If we have a definition that matches, we want to use that instead. This should # let you do some really crazy over-riding of "native" types, if you really want # to. - if run_context.definitions.has_key?(method_symbol) - # This dupes the high level object, but we still need to dup the params - new_def = run_context.definitions[method_symbol].dup - new_def.params = new_def.params.dup - new_def.node = run_context.node - # This sets up the parameter overrides - new_def.instance_eval(&block) if block - new_recipe = Chef::Recipe.new(cookbook_name, @recipe_name, run_context) - new_recipe.params = new_def.params - new_recipe.params[:name] = args[0] - new_recipe.instance_eval(&new_def.recipe) + if has_resource_definition?(method_symbol) + evaluate_resource_definition(method_symbol, *args, &block) else # Otherwise, we're rocking the regular resource call route. - - # Checks the new platform => short_name => resource mapping initially - # then fall back to the older approach (Chef::Resource.const_get) for - # backward compatibility - resource_class = Chef::Resource.resource_for_node(method_symbol, run_context.node) - - super unless resource_class - raise ArgumentError, "You must supply a name when declaring a #{method_symbol} resource" unless args.size > 0 - - # If we have a resource like this one, we want to steal its state - args << run_context - resource = resource_class.new(*args) - resource.source_line = caller[0] - resource.load_prior_resource - resource.cookbook_name = cookbook_name - resource.recipe_name = @recipe_name - resource.params = @params - # Determine whether this resource is being created in the context of an enclosing Provider - resource.enclosing_provider = self.is_a?(Chef::Provider) ? self : nil - # Evaluate resource attribute DSL - resource.instance_eval(&block) if block - - # Run optional resource hook - resource.after_created - - run_context.resource_collection.insert(resource) - resource + declare_resource(method_symbol, args[0], caller[0], &block) end end + def has_resource_definition?(name) + yes_or_no = run_context.definitions.has_key?(name) + + yes_or_no + end + + # Processes the arguments and block as a resource definition. + def evaluate_resource_definition(definition_name, *args, &block) + + # This dupes the high level object, but we still need to dup the params + new_def = run_context.definitions[definition_name].dup + + new_def.params = new_def.params.dup + new_def.node = run_context.node + # This sets up the parameter overrides + new_def.instance_eval(&block) if block + + + new_recipe = Chef::Recipe.new(cookbook_name, recipe_name, run_context) + new_recipe.params = new_def.params + new_recipe.params[:name] = args[0] + new_recipe.instance_eval(&new_def.recipe) + new_recipe + end + + # Instantiates a resource (via #build_resource), then adds it to the + # resource collection. Note that resource classes are looked up directly, + # so this will create the resource you intended even if the method name + # corresponding to that resource has been overridden. + def declare_resource(type, name, created_at=nil, &resource_attrs_block) + created_at ||= caller[0] + + resource = build_resource(type, name, created_at, &resource_attrs_block) + + run_context.resource_collection.insert(resource) + resource + end + + # Instantiate a resource of the given +type+ with the given +name+ and + # attributes as given in the +resource_attrs_block+. + # + # The resource is NOT added to the resource collection. + def build_resource(type, name, created_at=nil, &resource_attrs_block) + created_at ||= caller[0] + + # Checks the new platform => short_name => resource mapping initially + # then fall back to the older approach (Chef::Resource.const_get) for + # backward compatibility + resource_class = resource_class_for(type) + + super unless resource_class + raise ArgumentError, "You must supply a name when declaring a #{type} resource" if name.nil? + + resource = resource_class.new(name, run_context) + resource.source_line = created_at + resource.cookbook_name = cookbook_name + resource.recipe_name = recipe_name + # If we have a resource like this one, we want to steal its state + # This behavior is very counter-intuitive and should be removed. + # See CHEF-3694, https://tickets.opscode.com/browse/CHEF-3694 + resource.load_prior_resource + # Determine whether this resource is being created in the context of an enclosing Provider + resource.enclosing_provider = self.is_a?(Chef::Provider) ? self : nil + + # XXX: This is very crufty, but it's required for resource definitions + # to work properly :( + resource.params = @params + + # Evaluate resource attribute DSL + resource.instance_eval(&resource_attrs_block) if block_given? + + # Run optional resource hook + resource.after_created + + resource + end + + def resource_class_for(snake_case_name) + Chef::Resource.resource_for_node(snake_case_name, run_context.node) + end + end end end |