Module: Chef::DSL::Recipe

Includes:
Mixin::ConvertToClassName, Mixin::ShellOut
Included in:
Provider::Deploy, Provider::LWRPBase, Recipe
Defined in:
lib/chef/dsl/recipe.rb

Overview

Chef::DSL::Recipe

Provides the primary recipe DSL functionality for defining Chef resource objects via method calls.

Constant Summary

Constants included from Mixin::ShellOut

Mixin::ShellOut::DEPRECATED_OPTIONS

Instance Method Summary collapse

Methods included from Mixin::ConvertToClassName

#constantize, #convert_to_class_name, #convert_to_snake_case, #filename_to_qualified_string, #snake_case_basename

Methods included from Mixin::ShellOut

#run_command_compatible_options, #shell_out, #shell_out!, #shell_out_with_systems_locale, #shell_out_with_systems_locale!

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_symbol, *args, &block) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/chef/dsl/recipe.rb', line 36

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 has_resource_definition?(method_symbol)
    evaluate_resource_definition(method_symbol, *args, &block)
  elsif have_resource_class_for?(method_symbol)
    # Otherwise, we're rocking the regular resource call route.
    declare_resource(method_symbol, args[0], caller[0], &block)
  else
    begin
      super
    rescue NoMethodError
      raise NoMethodError, "No resource or method named `#{method_symbol}' for #{describe_self_for_error}"
    rescue NameError
      raise NameError, "No resource, method, or local variable named `#{method_symbol}' for #{describe_self_for_error}"
    end
  end
end

Instance Method Details

#build_resource(type, name, created_at = nil, &resource_attrs_block) ⇒ Chef::Resource

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.

Examples:

build_resource(:file, '/x/y.txy', caller[0]) do
  action :delete
end

Parameters:

  • type (Symbol)

    The type of resource (e.g. :file or :package)

  • name (String)

    The name of the resource (e.g. ‘/x/y.txt’ or ‘apache2’)

  • created_at (String) (defaults to: nil)

    The caller of the resource. Use caller[0] to get the caller of your function. Defaults to the caller of this function.

  • resource_attrs_block

    A block that lets you set attributes of the resource (it is instance_eval’d on the resource instance).

Returns:



132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/chef/dsl/recipe.rb', line 132

def build_resource(type, name, created_at=nil, &resource_attrs_block)
  created_at ||= caller[0]

  Chef::ResourceBuilder.new(
    type:                type,
    name:                name,
    created_at:          created_at,
    params:              @params,
    run_context:         run_context,
    cookbook_name:       cookbook_name,
    recipe_name:         recipe_name,
    enclosing_provider:  self.is_a?(Chef::Provider) ? self :  nil
  ).build(&resource_attrs_block)
end

#declare_resource(type, name, created_at = nil, &resource_attrs_block) ⇒ Chef::Resource

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.

Examples:

declare_resource(:file, '/x/y.txy', caller[0]) do
  action :delete
end
# Equivalent to
file '/x/y.txt' do
  action :delete
end

Parameters:

  • type (Symbol)

    The type of resource (e.g. :file or :package)

  • name (String)

    The name of the resource (e.g. ‘/x/y.txt’ or ‘apache2’)

  • created_at (String) (defaults to: nil)

    The caller of the resource. Use caller[0] to get the caller of your function. Defaults to the caller of this function.

  • resource_attrs_block

    A block that lets you set attributes of the resource (it is instance_eval’d on the resource instance).

Returns:



102
103
104
105
106
107
108
109
# File 'lib/chef/dsl/recipe.rb', line 102

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_type: type, instance_name: name)
  resource
end

#describe_self_for_errorObject



157
158
159
160
161
162
163
164
165
# File 'lib/chef/dsl/recipe.rb', line 157

def describe_self_for_error
  if respond_to?(:name)
    %Q[`#{self.class.name} "#{name}"']
  elsif respond_to?(:recipe_name)
    %Q[`#{self.class.name} "#{recipe_name}"']
  else
    to_s
  end
end

#evaluate_resource_definition(definition_name, *args, &block) ⇒ Object

Processes the arguments and block as a resource definition.



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/chef/dsl/recipe.rb', line 61

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)
end

#exec(args) ⇒ Object



167
168
169
# File 'lib/chef/dsl/recipe.rb', line 167

def exec(args)
  raise Chef::Exceptions::ResourceNotFound, "exec was called, but you probably meant to use an execute resource.  If not, please call Kernel#exec explicitly.  The exec block called was \"#{args}\""
end

#has_resource_definition?(name) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/chef/dsl/recipe.rb', line 56

def has_resource_definition?(name)
  run_context.definitions.has_key?(name)
end

#have_resource_class_for?(snake_case_name) ⇒ Boolean

Returns:

  • (Boolean)


151
152
153
154
155
# File 'lib/chef/dsl/recipe.rb', line 151

def have_resource_class_for?(snake_case_name)
  not resource_class_for(snake_case_name).nil?
rescue NameError
  false
end

#resource_class_for(snake_case_name) ⇒ Object



147
148
149
# File 'lib/chef/dsl/recipe.rb', line 147

def resource_class_for(snake_case_name)
  Chef::Resource.resource_for_node(snake_case_name, run_context.node)
end